diff options
706 files changed, 59632 insertions, 21331 deletions
diff --git a/.clang-format b/.clang-format index ca411edd..0ff68114 100644 --- a/.clang-format +++ b/.clang-format | |||
| @@ -4,7 +4,7 @@ TabWidth: 4 | |||
| 4 | AllowShortIfStatementsOnASingleLine: false | 4 | AllowShortIfStatementsOnASingleLine: false |
| 5 | BreakBeforeBraces: Attach | 5 | BreakBeforeBraces: Attach |
| 6 | AlignConsecutiveMacros: true | 6 | AlignConsecutiveMacros: true |
| 7 | ColumnLimit: 140 | 7 | ColumnLimit: 100 |
| 8 | IndentPPDirectives: AfterHash | 8 | IndentPPDirectives: AfterHash |
| 9 | SortIncludes: Never | 9 | SortIncludes: Never |
| 10 | AllowShortEnumsOnASingleLine: false | 10 | AllowShortEnumsOnASingleLine: false |
diff --git a/.github/monitoring-plugins.spec b/.github/monitoring-plugins.spec index 64ee34f2..e3465227 100644 --- a/.github/monitoring-plugins.spec +++ b/.github/monitoring-plugins.spec | |||
| @@ -88,6 +88,9 @@ BuildRequires: postgresql-devel | |||
| 88 | # check_radius | 88 | # check_radius |
| 89 | BuildRequires: radcli-devel | 89 | BuildRequires: radcli-devel |
| 90 | 90 | ||
| 91 | # check_snmp | ||
| 92 | BuildRequires: net-snmp-devel | ||
| 93 | |||
| 91 | %description | 94 | %description |
| 92 | Common files for Monitoring Plugins | 95 | Common files for Monitoring Plugins |
| 93 | 96 | ||
| @@ -191,7 +194,6 @@ Requires: %{name}-nt | |||
| 191 | Requires: %{name}-ntp | 194 | Requires: %{name}-ntp |
| 192 | Requires: %{name}-ntp_peer | 195 | Requires: %{name}-ntp_peer |
| 193 | Requires: %{name}-ntp_time | 196 | Requires: %{name}-ntp_time |
| 194 | Requires: %{name}-nwstat | ||
| 195 | Requires: %{name}-oracle | 197 | Requires: %{name}-oracle |
| 196 | Requires: %{name}-pgsql | 198 | Requires: %{name}-pgsql |
| 197 | Requires: %{name}-ping | 199 | Requires: %{name}-ping |
| @@ -650,32 +652,6 @@ Provides check_nagios of the Monitoring Plugins. | |||
| 650 | 652 | ||
| 651 | 653 | ||
| 652 | 654 | ||
| 653 | # check_nt | ||
| 654 | %package nt | ||
| 655 | Summary: Monitoring Plugins - check_nt | ||
| 656 | Requires: %{name} = %{version}-%{release} | ||
| 657 | |||
| 658 | %description nt | ||
| 659 | Provides check_nt of the Monitoring Plugins. | ||
| 660 | |||
| 661 | %files nt | ||
| 662 | %{plugindir}/check_nt | ||
| 663 | |||
| 664 | |||
| 665 | |||
| 666 | # check_ntp | ||
| 667 | %package ntp | ||
| 668 | Summary: Monitoring Plugins - check_ntp | ||
| 669 | Requires: %{name} = %{version}-%{release} | ||
| 670 | |||
| 671 | %description ntp | ||
| 672 | Provides check_ntp of the Monitoring Plugins. | ||
| 673 | |||
| 674 | %files ntp | ||
| 675 | %{plugindir}/check_ntp | ||
| 676 | |||
| 677 | |||
| 678 | |||
| 679 | # check_ntp_peer | 655 | # check_ntp_peer |
| 680 | %package ntp_peer | 656 | %package ntp_peer |
| 681 | Summary: Monitoring Plugins - check_ntp_peer | 657 | Summary: Monitoring Plugins - check_ntp_peer |
| @@ -702,19 +678,6 @@ Provides check_ntp_time of the Monitoring Plugins. | |||
| 702 | 678 | ||
| 703 | 679 | ||
| 704 | 680 | ||
| 705 | # check_nwstat | ||
| 706 | %package nwstat | ||
| 707 | Summary: Monitoring Plugins - check_nwstat | ||
| 708 | Requires: %{name} = %{version}-%{release} | ||
| 709 | |||
| 710 | %description nwstat | ||
| 711 | Provides check_nwstat of the Monitoring Plugins. | ||
| 712 | |||
| 713 | %files nwstat | ||
| 714 | %{plugindir}/check_nwstat | ||
| 715 | |||
| 716 | |||
| 717 | |||
| 718 | # check_oracle | 681 | # check_oracle |
| 719 | %package oracle | 682 | %package oracle |
| 720 | Summary: Monitoring Plugins - check_oracle | 683 | Summary: Monitoring Plugins - check_oracle |
| @@ -959,3 +922,7 @@ Provides check_wave of the Monitoring Plugins. | |||
| 959 | 922 | ||
| 960 | %files wave | 923 | %files wave |
| 961 | %{plugindir}/check_wave | 924 | %{plugindir}/check_wave |
| 925 | |||
| 926 | %changelog | ||
| 927 | * Wed Oct 20 2011 John Doe <jdoe@example.com> 0.8.18.1-0.1 | ||
| 928 | - Initial RPM release | ||
diff --git a/.github/os_detect.sh b/.github/os_detect.sh index ee9c145d..3c5956de 100644 --- a/.github/os_detect.sh +++ b/.github/os_detect.sh | |||
| @@ -1,10 +1,17 @@ | |||
| 1 | #!/bin/sh -e | 1 | #!/bin/sh -e |
| 2 | |||
| 3 | . /etc/os-release | ||
| 4 | |||
| 2 | # workaround for really bare-bones Archlinux containers: | 5 | # workaround for really bare-bones Archlinux containers: |
| 3 | if [ -x "$(command -v pacman)" ]; then | 6 | if [ -x "$(command -v pacman)" ]; then |
| 4 | pacman --noconfirm -Sy | 7 | pacman --noconfirm -Sy |
| 5 | pacman --noconfirm -S grep gawk sed | 8 | pacman --noconfirm -S grep gawk sed |
| 6 | fi | 9 | fi |
| 7 | 10 | ||
| 11 | if [ ${ID} == "fedora" -a ${VERSION_ID} -gt 41 ]; then | ||
| 12 | dnf install -y gawk | ||
| 13 | fi | ||
| 14 | |||
| 8 | os_release_file= | 15 | os_release_file= |
| 9 | if [ -s "/etc/os-release" ]; then | 16 | if [ -s "/etc/os-release" ]; then |
| 10 | os_release_file="/etc/os-release" | 17 | os_release_file="/etc/os-release" |
| @@ -15,4 +22,7 @@ else | |||
| 15 | return 1 | 22 | return 1 |
| 16 | fi | 23 | fi |
| 17 | export distro_id=$(grep '^ID=' $os_release_file|awk -F = '{print $2}'|sed 's/\"//g') | 24 | export distro_id=$(grep '^ID=' $os_release_file|awk -F = '{print $2}'|sed 's/\"//g') |
| 25 | export version_id=$(grep '^VERSION_ID=' $os_release_file|awk -F = '{print $2}'|sed 's/\"//g') | ||
| 18 | export platform_id=$(grep '^PLATFORM_ID=' /etc/os-release|awk -F = '{print $2}'|sed 's/\"//g'| cut -d":" -f2) | 26 | export platform_id=$(grep '^PLATFORM_ID=' /etc/os-release|awk -F = '{print $2}'|sed 's/\"//g'| cut -d":" -f2) |
| 27 | # Fedora dropped PLATFORM_ID: https://fedoraproject.org/wiki/Changes/Drop_PLATFORM_ID?#Drop_PLATFORM_ID | ||
| 28 | if [ -z $platform_id ]; then export platform_id=$(echo ${distro_id:0:1}${version_id}); fi | ||
diff --git a/.github/prepare_debian.sh b/.github/prepare_debian.sh index f7b6cf9f..cffe98c5 100755 --- a/.github/prepare_debian.sh +++ b/.github/prepare_debian.sh | |||
| @@ -24,6 +24,7 @@ apt-get -y install perl \ | |||
| 24 | libpq-dev \ | 24 | libpq-dev \ |
| 25 | libradcli-dev \ | 25 | libradcli-dev \ |
| 26 | libnet-snmp-perl \ | 26 | libnet-snmp-perl \ |
| 27 | libsnmp-dev \ | ||
| 27 | procps \ | 28 | procps \ |
| 28 | libdbi0-dev \ | 29 | libdbi0-dev \ |
| 29 | libdbd-sqlite3 \ | 30 | libdbd-sqlite3 \ |
| @@ -111,6 +112,8 @@ mkdir -p /var/lib/snmp/mib_indexes | |||
| 111 | sed -e 's/^agentaddress.*/agentaddress 127.0.0.1/' -i /etc/snmp/snmpd.conf | 112 | sed -e 's/^agentaddress.*/agentaddress 127.0.0.1/' -i /etc/snmp/snmpd.conf |
| 112 | service snmpd start | 113 | service snmpd start |
| 113 | 114 | ||
| 115 | sed 's/^mibs ://' -i /etc/snmp/snmp.conf | ||
| 116 | |||
| 114 | # start cron, will be used by check_nagios | 117 | # start cron, will be used by check_nagios |
| 115 | cron | 118 | cron |
| 116 | 119 | ||
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c402e0cf..bd1037f4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | name: "CodeQL" | 13 | name: "CodeQL" |
| 14 | 14 | ||
| 15 | on: | 15 | on: |
| 16 | workflow_dispatch: {} | ||
| 16 | push: | 17 | push: |
| 17 | branches: [master] | 18 | branches: [master] |
| 18 | pull_request: | 19 | pull_request: |
| @@ -40,11 +41,11 @@ jobs: | |||
| 40 | 41 | ||
| 41 | steps: | 42 | steps: |
| 42 | - name: Checkout repository | 43 | - name: Checkout repository |
| 43 | uses: actions/checkout@v4 | 44 | uses: actions/checkout@v6 |
| 44 | 45 | ||
| 45 | # Initializes the CodeQL tools for scanning. | 46 | # Initializes the CodeQL tools for scanning. |
| 46 | - name: Initialize CodeQL | 47 | - name: Initialize CodeQL |
| 47 | uses: github/codeql-action/init@v3 | 48 | uses: github/codeql-action/init@v4 |
| 48 | with: | 49 | with: |
| 49 | languages: ${{ matrix.language }} | 50 | languages: ${{ matrix.language }} |
| 50 | # If you wish to specify custom queries, you can do so here or in a config file. | 51 | # If you wish to specify custom queries, you can do so here or in a config file. |
| @@ -56,9 +57,20 @@ jobs: | |||
| 56 | run: | | 57 | run: | |
| 57 | sudo apt update | 58 | sudo apt update |
| 58 | sudo apt-get install -y --no-install-recommends m4 gettext automake autoconf make build-essential | 59 | sudo apt-get install -y --no-install-recommends m4 gettext automake autoconf make build-essential |
| 59 | sudo apt-get install -y --no-install-recommends perl autotools-dev libdbi-dev libldap2-dev libpq-dev \ | 60 | sudo apt-get install -y --no-install-recommends perl \ |
| 60 | libmysqlclient-dev libradcli-dev libkrb5-dev libdbi0-dev \ | 61 | autotools-dev \ |
| 61 | libdbd-sqlite3 libssl-dev libcurl4-openssl-dev liburiparser-dev | 62 | libdbi-dev \ |
| 63 | libldap2-dev \ | ||
| 64 | libpq-dev \ | ||
| 65 | libmysqlclient-dev \ | ||
| 66 | libradcli-dev \ | ||
| 67 | libkrb5-dev \ | ||
| 68 | libdbi0-dev \ | ||
| 69 | libdbd-sqlite3 \ | ||
| 70 | libssl-dev \ | ||
| 71 | libcurl4-openssl-dev \ | ||
| 72 | liburiparser-dev \ | ||
| 73 | libsnmp-dev | ||
| 62 | 74 | ||
| 63 | - name: Configure build | 75 | - name: Configure build |
| 64 | run: | | 76 | run: | |
| @@ -70,4 +82,4 @@ jobs: | |||
| 70 | make | 82 | make |
| 71 | 83 | ||
| 72 | - name: Perform CodeQL Analysis | 84 | - name: Perform CodeQL Analysis |
| 73 | uses: github/codeql-action/analyze@v3 | 85 | uses: github/codeql-action/analyze@v4 |
diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml index 72f7c7eb..f19cc920 100644 --- a/.github/workflows/spellcheck.yml +++ b/.github/workflows/spellcheck.yml | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | name: Spellcheck | 2 | name: Spellcheck |
| 3 | 3 | ||
| 4 | on: | 4 | on: |
| 5 | workflow_dispatch: {} | ||
| 5 | # Run for pushes on any branch | 6 | # Run for pushes on any branch |
| 6 | push: | 7 | push: |
| 7 | branches: | 8 | branches: |
| @@ -17,7 +18,7 @@ jobs: | |||
| 17 | runs-on: ubuntu-latest | 18 | runs-on: ubuntu-latest |
| 18 | steps: | 19 | steps: |
| 19 | - name: Checkout | 20 | - name: Checkout |
| 20 | uses: actions/checkout@v4 | 21 | uses: actions/checkout@v6 |
| 21 | - name: Codespell | 22 | - name: Codespell |
| 22 | uses: codespell-project/actions-codespell@v2 | 23 | uses: codespell-project/actions-codespell@v2 |
| 23 | with: | 24 | with: |
diff --git a/.github/workflows/test-next.yml b/.github/workflows/test-next.yml index 81240759..a7e9b9d6 100644 --- a/.github/workflows/test-next.yml +++ b/.github/workflows/test-next.yml | |||
| @@ -2,7 +2,13 @@ | |||
| 2 | name: Tests Debian:Testing and Fedora:Rawhide | 2 | name: Tests Debian:Testing and Fedora:Rawhide |
| 3 | 3 | ||
| 4 | on: | 4 | on: |
| 5 | workflow_dispatch: {} | 5 | workflow_dispatch: |
| 6 | inputs: | ||
| 7 | debug_enabled: | ||
| 8 | type: boolean | ||
| 9 | description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)' | ||
| 10 | required: false | ||
| 11 | default: false | ||
| 6 | push: | 12 | push: |
| 7 | branches-ignore: | 13 | branches-ignore: |
| 8 | - '*' | 14 | - '*' |
| @@ -24,7 +30,10 @@ jobs: | |||
| 24 | prepare: .github/prepare_debian.sh | 30 | prepare: .github/prepare_debian.sh |
| 25 | steps: | 31 | steps: |
| 26 | - name: Git clone repository | 32 | - name: Git clone repository |
| 27 | uses: actions/checkout@v4 | 33 | uses: actions/checkout@v6 |
| 34 | - name: Setup tmate session, see https://github.com/marketplace/actions/debugging-with-tmate | ||
| 35 | uses: mxschmitt/action-tmate@v3 | ||
| 36 | if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} | ||
| 28 | - name: Run the tests on ${{ matrix.distro }} | 37 | - name: Run the tests on ${{ matrix.distro }} |
| 29 | run: | | 38 | run: | |
| 30 | docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol | 39 | docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol |
| @@ -38,7 +47,7 @@ jobs: | |||
| 38 | ${{ matrix.distro }} \ | 47 | ${{ matrix.distro }} \ |
| 39 | /bin/sh -c '${{ matrix.prepare }} && \ | 48 | /bin/sh -c '${{ matrix.prepare }} && \ |
| 40 | tools/setup && \ | 49 | tools/setup && \ |
| 41 | ./configure --enable-libtap --with-ipv6=no && \ | 50 | ./configure --enable-libtap && \ |
| 42 | make && \ | 51 | make && \ |
| 43 | make test && \ | 52 | make test && \ |
| 44 | make dist && \ | 53 | make dist && \ |
| @@ -59,7 +68,10 @@ jobs: | |||
| 59 | - {"distro": "fedora:rawhide", "build": ".github/mock.sh"} | 68 | - {"distro": "fedora:rawhide", "build": ".github/mock.sh"} |
| 60 | steps: | 69 | steps: |
| 61 | - name: Git clone repository | 70 | - name: Git clone repository |
| 62 | uses: actions/checkout@v4 | 71 | uses: actions/checkout@v6 |
| 72 | - name: Setup tmate session, see https://github.com/marketplace/actions/debugging-with-tmate | ||
| 73 | uses: mxschmitt/action-tmate@v3 | ||
| 74 | if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} | ||
| 63 | - name: Run the tests on ${{ matrix.distro }} | 75 | - name: Run the tests on ${{ matrix.distro }} |
| 64 | run: | | 76 | run: | |
| 65 | docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol | 77 | docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol |
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 77ca6585..5a0b2943 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml | |||
| @@ -2,6 +2,13 @@ | |||
| 2 | name: Tests | 2 | name: Tests |
| 3 | 3 | ||
| 4 | on: | 4 | on: |
| 5 | workflow_dispatch: | ||
| 6 | inputs: | ||
| 7 | debug_enabled: | ||
| 8 | type: boolean | ||
| 9 | description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)' | ||
| 10 | required: false | ||
| 11 | default: false | ||
| 5 | push: | 12 | push: |
| 6 | branches: | 13 | branches: |
| 7 | - '*' | 14 | - '*' |
| @@ -21,7 +28,10 @@ jobs: | |||
| 21 | prepare: .github/prepare_debian.sh | 28 | prepare: .github/prepare_debian.sh |
| 22 | steps: | 29 | steps: |
| 23 | - name: Git clone repository | 30 | - name: Git clone repository |
| 24 | uses: actions/checkout@v4 | 31 | uses: actions/checkout@v6 |
| 32 | - name: Setup tmate session, see https://github.com/marketplace/actions/debugging-with-tmate | ||
| 33 | uses: mxschmitt/action-tmate@v3 | ||
| 34 | if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} | ||
| 25 | - name: Run the tests on ${{ matrix.distro }} | 35 | - name: Run the tests on ${{ matrix.distro }} |
| 26 | run: | | 36 | run: | |
| 27 | docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol | 37 | docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol |
| @@ -35,7 +45,7 @@ jobs: | |||
| 35 | ${{ matrix.distro }} \ | 45 | ${{ matrix.distro }} \ |
| 36 | /bin/sh -c '${{ matrix.prepare }} && \ | 46 | /bin/sh -c '${{ matrix.prepare }} && \ |
| 37 | tools/setup && \ | 47 | tools/setup && \ |
| 38 | ./configure --enable-libtap --with-ipv6=no && \ | 48 | ./configure --enable-libtap && \ |
| 39 | make && \ | 49 | make && \ |
| 40 | make test && \ | 50 | make test && \ |
| 41 | make dist && \ | 51 | make dist && \ |
| @@ -59,7 +69,10 @@ jobs: | |||
| 59 | # - {"distro": "oraclelinux:9", "build": ".github/mock.sh"} | 69 | # - {"distro": "oraclelinux:9", "build": ".github/mock.sh"} |
| 60 | steps: | 70 | steps: |
| 61 | - name: Git clone repository | 71 | - name: Git clone repository |
| 62 | uses: actions/checkout@v4 | 72 | uses: actions/checkout@v6 |
| 73 | - name: Setup tmate session, see https://github.com/marketplace/actions/debugging-with-tmate | ||
| 74 | uses: mxschmitt/action-tmate@v3 | ||
| 75 | if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} | ||
| 63 | - name: Run the tests on ${{ matrix.distro }} | 76 | - name: Run the tests on ${{ matrix.distro }} |
| 64 | run: | | 77 | run: | |
| 65 | docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol | 78 | docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=size=100m,uid=1000 tmp-vol |
| @@ -114,7 +114,6 @@ NP-VERSION-FILE | |||
| 114 | /lib/tests/Makefile.in | 114 | /lib/tests/Makefile.in |
| 115 | /lib/tests/test_base64 | 115 | /lib/tests/test_base64 |
| 116 | /lib/tests/test_cmd | 116 | /lib/tests/test_cmd |
| 117 | /lib/tests/test_disk | ||
| 118 | /lib/tests/test_tcp | 117 | /lib/tests/test_tcp |
| 119 | /lib/tests/test_utils | 118 | /lib/tests/test_utils |
| 120 | /lib/tests/utils_base.Po | 119 | /lib/tests/utils_base.Po |
| @@ -153,6 +152,8 @@ NP-VERSION-FILE | |||
| 153 | /plugins/check_dbi | 152 | /plugins/check_dbi |
| 154 | /plugins/check_dig | 153 | /plugins/check_dig |
| 155 | /plugins/check_disk | 154 | /plugins/check_disk |
| 155 | plugins/check_disk.d/.deps/ | ||
| 156 | plugins/check_disk.d/.dirstamp | ||
| 156 | /plugins/check_dns | 157 | /plugins/check_dns |
| 157 | /plugins/check_dummy | 158 | /plugins/check_dummy |
| 158 | /plugins/check_fping | 159 | /plugins/check_fping |
| @@ -173,11 +174,8 @@ NP-VERSION-FILE | |||
| 173 | /plugins/check_netsaint | 174 | /plugins/check_netsaint |
| 174 | /plugins/check_nntp | 175 | /plugins/check_nntp |
| 175 | /plugins/check_nntps | 176 | /plugins/check_nntps |
| 176 | /plugins/check_nt | ||
| 177 | /plugins/check_ntp | ||
| 178 | /plugins/check_ntp_peer | 177 | /plugins/check_ntp_peer |
| 179 | /plugins/check_ntp_time | 178 | /plugins/check_ntp_time |
| 180 | /plugins/check_nwstat | ||
| 181 | /plugins/check_pgsql | 179 | /plugins/check_pgsql |
| 182 | /plugins/check_ping | 180 | /plugins/check_ping |
| 183 | /plugins/check_pop | 181 | /plugins/check_pop |
| @@ -197,6 +195,8 @@ NP-VERSION-FILE | |||
| 197 | /plugins/check_udp | 195 | /plugins/check_udp |
| 198 | /plugins/check_ups | 196 | /plugins/check_ups |
| 199 | /plugins/check_users | 197 | /plugins/check_users |
| 198 | /plugins/check_users.d/.deps | ||
| 199 | /plugins/check_users.d/.dirstamp | ||
| 200 | /plugins/check_vsz | 200 | /plugins/check_vsz |
| 201 | /plugins/config.h | 201 | /plugins/config.h |
| 202 | /plugins/config.h.in | 202 | /plugins/config.h.in |
| @@ -222,7 +222,7 @@ NP-VERSION-FILE | |||
| 222 | /plugins/tests/Makefile | 222 | /plugins/tests/Makefile |
| 223 | /plugins/tests/Makefile.in | 223 | /plugins/tests/Makefile.in |
| 224 | /plugins/tests/test_utils | 224 | /plugins/tests/test_utils |
| 225 | /plugins/tests/test_disk | 225 | /plugins/tests/test_check_disk |
| 226 | /plugins/tests/test_check_swap | 226 | /plugins/tests/test_check_swap |
| 227 | /plugins/tests/.deps | 227 | /plugins/tests/.deps |
| 228 | /plugins/tests/.dirstamp | 228 | /plugins/tests/.dirstamp |
| @@ -231,6 +231,14 @@ NP-VERSION-FILE | |||
| 231 | /plugins/check_swap.d/.deps | 231 | /plugins/check_swap.d/.deps |
| 232 | /plugins/check_swap.d/.dirstamp | 232 | /plugins/check_swap.d/.dirstamp |
| 233 | 233 | ||
| 234 | # /plugins/check_snmp.d | ||
| 235 | /plugins/check_snmp.d/.deps | ||
| 236 | /plugins/check_snmp.d/.dirstamp | ||
| 237 | |||
| 238 | # /plugins/check_curl.d | ||
| 239 | /plugins/check_curl.d/.deps | ||
| 240 | /plugins/check_curl.d/.dirstamp | ||
| 241 | |||
| 234 | # /plugins-root/ | 242 | # /plugins-root/ |
| 235 | /plugins-root/.deps | 243 | /plugins-root/.deps |
| 236 | /plugins-root/.libs | 244 | /plugins-root/.libs |
| @@ -239,6 +247,8 @@ NP-VERSION-FILE | |||
| 239 | /plugins-root/check_dhcp | 247 | /plugins-root/check_dhcp |
| 240 | /plugins-root/check_icmp | 248 | /plugins-root/check_icmp |
| 241 | /plugins-root/pst3 | 249 | /plugins-root/pst3 |
| 250 | /plugins-root/check_icmp.d/.dirstamp | ||
| 251 | /plugins-root/check_icmp.d/.deps | ||
| 242 | 252 | ||
| 243 | # /plugins-scripts/ | 253 | # /plugins-scripts/ |
| 244 | /plugins-scripts/Makefile | 254 | /plugins-scripts/Makefile |
diff --git a/REQUIREMENTS b/REQUIREMENTS index f3b1c01d..8f1befbd 100644 --- a/REQUIREMENTS +++ b/REQUIREMENTS | |||
| @@ -26,7 +26,7 @@ check_curl: | |||
| 26 | other SSL implementations are currently not supported | 26 | other SSL implementations are currently not supported |
| 27 | - uriparser 0.7.5 or later | 27 | - uriparser 0.7.5 or later |
| 28 | https://uriparser.github.io/ | 28 | https://uriparser.github.io/ |
| 29 | 29 | ||
| 30 | check_fping: | 30 | check_fping: |
| 31 | - Requires the fping utility distributed with SATAN. Either | 31 | - Requires the fping utility distributed with SATAN. Either |
| 32 | download and install SATAN or grab the fping program from | 32 | download and install SATAN or grab the fping program from |
| @@ -87,20 +87,12 @@ check_ifstatus/check_ifoperstatus | |||
| 87 | - Requires Net::SNMP perl module | 87 | - Requires Net::SNMP perl module |
| 88 | http://www.perl.com/CPAN/modules/by-authors/id/D/DT/DTOWN/ | 88 | http://www.perl.com/CPAN/modules/by-authors/id/D/DT/DTOWN/ |
| 89 | 89 | ||
| 90 | check_nwstat: | ||
| 91 | - Requires MRTGEXT NLM for Novell Servers | ||
| 92 | http://forge.novell.com/modules/xfmod/project/?mrtgext | ||
| 93 | |||
| 94 | check_nt: | ||
| 95 | - Requires NSClient to run on the NT server to monitor | ||
| 96 | http://nsclient.ready2run.nl/ | ||
| 97 | |||
| 98 | check_ups: | 90 | check_ups: |
| 99 | - Requires Network UPS Tools (>= 1.4) to run on the server to monitor | 91 | - Requires Network UPS Tools (>= 1.4) to run on the server to monitor |
| 100 | http://www.networkupstools.org/ | 92 | http://www.networkupstools.org/ |
| 101 | 93 | ||
| 102 | check_ide_smart: | 94 | check_ide_smart: |
| 103 | - Uses the Linux specific SMART interface [http://smartlinux.sourceforge.net/smart/index.php]. | 95 | - Uses the Linux specific SMART interface [http://smartlinux.sourceforge.net/smart/index.php]. |
| 104 | 96 | ||
| 105 | OS Specific Issues | 97 | OS Specific Issues |
| 106 | ------------------ | 98 | ------------------ |
| @@ -426,3 +426,4 @@ Eunice Remoquillo | |||
| 426 | Louis Sautier | 426 | Louis Sautier |
| 427 | Sven Hartge | 427 | Sven Hartge |
| 428 | Alvar Penning | 428 | Alvar Penning |
| 429 | Michael Jeanson | ||
diff --git a/configure.ac b/configure.ac index 204fc6e3..abd90413 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -181,10 +181,10 @@ fi | |||
| 181 | 181 | ||
| 182 | # Finally, define tests if we use libtap | 182 | # Finally, define tests if we use libtap |
| 183 | if test "$enable_libtap" = "yes" ; then | 183 | if test "$enable_libtap" = "yes" ; then |
| 184 | EXTRA_TEST="test_utils test_disk test_tcp test_cmd test_base64" | 184 | EXTRA_TEST="test_utils test_tcp test_cmd test_base64" |
| 185 | AC_SUBST(EXTRA_TEST) | 185 | AC_SUBST(EXTRA_TEST) |
| 186 | 186 | ||
| 187 | EXTRA_PLUGIN_TESTS="tests/test_check_swap" | 187 | EXTRA_PLUGIN_TESTS="tests/test_check_swap tests/test_check_disk" |
| 188 | AC_SUBST(EXTRA_PLUGIN_TESTS) | 188 | AC_SUBST(EXTRA_PLUGIN_TESTS) |
| 189 | fi | 189 | fi |
| 190 | 190 | ||
| @@ -205,32 +205,46 @@ fi | |||
| 205 | dnl Check for PostgreSQL libraries | 205 | dnl Check for PostgreSQL libraries |
| 206 | _SAVEDLIBS="$LIBS" | 206 | _SAVEDLIBS="$LIBS" |
| 207 | _SAVEDCPPFLAGS="$CPPFLAGS" | 207 | _SAVEDCPPFLAGS="$CPPFLAGS" |
| 208 | case $host in | ||
| 209 | *openbsd*) | ||
| 210 | _CRYPTLIB="crypto" | ||
| 211 | ;; | ||
| 212 | *) | ||
| 213 | _CRYPTLIB="crypt" | ||
| 214 | esac | ||
| 215 | |||
| 208 | AC_ARG_WITH(pgsql, | 216 | AC_ARG_WITH(pgsql, |
| 209 | ACX_HELP_STRING([--with-pgsql=DIR], | 217 | ACX_HELP_STRING([--with-pgsql=DIR], |
| 210 | [sets path to pgsql installation]), | 218 | [sets path to pgsql installation]), |
| 211 | PGSQL=$withval,) | 219 | PGSQL=$withval,) |
| 212 | AC_CHECK_LIB(crypt,main) | 220 | AC_CHECK_LIB(crypt,main) |
| 213 | if test "$ac_cv_lib_crypt_main" = "yes" -a "x$PGSQL" != "xno"; then | 221 | AC_CHECK_LIB(crypto,main) |
| 222 | if test \( "$ac_cv_lib_crypt_main" = "yes" -o "$ac_cv_lib_crypto_main" = "yes" \) -a "x$PGSQL" != "xno"; then | ||
| 214 | if test -n "$PGSQL"; then | 223 | if test -n "$PGSQL"; then |
| 215 | LDFLAGS="$LDFLAGS -L$PGSQL/lib" | 224 | LDFLAGS="$LDFLAGS -L$PGSQL/lib" |
| 216 | CPPFLAGS="$CPPFLAGS -I$PGSQL/include" | 225 | CPPFLAGS="$CPPFLAGS -I$PGSQL/include" |
| 217 | fi | 226 | fi |
| 218 | AC_CHECK_LIB(pq,PQsetdbLogin,,,-lcrypt) | 227 | AC_CHECK_LIB(pq,PQsetdbLogin,,,"-l$_CRYPTLIB") |
| 219 | if test "$ac_cv_lib_pq_PQsetdbLogin" = "yes"; then | 228 | if test "$ac_cv_lib_pq_PQsetdbLogin" = "yes"; then |
| 220 | AC_CHECK_HEADERS(pgsql/libpq-fe.h) | 229 | AC_CHECK_HEADERS(pgsql/libpq-fe.h) |
| 221 | AC_CHECK_HEADERS(postgresql/libpq-fe.h) | 230 | AC_CHECK_HEADERS(postgresql/libpq-fe.h) |
| 222 | AC_CHECK_HEADERS(libpq-fe.h) | 231 | AC_CHECK_HEADERS(libpq-fe.h) |
| 223 | if [[ -n "$PGSQL" -a "$ac_cv_header_libpq_fe_h" = "yes" ]]; then | 232 | if [[ -n "$PGSQL" -a "$ac_cv_header_libpq_fe_h" = "yes" ]]; then |
| 224 | PGLIBS="-L$PGSQL/lib -lpq -lcrypt" | 233 | PGLIBS="-L$PGSQL/lib -lpq -l$_CRYPTLIB" |
| 225 | PGINCLUDE="-I$PGSQL/include" | 234 | PGINCLUDE="-I$PGSQL/include" |
| 226 | elif test "$ac_cv_header_pgsql_libpq_fe_h" = "yes"; then | 235 | elif test "$ac_cv_header_pgsql_libpq_fe_h" = "yes"; then |
| 227 | PGLIBS="-lpq -lcrypt" | 236 | PGLIBS="-lpq -l$_CRYPTLIB" |
| 228 | PGINCLUDE="-I/usr/include/pgsql" | 237 | PGINCLUDE="-I/usr/include/pgsql" |
| 229 | elif test "$ac_cv_header_postgresql_libpq_fe_h" = "yes"; then | 238 | elif test "$ac_cv_header_postgresql_libpq_fe_h" = "yes"; then |
| 230 | PGLIBS="-L$PGSQL/lib -lpq -lcrypt" | 239 | PGLIBS="-L$PGSQL/lib -lpq -l$_CRYPTLIB" |
| 231 | PGINCLUDE="-I/usr/include/postgresql" | 240 | case $host in |
| 241 | *openbsd*) | ||
| 242 | PGINCLUDE="-I$PGSQL/include/postgresql" ;; | ||
| 243 | *) | ||
| 244 | PGINCLUDE="-I/usr/include/postgresql" | ||
| 245 | esac | ||
| 232 | elif test "$ac_cv_header_libpq_fe_h" = "yes"; then | 246 | elif test "$ac_cv_header_libpq_fe_h" = "yes"; then |
| 233 | PGLIBS="-L$PGSQL/lib -lpq -lcrypt" | 247 | PGLIBS="-L$PGSQL/lib -lpq -l$_CRYPTLIB" |
| 234 | PGINCLUDE="-I$PGSQL/include" | 248 | PGINCLUDE="-I$PGSQL/include" |
| 235 | fi | 249 | fi |
| 236 | if test -z "$PGINCLUDE"; then | 250 | if test -z "$PGINCLUDE"; then |
| @@ -796,7 +810,7 @@ elif ps axwo 'stat comm vsz rss user uid pid ppid etime args' 2>/dev/null | \ | |||
| 796 | then | 810 | then |
| 797 | ac_cv_ps_varlist="[procstat,&procuid,&procpid,&procppid,&procvsz,&procrss,&procpcpu,procetime,procprog,&pos]" | 811 | ac_cv_ps_varlist="[procstat,&procuid,&procpid,&procppid,&procvsz,&procrss,&procpcpu,procetime,procprog,&pos]" |
| 798 | ac_cv_ps_command="$PATH_TO_PS axwo 'stat uid pid ppid vsz rss pcpu etime comm args'" | 812 | ac_cv_ps_command="$PATH_TO_PS axwo 'stat uid pid ppid vsz rss pcpu etime comm args'" |
| 799 | ac_cv_ps_format="%s %d %d %d %d %d %f %s %s %n" | 813 | ac_cv_ps_format="%s %u %d %d %d %d %f %s %s %n" |
| 800 | ac_cv_ps_cols=10 | 814 | ac_cv_ps_cols=10 |
| 801 | AC_MSG_RESULT([$ac_cv_ps_command]) | 815 | AC_MSG_RESULT([$ac_cv_ps_command]) |
| 802 | 816 | ||
| @@ -1470,17 +1484,6 @@ AC_ARG_WITH(snmpgetnext_command, | |||
| 1470 | AS_IF([test -n "$PATH_TO_SNMPGET"], [ | 1484 | AS_IF([test -n "$PATH_TO_SNMPGET"], [ |
| 1471 | AC_DEFINE_UNQUOTED(PATH_TO_SNMPGET,"$PATH_TO_SNMPGET",[path to snmpget binary]) | 1485 | AC_DEFINE_UNQUOTED(PATH_TO_SNMPGET,"$PATH_TO_SNMPGET",[path to snmpget binary]) |
| 1472 | EXTRAS="$EXTRAS check_hpjd" | 1486 | EXTRAS="$EXTRAS check_hpjd" |
| 1473 | |||
| 1474 | dnl PATH_TO_SNMPGETNEXT is used unconditionally in check_snmp: | ||
| 1475 | dnl | ||
| 1476 | dnl https://github.com/nagios-plugins/nagios-plugins/issues/788 | ||
| 1477 | dnl | ||
| 1478 | AS_IF([test -n "$PATH_TO_SNMPGETNEXT"], [ | ||
| 1479 | AC_DEFINE_UNQUOTED(PATH_TO_SNMPGETNEXT,"$PATH_TO_SNMPGETNEXT",[path to snmpgetnext binary]) | ||
| 1480 | EXTRAS="$EXTRAS check_snmp\$(EXEEXT)" | ||
| 1481 | ], [ | ||
| 1482 | AC_MSG_WARN([Get snmpgetnext from https://net-snmp.sourceforge.io/ to build the check_snmp plugin]) | ||
| 1483 | ]) | ||
| 1484 | ], [ | 1487 | ], [ |
| 1485 | AC_MSG_WARN([Get snmpget from https://net-snmp.sourceforge.io/ to build the check_hpjd and check_snmp plugins]) | 1488 | AC_MSG_WARN([Get snmpget from https://net-snmp.sourceforge.io/ to build the check_hpjd and check_snmp plugins]) |
| 1486 | ]) | 1489 | ]) |
| @@ -1493,6 +1496,16 @@ else | |||
| 1493 | AC_MSG_WARN([Tried $PERL - install Net::SNMP perl module if you want to use the perl snmp plugins]) | 1496 | AC_MSG_WARN([Tried $PERL - install Net::SNMP perl module if you want to use the perl snmp plugins]) |
| 1494 | fi | 1497 | fi |
| 1495 | 1498 | ||
| 1499 | dnl Check whether DES encryption is available (might not on RHEL) | ||
| 1500 | AC_COMPILE_IFELSE( | ||
| 1501 | [AC_LANG_PROGRAM( | ||
| 1502 | [[#include <net-snmp/net-snmp-config.h> | ||
| 1503 | #include <net-snmp/net-snmp-includes.h>]], [[oid *foo = usmDESPrivProtocol;]] | ||
| 1504 | )], | ||
| 1505 | [AC_DEFINE(HAVE_USM_DES_PRIV_PROTOCOL,1,Define whether we have DES Privacy Protocol)], | ||
| 1506 | [] | ||
| 1507 | ) | ||
| 1508 | |||
| 1496 | AC_PATH_PROG(PATH_TO_QUAKESTAT,quakestat) | 1509 | AC_PATH_PROG(PATH_TO_QUAKESTAT,quakestat) |
| 1497 | AC_PATH_PROG(PATH_TO_QSTAT,qstat) | 1510 | AC_PATH_PROG(PATH_TO_QSTAT,qstat) |
| 1498 | AC_ARG_WITH(qstat_command, | 1511 | AC_ARG_WITH(qstat_command, |
| @@ -1519,21 +1532,47 @@ then | |||
| 1519 | fi | 1532 | fi |
| 1520 | 1533 | ||
| 1521 | AC_PATH_PROG(PATH_TO_FPING,fping) | 1534 | AC_PATH_PROG(PATH_TO_FPING,fping) |
| 1522 | AC_PATH_PROG(PATH_TO_FPING6,fping6) | ||
| 1523 | 1535 | ||
| 1524 | AC_ARG_WITH(fping_command, | 1536 | AC_ARG_WITH(fping_command, |
| 1525 | ACX_HELP_STRING([--with-fping-command=PATH], | 1537 | ACX_HELP_STRING([--with-fping-command=PATH], |
| 1526 | [Path to fping command]), PATH_TO_FPING=$withval) | 1538 | [Path to fping command]), PATH_TO_FPING=$withval) |
| 1527 | AC_ARG_WITH(fping6_command, | 1539 | if test -n "$PATH_TO_FPING"; then |
| 1528 | ACX_HELP_STRING([--with-fping6-command=PATH], | ||
| 1529 | [Path to fping6 command]), PATH_TO_FPING6=$withval) | ||
| 1530 | |||
| 1531 | if test -n "$PATH_TO_FPING" | ||
| 1532 | then | ||
| 1533 | AC_DEFINE_UNQUOTED(PATH_TO_FPING,"$PATH_TO_FPING",[path to fping]) | 1540 | AC_DEFINE_UNQUOTED(PATH_TO_FPING,"$PATH_TO_FPING",[path to fping]) |
| 1534 | EXTRAS="$EXTRAS check_fping\$(EXEEXT)" | 1541 | EXTRAS="$EXTRAS check_fping\$(EXEEXT)" |
| 1535 | if test x"$with_ipv6" != xno && test -n "$PATH_TO_FPING6"; then | 1542 | |
| 1536 | AC_DEFINE_UNQUOTED(PATH_TO_FPING6,"$PATH_TO_FPING6",[path to fping6]) | 1543 | if test -z "$($PATH_TO_FPING --version)" ; then |
| 1544 | AC_MSG_NOTICE([failed to get version of fping]) | ||
| 1545 | else | ||
| 1546 | FPING_MAJOR_VERSION="$($PATH_TO_FPING --version | sed 's/.*fping: Version //' | sed 's/\..*//')" | ||
| 1547 | FPING_MINOR_VERSION="$($PATH_TO_FPING --version | sed 's/.*fping: Version //' | sed 's/.*\.//')" | ||
| 1548 | |||
| 1549 | if test $FPING_MAJOR_VERSION -eq 5 ; then | ||
| 1550 | if test $FPING_MINOR_VERSION -ge 3 ; then | ||
| 1551 | AC_DEFINE(FPING_VERSION_5_3_OR_HIGHER, "true", [fping is of version 5.3 or higher]) | ||
| 1552 | AC_MSG_NOTICE([fping is of version 5.3 or higher]) | ||
| 1553 | AC_DEFINE(FPING_VERSION_5_2_OR_HIGHER, "true", [fping is of version 5.2 or higher]) | ||
| 1554 | AC_MSG_NOTICE([fping is of version 5.2 or higher]) | ||
| 1555 | elif test $FPING_MINOR_VERSION -ge 2 ; then | ||
| 1556 | AC_DEFINE(FPING_VERSION_5_2_OR_HIGHER, "true", [fping is of version 5.2 or higher]) | ||
| 1557 | AC_MSG_NOTICE([fping is of version 5.2 or higher]) | ||
| 1558 | else | ||
| 1559 | AC_MSG_NOTICE([fping is of a version lower then 5.2]) | ||
| 1560 | fi | ||
| 1561 | |||
| 1562 | elif $FPING_MAJOR_VERSION > 5 ; then | ||
| 1563 | AC_DEFINE(FPING_VERSION_5_2_OR_HIGHER, "true", [fping is of version 5.2 or higher]) | ||
| 1564 | AC_MSG_NOTICE([fping is of version 5.2 or higher]) | ||
| 1565 | AC_DEFINE(FPING_VERSION_5_3_OR_HIGHER, "true", [fping is of version 5.2 or higher]) | ||
| 1566 | AC_MSG_NOTICE([fping is of version 5.3 or higher]) | ||
| 1567 | fi | ||
| 1568 | |||
| 1569 | if test "`fping --version | sed 's/.*fping: Version //'`" = "5.2" ; then | ||
| 1570 | AC_DEFINE(FPING_VERSION, "5.2", [the version of fping available]) | ||
| 1571 | AC_MSG_NOTICE([fping version: 5.2]) | ||
| 1572 | elif test "`fping --version | sed 's/.*fping: Version //'`" = "5.3"; then | ||
| 1573 | AC_DEFINE(FPING_VERSION, "5.3", [the version of fping available]) | ||
| 1574 | AC_MSG_NOTICE([fping version: 5.3]) | ||
| 1575 | fi | ||
| 1537 | fi | 1576 | fi |
| 1538 | else | 1577 | else |
| 1539 | AC_MSG_WARN([Get fping from http://www.fping.com in order to make check_fping plugin]) | 1578 | AC_MSG_WARN([Get fping from http://www.fping.com in order to make check_fping plugin]) |
| @@ -1807,11 +1846,6 @@ if test -n "$PATH_TO_APTGET" ; then | |||
| 1807 | fi | 1846 | fi |
| 1808 | 1847 | ||
| 1809 | 1848 | ||
| 1810 | if test -f $srcdir/plugins/check_nt.c ; then | ||
| 1811 | EXTRAS="$EXTRAS check_nt\$(EXEEXT)" | ||
| 1812 | fi | ||
| 1813 | |||
| 1814 | |||
| 1815 | dnl used in check_dhcp | 1849 | dnl used in check_dhcp |
| 1816 | AC_CHECK_HEADERS(sys/sockio.h) | 1850 | AC_CHECK_HEADERS(sys/sockio.h) |
| 1817 | 1851 | ||
diff --git a/gl/Makefile.am b/gl/Makefile.am index df988b37..f462fdb7 100644 --- a/gl/Makefile.am +++ b/gl/Makefile.am | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ## DO NOT EDIT! GENERATED AUTOMATICALLY! | 1 | ## DO NOT EDIT! GENERATED AUTOMATICALLY! |
| 2 | ## Process this file with automake to produce Makefile.in. | 2 | ## Process this file with automake to produce Makefile.in. |
| 3 | # Copyright (C) 2002-2024 Free Software Foundation, Inc. | 3 | # Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 4 | # | 4 | # |
| 5 | # This file is free software; you can redistribute it and/or modify | 5 | # This file is free software; you can redistribute it and/or modify |
| 6 | # it under the terms of the GNU General Public License as published by | 6 | # it under the terms of the GNU General Public License as published by |
| @@ -80,9 +80,9 @@ AM_CFLAGS = | |||
| 80 | noinst_LIBRARIES += libgnu.a | 80 | noinst_LIBRARIES += libgnu.a |
| 81 | 81 | ||
| 82 | libgnu_a_SOURCES = | 82 | libgnu_a_SOURCES = |
| 83 | libgnu_a_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS) | 83 | libgnu_a_CFLAGS = $(AM_CFLAGS) $(GL_CFLAG_GNULIB_WARNINGS) $(GL_CFLAG_ALLOW_WARNINGS) |
| 84 | libgnu_a_LIBADD = $(gl_LIBOBJS) | 84 | libgnu_a_LIBADD = $(gl_libgnu_LIBOBJS) |
| 85 | libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) | 85 | libgnu_a_DEPENDENCIES = $(gl_libgnu_LIBOBJS) |
| 86 | EXTRA_libgnu_a_SOURCES = | 86 | EXTRA_libgnu_a_SOURCES = |
| 87 | 87 | ||
| 88 | ## begin gnulib module absolute-header | 88 | ## begin gnulib module absolute-header |
| @@ -116,9 +116,10 @@ EXTRA_DIST += alloca.in.h | |||
| 116 | 116 | ||
| 117 | ## end gnulib module alloca-opt | 117 | ## end gnulib module alloca-opt |
| 118 | 118 | ||
| 119 | ## begin gnulib module arpa_inet | 119 | ## begin gnulib module arpa_inet-h |
| 120 | 120 | ||
| 121 | BUILT_SOURCES += arpa/inet.h | 121 | BUILT_SOURCES += arpa/inet.h |
| 122 | libgnu_a_SOURCES += arpa_inet.c | ||
| 122 | 123 | ||
| 123 | # We need the following in order to create <arpa/inet.h> when the system | 124 | # We need the following in order to create <arpa/inet.h> when the system |
| 124 | # doesn't have one. | 125 | # doesn't have one. |
| @@ -135,8 +136,12 @@ arpa/inet.h: arpa_inet.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON | |||
| 135 | -e 's/@''GNULIB_INET_NTOP''@/$(GL_GNULIB_INET_NTOP)/g' \ | 136 | -e 's/@''GNULIB_INET_NTOP''@/$(GL_GNULIB_INET_NTOP)/g' \ |
| 136 | -e 's/@''GNULIB_INET_PTON''@/$(GL_GNULIB_INET_PTON)/g' \ | 137 | -e 's/@''GNULIB_INET_PTON''@/$(GL_GNULIB_INET_PTON)/g' \ |
| 137 | -e 's|@''HAVE_WS2TCPIP_H''@|$(HAVE_WS2TCPIP_H)|g' \ | 138 | -e 's|@''HAVE_WS2TCPIP_H''@|$(HAVE_WS2TCPIP_H)|g' \ |
| 139 | -e 's|@''HAVE_DECL_HTONL''@|$(HAVE_DECL_HTONL)|g' \ | ||
| 140 | -e 's|@''HAVE_DECL_HTONS''@|$(HAVE_DECL_HTONS)|g' \ | ||
| 138 | -e 's|@''HAVE_DECL_INET_NTOP''@|$(HAVE_DECL_INET_NTOP)|g' \ | 141 | -e 's|@''HAVE_DECL_INET_NTOP''@|$(HAVE_DECL_INET_NTOP)|g' \ |
| 139 | -e 's|@''HAVE_DECL_INET_PTON''@|$(HAVE_DECL_INET_PTON)|g' \ | 142 | -e 's|@''HAVE_DECL_INET_PTON''@|$(HAVE_DECL_INET_PTON)|g' \ |
| 143 | -e 's|@''HAVE_DECL_NTOHL''@|$(HAVE_DECL_NTOHL)|g' \ | ||
| 144 | -e 's|@''HAVE_DECL_NTOHS''@|$(HAVE_DECL_NTOHS)|g' \ | ||
| 140 | -e 's|@''REPLACE_INET_NTOP''@|$(REPLACE_INET_NTOP)|g' \ | 145 | -e 's|@''REPLACE_INET_NTOP''@|$(REPLACE_INET_NTOP)|g' \ |
| 141 | -e 's|@''REPLACE_INET_PTON''@|$(REPLACE_INET_PTON)|g' \ | 146 | -e 's|@''REPLACE_INET_PTON''@|$(REPLACE_INET_PTON)|g' \ |
| 142 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ | 147 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ |
| @@ -149,7 +154,7 @@ MOSTLYCLEANDIRS += arpa | |||
| 149 | 154 | ||
| 150 | EXTRA_DIST += arpa_inet.in.h | 155 | EXTRA_DIST += arpa_inet.in.h |
| 151 | 156 | ||
| 152 | ## end gnulib module arpa_inet | 157 | ## end gnulib module arpa_inet-h |
| 153 | 158 | ||
| 154 | ## begin gnulib module assert-h | 159 | ## begin gnulib module assert-h |
| 155 | 160 | ||
| @@ -221,6 +226,7 @@ if GL_GENERATE_BYTESWAP_H | |||
| 221 | byteswap.h: byteswap.in.h $(top_builddir)/config.status | 226 | byteswap.h: byteswap.in.h $(top_builddir)/config.status |
| 222 | $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/byteswap.in.h | 227 | $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/byteswap.in.h |
| 223 | $(AM_V_at)mv $@-t $@ | 228 | $(AM_V_at)mv $@-t $@ |
| 229 | libgnu_a_SOURCES += byteswap.c | ||
| 224 | else | 230 | else |
| 225 | byteswap.h: $(top_builddir)/config.status | 231 | byteswap.h: $(top_builddir)/config.status |
| 226 | rm -f $@ | 232 | rm -f $@ |
| @@ -231,6 +237,122 @@ EXTRA_DIST += byteswap.in.h | |||
| 231 | 237 | ||
| 232 | ## end gnulib module byteswap | 238 | ## end gnulib module byteswap |
| 233 | 239 | ||
| 240 | ## begin gnulib module c-ctype | ||
| 241 | |||
| 242 | libgnu_a_SOURCES += c-ctype.h c-ctype.c | ||
| 243 | |||
| 244 | ## end gnulib module c-ctype | ||
| 245 | |||
| 246 | ## begin gnulib module c32isalnum | ||
| 247 | |||
| 248 | libgnu_a_SOURCES += c32isalnum.c | ||
| 249 | |||
| 250 | EXTRA_DIST += c32is-impl.h | ||
| 251 | |||
| 252 | ## end gnulib module c32isalnum | ||
| 253 | |||
| 254 | ## begin gnulib module c32isalpha | ||
| 255 | |||
| 256 | libgnu_a_SOURCES += c32isalpha.c | ||
| 257 | |||
| 258 | EXTRA_DIST += c32is-impl.h | ||
| 259 | |||
| 260 | ## end gnulib module c32isalpha | ||
| 261 | |||
| 262 | ## begin gnulib module c32isblank | ||
| 263 | |||
| 264 | libgnu_a_SOURCES += c32isblank.c | ||
| 265 | |||
| 266 | EXTRA_DIST += c32is-impl.h | ||
| 267 | |||
| 268 | ## end gnulib module c32isblank | ||
| 269 | |||
| 270 | ## begin gnulib module c32iscntrl | ||
| 271 | |||
| 272 | libgnu_a_SOURCES += c32iscntrl.c | ||
| 273 | |||
| 274 | EXTRA_DIST += c32is-impl.h | ||
| 275 | |||
| 276 | ## end gnulib module c32iscntrl | ||
| 277 | |||
| 278 | ## begin gnulib module c32isdigit | ||
| 279 | |||
| 280 | libgnu_a_SOURCES += c32isdigit.c | ||
| 281 | |||
| 282 | EXTRA_DIST += c32is-impl.h | ||
| 283 | |||
| 284 | ## end gnulib module c32isdigit | ||
| 285 | |||
| 286 | ## begin gnulib module c32isgraph | ||
| 287 | |||
| 288 | libgnu_a_SOURCES += c32isgraph.c | ||
| 289 | |||
| 290 | EXTRA_DIST += c32is-impl.h | ||
| 291 | |||
| 292 | ## end gnulib module c32isgraph | ||
| 293 | |||
| 294 | ## begin gnulib module c32islower | ||
| 295 | |||
| 296 | libgnu_a_SOURCES += c32islower.c | ||
| 297 | |||
| 298 | EXTRA_DIST += c32is-impl.h | ||
| 299 | |||
| 300 | ## end gnulib module c32islower | ||
| 301 | |||
| 302 | ## begin gnulib module c32isprint | ||
| 303 | |||
| 304 | libgnu_a_SOURCES += c32isprint.c | ||
| 305 | |||
| 306 | EXTRA_DIST += c32is-impl.h | ||
| 307 | |||
| 308 | ## end gnulib module c32isprint | ||
| 309 | |||
| 310 | ## begin gnulib module c32ispunct | ||
| 311 | |||
| 312 | libgnu_a_SOURCES += c32ispunct.c | ||
| 313 | |||
| 314 | EXTRA_DIST += c32is-impl.h | ||
| 315 | |||
| 316 | ## end gnulib module c32ispunct | ||
| 317 | |||
| 318 | ## begin gnulib module c32isspace | ||
| 319 | |||
| 320 | libgnu_a_SOURCES += c32isspace.c | ||
| 321 | |||
| 322 | EXTRA_DIST += c32is-impl.h | ||
| 323 | |||
| 324 | ## end gnulib module c32isspace | ||
| 325 | |||
| 326 | ## begin gnulib module c32isupper | ||
| 327 | |||
| 328 | libgnu_a_SOURCES += c32isupper.c | ||
| 329 | |||
| 330 | EXTRA_DIST += c32is-impl.h | ||
| 331 | |||
| 332 | ## end gnulib module c32isupper | ||
| 333 | |||
| 334 | ## begin gnulib module c32isxdigit | ||
| 335 | |||
| 336 | libgnu_a_SOURCES += c32isxdigit.c | ||
| 337 | |||
| 338 | EXTRA_DIST += c32is-impl.h | ||
| 339 | |||
| 340 | ## end gnulib module c32isxdigit | ||
| 341 | |||
| 342 | ## begin gnulib module c32tolower | ||
| 343 | |||
| 344 | libgnu_a_SOURCES += c32tolower.c | ||
| 345 | |||
| 346 | EXTRA_DIST += c32to-impl.h | ||
| 347 | |||
| 348 | ## end gnulib module c32tolower | ||
| 349 | |||
| 350 | ## begin gnulib module c32width | ||
| 351 | |||
| 352 | libgnu_a_SOURCES += c32width.c | ||
| 353 | |||
| 354 | ## end gnulib module c32width | ||
| 355 | |||
| 234 | ## begin gnulib module calloc-gnu | 356 | ## begin gnulib module calloc-gnu |
| 235 | 357 | ||
| 236 | 358 | ||
| @@ -313,7 +435,7 @@ endif | |||
| 313 | 435 | ||
| 314 | ## end gnulib module dup2 | 436 | ## end gnulib module dup2 |
| 315 | 437 | ||
| 316 | ## begin gnulib module errno | 438 | ## begin gnulib module errno-h |
| 317 | 439 | ||
| 318 | BUILT_SOURCES += $(ERRNO_H) | 440 | BUILT_SOURCES += $(ERRNO_H) |
| 319 | 441 | ||
| @@ -343,7 +465,7 @@ MOSTLYCLEANFILES += errno.h errno.h-t | |||
| 343 | 465 | ||
| 344 | EXTRA_DIST += errno.in.h | 466 | EXTRA_DIST += errno.in.h |
| 345 | 467 | ||
| 346 | ## end gnulib module errno | 468 | ## end gnulib module errno-h |
| 347 | 469 | ||
| 348 | ## begin gnulib module error | 470 | ## begin gnulib module error |
| 349 | 471 | ||
| @@ -455,7 +577,7 @@ EXTRA_DIST += filename.h | |||
| 455 | 577 | ||
| 456 | ## end gnulib module filename | 578 | ## end gnulib module filename |
| 457 | 579 | ||
| 458 | ## begin gnulib module float | 580 | ## begin gnulib module float-h |
| 459 | 581 | ||
| 460 | BUILT_SOURCES += $(FLOAT_H) | 582 | BUILT_SOURCES += $(FLOAT_H) |
| 461 | 583 | ||
| @@ -487,7 +609,7 @@ endif | |||
| 487 | 609 | ||
| 488 | EXTRA_DIST += float.in.h | 610 | EXTRA_DIST += float.in.h |
| 489 | 611 | ||
| 490 | ## end gnulib module float | 612 | ## end gnulib module float-h |
| 491 | 613 | ||
| 492 | ## begin gnulib module floorf | 614 | ## begin gnulib module floorf |
| 493 | 615 | ||
| @@ -563,6 +685,16 @@ EXTRA_DIST += stdio-impl.h | |||
| 563 | 685 | ||
| 564 | ## end gnulib module fseeko | 686 | ## end gnulib module fseeko |
| 565 | 687 | ||
| 688 | ## begin gnulib module fseterr | ||
| 689 | |||
| 690 | if GL_COND_OBJ_FSETERR | ||
| 691 | libgnu_a_SOURCES += fseterr.c | ||
| 692 | endif | ||
| 693 | |||
| 694 | EXTRA_DIST += fseterr.h stdio-impl.h | ||
| 695 | |||
| 696 | ## end gnulib module fseterr | ||
| 697 | |||
| 566 | ## begin gnulib module fstat | 698 | ## begin gnulib module fstat |
| 567 | 699 | ||
| 568 | if GL_COND_OBJ_FSTAT | 700 | if GL_COND_OBJ_FSTAT |
| @@ -807,6 +939,14 @@ endif | |||
| 807 | 939 | ||
| 808 | ## end gnulib module inet_ntop | 940 | ## end gnulib module inet_ntop |
| 809 | 941 | ||
| 942 | ## begin gnulib module inet_pton | ||
| 943 | |||
| 944 | if GL_COND_OBJ_INET_PTON | ||
| 945 | libgnu_a_SOURCES += inet_pton.c | ||
| 946 | endif | ||
| 947 | |||
| 948 | ## end gnulib module inet_pton | ||
| 949 | |||
| 810 | ## begin gnulib module intprops | 950 | ## begin gnulib module intprops |
| 811 | 951 | ||
| 812 | 952 | ||
| @@ -814,7 +954,7 @@ EXTRA_DIST += intprops-internal.h intprops.h | |||
| 814 | 954 | ||
| 815 | ## end gnulib module intprops | 955 | ## end gnulib module intprops |
| 816 | 956 | ||
| 817 | ## begin gnulib module inttypes-incomplete | 957 | ## begin gnulib module inttypes-h-incomplete |
| 818 | 958 | ||
| 819 | BUILT_SOURCES += inttypes.h | 959 | BUILT_SOURCES += inttypes.h |
| 820 | 960 | ||
| @@ -855,7 +995,7 @@ MOSTLYCLEANFILES += inttypes.h inttypes.h-t | |||
| 855 | 995 | ||
| 856 | EXTRA_DIST += inttypes.in.h | 996 | EXTRA_DIST += inttypes.in.h |
| 857 | 997 | ||
| 858 | ## end gnulib module inttypes-incomplete | 998 | ## end gnulib module inttypes-h-incomplete |
| 859 | 999 | ||
| 860 | ## begin gnulib module iswblank | 1000 | ## begin gnulib module iswblank |
| 861 | 1001 | ||
| @@ -899,7 +1039,7 @@ endif | |||
| 899 | 1039 | ||
| 900 | ## end gnulib module iswxdigit | 1040 | ## end gnulib module iswxdigit |
| 901 | 1041 | ||
| 902 | ## begin gnulib module langinfo | 1042 | ## begin gnulib module langinfo-h |
| 903 | 1043 | ||
| 904 | BUILT_SOURCES += langinfo.h | 1044 | BUILT_SOURCES += langinfo.h |
| 905 | 1045 | ||
| @@ -917,6 +1057,7 @@ langinfo.h: langinfo.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_U | |||
| 917 | -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \ | 1057 | -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \ |
| 918 | -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \ | 1058 | -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \ |
| 919 | -e 's|@''HAVE_LANGINFO_ALTMON''@|$(HAVE_LANGINFO_ALTMON)|g' \ | 1059 | -e 's|@''HAVE_LANGINFO_ALTMON''@|$(HAVE_LANGINFO_ALTMON)|g' \ |
| 1060 | -e 's|@''HAVE_LANGINFO_ABALTMON''@|$(HAVE_LANGINFO_ABALTMON)|g' \ | ||
| 920 | -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \ | 1061 | -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \ |
| 921 | -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \ | 1062 | -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \ |
| 922 | -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \ | 1063 | -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \ |
| @@ -929,7 +1070,7 @@ MOSTLYCLEANFILES += langinfo.h langinfo.h-t | |||
| 929 | 1070 | ||
| 930 | EXTRA_DIST += langinfo.in.h | 1071 | EXTRA_DIST += langinfo.in.h |
| 931 | 1072 | ||
| 932 | ## end gnulib module langinfo | 1073 | ## end gnulib module langinfo-h |
| 933 | 1074 | ||
| 934 | ## begin gnulib module libc-config | 1075 | ## begin gnulib module libc-config |
| 935 | 1076 | ||
| @@ -972,7 +1113,7 @@ EXTRA_DIST += localcharset.h | |||
| 972 | 1113 | ||
| 973 | ## end gnulib module localcharset | 1114 | ## end gnulib module localcharset |
| 974 | 1115 | ||
| 975 | ## begin gnulib module locale | 1116 | ## begin gnulib module locale-h |
| 976 | 1117 | ||
| 977 | BUILT_SOURCES += locale.h | 1118 | BUILT_SOURCES += locale.h |
| 978 | 1119 | ||
| @@ -985,20 +1126,28 @@ locale.h: locale.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H | |||
| 985 | -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ | 1126 | -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ |
| 986 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | 1127 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ |
| 987 | -e 's|@''NEXT_LOCALE_H''@|$(NEXT_LOCALE_H)|g' \ | 1128 | -e 's|@''NEXT_LOCALE_H''@|$(NEXT_LOCALE_H)|g' \ |
| 1129 | -e 's|@''HAVE_LOCALE_T''@|$(HAVE_LOCALE_T)|g' \ | ||
| 1130 | -e 's|@''HAVE_WINDOWS_LOCALE_T''@|$(HAVE_WINDOWS_LOCALE_T)|g' \ | ||
| 988 | -e 's/@''GNULIB_LOCALECONV''@/$(GL_GNULIB_LOCALECONV)/g' \ | 1131 | -e 's/@''GNULIB_LOCALECONV''@/$(GL_GNULIB_LOCALECONV)/g' \ |
| 989 | -e 's/@''GNULIB_SETLOCALE''@/$(GL_GNULIB_SETLOCALE)/g' \ | 1132 | -e 's/@''GNULIB_SETLOCALE''@/$(GL_GNULIB_SETLOCALE)/g' \ |
| 990 | -e 's/@''GNULIB_SETLOCALE_NULL''@/$(GL_GNULIB_SETLOCALE_NULL)/g' \ | 1133 | -e 's/@''GNULIB_SETLOCALE_NULL''@/$(GL_GNULIB_SETLOCALE_NULL)/g' \ |
| 1134 | -e 's/@''GNULIB_NEWLOCALE''@/$(GL_GNULIB_NEWLOCALE)/g' \ | ||
| 991 | -e 's/@''GNULIB_DUPLOCALE''@/$(GL_GNULIB_DUPLOCALE)/g' \ | 1135 | -e 's/@''GNULIB_DUPLOCALE''@/$(GL_GNULIB_DUPLOCALE)/g' \ |
| 1136 | -e 's/@''GNULIB_FREELOCALE''@/$(GL_GNULIB_FREELOCALE)/g' \ | ||
| 1137 | -e 's/@''GNULIB_GETLOCALENAME_L''@/$(GL_GNULIB_GETLOCALENAME_L)/g' \ | ||
| 1138 | -e 's/@''GNULIB_GETLOCALENAME_L_UNSAFE''@/$(GL_GNULIB_GETLOCALENAME_L_UNSAFE)/g' \ | ||
| 992 | -e 's/@''GNULIB_LOCALENAME_UNSAFE''@/$(GL_GNULIB_LOCALENAME_UNSAFE)/g' \ | 1139 | -e 's/@''GNULIB_LOCALENAME_UNSAFE''@/$(GL_GNULIB_LOCALENAME_UNSAFE)/g' \ |
| 993 | -e 's|@''HAVE_NEWLOCALE''@|$(HAVE_NEWLOCALE)|g' \ | 1140 | -e 's|@''HAVE_NEWLOCALE''@|$(HAVE_NEWLOCALE)|g' \ |
| 994 | -e 's|@''HAVE_DUPLOCALE''@|$(HAVE_DUPLOCALE)|g' \ | 1141 | -e 's|@''HAVE_DUPLOCALE''@|$(HAVE_DUPLOCALE)|g' \ |
| 995 | -e 's|@''HAVE_FREELOCALE''@|$(HAVE_FREELOCALE)|g' \ | 1142 | -e 's|@''HAVE_FREELOCALE''@|$(HAVE_FREELOCALE)|g' \ |
| 1143 | -e 's|@''HAVE_GETLOCALENAME_L''@|$(HAVE_GETLOCALENAME_L)|g' \ | ||
| 996 | -e 's|@''HAVE_XLOCALE_H''@|$(HAVE_XLOCALE_H)|g' \ | 1144 | -e 's|@''HAVE_XLOCALE_H''@|$(HAVE_XLOCALE_H)|g' \ |
| 997 | -e 's|@''REPLACE_LOCALECONV''@|$(REPLACE_LOCALECONV)|g' \ | 1145 | -e 's|@''REPLACE_LOCALECONV''@|$(REPLACE_LOCALECONV)|g' \ |
| 998 | -e 's|@''REPLACE_SETLOCALE''@|$(REPLACE_SETLOCALE)|g' \ | 1146 | -e 's|@''REPLACE_SETLOCALE''@|$(REPLACE_SETLOCALE)|g' \ |
| 999 | -e 's|@''REPLACE_NEWLOCALE''@|$(REPLACE_NEWLOCALE)|g' \ | 1147 | -e 's|@''REPLACE_NEWLOCALE''@|$(REPLACE_NEWLOCALE)|g' \ |
| 1000 | -e 's|@''REPLACE_DUPLOCALE''@|$(REPLACE_DUPLOCALE)|g' \ | 1148 | -e 's|@''REPLACE_DUPLOCALE''@|$(REPLACE_DUPLOCALE)|g' \ |
| 1001 | -e 's|@''REPLACE_FREELOCALE''@|$(REPLACE_FREELOCALE)|g' \ | 1149 | -e 's|@''REPLACE_FREELOCALE''@|$(REPLACE_FREELOCALE)|g' \ |
| 1150 | -e 's|@''REPLACE_GETLOCALENAME_L''@|$(REPLACE_GETLOCALENAME_L)|g' \ | ||
| 1002 | -e 's|@''REPLACE_STRUCT_LCONV''@|$(REPLACE_STRUCT_LCONV)|g' \ | 1151 | -e 's|@''REPLACE_STRUCT_LCONV''@|$(REPLACE_STRUCT_LCONV)|g' \ |
| 1003 | -e 's|@''LOCALENAME_ENHANCE_LOCALE_FUNCS''@|$(LOCALENAME_ENHANCE_LOCALE_FUNCS)|g' \ | 1152 | -e 's|@''LOCALENAME_ENHANCE_LOCALE_FUNCS''@|$(LOCALENAME_ENHANCE_LOCALE_FUNCS)|g' \ |
| 1004 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ | 1153 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ |
| @@ -1010,7 +1159,7 @@ MOSTLYCLEANFILES += locale.h locale.h-t | |||
| 1010 | 1159 | ||
| 1011 | EXTRA_DIST += locale.in.h | 1160 | EXTRA_DIST += locale.in.h |
| 1012 | 1161 | ||
| 1013 | ## end gnulib module locale | 1162 | ## end gnulib module locale-h |
| 1014 | 1163 | ||
| 1015 | ## begin gnulib module localeconv | 1164 | ## begin gnulib module localeconv |
| 1016 | 1165 | ||
| @@ -1034,6 +1183,14 @@ endif | |||
| 1034 | 1183 | ||
| 1035 | ## end gnulib module lseek | 1184 | ## end gnulib module lseek |
| 1036 | 1185 | ||
| 1186 | ## begin gnulib module lstat | ||
| 1187 | |||
| 1188 | if GL_COND_OBJ_LSTAT | ||
| 1189 | libgnu_a_SOURCES += lstat.c | ||
| 1190 | endif | ||
| 1191 | |||
| 1192 | ## end gnulib module lstat | ||
| 1193 | |||
| 1037 | ## begin gnulib module malloc-gnu | 1194 | ## begin gnulib module malloc-gnu |
| 1038 | 1195 | ||
| 1039 | 1196 | ||
| @@ -1060,7 +1217,7 @@ EXTRA_DIST += malloca.h | |||
| 1060 | 1217 | ||
| 1061 | ## end gnulib module malloca | 1218 | ## end gnulib module malloca |
| 1062 | 1219 | ||
| 1063 | ## begin gnulib module math | 1220 | ## begin gnulib module math-h |
| 1064 | 1221 | ||
| 1065 | BUILT_SOURCES += math.h | 1222 | BUILT_SOURCES += math.h |
| 1066 | libgnu_a_SOURCES += math.c | 1223 | libgnu_a_SOURCES += math.c |
| @@ -1150,6 +1307,9 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( | |||
| 1150 | -e 's/@''GNULIB_LOGB''@/$(GL_GNULIB_LOGB)/g' \ | 1307 | -e 's/@''GNULIB_LOGB''@/$(GL_GNULIB_LOGB)/g' \ |
| 1151 | -e 's/@''GNULIB_LOGBF''@/$(GL_GNULIB_LOGBF)/g' \ | 1308 | -e 's/@''GNULIB_LOGBF''@/$(GL_GNULIB_LOGBF)/g' \ |
| 1152 | -e 's/@''GNULIB_LOGBL''@/$(GL_GNULIB_LOGBL)/g' \ | 1309 | -e 's/@''GNULIB_LOGBL''@/$(GL_GNULIB_LOGBL)/g' \ |
| 1310 | -e 's/@''GNULIB_LOGP1''@/$(GL_GNULIB_LOGP1)/g' \ | ||
| 1311 | -e 's/@''GNULIB_LOGP1F''@/$(GL_GNULIB_LOGP1F)/g' \ | ||
| 1312 | -e 's/@''GNULIB_LOGP1L''@/$(GL_GNULIB_LOGP1L)/g' \ | ||
| 1153 | -e 's/@''GNULIB_MODF''@/$(GL_GNULIB_MODF)/g' \ | 1313 | -e 's/@''GNULIB_MODF''@/$(GL_GNULIB_MODF)/g' \ |
| 1154 | -e 's/@''GNULIB_MODFF''@/$(GL_GNULIB_MODFF)/g' \ | 1314 | -e 's/@''GNULIB_MODFF''@/$(GL_GNULIB_MODFF)/g' \ |
| 1155 | -e 's/@''GNULIB_MODFL''@/$(GL_GNULIB_MODFL)/g' \ | 1315 | -e 's/@''GNULIB_MODFL''@/$(GL_GNULIB_MODFL)/g' \ |
| @@ -1243,6 +1403,9 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( | |||
| 1243 | -e 's|@''HAVE_LOG1PL''@|$(HAVE_LOG1PL)|g' \ | 1403 | -e 's|@''HAVE_LOG1PL''@|$(HAVE_LOG1PL)|g' \ |
| 1244 | -e 's|@''HAVE_LOGBF''@|$(HAVE_LOGBF)|g' \ | 1404 | -e 's|@''HAVE_LOGBF''@|$(HAVE_LOGBF)|g' \ |
| 1245 | -e 's|@''HAVE_LOGBL''@|$(HAVE_LOGBL)|g' \ | 1405 | -e 's|@''HAVE_LOGBL''@|$(HAVE_LOGBL)|g' \ |
| 1406 | -e 's|@''HAVE_LOGP1''@|$(HAVE_LOGP1)|g' \ | ||
| 1407 | -e 's|@''HAVE_LOGP1F''@|$(HAVE_LOGP1F)|g' \ | ||
| 1408 | -e 's|@''HAVE_LOGP1L''@|$(HAVE_LOGP1L)|g' \ | ||
| 1246 | -e 's|@''HAVE_MODFF''@|$(HAVE_MODFF)|g' \ | 1409 | -e 's|@''HAVE_MODFF''@|$(HAVE_MODFF)|g' \ |
| 1247 | -e 's|@''HAVE_MODFL''@|$(HAVE_MODFL)|g' \ | 1410 | -e 's|@''HAVE_MODFL''@|$(HAVE_MODFL)|g' \ |
| 1248 | -e 's|@''HAVE_POWF''@|$(HAVE_POWF)|g' \ | 1411 | -e 's|@''HAVE_POWF''@|$(HAVE_POWF)|g' \ |
| @@ -1389,6 +1552,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( | |||
| 1389 | -e 's|@''REPLACE_SIGNBIT_USING_BUILTINS''@|$(REPLACE_SIGNBIT_USING_BUILTINS)|g' \ | 1552 | -e 's|@''REPLACE_SIGNBIT_USING_BUILTINS''@|$(REPLACE_SIGNBIT_USING_BUILTINS)|g' \ |
| 1390 | -e 's|@''REPLACE_SINF''@|$(REPLACE_SINF)|g' \ | 1553 | -e 's|@''REPLACE_SINF''@|$(REPLACE_SINF)|g' \ |
| 1391 | -e 's|@''REPLACE_SINHF''@|$(REPLACE_SINHF)|g' \ | 1554 | -e 's|@''REPLACE_SINHF''@|$(REPLACE_SINHF)|g' \ |
| 1555 | -e 's|@''REPLACE_SINL''@|$(REPLACE_SINL)|g' \ | ||
| 1392 | -e 's|@''REPLACE_SQRTF''@|$(REPLACE_SQRTF)|g' \ | 1556 | -e 's|@''REPLACE_SQRTF''@|$(REPLACE_SQRTF)|g' \ |
| 1393 | -e 's|@''REPLACE_SQRTL''@|$(REPLACE_SQRTL)|g' \ | 1557 | -e 's|@''REPLACE_SQRTL''@|$(REPLACE_SQRTL)|g' \ |
| 1394 | -e 's|@''REPLACE_TANF''@|$(REPLACE_TANF)|g' \ | 1558 | -e 's|@''REPLACE_TANF''@|$(REPLACE_TANF)|g' \ |
| @@ -1412,7 +1576,33 @@ MOSTLYCLEANFILES += math.h math.h-t1 math.h-t2 math.h-t3 math.h-t4 math.h-t5 mat | |||
| 1412 | 1576 | ||
| 1413 | EXTRA_DIST += math.in.h | 1577 | EXTRA_DIST += math.in.h |
| 1414 | 1578 | ||
| 1415 | ## end gnulib module math | 1579 | ## end gnulib module math-h |
| 1580 | |||
| 1581 | ## begin gnulib module mbchar | ||
| 1582 | |||
| 1583 | libgnu_a_SOURCES += mbchar.c | ||
| 1584 | |||
| 1585 | EXTRA_DIST += mbchar.h | ||
| 1586 | |||
| 1587 | ## end gnulib module mbchar | ||
| 1588 | |||
| 1589 | ## begin gnulib module mbiterf | ||
| 1590 | |||
| 1591 | libgnu_a_SOURCES += mbiterf.h mbiterf.c | ||
| 1592 | |||
| 1593 | ## end gnulib module mbiterf | ||
| 1594 | |||
| 1595 | ## begin gnulib module mbrtoc32 | ||
| 1596 | |||
| 1597 | if GL_COND_OBJ_MBRTOC32 | ||
| 1598 | libgnu_a_SOURCES += mbrtoc32.c | ||
| 1599 | endif | ||
| 1600 | |||
| 1601 | EXTRA_DIST += lc-charset-dispatch.c lc-charset-dispatch.h mbrtowc-impl-utf8.h mbrtowc-impl.h mbtowc-lock.c mbtowc-lock.h windows-initguard.h | ||
| 1602 | |||
| 1603 | EXTRA_libgnu_a_SOURCES += lc-charset-dispatch.c mbtowc-lock.c | ||
| 1604 | |||
| 1605 | ## end gnulib module mbrtoc32 | ||
| 1416 | 1606 | ||
| 1417 | ## begin gnulib module mbrtowc | 1607 | ## begin gnulib module mbrtowc |
| 1418 | 1608 | ||
| @@ -1434,6 +1624,12 @@ endif | |||
| 1434 | 1624 | ||
| 1435 | ## end gnulib module mbsinit | 1625 | ## end gnulib module mbsinit |
| 1436 | 1626 | ||
| 1627 | ## begin gnulib module mbsnlen | ||
| 1628 | |||
| 1629 | libgnu_a_SOURCES += mbsnlen.c | ||
| 1630 | |||
| 1631 | ## end gnulib module mbsnlen | ||
| 1632 | |||
| 1437 | ## begin gnulib module mbszero | 1633 | ## begin gnulib module mbszero |
| 1438 | 1634 | ||
| 1439 | libgnu_a_SOURCES += mbszero.c | 1635 | libgnu_a_SOURCES += mbszero.c |
| @@ -1486,9 +1682,7 @@ EXTRA_libgnu_a_SOURCES += mktime.c | |||
| 1486 | 1682 | ||
| 1487 | ## begin gnulib module mountlist | 1683 | ## begin gnulib module mountlist |
| 1488 | 1684 | ||
| 1489 | if GL_COND_OBJ_MOUNTLIST | ||
| 1490 | libgnu_a_SOURCES += mountlist.c | 1685 | libgnu_a_SOURCES += mountlist.c |
| 1491 | endif | ||
| 1492 | 1686 | ||
| 1493 | EXTRA_DIST += mountlist.h | 1687 | EXTRA_DIST += mountlist.h |
| 1494 | 1688 | ||
| @@ -1514,7 +1708,7 @@ EXTRA_DIST += msvc-nothrow.h | |||
| 1514 | 1708 | ||
| 1515 | ## end gnulib module msvc-nothrow | 1709 | ## end gnulib module msvc-nothrow |
| 1516 | 1710 | ||
| 1517 | ## begin gnulib module netdb | 1711 | ## begin gnulib module netdb-h |
| 1518 | 1712 | ||
| 1519 | BUILT_SOURCES += netdb.h | 1713 | BUILT_SOURCES += netdb.h |
| 1520 | 1714 | ||
| @@ -1545,9 +1739,9 @@ MOSTLYCLEANFILES += netdb.h netdb.h-t | |||
| 1545 | 1739 | ||
| 1546 | EXTRA_DIST += netdb.in.h | 1740 | EXTRA_DIST += netdb.in.h |
| 1547 | 1741 | ||
| 1548 | ## end gnulib module netdb | 1742 | ## end gnulib module netdb-h |
| 1549 | 1743 | ||
| 1550 | ## begin gnulib module netinet_in | 1744 | ## begin gnulib module netinet_in-h |
| 1551 | 1745 | ||
| 1552 | BUILT_SOURCES += $(NETINET_IN_H) | 1746 | BUILT_SOURCES += $(NETINET_IN_H) |
| 1553 | 1747 | ||
| @@ -1574,7 +1768,7 @@ MOSTLYCLEANDIRS += netinet | |||
| 1574 | 1768 | ||
| 1575 | EXTRA_DIST += netinet_in.in.h | 1769 | EXTRA_DIST += netinet_in.in.h |
| 1576 | 1770 | ||
| 1577 | ## end gnulib module netinet_in | 1771 | ## end gnulib module netinet_in-h |
| 1578 | 1772 | ||
| 1579 | ## begin gnulib module nl_langinfo | 1773 | ## begin gnulib module nl_langinfo |
| 1580 | 1774 | ||
| @@ -1589,6 +1783,12 @@ EXTRA_DIST += windows-initguard.h | |||
| 1589 | 1783 | ||
| 1590 | ## end gnulib module nl_langinfo | 1784 | ## end gnulib module nl_langinfo |
| 1591 | 1785 | ||
| 1786 | ## begin gnulib module once | ||
| 1787 | |||
| 1788 | libgnu_a_SOURCES += glthread/once.h glthread/once.c | ||
| 1789 | |||
| 1790 | ## end gnulib module once | ||
| 1791 | |||
| 1592 | ## begin gnulib module open | 1792 | ## begin gnulib module open |
| 1593 | 1793 | ||
| 1594 | if GL_COND_OBJ_OPEN | 1794 | if GL_COND_OBJ_OPEN |
| @@ -1604,21 +1804,168 @@ EXTRA_DIST += pathmax.h | |||
| 1604 | 1804 | ||
| 1605 | ## end gnulib module pathmax | 1805 | ## end gnulib module pathmax |
| 1606 | 1806 | ||
| 1607 | ## begin gnulib module realloc-gnu | 1807 | ## begin gnulib module pthread-h |
| 1608 | 1808 | ||
| 1809 | BUILT_SOURCES += pthread.h | ||
| 1810 | |||
| 1811 | # We need the following in order to create <pthread.h> when the system | ||
| 1812 | # doesn't have one that works with the given compiler. | ||
| 1813 | pthread.h: pthread.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) | ||
| 1814 | $(gl_V_at)$(SED_HEADER_STDOUT) \ | ||
| 1815 | -e 's|@''GUARD_PREFIX''@|GL|g' \ | ||
| 1816 | -e 's|@''HAVE_PTHREAD_H''@|$(HAVE_PTHREAD_H)|g' \ | ||
| 1817 | -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ | ||
| 1818 | -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ | ||
| 1819 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | ||
| 1820 | -e 's|@''NEXT_PTHREAD_H''@|$(NEXT_PTHREAD_H)|g' \ | ||
| 1821 | -e 's/@''GNULIB_PTHREAD_THREAD''@/$(GL_GNULIB_PTHREAD_THREAD)/g' \ | ||
| 1822 | -e 's/@''GNULIB_PTHREAD_ONCE''@/$(GL_GNULIB_PTHREAD_ONCE)/g' \ | ||
| 1823 | -e 's/@''GNULIB_PTHREAD_MUTEX''@/$(GL_GNULIB_PTHREAD_MUTEX)/g' \ | ||
| 1824 | -e 's/@''GNULIB_PTHREAD_RWLOCK''@/$(GL_GNULIB_PTHREAD_RWLOCK)/g' \ | ||
| 1825 | -e 's/@''GNULIB_PTHREAD_COND''@/$(GL_GNULIB_PTHREAD_COND)/g' \ | ||
| 1826 | -e 's/@''GNULIB_PTHREAD_TSS''@/$(GL_GNULIB_PTHREAD_TSS)/g' \ | ||
| 1827 | -e 's/@''GNULIB_PTHREAD_SPIN''@/$(GL_GNULIB_PTHREAD_SPIN)/g' \ | ||
| 1828 | -e 's/@''GNULIB_PTHREAD_MUTEX_TIMEDLOCK''@/$(GL_GNULIB_PTHREAD_MUTEX_TIMEDLOCK)/g' \ | ||
| 1829 | -e 's|@''HAVE_PTHREAD_T''@|$(HAVE_PTHREAD_T)|g' \ | ||
| 1830 | -e 's|@''HAVE_PTHREAD_SPINLOCK_T''@|$(HAVE_PTHREAD_SPINLOCK_T)|g' \ | ||
| 1831 | -e 's|@''HAVE_PTHREAD_CREATE_DETACHED''@|$(HAVE_PTHREAD_CREATE_DETACHED)|g' \ | ||
| 1832 | -e 's|@''HAVE_PTHREAD_MUTEX_RECURSIVE''@|$(HAVE_PTHREAD_MUTEX_RECURSIVE)|g' \ | ||
| 1833 | -e 's|@''HAVE_PTHREAD_MUTEX_ROBUST''@|$(HAVE_PTHREAD_MUTEX_ROBUST)|g' \ | ||
| 1834 | -e 's|@''HAVE_PTHREAD_PROCESS_SHARED''@|$(HAVE_PTHREAD_PROCESS_SHARED)|g' \ | ||
| 1835 | -e 's|@''HAVE_PTHREAD_CREATE''@|$(HAVE_PTHREAD_CREATE)|g' \ | ||
| 1836 | -e 's|@''HAVE_PTHREAD_ATTR_INIT''@|$(HAVE_PTHREAD_ATTR_INIT)|g' \ | ||
| 1837 | -e 's|@''HAVE_PTHREAD_ATTR_GETDETACHSTATE''@|$(HAVE_PTHREAD_ATTR_GETDETACHSTATE)|g' \ | ||
| 1838 | -e 's|@''HAVE_PTHREAD_ATTR_SETDETACHSTATE''@|$(HAVE_PTHREAD_ATTR_SETDETACHSTATE)|g' \ | ||
| 1839 | -e 's|@''HAVE_PTHREAD_ATTR_DESTROY''@|$(HAVE_PTHREAD_ATTR_DESTROY)|g' \ | ||
| 1840 | -e 's|@''HAVE_PTHREAD_SELF''@|$(HAVE_PTHREAD_SELF)|g' \ | ||
| 1841 | -e 's|@''HAVE_PTHREAD_EQUAL''@|$(HAVE_PTHREAD_EQUAL)|g' \ | ||
| 1842 | -e 's|@''HAVE_PTHREAD_DETACH''@|$(HAVE_PTHREAD_DETACH)|g' \ | ||
| 1843 | -e 's|@''HAVE_PTHREAD_JOIN''@|$(HAVE_PTHREAD_JOIN)|g' \ | ||
| 1844 | -e 's|@''HAVE_PTHREAD_EXIT''@|$(HAVE_PTHREAD_EXIT)|g' \ | ||
| 1845 | < $(srcdir)/pthread.in.h > $@-t1 | ||
| 1846 | $(AM_V_at)sed \ | ||
| 1847 | -e 's|@''HAVE_PTHREAD_ONCE''@|$(HAVE_PTHREAD_ONCE)|g' \ | ||
| 1848 | -e 's|@''HAVE_PTHREAD_MUTEX_INIT''@|$(HAVE_PTHREAD_MUTEX_INIT)|g' \ | ||
| 1849 | -e 's|@''HAVE_PTHREAD_MUTEXATTR_INIT''@|$(HAVE_PTHREAD_MUTEXATTR_INIT)|g' \ | ||
| 1850 | -e 's|@''HAVE_PTHREAD_MUTEXATTR_GETTYPE''@|$(HAVE_PTHREAD_MUTEXATTR_GETTYPE)|g' \ | ||
| 1851 | -e 's|@''HAVE_PTHREAD_MUTEXATTR_SETTYPE''@|$(HAVE_PTHREAD_MUTEXATTR_SETTYPE)|g' \ | ||
| 1852 | -e 's|@''HAVE_PTHREAD_MUTEXATTR_GETROBUST''@|$(HAVE_PTHREAD_MUTEXATTR_GETROBUST)|g' \ | ||
| 1853 | -e 's|@''HAVE_PTHREAD_MUTEXATTR_SETROBUST''@|$(HAVE_PTHREAD_MUTEXATTR_SETROBUST)|g' \ | ||
| 1854 | -e 's|@''HAVE_PTHREAD_MUTEXATTR_DESTROY''@|$(HAVE_PTHREAD_MUTEXATTR_DESTROY)|g' \ | ||
| 1855 | -e 's|@''HAVE_PTHREAD_MUTEX_LOCK''@|$(HAVE_PTHREAD_MUTEX_LOCK)|g' \ | ||
| 1856 | -e 's|@''HAVE_PTHREAD_MUTEX_TRYLOCK''@|$(HAVE_PTHREAD_MUTEX_TRYLOCK)|g' \ | ||
| 1857 | -e 's|@''HAVE_PTHREAD_MUTEX_TIMEDLOCK''@|$(HAVE_PTHREAD_MUTEX_TIMEDLOCK)|g' \ | ||
| 1858 | -e 's|@''HAVE_PTHREAD_MUTEX_UNLOCK''@|$(HAVE_PTHREAD_MUTEX_UNLOCK)|g' \ | ||
| 1859 | -e 's|@''HAVE_PTHREAD_MUTEX_DESTROY''@|$(HAVE_PTHREAD_MUTEX_DESTROY)|g' \ | ||
| 1860 | -e 's|@''HAVE_PTHREAD_RWLOCK_INIT''@|$(HAVE_PTHREAD_RWLOCK_INIT)|g' \ | ||
| 1861 | -e 's|@''HAVE_PTHREAD_RWLOCKATTR_INIT''@|$(HAVE_PTHREAD_RWLOCKATTR_INIT)|g' \ | ||
| 1862 | -e 's|@''HAVE_PTHREAD_RWLOCKATTR_DESTROY''@|$(HAVE_PTHREAD_RWLOCKATTR_DESTROY)|g' \ | ||
| 1863 | -e 's|@''HAVE_PTHREAD_RWLOCK_RDLOCK''@|$(HAVE_PTHREAD_RWLOCK_RDLOCK)|g' \ | ||
| 1864 | -e 's|@''HAVE_PTHREAD_RWLOCK_WRLOCK''@|$(HAVE_PTHREAD_RWLOCK_WRLOCK)|g' \ | ||
| 1865 | -e 's|@''HAVE_PTHREAD_RWLOCK_TRYRDLOCK''@|$(HAVE_PTHREAD_RWLOCK_TRYRDLOCK)|g' \ | ||
| 1866 | -e 's|@''HAVE_PTHREAD_RWLOCK_TRYWRLOCK''@|$(HAVE_PTHREAD_RWLOCK_TRYWRLOCK)|g' \ | ||
| 1867 | -e 's|@''HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK''@|$(HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK)|g' \ | ||
| 1868 | -e 's|@''HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK''@|$(HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK)|g' \ | ||
| 1869 | -e 's|@''HAVE_PTHREAD_RWLOCK_UNLOCK''@|$(HAVE_PTHREAD_RWLOCK_UNLOCK)|g' \ | ||
| 1870 | -e 's|@''HAVE_PTHREAD_RWLOCK_DESTROY''@|$(HAVE_PTHREAD_RWLOCK_DESTROY)|g' \ | ||
| 1871 | -e 's|@''HAVE_PTHREAD_COND_INIT''@|$(HAVE_PTHREAD_COND_INIT)|g' \ | ||
| 1872 | -e 's|@''HAVE_PTHREAD_CONDATTR_INIT''@|$(HAVE_PTHREAD_CONDATTR_INIT)|g' \ | ||
| 1873 | -e 's|@''HAVE_PTHREAD_CONDATTR_DESTROY''@|$(HAVE_PTHREAD_CONDATTR_DESTROY)|g' \ | ||
| 1874 | -e 's|@''HAVE_PTHREAD_COND_WAIT''@|$(HAVE_PTHREAD_COND_WAIT)|g' \ | ||
| 1875 | -e 's|@''HAVE_PTHREAD_COND_TIMEDWAIT''@|$(HAVE_PTHREAD_COND_TIMEDWAIT)|g' \ | ||
| 1876 | -e 's|@''HAVE_PTHREAD_COND_SIGNAL''@|$(HAVE_PTHREAD_COND_SIGNAL)|g' \ | ||
| 1877 | -e 's|@''HAVE_PTHREAD_COND_BROADCAST''@|$(HAVE_PTHREAD_COND_BROADCAST)|g' \ | ||
| 1878 | -e 's|@''HAVE_PTHREAD_COND_DESTROY''@|$(HAVE_PTHREAD_COND_DESTROY)|g' \ | ||
| 1879 | -e 's|@''HAVE_PTHREAD_KEY_CREATE''@|$(HAVE_PTHREAD_KEY_CREATE)|g' \ | ||
| 1880 | -e 's|@''HAVE_PTHREAD_SETSPECIFIC''@|$(HAVE_PTHREAD_SETSPECIFIC)|g' \ | ||
| 1881 | -e 's|@''HAVE_PTHREAD_GETSPECIFIC''@|$(HAVE_PTHREAD_GETSPECIFIC)|g' \ | ||
| 1882 | -e 's|@''HAVE_PTHREAD_KEY_DELETE''@|$(HAVE_PTHREAD_KEY_DELETE)|g' \ | ||
| 1883 | -e 's|@''HAVE_PTHREAD_SPIN_INIT''@|$(HAVE_PTHREAD_SPIN_INIT)|g' \ | ||
| 1884 | -e 's|@''HAVE_PTHREAD_SPIN_LOCK''@|$(HAVE_PTHREAD_SPIN_LOCK)|g' \ | ||
| 1885 | -e 's|@''HAVE_PTHREAD_SPIN_TRYLOCK''@|$(HAVE_PTHREAD_SPIN_TRYLOCK)|g' \ | ||
| 1886 | -e 's|@''HAVE_PTHREAD_SPIN_UNLOCK''@|$(HAVE_PTHREAD_SPIN_UNLOCK)|g' \ | ||
| 1887 | -e 's|@''HAVE_PTHREAD_SPIN_DESTROY''@|$(HAVE_PTHREAD_SPIN_DESTROY)|g' \ | ||
| 1888 | < $@-t1 > $@-t2 | ||
| 1889 | $(AM_V_at)sed \ | ||
| 1890 | -e 's|@''REPLACE_PTHREAD_CREATE''@|$(REPLACE_PTHREAD_CREATE)|g' \ | ||
| 1891 | -e 's|@''REPLACE_PTHREAD_ATTR_INIT''@|$(REPLACE_PTHREAD_ATTR_INIT)|g' \ | ||
| 1892 | -e 's|@''REPLACE_PTHREAD_ATTR_GETDETACHSTATE''@|$(REPLACE_PTHREAD_ATTR_GETDETACHSTATE)|g' \ | ||
| 1893 | -e 's|@''REPLACE_PTHREAD_ATTR_SETDETACHSTATE''@|$(REPLACE_PTHREAD_ATTR_SETDETACHSTATE)|g' \ | ||
| 1894 | -e 's|@''REPLACE_PTHREAD_ATTR_DESTROY''@|$(REPLACE_PTHREAD_ATTR_DESTROY)|g' \ | ||
| 1895 | -e 's|@''REPLACE_PTHREAD_SELF''@|$(REPLACE_PTHREAD_SELF)|g' \ | ||
| 1896 | -e 's|@''REPLACE_PTHREAD_EQUAL''@|$(REPLACE_PTHREAD_EQUAL)|g' \ | ||
| 1897 | -e 's|@''REPLACE_PTHREAD_DETACH''@|$(REPLACE_PTHREAD_DETACH)|g' \ | ||
| 1898 | -e 's|@''REPLACE_PTHREAD_JOIN''@|$(REPLACE_PTHREAD_JOIN)|g' \ | ||
| 1899 | -e 's|@''REPLACE_PTHREAD_EXIT''@|$(REPLACE_PTHREAD_EXIT)|g' \ | ||
| 1900 | -e 's|@''REPLACE_PTHREAD_ONCE''@|$(REPLACE_PTHREAD_ONCE)|g' \ | ||
| 1901 | -e 's|@''REPLACE_PTHREAD_MUTEX_INIT''@|$(REPLACE_PTHREAD_MUTEX_INIT)|g' \ | ||
| 1902 | -e 's|@''REPLACE_PTHREAD_MUTEXATTR_INIT''@|$(REPLACE_PTHREAD_MUTEXATTR_INIT)|g' \ | ||
| 1903 | -e 's|@''REPLACE_PTHREAD_MUTEXATTR_GETTYPE''@|$(REPLACE_PTHREAD_MUTEXATTR_GETTYPE)|g' \ | ||
| 1904 | -e 's|@''REPLACE_PTHREAD_MUTEXATTR_SETTYPE''@|$(REPLACE_PTHREAD_MUTEXATTR_SETTYPE)|g' \ | ||
| 1905 | -e 's|@''REPLACE_PTHREAD_MUTEXATTR_GETROBUST''@|$(REPLACE_PTHREAD_MUTEXATTR_GETROBUST)|g' \ | ||
| 1906 | -e 's|@''REPLACE_PTHREAD_MUTEXATTR_SETROBUST''@|$(REPLACE_PTHREAD_MUTEXATTR_SETROBUST)|g' \ | ||
| 1907 | -e 's|@''REPLACE_PTHREAD_MUTEXATTR_DESTROY''@|$(REPLACE_PTHREAD_MUTEXATTR_DESTROY)|g' \ | ||
| 1908 | -e 's|@''REPLACE_PTHREAD_MUTEX_LOCK''@|$(REPLACE_PTHREAD_MUTEX_LOCK)|g' \ | ||
| 1909 | -e 's|@''REPLACE_PTHREAD_MUTEX_TRYLOCK''@|$(REPLACE_PTHREAD_MUTEX_TRYLOCK)|g' \ | ||
| 1910 | -e 's|@''REPLACE_PTHREAD_MUTEX_TIMEDLOCK''@|$(REPLACE_PTHREAD_MUTEX_TIMEDLOCK)|g' \ | ||
| 1911 | -e 's|@''REPLACE_PTHREAD_MUTEX_UNLOCK''@|$(REPLACE_PTHREAD_MUTEX_UNLOCK)|g' \ | ||
| 1912 | -e 's|@''REPLACE_PTHREAD_MUTEX_DESTROY''@|$(REPLACE_PTHREAD_MUTEX_DESTROY)|g' \ | ||
| 1913 | -e 's|@''REPLACE_PTHREAD_RWLOCK_INIT''@|$(REPLACE_PTHREAD_RWLOCK_INIT)|g' \ | ||
| 1914 | -e 's|@''REPLACE_PTHREAD_RWLOCKATTR_INIT''@|$(REPLACE_PTHREAD_RWLOCKATTR_INIT)|g' \ | ||
| 1915 | -e 's|@''REPLACE_PTHREAD_RWLOCKATTR_DESTROY''@|$(REPLACE_PTHREAD_RWLOCKATTR_DESTROY)|g' \ | ||
| 1916 | -e 's|@''REPLACE_PTHREAD_RWLOCK_RDLOCK''@|$(REPLACE_PTHREAD_RWLOCK_RDLOCK)|g' \ | ||
| 1917 | -e 's|@''REPLACE_PTHREAD_RWLOCK_WRLOCK''@|$(REPLACE_PTHREAD_RWLOCK_WRLOCK)|g' \ | ||
| 1918 | -e 's|@''REPLACE_PTHREAD_RWLOCK_TRYRDLOCK''@|$(REPLACE_PTHREAD_RWLOCK_TRYRDLOCK)|g' \ | ||
| 1919 | -e 's|@''REPLACE_PTHREAD_RWLOCK_TRYWRLOCK''@|$(REPLACE_PTHREAD_RWLOCK_TRYWRLOCK)|g' \ | ||
| 1920 | -e 's|@''REPLACE_PTHREAD_RWLOCK_TIMEDRDLOCK''@|$(REPLACE_PTHREAD_RWLOCK_TIMEDRDLOCK)|g' \ | ||
| 1921 | -e 's|@''REPLACE_PTHREAD_RWLOCK_TIMEDWRLOCK''@|$(REPLACE_PTHREAD_RWLOCK_TIMEDWRLOCK)|g' \ | ||
| 1922 | -e 's|@''REPLACE_PTHREAD_RWLOCK_UNLOCK''@|$(REPLACE_PTHREAD_RWLOCK_UNLOCK)|g' \ | ||
| 1923 | -e 's|@''REPLACE_PTHREAD_RWLOCK_DESTROY''@|$(REPLACE_PTHREAD_RWLOCK_DESTROY)|g' \ | ||
| 1924 | < $@-t2 > $@-t3 | ||
| 1925 | $(AM_V_at)sed \ | ||
| 1926 | -e 's|@''REPLACE_PTHREAD_COND_INIT''@|$(REPLACE_PTHREAD_COND_INIT)|g' \ | ||
| 1927 | -e 's|@''REPLACE_PTHREAD_CONDATTR_INIT''@|$(REPLACE_PTHREAD_CONDATTR_INIT)|g' \ | ||
| 1928 | -e 's|@''REPLACE_PTHREAD_CONDATTR_DESTROY''@|$(REPLACE_PTHREAD_CONDATTR_DESTROY)|g' \ | ||
| 1929 | -e 's|@''REPLACE_PTHREAD_COND_WAIT''@|$(REPLACE_PTHREAD_COND_WAIT)|g' \ | ||
| 1930 | -e 's|@''REPLACE_PTHREAD_COND_TIMEDWAIT''@|$(REPLACE_PTHREAD_COND_TIMEDWAIT)|g' \ | ||
| 1931 | -e 's|@''REPLACE_PTHREAD_COND_SIGNAL''@|$(REPLACE_PTHREAD_COND_SIGNAL)|g' \ | ||
| 1932 | -e 's|@''REPLACE_PTHREAD_COND_BROADCAST''@|$(REPLACE_PTHREAD_COND_BROADCAST)|g' \ | ||
| 1933 | -e 's|@''REPLACE_PTHREAD_COND_DESTROY''@|$(REPLACE_PTHREAD_COND_DESTROY)|g' \ | ||
| 1934 | -e 's|@''REPLACE_PTHREAD_KEY_CREATE''@|$(REPLACE_PTHREAD_KEY_CREATE)|g' \ | ||
| 1935 | -e 's|@''REPLACE_PTHREAD_SETSPECIFIC''@|$(REPLACE_PTHREAD_SETSPECIFIC)|g' \ | ||
| 1936 | -e 's|@''REPLACE_PTHREAD_GETSPECIFIC''@|$(REPLACE_PTHREAD_GETSPECIFIC)|g' \ | ||
| 1937 | -e 's|@''REPLACE_PTHREAD_KEY_DELETE''@|$(REPLACE_PTHREAD_KEY_DELETE)|g' \ | ||
| 1938 | -e 's|@''REPLACE_PTHREAD_SPIN_INIT''@|$(REPLACE_PTHREAD_SPIN_INIT)|g' \ | ||
| 1939 | -e 's|@''REPLACE_PTHREAD_SPIN_LOCK''@|$(REPLACE_PTHREAD_SPIN_LOCK)|g' \ | ||
| 1940 | -e 's|@''REPLACE_PTHREAD_SPIN_TRYLOCK''@|$(REPLACE_PTHREAD_SPIN_TRYLOCK)|g' \ | ||
| 1941 | -e 's|@''REPLACE_PTHREAD_SPIN_UNLOCK''@|$(REPLACE_PTHREAD_SPIN_UNLOCK)|g' \ | ||
| 1942 | -e 's|@''REPLACE_PTHREAD_SPIN_DESTROY''@|$(REPLACE_PTHREAD_SPIN_DESTROY)|g' \ | ||
| 1943 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ | ||
| 1944 | -e '/definition of _Noreturn/r $(_NORETURN_H)' \ | ||
| 1945 | -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ | ||
| 1946 | -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ | ||
| 1947 | < $@-t3 > $@-t4 | ||
| 1948 | $(AM_V_at)rm -f $@-t1 $@-t2 $@-t3 | ||
| 1949 | $(AM_V_at)mv $@-t4 $@ | ||
| 1950 | MOSTLYCLEANFILES += pthread.h pthread.h-t1 pthread.h-t2 pthread.h-t3 pthread.h-t4 | ||
| 1609 | 1951 | ||
| 1610 | EXTRA_DIST += realloc.c | 1952 | EXTRA_DIST += pthread.in.h |
| 1611 | 1953 | ||
| 1612 | EXTRA_libgnu_a_SOURCES += realloc.c | 1954 | ## end gnulib module pthread-h |
| 1613 | 1955 | ||
| 1614 | ## end gnulib module realloc-gnu | 1956 | ## begin gnulib module pthread-once |
| 1615 | 1957 | ||
| 1616 | ## begin gnulib module realloc-posix | 1958 | if GL_COND_OBJ_PTHREAD_ONCE |
| 1959 | libgnu_a_SOURCES += pthread-once.c | ||
| 1960 | endif | ||
| 1617 | 1961 | ||
| 1962 | ## end gnulib module pthread-once | ||
| 1618 | 1963 | ||
| 1619 | EXTRA_DIST += realloc.c | 1964 | ## begin gnulib module realloc-posix |
| 1620 | 1965 | ||
| 1621 | EXTRA_libgnu_a_SOURCES += realloc.c | 1966 | if GL_COND_OBJ_REALLOC_POSIX |
| 1967 | libgnu_a_SOURCES += realloc.c | ||
| 1968 | endif | ||
| 1622 | 1969 | ||
| 1623 | ## end gnulib module realloc-posix | 1970 | ## end gnulib module realloc-posix |
| 1624 | 1971 | ||
| @@ -1642,6 +1989,35 @@ EXTRA_libgnu_a_SOURCES += regcomp.c regex_internal.c regexec.c | |||
| 1642 | 1989 | ||
| 1643 | ## end gnulib module regex | 1990 | ## end gnulib module regex |
| 1644 | 1991 | ||
| 1992 | ## begin gnulib module sched-h | ||
| 1993 | |||
| 1994 | BUILT_SOURCES += sched.h | ||
| 1995 | |||
| 1996 | # We need the following in order to create a replacement for <sched.h> when | ||
| 1997 | # the system doesn't have one. | ||
| 1998 | sched.h: sched.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) | ||
| 1999 | $(gl_V_at)$(SED_HEADER_STDOUT) \ | ||
| 2000 | -e 's|@''GUARD_PREFIX''@|GL|g' \ | ||
| 2001 | -e 's|@''HAVE_SCHED_H''@|$(HAVE_SCHED_H)|g' \ | ||
| 2002 | -e 's|@''HAVE_SYS_CDEFS_H''@|$(HAVE_SYS_CDEFS_H)|g' \ | ||
| 2003 | -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ | ||
| 2004 | -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ | ||
| 2005 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | ||
| 2006 | -e 's|@''NEXT_SCHED_H''@|$(NEXT_SCHED_H)|g' \ | ||
| 2007 | -e 's|@''HAVE_STRUCT_SCHED_PARAM''@|$(HAVE_STRUCT_SCHED_PARAM)|g' \ | ||
| 2008 | -e 's/@''GNULIB_SCHED_YIELD''@/$(GL_GNULIB_SCHED_YIELD)/g' \ | ||
| 2009 | -e 's|@''HAVE_SCHED_YIELD''@|$(HAVE_SCHED_YIELD)|g' \ | ||
| 2010 | -e 's|@''REPLACE_SCHED_YIELD''@|$(REPLACE_SCHED_YIELD)|g' \ | ||
| 2011 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ | ||
| 2012 | -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ | ||
| 2013 | $(srcdir)/sched.in.h > $@-t | ||
| 2014 | $(AM_V_at)mv $@-t $@ | ||
| 2015 | MOSTLYCLEANFILES += sched.h sched.h-t | ||
| 2016 | |||
| 2017 | EXTRA_DIST += sched.in.h | ||
| 2018 | |||
| 2019 | ## end gnulib module sched-h | ||
| 2020 | |||
| 1645 | ## begin gnulib module setenv | 2021 | ## begin gnulib module setenv |
| 1646 | 2022 | ||
| 1647 | if GL_COND_OBJ_SETENV | 2023 | if GL_COND_OBJ_SETENV |
| @@ -1760,7 +2136,7 @@ EXTRA_DIST += stat-time.h | |||
| 1760 | 2136 | ||
| 1761 | ## end gnulib module stat-time | 2137 | ## end gnulib module stat-time |
| 1762 | 2138 | ||
| 1763 | ## begin gnulib module stdckdint | 2139 | ## begin gnulib module stdckdint-h |
| 1764 | 2140 | ||
| 1765 | BUILT_SOURCES += $(STDCKDINT_H) | 2141 | BUILT_SOURCES += $(STDCKDINT_H) |
| 1766 | 2142 | ||
| @@ -1769,6 +2145,15 @@ BUILT_SOURCES += $(STDCKDINT_H) | |||
| 1769 | if GL_GENERATE_STDCKDINT_H | 2145 | if GL_GENERATE_STDCKDINT_H |
| 1770 | stdckdint.h: stdckdint.in.h $(top_builddir)/config.status | 2146 | stdckdint.h: stdckdint.in.h $(top_builddir)/config.status |
| 1771 | $(gl_V_at)$(SED_HEADER_STDOUT) \ | 2147 | $(gl_V_at)$(SED_HEADER_STDOUT) \ |
| 2148 | -e 's|@''GUARD_PREFIX''@|GL|g' \ | ||
| 2149 | -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ | ||
| 2150 | -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ | ||
| 2151 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | ||
| 2152 | -e 's|@''NEXT_STDCKDINT_H''@|$(NEXT_STDCKDINT_H)|g' \ | ||
| 2153 | -e 's|@''HAVE_C_STDCKDINT_H''@|$(HAVE_C_STDCKDINT_H)|g' \ | ||
| 2154 | -e 's|@''HAVE_WORKING_C_STDCKDINT_H''@|$(HAVE_WORKING_C_STDCKDINT_H)|g' \ | ||
| 2155 | -e 's|@''HAVE_CXX_STDCKDINT_H''@|$(HAVE_CXX_STDCKDINT_H)|g' \ | ||
| 2156 | -e 's|@''HAVE_WORKING_CXX_STDCKDINT_H''@|$(HAVE_WORKING_CXX_STDCKDINT_H)|g' \ | ||
| 1772 | $(srcdir)/stdckdint.in.h > $@-t | 2157 | $(srcdir)/stdckdint.in.h > $@-t |
| 1773 | $(AM_V_at)mv $@-t $@ | 2158 | $(AM_V_at)mv $@-t $@ |
| 1774 | else | 2159 | else |
| @@ -1779,9 +2164,9 @@ MOSTLYCLEANFILES += stdckdint.h stdckdint.h-t | |||
| 1779 | 2164 | ||
| 1780 | EXTRA_DIST += intprops-internal.h stdckdint.in.h | 2165 | EXTRA_DIST += intprops-internal.h stdckdint.in.h |
| 1781 | 2166 | ||
| 1782 | ## end gnulib module stdckdint | 2167 | ## end gnulib module stdckdint-h |
| 1783 | 2168 | ||
| 1784 | ## begin gnulib module stddef | 2169 | ## begin gnulib module stddef-h |
| 1785 | 2170 | ||
| 1786 | BUILT_SOURCES += $(STDDEF_H) | 2171 | BUILT_SOURCES += $(STDDEF_H) |
| 1787 | 2172 | ||
| @@ -1795,9 +2180,11 @@ stddef.h: stddef.in.h $(top_builddir)/config.status | |||
| 1795 | -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ | 2180 | -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ |
| 1796 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | 2181 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ |
| 1797 | -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \ | 2182 | -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \ |
| 1798 | -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \ | 2183 | -e 's|@''NULLPTR_T_NEEDS_STDDEF''@|$(NULLPTR_T_NEEDS_STDDEF)|g' \ |
| 1799 | -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \ | 2184 | -e 's|@''STDDEF_NOT_IDEMPOTENT''@|$(STDDEF_NOT_IDEMPOTENT)|g' \ |
| 1800 | -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ | 2185 | -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ |
| 2186 | -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \ | ||
| 2187 | -e 's|@''HAVE_C_UNREACHABLE''@|$(HAVE_C_UNREACHABLE)|g' \ | ||
| 1801 | $(srcdir)/stddef.in.h > $@-t | 2188 | $(srcdir)/stddef.in.h > $@-t |
| 1802 | $(AM_V_at)mv $@-t $@ | 2189 | $(AM_V_at)mv $@-t $@ |
| 1803 | else | 2190 | else |
| @@ -1808,9 +2195,9 @@ MOSTLYCLEANFILES += stddef.h stddef.h-t | |||
| 1808 | 2195 | ||
| 1809 | EXTRA_DIST += stddef.in.h | 2196 | EXTRA_DIST += stddef.in.h |
| 1810 | 2197 | ||
| 1811 | ## end gnulib module stddef | 2198 | ## end gnulib module stddef-h |
| 1812 | 2199 | ||
| 1813 | ## begin gnulib module stdint | 2200 | ## begin gnulib module stdint-h |
| 1814 | 2201 | ||
| 1815 | BUILT_SOURCES += $(STDINT_H) | 2202 | BUILT_SOURCES += $(STDINT_H) |
| 1816 | 2203 | ||
| @@ -1856,9 +2243,9 @@ MOSTLYCLEANFILES += stdint.h stdint.h-t | |||
| 1856 | 2243 | ||
| 1857 | EXTRA_DIST += stdint.in.h | 2244 | EXTRA_DIST += stdint.in.h |
| 1858 | 2245 | ||
| 1859 | ## end gnulib module stdint | 2246 | ## end gnulib module stdint-h |
| 1860 | 2247 | ||
| 1861 | ## begin gnulib module stdio | 2248 | ## begin gnulib module stdio-h |
| 1862 | 2249 | ||
| 1863 | BUILT_SOURCES += stdio.h | 2250 | BUILT_SOURCES += stdio.h |
| 1864 | 2251 | ||
| @@ -1872,6 +2259,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) | |||
| 1872 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | 2259 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ |
| 1873 | -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ | 2260 | -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ |
| 1874 | -e 's/@''GNULIB_DPRINTF''@/$(GL_GNULIB_DPRINTF)/g' \ | 2261 | -e 's/@''GNULIB_DPRINTF''@/$(GL_GNULIB_DPRINTF)/g' \ |
| 2262 | -e 's/@''GNULIB_DZPRINTF''@/$(GL_GNULIB_DZPRINTF)/g' \ | ||
| 1875 | -e 's/@''GNULIB_FCLOSE''@/$(GL_GNULIB_FCLOSE)/g' \ | 2263 | -e 's/@''GNULIB_FCLOSE''@/$(GL_GNULIB_FCLOSE)/g' \ |
| 1876 | -e 's/@''GNULIB_FDOPEN''@/$(GL_GNULIB_FDOPEN)/g' \ | 2264 | -e 's/@''GNULIB_FDOPEN''@/$(GL_GNULIB_FDOPEN)/g' \ |
| 1877 | -e 's/@''GNULIB_FFLUSH''@/$(GL_GNULIB_FFLUSH)/g' \ | 2265 | -e 's/@''GNULIB_FFLUSH''@/$(GL_GNULIB_FFLUSH)/g' \ |
| @@ -1892,12 +2280,14 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) | |||
| 1892 | -e 's/@''GNULIB_FTELL''@/$(GL_GNULIB_FTELL)/g' \ | 2280 | -e 's/@''GNULIB_FTELL''@/$(GL_GNULIB_FTELL)/g' \ |
| 1893 | -e 's/@''GNULIB_FTELLO''@/$(GL_GNULIB_FTELLO)/g' \ | 2281 | -e 's/@''GNULIB_FTELLO''@/$(GL_GNULIB_FTELLO)/g' \ |
| 1894 | -e 's/@''GNULIB_FWRITE''@/$(GL_GNULIB_FWRITE)/g' \ | 2282 | -e 's/@''GNULIB_FWRITE''@/$(GL_GNULIB_FWRITE)/g' \ |
| 2283 | -e 's/@''GNULIB_FZPRINTF''@/$(GL_GNULIB_FZPRINTF)/g' \ | ||
| 1895 | -e 's/@''GNULIB_GETC''@/$(GL_GNULIB_GETC)/g' \ | 2284 | -e 's/@''GNULIB_GETC''@/$(GL_GNULIB_GETC)/g' \ |
| 1896 | -e 's/@''GNULIB_GETCHAR''@/$(GL_GNULIB_GETCHAR)/g' \ | 2285 | -e 's/@''GNULIB_GETCHAR''@/$(GL_GNULIB_GETCHAR)/g' \ |
| 1897 | -e 's/@''GNULIB_GETDELIM''@/$(GL_GNULIB_GETDELIM)/g' \ | 2286 | -e 's/@''GNULIB_GETDELIM''@/$(GL_GNULIB_GETDELIM)/g' \ |
| 1898 | -e 's/@''GNULIB_GETLINE''@/$(GL_GNULIB_GETLINE)/g' \ | 2287 | -e 's/@''GNULIB_GETLINE''@/$(GL_GNULIB_GETLINE)/g' \ |
| 1899 | -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GL_GNULIB_OBSTACK_PRINTF)/g' \ | 2288 | -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GL_GNULIB_OBSTACK_PRINTF)/g' \ |
| 1900 | -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GL_GNULIB_OBSTACK_PRINTF_POSIX)/g' \ | 2289 | -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GL_GNULIB_OBSTACK_PRINTF_POSIX)/g' \ |
| 2290 | -e 's/@''GNULIB_OBSTACK_ZPRINTF''@/$(GL_GNULIB_OBSTACK_ZPRINTF)/g' \ | ||
| 1901 | -e 's/@''GNULIB_PCLOSE''@/$(GL_GNULIB_PCLOSE)/g' \ | 2291 | -e 's/@''GNULIB_PCLOSE''@/$(GL_GNULIB_PCLOSE)/g' \ |
| 1902 | -e 's/@''GNULIB_PERROR''@/$(GL_GNULIB_PERROR)/g' \ | 2292 | -e 's/@''GNULIB_PERROR''@/$(GL_GNULIB_PERROR)/g' \ |
| 1903 | -e 's/@''GNULIB_POPEN''@/$(GL_GNULIB_POPEN)/g' \ | 2293 | -e 's/@''GNULIB_POPEN''@/$(GL_GNULIB_POPEN)/g' \ |
| @@ -1911,20 +2301,29 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) | |||
| 1911 | -e 's/@''GNULIB_RENAMEAT''@/$(GL_GNULIB_RENAMEAT)/g' \ | 2301 | -e 's/@''GNULIB_RENAMEAT''@/$(GL_GNULIB_RENAMEAT)/g' \ |
| 1912 | -e 's/@''GNULIB_SCANF''@/$(GL_GNULIB_SCANF)/g' \ | 2302 | -e 's/@''GNULIB_SCANF''@/$(GL_GNULIB_SCANF)/g' \ |
| 1913 | -e 's/@''GNULIB_SNPRINTF''@/$(GL_GNULIB_SNPRINTF)/g' \ | 2303 | -e 's/@''GNULIB_SNPRINTF''@/$(GL_GNULIB_SNPRINTF)/g' \ |
| 2304 | -e 's/@''GNULIB_SNZPRINTF''@/$(GL_GNULIB_SNZPRINTF)/g' \ | ||
| 1914 | -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GL_GNULIB_SPRINTF_POSIX)/g' \ | 2305 | -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GL_GNULIB_SPRINTF_POSIX)/g' \ |
| 1915 | -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GL_GNULIB_STDIO_H_NONBLOCKING)/g' \ | 2306 | -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GL_GNULIB_STDIO_H_NONBLOCKING)/g' \ |
| 1916 | -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GL_GNULIB_STDIO_H_SIGPIPE)/g' \ | 2307 | -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GL_GNULIB_STDIO_H_SIGPIPE)/g' \ |
| 2308 | -e 's/@''GNULIB_SZPRINTF''@/$(GL_GNULIB_SZPRINTF)/g' \ | ||
| 1917 | -e 's/@''GNULIB_TMPFILE''@/$(GL_GNULIB_TMPFILE)/g' \ | 2309 | -e 's/@''GNULIB_TMPFILE''@/$(GL_GNULIB_TMPFILE)/g' \ |
| 1918 | -e 's/@''GNULIB_VASPRINTF''@/$(GL_GNULIB_VASPRINTF)/g' \ | 2310 | -e 's/@''GNULIB_VASPRINTF''@/$(GL_GNULIB_VASPRINTF)/g' \ |
| 2311 | -e 's/@''GNULIB_VASZPRINTF''@/$(GL_GNULIB_VASZPRINTF)/g' \ | ||
| 1919 | -e 's/@''GNULIB_VDPRINTF''@/$(GL_GNULIB_VDPRINTF)/g' \ | 2312 | -e 's/@''GNULIB_VDPRINTF''@/$(GL_GNULIB_VDPRINTF)/g' \ |
| 2313 | -e 's/@''GNULIB_VDZPRINTF''@/$(GL_GNULIB_VDZPRINTF)/g' \ | ||
| 1920 | -e 's/@''GNULIB_VFPRINTF''@/$(GL_GNULIB_VFPRINTF)/g' \ | 2314 | -e 's/@''GNULIB_VFPRINTF''@/$(GL_GNULIB_VFPRINTF)/g' \ |
| 1921 | -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GL_GNULIB_VFPRINTF_POSIX)/g' \ | 2315 | -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GL_GNULIB_VFPRINTF_POSIX)/g' \ |
| 2316 | -e 's/@''GNULIB_VFZPRINTF''@/$(GL_GNULIB_VFZPRINTF)/g' \ | ||
| 1922 | -e 's/@''GNULIB_VFSCANF''@/$(GL_GNULIB_VFSCANF)/g' \ | 2317 | -e 's/@''GNULIB_VFSCANF''@/$(GL_GNULIB_VFSCANF)/g' \ |
| 1923 | -e 's/@''GNULIB_VSCANF''@/$(GL_GNULIB_VSCANF)/g' \ | 2318 | -e 's/@''GNULIB_VSCANF''@/$(GL_GNULIB_VSCANF)/g' \ |
| 1924 | -e 's/@''GNULIB_VPRINTF''@/$(GL_GNULIB_VPRINTF)/g' \ | 2319 | -e 's/@''GNULIB_VPRINTF''@/$(GL_GNULIB_VPRINTF)/g' \ |
| 1925 | -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GL_GNULIB_VPRINTF_POSIX)/g' \ | 2320 | -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GL_GNULIB_VPRINTF_POSIX)/g' \ |
| 1926 | -e 's/@''GNULIB_VSNPRINTF''@/$(GL_GNULIB_VSNPRINTF)/g' \ | 2321 | -e 's/@''GNULIB_VSNPRINTF''@/$(GL_GNULIB_VSNPRINTF)/g' \ |
| 2322 | -e 's/@''GNULIB_VSNZPRINTF''@/$(GL_GNULIB_VSNZPRINTF)/g' \ | ||
| 1927 | -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GL_GNULIB_VSPRINTF_POSIX)/g' \ | 2323 | -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GL_GNULIB_VSPRINTF_POSIX)/g' \ |
| 2324 | -e 's/@''GNULIB_VSZPRINTF''@/$(GL_GNULIB_VSZPRINTF)/g' \ | ||
| 2325 | -e 's/@''GNULIB_VZPRINTF''@/$(GL_GNULIB_VZPRINTF)/g' \ | ||
| 2326 | -e 's/@''GNULIB_ZPRINTF''@/$(GL_GNULIB_ZPRINTF)/g' \ | ||
| 1928 | -e 's/@''GNULIB_MDA_FCLOSEALL''@/$(GL_GNULIB_MDA_FCLOSEALL)/g' \ | 2327 | -e 's/@''GNULIB_MDA_FCLOSEALL''@/$(GL_GNULIB_MDA_FCLOSEALL)/g' \ |
| 1929 | -e 's/@''GNULIB_MDA_FDOPEN''@/$(GL_GNULIB_MDA_FDOPEN)/g' \ | 2328 | -e 's/@''GNULIB_MDA_FDOPEN''@/$(GL_GNULIB_MDA_FDOPEN)/g' \ |
| 1930 | -e 's/@''GNULIB_MDA_FILENO''@/$(GL_GNULIB_MDA_FILENO)/g' \ | 2329 | -e 's/@''GNULIB_MDA_FILENO''@/$(GL_GNULIB_MDA_FILENO)/g' \ |
| @@ -1996,6 +2395,9 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) | |||
| 1996 | $(AM_V_at)mv $@-t3 $@ | 2395 | $(AM_V_at)mv $@-t3 $@ |
| 1997 | MOSTLYCLEANFILES += stdio.h stdio.h-t1 stdio.h-t2 stdio.h-t3 | 2396 | MOSTLYCLEANFILES += stdio.h stdio.h-t1 stdio.h-t2 stdio.h-t3 |
| 1998 | 2397 | ||
| 2398 | if GL_COND_OBJ_STDIO_CONSOLESAFE | ||
| 2399 | libgnu_a_SOURCES += stdio-consolesafe.c | ||
| 2400 | endif | ||
| 1999 | if GL_COND_OBJ_STDIO_READ | 2401 | if GL_COND_OBJ_STDIO_READ |
| 2000 | libgnu_a_SOURCES += stdio-read.c | 2402 | libgnu_a_SOURCES += stdio-read.c |
| 2001 | endif | 2403 | endif |
| @@ -2005,14 +2407,13 @@ endif | |||
| 2005 | 2407 | ||
| 2006 | EXTRA_DIST += stdio.in.h | 2408 | EXTRA_DIST += stdio.in.h |
| 2007 | 2409 | ||
| 2008 | ## end gnulib module stdio | 2410 | ## end gnulib module stdio-h |
| 2009 | 2411 | ||
| 2010 | ## begin gnulib module stdlib | 2412 | ## begin gnulib module stdlib-h |
| 2011 | 2413 | ||
| 2012 | BUILT_SOURCES += stdlib.h | 2414 | BUILT_SOURCES += stdlib.h |
| 2415 | libgnu_a_SOURCES += stdlib.c | ||
| 2013 | 2416 | ||
| 2014 | # We need the following in order to create <stdlib.h> when the system | ||
| 2015 | # doesn't have one that works with the given compiler. | ||
| 2016 | stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ | 2417 | stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ |
| 2017 | $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) | 2418 | $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) |
| 2018 | $(gl_V_at)$(SED_HEADER_STDOUT) \ | 2419 | $(gl_V_at)$(SED_HEADER_STDOUT) \ |
| @@ -2022,6 +2423,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ | |||
| 2022 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | 2423 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ |
| 2023 | -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ | 2424 | -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ |
| 2024 | -e 's/@''GNULIB__EXIT''@/$(GL_GNULIB__EXIT)/g' \ | 2425 | -e 's/@''GNULIB__EXIT''@/$(GL_GNULIB__EXIT)/g' \ |
| 2426 | -e 's/@''GNULIB_ABORT_DEBUG''@/$(GL_GNULIB_ABORT_DEBUG)/g' \ | ||
| 2025 | -e 's/@''GNULIB_ALIGNED_ALLOC''@/$(GL_GNULIB_ALIGNED_ALLOC)/g' \ | 2427 | -e 's/@''GNULIB_ALIGNED_ALLOC''@/$(GL_GNULIB_ALIGNED_ALLOC)/g' \ |
| 2026 | -e 's/@''GNULIB_ATOLL''@/$(GL_GNULIB_ATOLL)/g' \ | 2428 | -e 's/@''GNULIB_ATOLL''@/$(GL_GNULIB_ATOLL)/g' \ |
| 2027 | -e 's/@''GNULIB_CALLOC_GNU''@/$(GL_GNULIB_CALLOC_GNU)/g' \ | 2429 | -e 's/@''GNULIB_CALLOC_GNU''@/$(GL_GNULIB_CALLOC_GNU)/g' \ |
| @@ -2050,13 +2452,13 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ | |||
| 2050 | -e 's/@''GNULIB_RAND''@/$(GL_GNULIB_RAND)/g' \ | 2452 | -e 's/@''GNULIB_RAND''@/$(GL_GNULIB_RAND)/g' \ |
| 2051 | -e 's/@''GNULIB_RANDOM''@/$(GL_GNULIB_RANDOM)/g' \ | 2453 | -e 's/@''GNULIB_RANDOM''@/$(GL_GNULIB_RANDOM)/g' \ |
| 2052 | -e 's/@''GNULIB_RANDOM_R''@/$(GL_GNULIB_RANDOM_R)/g' \ | 2454 | -e 's/@''GNULIB_RANDOM_R''@/$(GL_GNULIB_RANDOM_R)/g' \ |
| 2053 | -e 's/@''GNULIB_REALLOC_GNU''@/$(GL_GNULIB_REALLOC_GNU)/g' \ | ||
| 2054 | -e 's/@''GNULIB_REALLOC_POSIX''@/$(GL_GNULIB_REALLOC_POSIX)/g' \ | 2455 | -e 's/@''GNULIB_REALLOC_POSIX''@/$(GL_GNULIB_REALLOC_POSIX)/g' \ |
| 2055 | -e 's/@''GNULIB_REALLOCARRAY''@/$(GL_GNULIB_REALLOCARRAY)/g' \ | 2456 | -e 's/@''GNULIB_REALLOCARRAY''@/$(GL_GNULIB_REALLOCARRAY)/g' \ |
| 2056 | -e 's/@''GNULIB_REALPATH''@/$(GL_GNULIB_REALPATH)/g' \ | 2457 | -e 's/@''GNULIB_REALPATH''@/$(GL_GNULIB_REALPATH)/g' \ |
| 2057 | -e 's/@''GNULIB_RPMATCH''@/$(GL_GNULIB_RPMATCH)/g' \ | 2458 | -e 's/@''GNULIB_RPMATCH''@/$(GL_GNULIB_RPMATCH)/g' \ |
| 2058 | -e 's/@''GNULIB_SECURE_GETENV''@/$(GL_GNULIB_SECURE_GETENV)/g' \ | 2459 | -e 's/@''GNULIB_SECURE_GETENV''@/$(GL_GNULIB_SECURE_GETENV)/g' \ |
| 2059 | -e 's/@''GNULIB_SETENV''@/$(GL_GNULIB_SETENV)/g' \ | 2460 | -e 's/@''GNULIB_SETENV''@/$(GL_GNULIB_SETENV)/g' \ |
| 2461 | -e 's/@''GNULIB_STACK_TRACE''@/$(GL_GNULIB_STACK_TRACE)/g' \ | ||
| 2060 | -e 's/@''GNULIB_STRTOD''@/$(GL_GNULIB_STRTOD)/g' \ | 2462 | -e 's/@''GNULIB_STRTOD''@/$(GL_GNULIB_STRTOD)/g' \ |
| 2061 | -e 's/@''GNULIB_STRTOF''@/$(GL_GNULIB_STRTOF)/g' \ | 2463 | -e 's/@''GNULIB_STRTOF''@/$(GL_GNULIB_STRTOF)/g' \ |
| 2062 | -e 's/@''GNULIB_STRTOL''@/$(GL_GNULIB_STRTOL)/g' \ | 2464 | -e 's/@''GNULIB_STRTOL''@/$(GL_GNULIB_STRTOL)/g' \ |
| @@ -2124,6 +2526,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ | |||
| 2124 | < $@-t1 > $@-t2 | 2526 | < $@-t1 > $@-t2 |
| 2125 | $(AM_V_at)sed \ | 2527 | $(AM_V_at)sed \ |
| 2126 | -e 's|@''REPLACE__EXIT''@|$(REPLACE__EXIT)|g' \ | 2528 | -e 's|@''REPLACE__EXIT''@|$(REPLACE__EXIT)|g' \ |
| 2529 | -e 's|@''REPLACE_ABORT''@|$(REPLACE_ABORT)|g' \ | ||
| 2127 | -e 's|@''REPLACE_ALIGNED_ALLOC''@|$(REPLACE_ALIGNED_ALLOC)|g' \ | 2530 | -e 's|@''REPLACE_ALIGNED_ALLOC''@|$(REPLACE_ALIGNED_ALLOC)|g' \ |
| 2128 | -e 's|@''REPLACE_CALLOC_FOR_CALLOC_GNU''@|$(REPLACE_CALLOC_FOR_CALLOC_GNU)|g' \ | 2531 | -e 's|@''REPLACE_CALLOC_FOR_CALLOC_GNU''@|$(REPLACE_CALLOC_FOR_CALLOC_GNU)|g' \ |
| 2129 | -e 's|@''REPLACE_CALLOC_FOR_CALLOC_POSIX''@|$(REPLACE_CALLOC_FOR_CALLOC_POSIX)|g' \ | 2532 | -e 's|@''REPLACE_CALLOC_FOR_CALLOC_POSIX''@|$(REPLACE_CALLOC_FOR_CALLOC_POSIX)|g' \ |
| @@ -2150,7 +2553,6 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ | |||
| 2150 | -e 's|@''REPLACE_RAND''@|$(REPLACE_RAND)|g' \ | 2553 | -e 's|@''REPLACE_RAND''@|$(REPLACE_RAND)|g' \ |
| 2151 | -e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \ | 2554 | -e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \ |
| 2152 | -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ | 2555 | -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ |
| 2153 | -e 's|@''REPLACE_REALLOC_FOR_REALLOC_GNU''@|$(REPLACE_REALLOC_FOR_REALLOC_GNU)|g' \ | ||
| 2154 | -e 's|@''REPLACE_REALLOC_FOR_REALLOC_POSIX''@|$(REPLACE_REALLOC_FOR_REALLOC_POSIX)|g' \ | 2556 | -e 's|@''REPLACE_REALLOC_FOR_REALLOC_POSIX''@|$(REPLACE_REALLOC_FOR_REALLOC_POSIX)|g' \ |
| 2155 | -e 's|@''REPLACE_REALLOCARRAY''@|$(REPLACE_REALLOCARRAY)|g' \ | 2557 | -e 's|@''REPLACE_REALLOCARRAY''@|$(REPLACE_REALLOCARRAY)|g' \ |
| 2156 | -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ | 2558 | -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ |
| @@ -2165,6 +2567,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ | |||
| 2165 | -e 's|@''REPLACE_STRTOULL''@|$(REPLACE_STRTOULL)|g' \ | 2567 | -e 's|@''REPLACE_STRTOULL''@|$(REPLACE_STRTOULL)|g' \ |
| 2166 | -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ | 2568 | -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ |
| 2167 | -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ | 2569 | -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ |
| 2570 | -e 's|@''CAN_PRINT_STACK_TRACE''@|$(CAN_PRINT_STACK_TRACE)|g' \ | ||
| 2168 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ | 2571 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ |
| 2169 | -e '/definition of _Noreturn/r $(_NORETURN_H)' \ | 2572 | -e '/definition of _Noreturn/r $(_NORETURN_H)' \ |
| 2170 | -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ | 2573 | -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ |
| @@ -2176,18 +2579,15 @@ MOSTLYCLEANFILES += stdlib.h stdlib.h-t1 stdlib.h-t2 stdlib.h-t3 | |||
| 2176 | 2579 | ||
| 2177 | EXTRA_DIST += stdlib.in.h | 2580 | EXTRA_DIST += stdlib.in.h |
| 2178 | 2581 | ||
| 2179 | ## end gnulib module stdlib | 2582 | ## end gnulib module stdlib-h |
| 2180 | 2583 | ||
| 2181 | ## begin gnulib module strcase | 2584 | ## begin gnulib module strcasecmp |
| 2182 | 2585 | ||
| 2183 | if GL_COND_OBJ_STRCASECMP | 2586 | if GL_COND_OBJ_STRCASECMP |
| 2184 | libgnu_a_SOURCES += strcasecmp.c | 2587 | libgnu_a_SOURCES += strcasecmp.c |
| 2185 | endif | 2588 | endif |
| 2186 | if GL_COND_OBJ_STRNCASECMP | ||
| 2187 | libgnu_a_SOURCES += strncasecmp.c | ||
| 2188 | endif | ||
| 2189 | 2589 | ||
| 2190 | ## end gnulib module strcase | 2590 | ## end gnulib module strcasecmp |
| 2191 | 2591 | ||
| 2192 | ## begin gnulib module strcasestr | 2592 | ## begin gnulib module strcasestr |
| 2193 | 2593 | ||
| @@ -2232,7 +2632,7 @@ EXTRA_DIST += strerror-override.h | |||
| 2232 | 2632 | ||
| 2233 | ## end gnulib module strerror-override | 2633 | ## end gnulib module strerror-override |
| 2234 | 2634 | ||
| 2235 | ## begin gnulib module string | 2635 | ## begin gnulib module string-h |
| 2236 | 2636 | ||
| 2237 | BUILT_SOURCES += string.h | 2637 | BUILT_SOURCES += string.h |
| 2238 | 2638 | ||
| @@ -2262,6 +2662,8 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H | |||
| 2262 | -e 's/@''GNULIB_MBSSPN''@/$(GL_GNULIB_MBSSPN)/g' \ | 2662 | -e 's/@''GNULIB_MBSSPN''@/$(GL_GNULIB_MBSSPN)/g' \ |
| 2263 | -e 's/@''GNULIB_MBSSEP''@/$(GL_GNULIB_MBSSEP)/g' \ | 2663 | -e 's/@''GNULIB_MBSSEP''@/$(GL_GNULIB_MBSSEP)/g' \ |
| 2264 | -e 's/@''GNULIB_MBSTOK_R''@/$(GL_GNULIB_MBSTOK_R)/g' \ | 2664 | -e 's/@''GNULIB_MBSTOK_R''@/$(GL_GNULIB_MBSTOK_R)/g' \ |
| 2665 | -e 's/@''GNULIB_MBS_ENDSWITH''@/$(GL_GNULIB_MBS_ENDSWITH)/g' \ | ||
| 2666 | -e 's/@''GNULIB_MBS_STARTSWITH''@/$(GL_GNULIB_MBS_STARTSWITH)/g' \ | ||
| 2265 | -e 's/@''GNULIB_MEMCHR''@/$(GL_GNULIB_MEMCHR)/g' \ | 2667 | -e 's/@''GNULIB_MEMCHR''@/$(GL_GNULIB_MEMCHR)/g' \ |
| 2266 | -e 's/@''GNULIB_MEMMEM''@/$(GL_GNULIB_MEMMEM)/g' \ | 2668 | -e 's/@''GNULIB_MEMMEM''@/$(GL_GNULIB_MEMMEM)/g' \ |
| 2267 | -e 's/@''GNULIB_MEMPCPY''@/$(GL_GNULIB_MEMPCPY)/g' \ | 2669 | -e 's/@''GNULIB_MEMPCPY''@/$(GL_GNULIB_MEMPCPY)/g' \ |
| @@ -2273,6 +2675,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H | |||
| 2273 | -e 's/@''GNULIB_STRCHRNUL''@/$(GL_GNULIB_STRCHRNUL)/g' \ | 2675 | -e 's/@''GNULIB_STRCHRNUL''@/$(GL_GNULIB_STRCHRNUL)/g' \ |
| 2274 | -e 's/@''GNULIB_STRDUP''@/$(GL_GNULIB_STRDUP)/g' \ | 2676 | -e 's/@''GNULIB_STRDUP''@/$(GL_GNULIB_STRDUP)/g' \ |
| 2275 | -e 's/@''GNULIB_STRNCAT''@/$(GL_GNULIB_STRNCAT)/g' \ | 2677 | -e 's/@''GNULIB_STRNCAT''@/$(GL_GNULIB_STRNCAT)/g' \ |
| 2678 | -e 's/@''GNULIB_STRNCPY''@/$(GL_GNULIB_STRNCPY)/g' \ | ||
| 2276 | -e 's/@''GNULIB_STRNDUP''@/$(GL_GNULIB_STRNDUP)/g' \ | 2679 | -e 's/@''GNULIB_STRNDUP''@/$(GL_GNULIB_STRNDUP)/g' \ |
| 2277 | -e 's/@''GNULIB_STRNLEN''@/$(GL_GNULIB_STRNLEN)/g' \ | 2680 | -e 's/@''GNULIB_STRNLEN''@/$(GL_GNULIB_STRNLEN)/g' \ |
| 2278 | -e 's/@''GNULIB_STRPBRK''@/$(GL_GNULIB_STRPBRK)/g' \ | 2681 | -e 's/@''GNULIB_STRPBRK''@/$(GL_GNULIB_STRPBRK)/g' \ |
| @@ -2280,8 +2683,11 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H | |||
| 2280 | -e 's/@''GNULIB_STRSTR''@/$(GL_GNULIB_STRSTR)/g' \ | 2683 | -e 's/@''GNULIB_STRSTR''@/$(GL_GNULIB_STRSTR)/g' \ |
| 2281 | -e 's/@''GNULIB_STRCASESTR''@/$(GL_GNULIB_STRCASESTR)/g' \ | 2684 | -e 's/@''GNULIB_STRCASESTR''@/$(GL_GNULIB_STRCASESTR)/g' \ |
| 2282 | -e 's/@''GNULIB_STRTOK_R''@/$(GL_GNULIB_STRTOK_R)/g' \ | 2685 | -e 's/@''GNULIB_STRTOK_R''@/$(GL_GNULIB_STRTOK_R)/g' \ |
| 2686 | -e 's/@''GNULIB_STR_ENDSWITH''@/$(GL_GNULIB_STR_ENDSWITH)/g' \ | ||
| 2687 | -e 's/@''GNULIB_STR_STARTSWITH''@/$(GL_GNULIB_STR_STARTSWITH)/g' \ | ||
| 2283 | -e 's/@''GNULIB_STRERROR''@/$(GL_GNULIB_STRERROR)/g' \ | 2688 | -e 's/@''GNULIB_STRERROR''@/$(GL_GNULIB_STRERROR)/g' \ |
| 2284 | -e 's/@''GNULIB_STRERROR_R''@/$(GL_GNULIB_STRERROR_R)/g' \ | 2689 | -e 's/@''GNULIB_STRERROR_R''@/$(GL_GNULIB_STRERROR_R)/g' \ |
| 2690 | -e 's/@''GNULIB_STRERROR_L''@/$(GL_GNULIB_STRERROR_L)/g' \ | ||
| 2285 | -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GL_GNULIB_STRERRORNAME_NP)/g' \ | 2691 | -e 's/@''GNULIB_STRERRORNAME_NP''@/$(GL_GNULIB_STRERRORNAME_NP)/g' \ |
| 2286 | -e 's/@''GNULIB_SIGABBREV_NP''@/$(GL_GNULIB_SIGABBREV_NP)/g' \ | 2692 | -e 's/@''GNULIB_SIGABBREV_NP''@/$(GL_GNULIB_SIGABBREV_NP)/g' \ |
| 2287 | -e 's/@''GNULIB_SIGDESCR_NP''@/$(GL_GNULIB_SIGDESCR_NP)/g' \ | 2693 | -e 's/@''GNULIB_SIGDESCR_NP''@/$(GL_GNULIB_SIGDESCR_NP)/g' \ |
| @@ -2312,6 +2718,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H | |||
| 2312 | -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ | 2718 | -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ |
| 2313 | -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ | 2719 | -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ |
| 2314 | -e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \ | 2720 | -e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \ |
| 2721 | -e 's|@''HAVE_STRERROR_L''@|$(HAVE_STRERROR_L)|g' \ | ||
| 2315 | -e 's|@''HAVE_STRERRORNAME_NP''@|$(HAVE_STRERRORNAME_NP)|g' \ | 2722 | -e 's|@''HAVE_STRERRORNAME_NP''@|$(HAVE_STRERRORNAME_NP)|g' \ |
| 2316 | -e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \ | 2723 | -e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \ |
| 2317 | -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \ | 2724 | -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \ |
| @@ -2328,6 +2735,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H | |||
| 2328 | -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \ | 2735 | -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \ |
| 2329 | -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ | 2736 | -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ |
| 2330 | -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ | 2737 | -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ |
| 2738 | -e 's|@''REPLACE_STRNCPY''@|$(REPLACE_STRNCPY)|g' \ | ||
| 2331 | -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ | 2739 | -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ |
| 2332 | -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \ | 2740 | -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \ |
| 2333 | -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ | 2741 | -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ |
| @@ -2335,6 +2743,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H | |||
| 2335 | -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \ | 2743 | -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \ |
| 2336 | -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ | 2744 | -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ |
| 2337 | -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ | 2745 | -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ |
| 2746 | -e 's|@''REPLACE_STRERROR_L''@|$(REPLACE_STRERROR_L)|g' \ | ||
| 2338 | -e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \ | 2747 | -e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \ |
| 2339 | -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ | 2748 | -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ |
| 2340 | -e 's|@''REPLACE_STRVERSCMP''@|$(REPLACE_STRVERSCMP)|g' \ | 2749 | -e 's|@''REPLACE_STRVERSCMP''@|$(REPLACE_STRVERSCMP)|g' \ |
| @@ -2349,9 +2758,9 @@ MOSTLYCLEANFILES += string.h string.h-t1 string.h-t2 | |||
| 2349 | 2758 | ||
| 2350 | EXTRA_DIST += string.in.h | 2759 | EXTRA_DIST += string.in.h |
| 2351 | 2760 | ||
| 2352 | ## end gnulib module string | 2761 | ## end gnulib module string-h |
| 2353 | 2762 | ||
| 2354 | ## begin gnulib module strings | 2763 | ## begin gnulib module strings-h |
| 2355 | 2764 | ||
| 2356 | BUILT_SOURCES += strings.h | 2765 | BUILT_SOURCES += strings.h |
| 2357 | 2766 | ||
| @@ -2366,9 +2775,20 @@ strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE | |||
| 2366 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | 2775 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ |
| 2367 | -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \ | 2776 | -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \ |
| 2368 | -e 's/@''GNULIB_FFS''@/$(GL_GNULIB_FFS)/g' \ | 2777 | -e 's/@''GNULIB_FFS''@/$(GL_GNULIB_FFS)/g' \ |
| 2778 | -e 's/@''GNULIB_STRCASECMP''@/$(GL_GNULIB_STRCASECMP)/g' \ | ||
| 2779 | -e 's/@''GNULIB_STRCASECMP_L''@/$(GL_GNULIB_STRCASECMP_L)/g' \ | ||
| 2780 | -e 's/@''GNULIB_STRNCASECMP''@/$(GL_GNULIB_STRNCASECMP)/g' \ | ||
| 2781 | -e 's/@''GNULIB_STRNCASECMP_L''@/$(GL_GNULIB_STRNCASECMP_L)/g' \ | ||
| 2369 | -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \ | 2782 | -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \ |
| 2370 | -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ | 2783 | -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ |
| 2784 | -e 's|@''HAVE_STRCASECMP_L''@|$(HAVE_STRCASECMP_L)|g' \ | ||
| 2785 | -e 's|@''HAVE_STRNCASECMP''@|$(HAVE_STRNCASECMP)|g' \ | ||
| 2786 | -e 's|@''HAVE_STRNCASECMP_L''@|$(HAVE_STRNCASECMP_L)|g' \ | ||
| 2371 | -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ | 2787 | -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ |
| 2788 | -e 's|@''REPLACE_STRCASECMP''@|$(REPLACE_STRCASECMP)|g' \ | ||
| 2789 | -e 's|@''REPLACE_STRCASECMP_L''@|$(REPLACE_STRCASECMP_L)|g' \ | ||
| 2790 | -e 's|@''REPLACE_STRNCASECMP''@|$(REPLACE_STRNCASECMP)|g' \ | ||
| 2791 | -e 's|@''REPLACE_STRNCASECMP_L''@|$(REPLACE_STRNCASECMP_L)|g' \ | ||
| 2372 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ | 2792 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ |
| 2373 | -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ | 2793 | -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ |
| 2374 | -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ | 2794 | -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ |
| @@ -2378,7 +2798,23 @@ MOSTLYCLEANFILES += strings.h strings.h-t | |||
| 2378 | 2798 | ||
| 2379 | EXTRA_DIST += strings.in.h | 2799 | EXTRA_DIST += strings.in.h |
| 2380 | 2800 | ||
| 2381 | ## end gnulib module strings | 2801 | ## end gnulib module strings-h |
| 2802 | |||
| 2803 | ## begin gnulib module strncasecmp | ||
| 2804 | |||
| 2805 | if GL_COND_OBJ_STRNCASECMP | ||
| 2806 | libgnu_a_SOURCES += strncasecmp.c | ||
| 2807 | endif | ||
| 2808 | |||
| 2809 | ## end gnulib module strncasecmp | ||
| 2810 | |||
| 2811 | ## begin gnulib module strncpy | ||
| 2812 | |||
| 2813 | if GL_COND_OBJ_STRNCPY | ||
| 2814 | libgnu_a_SOURCES += strncpy.c | ||
| 2815 | endif | ||
| 2816 | |||
| 2817 | ## end gnulib module strncpy | ||
| 2382 | 2818 | ||
| 2383 | ## begin gnulib module strsep | 2819 | ## begin gnulib module strsep |
| 2384 | 2820 | ||
| @@ -2397,7 +2833,7 @@ EXTRA_libgnu_a_SOURCES += strstr.c | |||
| 2397 | 2833 | ||
| 2398 | ## end gnulib module strstr-simple | 2834 | ## end gnulib module strstr-simple |
| 2399 | 2835 | ||
| 2400 | ## begin gnulib module sys_socket | 2836 | ## begin gnulib module sys_socket-h |
| 2401 | 2837 | ||
| 2402 | BUILT_SOURCES += sys/socket.h | 2838 | BUILT_SOURCES += sys/socket.h |
| 2403 | libgnu_a_SOURCES += sys_socket.c | 2839 | libgnu_a_SOURCES += sys_socket.c |
| @@ -2445,9 +2881,9 @@ MOSTLYCLEANDIRS += sys | |||
| 2445 | 2881 | ||
| 2446 | EXTRA_DIST += sys_socket.in.h | 2882 | EXTRA_DIST += sys_socket.in.h |
| 2447 | 2883 | ||
| 2448 | ## end gnulib module sys_socket | 2884 | ## end gnulib module sys_socket-h |
| 2449 | 2885 | ||
| 2450 | ## begin gnulib module sys_stat | 2886 | ## begin gnulib module sys_stat-h |
| 2451 | 2887 | ||
| 2452 | BUILT_SOURCES += sys/stat.h | 2888 | BUILT_SOURCES += sys/stat.h |
| 2453 | 2889 | ||
| @@ -2518,9 +2954,9 @@ MOSTLYCLEANDIRS += sys | |||
| 2518 | 2954 | ||
| 2519 | EXTRA_DIST += sys_stat.in.h | 2955 | EXTRA_DIST += sys_stat.in.h |
| 2520 | 2956 | ||
| 2521 | ## end gnulib module sys_stat | 2957 | ## end gnulib module sys_stat-h |
| 2522 | 2958 | ||
| 2523 | ## begin gnulib module sys_types | 2959 | ## begin gnulib module sys_types-h |
| 2524 | 2960 | ||
| 2525 | BUILT_SOURCES += sys/types.h | 2961 | BUILT_SOURCES += sys/types.h |
| 2526 | 2962 | ||
| @@ -2535,16 +2971,20 @@ sys/types.h: sys_types.in.h $(top_builddir)/config.status | |||
| 2535 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | 2971 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ |
| 2536 | -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \ | 2972 | -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \ |
| 2537 | -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ | 2973 | -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ |
| 2974 | -e 's|@''HAVE_OFF64_T''@|$(HAVE_OFF64_T)|g' \ | ||
| 2538 | -e 's|@''WINDOWS_STAT_INODES''@|$(WINDOWS_STAT_INODES)|g' \ | 2975 | -e 's|@''WINDOWS_STAT_INODES''@|$(WINDOWS_STAT_INODES)|g' \ |
| 2976 | -e 's|@''HAVE_BLKSIZE_T''@|$(HAVE_BLKSIZE_T)|g' \ | ||
| 2977 | -e 's|@''HAVE_BLKCNT_T''@|$(HAVE_BLKCNT_T)|g' \ | ||
| 2539 | $(srcdir)/sys_types.in.h > $@-t | 2978 | $(srcdir)/sys_types.in.h > $@-t |
| 2540 | $(AM_V_at)mv $@-t $@ | 2979 | $(AM_V_at)mv $@-t $@ |
| 2541 | MOSTLYCLEANFILES += sys/types.h sys/types.h-t | 2980 | MOSTLYCLEANFILES += sys/types.h sys/types.h-t |
| 2981 | MOSTLYCLEANDIRS += sys | ||
| 2542 | 2982 | ||
| 2543 | EXTRA_DIST += sys_types.in.h | 2983 | EXTRA_DIST += sys_types.in.h |
| 2544 | 2984 | ||
| 2545 | ## end gnulib module sys_types | 2985 | ## end gnulib module sys_types-h |
| 2546 | 2986 | ||
| 2547 | ## begin gnulib module sys_uio | 2987 | ## begin gnulib module sys_uio-h |
| 2548 | 2988 | ||
| 2549 | BUILT_SOURCES += sys/uio.h | 2989 | BUILT_SOURCES += sys/uio.h |
| 2550 | 2990 | ||
| @@ -2566,7 +3006,7 @@ MOSTLYCLEANDIRS += sys | |||
| 2566 | 3006 | ||
| 2567 | EXTRA_DIST += sys_uio.in.h | 3007 | EXTRA_DIST += sys_uio.in.h |
| 2568 | 3008 | ||
| 2569 | ## end gnulib module sys_uio | 3009 | ## end gnulib module sys_uio-h |
| 2570 | 3010 | ||
| 2571 | ## begin gnulib module threadlib | 3011 | ## begin gnulib module threadlib |
| 2572 | 3012 | ||
| @@ -2599,6 +3039,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( | |||
| 2599 | -e 's/@''GNULIB_TIMESPEC_GETRES''@/$(GL_GNULIB_TIMESPEC_GETRES)/g' \ | 3039 | -e 's/@''GNULIB_TIMESPEC_GETRES''@/$(GL_GNULIB_TIMESPEC_GETRES)/g' \ |
| 2600 | -e 's/@''GNULIB_TIME_R''@/$(GL_GNULIB_TIME_R)/g' \ | 3040 | -e 's/@''GNULIB_TIME_R''@/$(GL_GNULIB_TIME_R)/g' \ |
| 2601 | -e 's/@''GNULIB_TIME_RZ''@/$(GL_GNULIB_TIME_RZ)/g' \ | 3041 | -e 's/@''GNULIB_TIME_RZ''@/$(GL_GNULIB_TIME_RZ)/g' \ |
| 3042 | -e 's/@''GNULIB_TZNAME''@/$(GL_GNULIB_TZNAME)/g' \ | ||
| 2602 | -e 's/@''GNULIB_TZSET''@/$(GL_GNULIB_TZSET)/g' \ | 3043 | -e 's/@''GNULIB_TZSET''@/$(GL_GNULIB_TZSET)/g' \ |
| 2603 | -e 's/@''GNULIB_MDA_TZSET''@/$(GL_GNULIB_MDA_TZSET)/g' \ | 3044 | -e 's/@''GNULIB_MDA_TZSET''@/$(GL_GNULIB_MDA_TZSET)/g' \ |
| 2604 | -e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \ | 3045 | -e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \ |
| @@ -2608,11 +3049,14 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( | |||
| 2608 | -e 's|@''HAVE_TIMESPEC_GET''@|$(HAVE_TIMESPEC_GET)|g' \ | 3049 | -e 's|@''HAVE_TIMESPEC_GET''@|$(HAVE_TIMESPEC_GET)|g' \ |
| 2609 | -e 's|@''HAVE_TIMESPEC_GETRES''@|$(HAVE_TIMESPEC_GETRES)|g' \ | 3050 | -e 's|@''HAVE_TIMESPEC_GETRES''@|$(HAVE_TIMESPEC_GETRES)|g' \ |
| 2610 | -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \ | 3051 | -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \ |
| 3052 | -e 's|@''HAVE_TZALLOC''@|$(HAVE_TZALLOC)|g' \ | ||
| 2611 | -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \ | 3053 | -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \ |
| 2612 | -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \ | 3054 | -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \ |
| 2613 | -e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \ | 3055 | -e 's|@''REPLACE_LOCALTIME''@|$(REPLACE_LOCALTIME)|g' \ |
| 2614 | -e 's|@''REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \ | 3056 | -e 's|@''REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \ |
| 3057 | -e 's|@''REPLACE_LOCALTIME_RZ''@|$(REPLACE_LOCALTIME_RZ)|g' \ | ||
| 2615 | -e 's|@''REPLACE_MKTIME''@|$(REPLACE_MKTIME)|g' \ | 3058 | -e 's|@''REPLACE_MKTIME''@|$(REPLACE_MKTIME)|g' \ |
| 3059 | -e 's|@''REPLACE_MKTIME_Z''@|$(REPLACE_MKTIME_Z)|g' \ | ||
| 2616 | -e 's|@''REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \ | 3060 | -e 's|@''REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \ |
| 2617 | -e 's|@''REPLACE_STRFTIME''@|$(REPLACE_STRFTIME)|g' \ | 3061 | -e 's|@''REPLACE_STRFTIME''@|$(REPLACE_STRFTIME)|g' \ |
| 2618 | -e 's|@''REPLACE_TIME''@|$(REPLACE_TIME)|g' \ | 3062 | -e 's|@''REPLACE_TIME''@|$(REPLACE_TIME)|g' \ |
| @@ -2654,7 +3098,412 @@ EXTRA_DIST += mktime-internal.h | |||
| 2654 | 3098 | ||
| 2655 | ## end gnulib module timegm | 3099 | ## end gnulib module timegm |
| 2656 | 3100 | ||
| 2657 | ## begin gnulib module unistd | 3101 | ## begin gnulib module uchar-h |
| 3102 | |||
| 3103 | BUILT_SOURCES += uchar.h | ||
| 3104 | |||
| 3105 | uchar.h: uchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) | ||
| 3106 | $(gl_V_at)$(SED_HEADER_STDOUT) \ | ||
| 3107 | -e 's|@''GUARD_PREFIX''@|GL|g' \ | ||
| 3108 | -e 's/@''HAVE_UCHAR_H''@/$(HAVE_UCHAR_H)/g' \ | ||
| 3109 | -e 's/@''CXX_HAVE_UCHAR_H''@/$(CXX_HAVE_UCHAR_H)/g' \ | ||
| 3110 | -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ | ||
| 3111 | -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ | ||
| 3112 | -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ | ||
| 3113 | -e 's|@''NEXT_UCHAR_H''@|$(NEXT_UCHAR_H)|g' \ | ||
| 3114 | -e 's|@''CXX_HAS_CHAR8_TYPE''@|$(CXX_HAS_CHAR8_TYPE)|g' \ | ||
| 3115 | -e 's|@''CXX_HAS_UCHAR_TYPES''@|$(CXX_HAS_UCHAR_TYPES)|g' \ | ||
| 3116 | -e 's|@''SMALL_WCHAR_T''@|$(SMALL_WCHAR_T)|g' \ | ||
| 3117 | -e 's|@''GNULIBHEADERS_OVERRIDE_CHAR8_T''@|$(GNULIBHEADERS_OVERRIDE_CHAR8_T)|g' \ | ||
| 3118 | -e 's|@''GNULIBHEADERS_OVERRIDE_CHAR16_T''@|$(GNULIBHEADERS_OVERRIDE_CHAR16_T)|g' \ | ||
| 3119 | -e 's|@''GNULIBHEADERS_OVERRIDE_CHAR32_T''@|$(GNULIBHEADERS_OVERRIDE_CHAR32_T)|g' \ | ||
| 3120 | -e 's/@''GNULIB_BTOC32''@/$(GL_GNULIB_BTOC32)/g' \ | ||
| 3121 | -e 's/@''GNULIB_BTOWC''@/$(GL_GNULIB_BTOWC)/g' \ | ||
| 3122 | -e 's/@''GNULIB_C32ISALNUM''@/$(GL_GNULIB_C32ISALNUM)/g' \ | ||
| 3123 | -e 's/@''GNULIB_C32ISALPHA''@/$(GL_GNULIB_C32ISALPHA)/g' \ | ||
| 3124 | -e 's/@''GNULIB_C32ISBLANK''@/$(GL_GNULIB_C32ISBLANK)/g' \ | ||
| 3125 | -e 's/@''GNULIB_C32ISCNTRL''@/$(GL_GNULIB_C32ISCNTRL)/g' \ | ||
| 3126 | -e 's/@''GNULIB_C32ISDIGIT''@/$(GL_GNULIB_C32ISDIGIT)/g' \ | ||
| 3127 | -e 's/@''GNULIB_C32ISGRAPH''@/$(GL_GNULIB_C32ISGRAPH)/g' \ | ||
| 3128 | -e 's/@''GNULIB_C32ISLOWER''@/$(GL_GNULIB_C32ISLOWER)/g' \ | ||
| 3129 | -e 's/@''GNULIB_C32ISPRINT''@/$(GL_GNULIB_C32ISPRINT)/g' \ | ||
| 3130 | -e 's/@''GNULIB_C32ISPUNCT''@/$(GL_GNULIB_C32ISPUNCT)/g' \ | ||
| 3131 | -e 's/@''GNULIB_C32ISSPACE''@/$(GL_GNULIB_C32ISSPACE)/g' \ | ||
| 3132 | -e 's/@''GNULIB_C32ISUPPER''@/$(GL_GNULIB_C32ISUPPER)/g' \ | ||
| 3133 | -e 's/@''GNULIB_C32ISXDIGIT''@/$(GL_GNULIB_C32ISXDIGIT)/g' \ | ||
| 3134 | -e 's/@''GNULIB_C32TOLOWER''@/$(GL_GNULIB_C32TOLOWER)/g' \ | ||
| 3135 | -e 's/@''GNULIB_C32TOUPPER''@/$(GL_GNULIB_C32TOUPPER)/g' \ | ||
| 3136 | -e 's/@''GNULIB_C32WIDTH''@/$(GL_GNULIB_C32WIDTH)/g' \ | ||
| 3137 | -e 's/@''GNULIB_C32RTOMB''@/$(GL_GNULIB_C32RTOMB)/g' \ | ||
| 3138 | -e 's/@''GNULIB_C32SNRTOMBS''@/$(GL_GNULIB_C32SNRTOMBS)/g' \ | ||
| 3139 | -e 's/@''GNULIB_C32SRTOMBS''@/$(GL_GNULIB_C32SRTOMBS)/g' \ | ||
| 3140 | -e 's/@''GNULIB_C32STOMBS''@/$(GL_GNULIB_C32STOMBS)/g' \ | ||
| 3141 | -e 's/@''GNULIB_C32SWIDTH''@/$(GL_GNULIB_C32SWIDTH)/g' \ | ||
| 3142 | -e 's/@''GNULIB_C32TOB''@/$(GL_GNULIB_C32TOB)/g' \ | ||
| 3143 | -e 's/@''GNULIB_C32_APPLY_MAPPING''@/$(GL_GNULIB_C32_APPLY_MAPPING)/g' \ | ||
| 3144 | -e 's/@''GNULIB_C32_APPLY_TYPE_TEST''@/$(GL_GNULIB_C32_APPLY_TYPE_TEST)/g' \ | ||
| 3145 | -e 's/@''GNULIB_C32_GET_MAPPING''@/$(GL_GNULIB_C32_GET_MAPPING)/g' \ | ||
| 3146 | -e 's/@''GNULIB_C32_GET_TYPE_TEST''@/$(GL_GNULIB_C32_GET_TYPE_TEST)/g' \ | ||
| 3147 | -e 's/@''GNULIB_ISWCTYPE''@/$(GL_GNULIB_ISWCTYPE)/g' \ | ||
| 3148 | -e 's/@''GNULIB_ISWDIGIT''@/$(GL_GNULIB_ISWDIGIT)/g' \ | ||
| 3149 | -e 's/@''GNULIB_ISWXDIGIT''@/$(GL_GNULIB_ISWXDIGIT)/g' \ | ||
| 3150 | -e 's/@''GNULIB_MBRTOC16''@/$(GL_GNULIB_MBRTOC16)/g' \ | ||
| 3151 | -e 's/@''GNULIB_MBRTOC32''@/$(GL_GNULIB_MBRTOC32)/g' \ | ||
| 3152 | -e 's/@''GNULIB_MBSNRTOC32S''@/$(GL_GNULIB_MBSNRTOC32S)/g' \ | ||
| 3153 | -e 's/@''GNULIB_MBSNRTOWCS''@/$(GL_GNULIB_MBSNRTOWCS)/g' \ | ||
| 3154 | -e 's/@''GNULIB_MBSRTOC32S''@/$(GL_GNULIB_MBSRTOC32S)/g' \ | ||
| 3155 | -e 's/@''GNULIB_MBSRTOWCS''@/$(GL_GNULIB_MBSRTOWCS)/g' \ | ||
| 3156 | -e 's/@''GNULIB_MBSTOC32S''@/$(GL_GNULIB_MBSTOC32S)/g' \ | ||
| 3157 | -e 's/@''GNULIB_TOWCTRANS''@/$(GL_GNULIB_TOWCTRANS)/g' \ | ||
| 3158 | -e 's/@''GNULIB_WCSNRTOMBS''@/$(GL_GNULIB_WCSNRTOMBS)/g' \ | ||
| 3159 | -e 's/@''GNULIB_WCSRTOMBS''@/$(GL_GNULIB_WCSRTOMBS)/g' \ | ||
| 3160 | -e 's/@''GNULIB_WCSWIDTH''@/$(GL_GNULIB_WCSWIDTH)/g' \ | ||
| 3161 | -e 's/@''GNULIB_WCTOB''@/$(GL_GNULIB_WCTOB)/g' \ | ||
| 3162 | -e 's/@''GNULIB_WCTRANS''@/$(GL_GNULIB_WCTRANS)/g' \ | ||
| 3163 | -e 's/@''GNULIB_WCTYPE''@/$(GL_GNULIB_WCTYPE)/g' \ | ||
| 3164 | -e 's/@''GNULIB_WCWIDTH''@/$(GL_GNULIB_WCWIDTH)/g' \ | ||
| 3165 | -e 's|@''HAVE_C32RTOMB''@|$(HAVE_C32RTOMB)|g' \ | ||
| 3166 | -e 's|@''HAVE_MBRTOC16''@|$(HAVE_MBRTOC16)|g' \ | ||
| 3167 | -e 's|@''HAVE_MBRTOC32''@|$(HAVE_MBRTOC32)|g' \ | ||
| 3168 | -e 's|@''REPLACE_C32RTOMB''@|$(REPLACE_C32RTOMB)|g' \ | ||
| 3169 | -e 's|@''REPLACE_MBRTOC16''@|$(REPLACE_MBRTOC16)|g' \ | ||
| 3170 | -e 's|@''REPLACE_MBRTOC32''@|$(REPLACE_MBRTOC32)|g' \ | ||
| 3171 | -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ | ||
| 3172 | -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ | ||
| 3173 | -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ | ||
| 3174 | $(srcdir)/uchar.in.h > $@-t | ||
| 3175 | $(AM_V_at)mv $@-t $@ | ||
| 3176 | MOSTLYCLEANFILES += uchar.h uchar.h-t | ||
| 3177 | |||
| 3178 | EXTRA_DIST += uchar.in.h | ||
| 3179 | |||
| 3180 | ## end gnulib module uchar-h | ||
| 3181 | |||
| 3182 | ## begin gnulib module unicase/base | ||
| 3183 | |||
| 3184 | BUILT_SOURCES += $(LIBUNISTRING_UNICASE_H) | ||
| 3185 | |||
| 3186 | unicase.h: unicase.in.h | ||
| 3187 | $(gl_V_at)$(SED_HEADER_STDOUT) \ | ||
| 3188 | -e 's|@''HAVE_UNISTRING_WOE32DLL_H''@|$(HAVE_UNISTRING_WOE32DLL_H)|g' \ | ||
| 3189 | -e 's/@''GNULIB_UNICASE_EMPTY_PREFIX_CONTEXT_DLL_VARIABLE''@/$(GL_GNULIB_UNICASE_EMPTY_PREFIX_CONTEXT_DLL_VARIABLE)/g' \ | ||
| 3190 | -e 's/@''GNULIB_UNICASE_EMPTY_SUFFIX_CONTEXT_DLL_VARIABLE''@/$(GL_GNULIB_UNICASE_EMPTY_SUFFIX_CONTEXT_DLL_VARIABLE)/g' \ | ||
| 3191 | $(srcdir)/unicase.in.h > $@-t | ||
| 3192 | $(AM_V_at)mv $@-t $@ | ||
| 3193 | MOSTLYCLEANFILES += unicase.h unicase.h-t | ||
| 3194 | |||
| 3195 | EXTRA_DIST += unicase.in.h | ||
| 3196 | |||
| 3197 | ## end gnulib module unicase/base | ||
| 3198 | |||
| 3199 | ## begin gnulib module unicase/tolower | ||
| 3200 | |||
| 3201 | if LIBUNISTRING_COMPILE_UNICASE_TOLOWER | ||
| 3202 | libgnu_a_SOURCES += unicase/tolower.c | ||
| 3203 | endif | ||
| 3204 | |||
| 3205 | EXTRA_DIST += unicase/simple-mapping.h unicase/tolower.h | ||
| 3206 | |||
| 3207 | ## end gnulib module unicase/tolower | ||
| 3208 | |||
| 3209 | ## begin gnulib module unictype/base | ||
| 3210 | |||
| 3211 | BUILT_SOURCES += $(LIBUNISTRING_UNICTYPE_H) | ||
| 3212 | |||
| 3213 | unictype.h: unictype.in.h | ||
| 3214 | $(gl_V_at)$(SED_HEADER_STDOUT) \ | ||
| 3215 | -e 's|@''HAVE_UNISTRING_WOE32DLL_H''@|$(HAVE_UNISTRING_WOE32DLL_H)|g' \ | ||
| 3216 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_L_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_L_DLL_VARIABLE)/g' \ | ||
| 3217 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_LC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_LC_DLL_VARIABLE)/g' \ | ||
| 3218 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_LU_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_LU_DLL_VARIABLE)/g' \ | ||
| 3219 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_LL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_LL_DLL_VARIABLE)/g' \ | ||
| 3220 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_LT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_LT_DLL_VARIABLE)/g' \ | ||
| 3221 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_LM_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_LM_DLL_VARIABLE)/g' \ | ||
| 3222 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_LO_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_LO_DLL_VARIABLE)/g' \ | ||
| 3223 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_M_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_M_DLL_VARIABLE)/g' \ | ||
| 3224 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_MN_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_MN_DLL_VARIABLE)/g' \ | ||
| 3225 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_MC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_MC_DLL_VARIABLE)/g' \ | ||
| 3226 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_ME_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_ME_DLL_VARIABLE)/g' \ | ||
| 3227 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_N_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_N_DLL_VARIABLE)/g' \ | ||
| 3228 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_ND_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_ND_DLL_VARIABLE)/g' \ | ||
| 3229 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_NL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_NL_DLL_VARIABLE)/g' \ | ||
| 3230 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_NO_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_NO_DLL_VARIABLE)/g' \ | ||
| 3231 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_P_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_P_DLL_VARIABLE)/g' \ | ||
| 3232 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_PC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_PC_DLL_VARIABLE)/g' \ | ||
| 3233 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_PD_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_PD_DLL_VARIABLE)/g' \ | ||
| 3234 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_PS_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_PS_DLL_VARIABLE)/g' \ | ||
| 3235 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_PE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_PE_DLL_VARIABLE)/g' \ | ||
| 3236 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_PI_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_PI_DLL_VARIABLE)/g' \ | ||
| 3237 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_PF_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_PF_DLL_VARIABLE)/g' \ | ||
| 3238 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_PO_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_PO_DLL_VARIABLE)/g' \ | ||
| 3239 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_S_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_S_DLL_VARIABLE)/g' \ | ||
| 3240 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_SM_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_SM_DLL_VARIABLE)/g' \ | ||
| 3241 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_SC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_SC_DLL_VARIABLE)/g' \ | ||
| 3242 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_SK_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_SK_DLL_VARIABLE)/g' \ | ||
| 3243 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_SO_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_SO_DLL_VARIABLE)/g' \ | ||
| 3244 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_Z_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_Z_DLL_VARIABLE)/g' \ | ||
| 3245 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_ZS_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_ZS_DLL_VARIABLE)/g' \ | ||
| 3246 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_ZL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_ZL_DLL_VARIABLE)/g' \ | ||
| 3247 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_ZP_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_ZP_DLL_VARIABLE)/g' \ | ||
| 3248 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_C_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_C_DLL_VARIABLE)/g' \ | ||
| 3249 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_CC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_CC_DLL_VARIABLE)/g' \ | ||
| 3250 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_CF_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_CF_DLL_VARIABLE)/g' \ | ||
| 3251 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_CS_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_CS_DLL_VARIABLE)/g' \ | ||
| 3252 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_CO_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_CO_DLL_VARIABLE)/g' \ | ||
| 3253 | -e 's/@''GNULIB_UNICTYPE_CATEGORY_CN_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_CATEGORY_CN_DLL_VARIABLE)/g' \ | ||
| 3254 | < $(srcdir)/unictype.in.h > $@-t1 | ||
| 3255 | $(AM_V_at)sed \ | ||
| 3256 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_WHITE_SPACE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_WHITE_SPACE_DLL_VARIABLE)/g' \ | ||
| 3257 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_ALPHABETIC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_ALPHABETIC_DLL_VARIABLE)/g' \ | ||
| 3258 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_OTHER_ALPHABETIC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_OTHER_ALPHABETIC_DLL_VARIABLE)/g' \ | ||
| 3259 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_NOT_A_CHARACTER_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_NOT_A_CHARACTER_DLL_VARIABLE)/g' \ | ||
| 3260 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_DLL_VARIABLE)/g' \ | ||
| 3261 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_OTHER_DEFAULT_IGNORABLE_CODE_POINT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_OTHER_DEFAULT_IGNORABLE_CODE_POINT_DLL_VARIABLE)/g' \ | ||
| 3262 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_DEPRECATED_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_DEPRECATED_DLL_VARIABLE)/g' \ | ||
| 3263 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_LOGICAL_ORDER_EXCEPTION_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_LOGICAL_ORDER_EXCEPTION_DLL_VARIABLE)/g' \ | ||
| 3264 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_VARIATION_SELECTOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_VARIATION_SELECTOR_DLL_VARIABLE)/g' \ | ||
| 3265 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_PRIVATE_USE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_PRIVATE_USE_DLL_VARIABLE)/g' \ | ||
| 3266 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_UNASSIGNED_CODE_VALUE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_UNASSIGNED_CODE_VALUE_DLL_VARIABLE)/g' \ | ||
| 3267 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_UPPERCASE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_UPPERCASE_DLL_VARIABLE)/g' \ | ||
| 3268 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_OTHER_UPPERCASE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_OTHER_UPPERCASE_DLL_VARIABLE)/g' \ | ||
| 3269 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_LOWERCASE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_LOWERCASE_DLL_VARIABLE)/g' \ | ||
| 3270 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_OTHER_LOWERCASE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_OTHER_LOWERCASE_DLL_VARIABLE)/g' \ | ||
| 3271 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_TITLECASE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_TITLECASE_DLL_VARIABLE)/g' \ | ||
| 3272 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_CASED_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_CASED_DLL_VARIABLE)/g' \ | ||
| 3273 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_CASE_IGNORABLE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_CASE_IGNORABLE_DLL_VARIABLE)/g' \ | ||
| 3274 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_LOWERCASED_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_LOWERCASED_DLL_VARIABLE)/g' \ | ||
| 3275 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_UPPERCASED_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_UPPERCASED_DLL_VARIABLE)/g' \ | ||
| 3276 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_TITLECASED_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_TITLECASED_DLL_VARIABLE)/g' \ | ||
| 3277 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_CASEFOLDED_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_CASEFOLDED_DLL_VARIABLE)/g' \ | ||
| 3278 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_CASEMAPPED_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_CASEMAPPED_DLL_VARIABLE)/g' \ | ||
| 3279 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_SOFT_DOTTED_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_SOFT_DOTTED_DLL_VARIABLE)/g' \ | ||
| 3280 | < $@-t1 > $@-t2 | ||
| 3281 | $(AM_V_at)sed \ | ||
| 3282 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_ID_START_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_ID_START_DLL_VARIABLE)/g' \ | ||
| 3283 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_OTHER_ID_START_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_OTHER_ID_START_DLL_VARIABLE)/g' \ | ||
| 3284 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_ID_CONTINUE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_ID_CONTINUE_DLL_VARIABLE)/g' \ | ||
| 3285 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_OTHER_ID_CONTINUE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_OTHER_ID_CONTINUE_DLL_VARIABLE)/g' \ | ||
| 3286 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_XID_START_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_XID_START_DLL_VARIABLE)/g' \ | ||
| 3287 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_XID_CONTINUE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_XID_CONTINUE_DLL_VARIABLE)/g' \ | ||
| 3288 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_ID_COMPAT_MATH_START_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_ID_COMPAT_MATH_START_DLL_VARIABLE)/g' \ | ||
| 3289 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_ID_COMPAT_MATH_CONTINUE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_ID_COMPAT_MATH_CONTINUE_DLL_VARIABLE)/g' \ | ||
| 3290 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_PATTERN_WHITE_SPACE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_PATTERN_WHITE_SPACE_DLL_VARIABLE)/g' \ | ||
| 3291 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_PATTERN_SYNTAX_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_PATTERN_SYNTAX_DLL_VARIABLE)/g' \ | ||
| 3292 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_JOIN_CONTROL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_JOIN_CONTROL_DLL_VARIABLE)/g' \ | ||
| 3293 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_GRAPHEME_BASE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_GRAPHEME_BASE_DLL_VARIABLE)/g' \ | ||
| 3294 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_GRAPHEME_EXTEND_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_GRAPHEME_EXTEND_DLL_VARIABLE)/g' \ | ||
| 3295 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_OTHER_GRAPHEME_EXTEND_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_OTHER_GRAPHEME_EXTEND_DLL_VARIABLE)/g' \ | ||
| 3296 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_GRAPHEME_LINK_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_GRAPHEME_LINK_DLL_VARIABLE)/g' \ | ||
| 3297 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_MODIFIER_COMBINING_MARK_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_MODIFIER_COMBINING_MARK_DLL_VARIABLE)/g' \ | ||
| 3298 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_CONTROL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_CONTROL_DLL_VARIABLE)/g' \ | ||
| 3299 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_LEFT_TO_RIGHT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_LEFT_TO_RIGHT_DLL_VARIABLE)/g' \ | ||
| 3300 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_HEBREW_RIGHT_TO_LEFT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_HEBREW_RIGHT_TO_LEFT_DLL_VARIABLE)/g' \ | ||
| 3301 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_ARABIC_RIGHT_TO_LEFT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_ARABIC_RIGHT_TO_LEFT_DLL_VARIABLE)/g' \ | ||
| 3302 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_EUROPEAN_DIGIT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_EUROPEAN_DIGIT_DLL_VARIABLE)/g' \ | ||
| 3303 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_EUR_NUM_SEPARATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_EUR_NUM_SEPARATOR_DLL_VARIABLE)/g' \ | ||
| 3304 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_EUR_NUM_TERMINATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_EUR_NUM_TERMINATOR_DLL_VARIABLE)/g' \ | ||
| 3305 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_ARABIC_DIGIT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_ARABIC_DIGIT_DLL_VARIABLE)/g' \ | ||
| 3306 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_COMMON_SEPARATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_COMMON_SEPARATOR_DLL_VARIABLE)/g' \ | ||
| 3307 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_BLOCK_SEPARATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_BLOCK_SEPARATOR_DLL_VARIABLE)/g' \ | ||
| 3308 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_SEGMENT_SEPARATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_SEGMENT_SEPARATOR_DLL_VARIABLE)/g' \ | ||
| 3309 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_WHITESPACE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_WHITESPACE_DLL_VARIABLE)/g' \ | ||
| 3310 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_NON_SPACING_MARK_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_NON_SPACING_MARK_DLL_VARIABLE)/g' \ | ||
| 3311 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_BOUNDARY_NEUTRAL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_BOUNDARY_NEUTRAL_DLL_VARIABLE)/g' \ | ||
| 3312 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_PDF_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_PDF_DLL_VARIABLE)/g' \ | ||
| 3313 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_EMBEDDING_OR_OVERRIDE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_EMBEDDING_OR_OVERRIDE_DLL_VARIABLE)/g' \ | ||
| 3314 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_BIDI_OTHER_NEUTRAL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_BIDI_OTHER_NEUTRAL_DLL_VARIABLE)/g' \ | ||
| 3315 | < $@-t2 > $@-t3 | ||
| 3316 | $(AM_V_at)sed \ | ||
| 3317 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_HEX_DIGIT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_HEX_DIGIT_DLL_VARIABLE)/g' \ | ||
| 3318 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_ASCII_HEX_DIGIT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_ASCII_HEX_DIGIT_DLL_VARIABLE)/g' \ | ||
| 3319 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_IDEOGRAPHIC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_IDEOGRAPHIC_DLL_VARIABLE)/g' \ | ||
| 3320 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_UNIFIED_IDEOGRAPH_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_UNIFIED_IDEOGRAPH_DLL_VARIABLE)/g' \ | ||
| 3321 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_RADICAL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_RADICAL_DLL_VARIABLE)/g' \ | ||
| 3322 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_IDS_UNARY_OPERATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_IDS_UNARY_OPERATOR_DLL_VARIABLE)/g' \ | ||
| 3323 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_IDS_BINARY_OPERATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_IDS_BINARY_OPERATOR_DLL_VARIABLE)/g' \ | ||
| 3324 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_IDS_TRINARY_OPERATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_IDS_TRINARY_OPERATOR_DLL_VARIABLE)/g' \ | ||
| 3325 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_EMOJI_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_EMOJI_DLL_VARIABLE)/g' \ | ||
| 3326 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_EMOJI_PRESENTATION_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_EMOJI_PRESENTATION_DLL_VARIABLE)/g' \ | ||
| 3327 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_EMOJI_MODIFIER_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_EMOJI_MODIFIER_DLL_VARIABLE)/g' \ | ||
| 3328 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_EMOJI_MODIFIER_BASE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_EMOJI_MODIFIER_BASE_DLL_VARIABLE)/g' \ | ||
| 3329 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_EMOJI_COMPONENT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_EMOJI_COMPONENT_DLL_VARIABLE)/g' \ | ||
| 3330 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_EXTENDED_PICTOGRAPHIC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_EXTENDED_PICTOGRAPHIC_DLL_VARIABLE)/g' \ | ||
| 3331 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_ZERO_WIDTH_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_ZERO_WIDTH_DLL_VARIABLE)/g' \ | ||
| 3332 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_SPACE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_SPACE_DLL_VARIABLE)/g' \ | ||
| 3333 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_NON_BREAK_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_NON_BREAK_DLL_VARIABLE)/g' \ | ||
| 3334 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_ISO_CONTROL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_ISO_CONTROL_DLL_VARIABLE)/g' \ | ||
| 3335 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_FORMAT_CONTROL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_FORMAT_CONTROL_DLL_VARIABLE)/g' \ | ||
| 3336 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_PREPENDED_CONCATENATION_MARK_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_PREPENDED_CONCATENATION_MARK_DLL_VARIABLE)/g' \ | ||
| 3337 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_DASH_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_DASH_DLL_VARIABLE)/g' \ | ||
| 3338 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_HYPHEN_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_HYPHEN_DLL_VARIABLE)/g' \ | ||
| 3339 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_PUNCTUATION_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_PUNCTUATION_DLL_VARIABLE)/g' \ | ||
| 3340 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_LINE_SEPARATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_LINE_SEPARATOR_DLL_VARIABLE)/g' \ | ||
| 3341 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_PARAGRAPH_SEPARATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_PARAGRAPH_SEPARATOR_DLL_VARIABLE)/g' \ | ||
| 3342 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_QUOTATION_MARK_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_QUOTATION_MARK_DLL_VARIABLE)/g' \ | ||
| 3343 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_SENTENCE_TERMINAL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_SENTENCE_TERMINAL_DLL_VARIABLE)/g' \ | ||
| 3344 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_TERMINAL_PUNCTUATION_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_TERMINAL_PUNCTUATION_DLL_VARIABLE)/g' \ | ||
| 3345 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_CURRENCY_SYMBOL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_CURRENCY_SYMBOL_DLL_VARIABLE)/g' \ | ||
| 3346 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_MATH_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_MATH_DLL_VARIABLE)/g' \ | ||
| 3347 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_OTHER_MATH_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_OTHER_MATH_DLL_VARIABLE)/g' \ | ||
| 3348 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_PAIRED_PUNCTUATION_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_PAIRED_PUNCTUATION_DLL_VARIABLE)/g' \ | ||
| 3349 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_LEFT_OF_PAIR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_LEFT_OF_PAIR_DLL_VARIABLE)/g' \ | ||
| 3350 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_COMBINING_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_COMBINING_DLL_VARIABLE)/g' \ | ||
| 3351 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_COMPOSITE_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_COMPOSITE_DLL_VARIABLE)/g' \ | ||
| 3352 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_DECIMAL_DIGIT_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_DECIMAL_DIGIT_DLL_VARIABLE)/g' \ | ||
| 3353 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_NUMERIC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_NUMERIC_DLL_VARIABLE)/g' \ | ||
| 3354 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_DIACRITIC_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_DIACRITIC_DLL_VARIABLE)/g' \ | ||
| 3355 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_EXTENDER_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_EXTENDER_DLL_VARIABLE)/g' \ | ||
| 3356 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_IGNORABLE_CONTROL_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_IGNORABLE_CONTROL_DLL_VARIABLE)/g' \ | ||
| 3357 | -e 's/@''GNULIB_UNICTYPE_PROPERTY_REGIONAL_INDICATOR_DLL_VARIABLE''@/$(GL_GNULIB_UNICTYPE_PROPERTY_REGIONAL_INDICATOR_DLL_VARIABLE)/g' \ | ||
| 3358 | < $@-t3 > $@-t4 | ||
| 3359 | $(AM_V_at)rm -f $@-t1 $@-t2 $@-t3 | ||
| 3360 | $(AM_V_at)mv $@-t4 $@ | ||
| 3361 | MOSTLYCLEANFILES += unictype.h unictype.h-t1 unictype.h-t2 unictype.h-t3 unictype.h-t4 | ||
| 3362 | |||
| 3363 | EXTRA_DIST += unictype.in.h | ||
| 3364 | |||
| 3365 | ## end gnulib module unictype/base | ||
| 3366 | |||
| 3367 | ## begin gnulib module unictype/ctype-alnum | ||
| 3368 | |||
| 3369 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_ALNUM | ||
| 3370 | libgnu_a_SOURCES += unictype/ctype_alnum.c | ||
| 3371 | endif | ||
| 3372 | |||
| 3373 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_alnum.h | ||
| 3374 | |||
| 3375 | ## end gnulib module unictype/ctype-alnum | ||
| 3376 | |||
| 3377 | ## begin gnulib module unictype/ctype-alpha | ||
| 3378 | |||
| 3379 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_ALPHA | ||
| 3380 | libgnu_a_SOURCES += unictype/ctype_alpha.c | ||
| 3381 | endif | ||
| 3382 | |||
| 3383 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_alpha.h | ||
| 3384 | |||
| 3385 | ## end gnulib module unictype/ctype-alpha | ||
| 3386 | |||
| 3387 | ## begin gnulib module unictype/ctype-blank | ||
| 3388 | |||
| 3389 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_BLANK | ||
| 3390 | libgnu_a_SOURCES += unictype/ctype_blank.c | ||
| 3391 | endif | ||
| 3392 | |||
| 3393 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_blank.h | ||
| 3394 | |||
| 3395 | ## end gnulib module unictype/ctype-blank | ||
| 3396 | |||
| 3397 | ## begin gnulib module unictype/ctype-cntrl | ||
| 3398 | |||
| 3399 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_CNTRL | ||
| 3400 | libgnu_a_SOURCES += unictype/ctype_cntrl.c | ||
| 3401 | endif | ||
| 3402 | |||
| 3403 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_cntrl.h | ||
| 3404 | |||
| 3405 | ## end gnulib module unictype/ctype-cntrl | ||
| 3406 | |||
| 3407 | ## begin gnulib module unictype/ctype-digit | ||
| 3408 | |||
| 3409 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_DIGIT | ||
| 3410 | libgnu_a_SOURCES += unictype/ctype_digit.c | ||
| 3411 | endif | ||
| 3412 | |||
| 3413 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_digit.h | ||
| 3414 | |||
| 3415 | ## end gnulib module unictype/ctype-digit | ||
| 3416 | |||
| 3417 | ## begin gnulib module unictype/ctype-graph | ||
| 3418 | |||
| 3419 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_GRAPH | ||
| 3420 | libgnu_a_SOURCES += unictype/ctype_graph.c | ||
| 3421 | endif | ||
| 3422 | |||
| 3423 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_graph.h | ||
| 3424 | |||
| 3425 | ## end gnulib module unictype/ctype-graph | ||
| 3426 | |||
| 3427 | ## begin gnulib module unictype/ctype-lower | ||
| 3428 | |||
| 3429 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_LOWER | ||
| 3430 | libgnu_a_SOURCES += unictype/ctype_lower.c | ||
| 3431 | endif | ||
| 3432 | |||
| 3433 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_lower.h | ||
| 3434 | |||
| 3435 | ## end gnulib module unictype/ctype-lower | ||
| 3436 | |||
| 3437 | ## begin gnulib module unictype/ctype-print | ||
| 3438 | |||
| 3439 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_PRINT | ||
| 3440 | libgnu_a_SOURCES += unictype/ctype_print.c | ||
| 3441 | endif | ||
| 3442 | |||
| 3443 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_print.h | ||
| 3444 | |||
| 3445 | ## end gnulib module unictype/ctype-print | ||
| 3446 | |||
| 3447 | ## begin gnulib module unictype/ctype-punct | ||
| 3448 | |||
| 3449 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_PUNCT | ||
| 3450 | libgnu_a_SOURCES += unictype/ctype_punct.c | ||
| 3451 | endif | ||
| 3452 | |||
| 3453 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_punct.h | ||
| 3454 | |||
| 3455 | ## end gnulib module unictype/ctype-punct | ||
| 3456 | |||
| 3457 | ## begin gnulib module unictype/ctype-space | ||
| 3458 | |||
| 3459 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_SPACE | ||
| 3460 | libgnu_a_SOURCES += unictype/ctype_space.c | ||
| 3461 | endif | ||
| 3462 | |||
| 3463 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_space.h | ||
| 3464 | |||
| 3465 | ## end gnulib module unictype/ctype-space | ||
| 3466 | |||
| 3467 | ## begin gnulib module unictype/ctype-upper | ||
| 3468 | |||
| 3469 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_UPPER | ||
| 3470 | libgnu_a_SOURCES += unictype/ctype_upper.c | ||
| 3471 | endif | ||
| 3472 | |||
| 3473 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_upper.h | ||
| 3474 | |||
| 3475 | ## end gnulib module unictype/ctype-upper | ||
| 3476 | |||
| 3477 | ## begin gnulib module unictype/ctype-xdigit | ||
| 3478 | |||
| 3479 | if LIBUNISTRING_COMPILE_UNICTYPE_CTYPE_XDIGIT | ||
| 3480 | libgnu_a_SOURCES += unictype/ctype_xdigit.c | ||
| 3481 | endif | ||
| 3482 | |||
| 3483 | EXTRA_DIST += unictype/bitmap.h unictype/ctype_xdigit.h | ||
| 3484 | |||
| 3485 | ## end gnulib module unictype/ctype-xdigit | ||
| 3486 | |||
| 3487 | ## begin gnulib module uninorm/base | ||
| 3488 | |||
| 3489 | BUILT_SOURCES += $(LIBUNISTRING_UNINORM_H) | ||
| 3490 | |||
| 3491 | uninorm.h: uninorm.in.h | ||
| 3492 | $(gl_V_at)$(SED_HEADER_STDOUT) \ | ||
| 3493 | -e 's|@''HAVE_UNISTRING_WOE32DLL_H''@|$(HAVE_UNISTRING_WOE32DLL_H)|g' \ | ||
| 3494 | -e 's/@''GNULIB_UNINORM_NFD_DLL_VARIABLE''@/$(GL_GNULIB_UNINORM_NFD_DLL_VARIABLE)/g' \ | ||
| 3495 | -e 's/@''GNULIB_UNINORM_NFC_DLL_VARIABLE''@/$(GL_GNULIB_UNINORM_NFC_DLL_VARIABLE)/g' \ | ||
| 3496 | -e 's/@''GNULIB_UNINORM_NFKD_DLL_VARIABLE''@/$(GL_GNULIB_UNINORM_NFKD_DLL_VARIABLE)/g' \ | ||
| 3497 | -e 's/@''GNULIB_UNINORM_NFKC_DLL_VARIABLE''@/$(GL_GNULIB_UNINORM_NFKC_DLL_VARIABLE)/g' \ | ||
| 3498 | $(srcdir)/uninorm.in.h > $@-t | ||
| 3499 | $(AM_V_at)mv $@-t $@ | ||
| 3500 | MOSTLYCLEANFILES += uninorm.h uninorm.h-t | ||
| 3501 | |||
| 3502 | EXTRA_DIST += uninorm.in.h | ||
| 3503 | |||
| 3504 | ## end gnulib module uninorm/base | ||
| 3505 | |||
| 3506 | ## begin gnulib module unistd-h | ||
| 2658 | 3507 | ||
| 2659 | BUILT_SOURCES += unistd.h | 3508 | BUILT_SOURCES += unistd.h |
| 2660 | libgnu_a_SOURCES += unistd.c | 3509 | libgnu_a_SOURCES += unistd.c |
| @@ -2830,11 +3679,13 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H | |||
| 2830 | -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ | 3679 | -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ |
| 2831 | -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \ | 3680 | -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \ |
| 2832 | -e 's|@''REPLACE_GETENTROPY''@|$(REPLACE_GETENTROPY)|g' \ | 3681 | -e 's|@''REPLACE_GETENTROPY''@|$(REPLACE_GETENTROPY)|g' \ |
| 3682 | -e 's|@''REPLACE_GETLOGIN''@|$(REPLACE_GETLOGIN)|g' \ | ||
| 2833 | -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ | 3683 | -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ |
| 2834 | -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ | 3684 | -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ |
| 2835 | -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ | 3685 | -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ |
| 2836 | -e 's|@''REPLACE_GETPASS''@|$(REPLACE_GETPASS)|g' \ | 3686 | -e 's|@''REPLACE_GETPASS''@|$(REPLACE_GETPASS)|g' \ |
| 2837 | -e 's|@''REPLACE_GETPASS_FOR_GETPASS_GNU''@|$(REPLACE_GETPASS_FOR_GETPASS_GNU)|g' \ | 3687 | -e 's|@''REPLACE_GETPASS_FOR_GETPASS_GNU''@|$(REPLACE_GETPASS_FOR_GETPASS_GNU)|g' \ |
| 3688 | -e 's|@''REPLACE_GETUSERSHELL''@|$(REPLACE_GETUSERSHELL)|g' \ | ||
| 2838 | -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \ | 3689 | -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \ |
| 2839 | -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ | 3690 | -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ |
| 2840 | -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \ | 3691 | -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \ |
| @@ -2870,7 +3721,43 @@ MOSTLYCLEANFILES += unistd.h unistd.h-t1 unistd.h-t2 unistd.h-t3 unistd.h-t4 | |||
| 2870 | 3721 | ||
| 2871 | EXTRA_DIST += unistd.in.h | 3722 | EXTRA_DIST += unistd.in.h |
| 2872 | 3723 | ||
| 2873 | ## end gnulib module unistd | 3724 | ## end gnulib module unistd-h |
| 3725 | |||
| 3726 | ## begin gnulib module unitypes-h | ||
| 3727 | |||
| 3728 | BUILT_SOURCES += $(LIBUNISTRING_UNITYPES_H) | ||
| 3729 | |||
| 3730 | unitypes.h: unitypes.in.h | ||
| 3731 | $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/unitypes.in.h | ||
| 3732 | $(AM_V_at)mv $@-t $@ | ||
| 3733 | MOSTLYCLEANFILES += unitypes.h unitypes.h-t | ||
| 3734 | |||
| 3735 | EXTRA_DIST += unitypes.in.h | ||
| 3736 | |||
| 3737 | ## end gnulib module unitypes-h | ||
| 3738 | |||
| 3739 | ## begin gnulib module uniwidth/base | ||
| 3740 | |||
| 3741 | BUILT_SOURCES += $(LIBUNISTRING_UNIWIDTH_H) | ||
| 3742 | |||
| 3743 | uniwidth.h: uniwidth.in.h | ||
| 3744 | $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/uniwidth.in.h | ||
| 3745 | $(AM_V_at)mv $@-t $@ | ||
| 3746 | MOSTLYCLEANFILES += uniwidth.h uniwidth.h-t | ||
| 3747 | |||
| 3748 | EXTRA_DIST += localcharset.h uniwidth.in.h | ||
| 3749 | |||
| 3750 | ## end gnulib module uniwidth/base | ||
| 3751 | |||
| 3752 | ## begin gnulib module uniwidth/width | ||
| 3753 | |||
| 3754 | if LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH | ||
| 3755 | libgnu_a_SOURCES += uniwidth/width.c | ||
| 3756 | endif | ||
| 3757 | |||
| 3758 | EXTRA_DIST += unictype/bitmap.h uniwidth/cjk.h uniwidth/width0.h uniwidth/width2.h | ||
| 3759 | |||
| 3760 | ## end gnulib module uniwidth/width | ||
| 2874 | 3761 | ||
| 2875 | ## begin gnulib module unlocked-io-internal | 3762 | ## begin gnulib module unlocked-io-internal |
| 2876 | 3763 | ||
| @@ -2921,7 +3808,13 @@ EXTRA_libgnu_a_SOURCES += vsnprintf.c | |||
| 2921 | 3808 | ||
| 2922 | ## end gnulib module vsnprintf | 3809 | ## end gnulib module vsnprintf |
| 2923 | 3810 | ||
| 2924 | ## begin gnulib module wchar | 3811 | ## begin gnulib module vsnzprintf |
| 3812 | |||
| 3813 | libgnu_a_SOURCES += vsnzprintf.c | ||
| 3814 | |||
| 3815 | ## end gnulib module vsnzprintf | ||
| 3816 | |||
| 3817 | ## begin gnulib module wchar-h | ||
| 2925 | 3818 | ||
| 2926 | BUILT_SOURCES += wchar.h | 3819 | BUILT_SOURCES += wchar.h |
| 2927 | 3820 | ||
| @@ -3046,6 +3939,7 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) | |||
| 3046 | -e 's|@''REPLACE_WCSWIDTH''@|$(REPLACE_WCSWIDTH)|g' \ | 3939 | -e 's|@''REPLACE_WCSWIDTH''@|$(REPLACE_WCSWIDTH)|g' \ |
| 3047 | -e 's|@''REPLACE_WCSFTIME''@|$(REPLACE_WCSFTIME)|g' \ | 3940 | -e 's|@''REPLACE_WCSFTIME''@|$(REPLACE_WCSFTIME)|g' \ |
| 3048 | -e 's|@''REPLACE_WCSCMP''@|$(REPLACE_WCSCMP)|g' \ | 3941 | -e 's|@''REPLACE_WCSCMP''@|$(REPLACE_WCSCMP)|g' \ |
| 3942 | -e 's|@''REPLACE_WCSNCAT''@|$(REPLACE_WCSNCAT)|g' \ | ||
| 3049 | -e 's|@''REPLACE_WCSNCMP''@|$(REPLACE_WCSNCMP)|g' \ | 3943 | -e 's|@''REPLACE_WCSNCMP''@|$(REPLACE_WCSNCMP)|g' \ |
| 3050 | -e 's|@''REPLACE_WCSSTR''@|$(REPLACE_WCSSTR)|g' \ | 3944 | -e 's|@''REPLACE_WCSSTR''@|$(REPLACE_WCSSTR)|g' \ |
| 3051 | -e 's|@''REPLACE_WCSTOK''@|$(REPLACE_WCSTOK)|g' \ | 3945 | -e 's|@''REPLACE_WCSTOK''@|$(REPLACE_WCSTOK)|g' \ |
| @@ -3061,7 +3955,7 @@ MOSTLYCLEANFILES += wchar.h wchar.h-t1 wchar.h-t2 wchar.h-t3 | |||
| 3061 | 3955 | ||
| 3062 | EXTRA_DIST += wchar.in.h | 3956 | EXTRA_DIST += wchar.in.h |
| 3063 | 3957 | ||
| 3064 | ## end gnulib module wchar | 3958 | ## end gnulib module wchar-h |
| 3065 | 3959 | ||
| 3066 | ## begin gnulib module wcrtomb | 3960 | ## begin gnulib module wcrtomb |
| 3067 | 3961 | ||
| @@ -3130,6 +4024,14 @@ EXTRA_DIST += wctype.in.h | |||
| 3130 | 4024 | ||
| 3131 | ## end gnulib module wctype-h | 4025 | ## end gnulib module wctype-h |
| 3132 | 4026 | ||
| 4027 | ## begin gnulib module wcwidth | ||
| 4028 | |||
| 4029 | if GL_COND_OBJ_WCWIDTH | ||
| 4030 | libgnu_a_SOURCES += wcwidth.c | ||
| 4031 | endif | ||
| 4032 | |||
| 4033 | ## end gnulib module wcwidth | ||
| 4034 | |||
| 3133 | ## begin gnulib module windows-mutex | 4035 | ## begin gnulib module windows-mutex |
| 3134 | 4036 | ||
| 3135 | if GL_COND_OBJ_WINDOWS_MUTEX | 4037 | if GL_COND_OBJ_WINDOWS_MUTEX |
| @@ -3209,5 +4111,5 @@ mostlyclean-local: mostlyclean-generic | |||
| 3209 | : | 4111 | : |
| 3210 | distclean-local: distclean-gnulib-libobjs | 4112 | distclean-local: distclean-gnulib-libobjs |
| 3211 | distclean-gnulib-libobjs: | 4113 | distclean-gnulib-libobjs: |
| 3212 | -rm -f @gl_LIBOBJDEPS@ | 4114 | -rm -f @gl_libgnu_LIBOBJDEPS@ |
| 3213 | maintainer-clean-local: distclean-gnulib-libobjs | 4115 | maintainer-clean-local: distclean-gnulib-libobjs |
diff --git a/gl/_Noreturn.h b/gl/_Noreturn.h index 7326bd47..d42f15ee 100644 --- a/gl/_Noreturn.h +++ b/gl/_Noreturn.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* A C macro for declaring that a function does not return. | 1 | /* A C macro for declaring that a function does not return. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify it | 4 | This program is free software: you can redistribute it and/or modify it |
| 5 | under the terms of the GNU Lesser General Public License as published | 5 | under the terms of the GNU Lesser General Public License as published |
| @@ -14,33 +14,26 @@ | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | 14 | You should have received a copy of the GNU Lesser General Public License |
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
| 16 | 16 | ||
| 17 | /* The _Noreturn keyword of C11. | ||
| 18 | Do not use [[noreturn]], because with it the syntax | ||
| 19 | extern _Noreturn void func (...); | ||
| 20 | would not be valid; such a declaration would be valid only with 'extern' | ||
| 21 | and '_Noreturn' swapped, or without the 'extern' keyword. However, some | ||
| 22 | AIX system header files and several gnulib header files use precisely | ||
| 23 | this syntax with 'extern'. So even though C23 deprecates _Noreturn, | ||
| 24 | it is currently more portable to prefer it to [[noreturn]]. | ||
| 25 | |||
| 26 | Also, do not try to work around LLVM bug 59792 (clang 15 or earlier). | ||
| 27 | This rare bug can be worked around by compiling with 'clang -D_Noreturn=', | ||
| 28 | though the workaround may generate many false-alarm warnings. */ | ||
| 17 | #ifndef _Noreturn | 29 | #ifndef _Noreturn |
| 18 | # if (defined __cplusplus \ | 30 | # if ((!defined __cplusplus || defined __clang__) \ |
| 19 | && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ | 31 | && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0))) |
| 20 | || (defined _MSC_VER && 1900 <= _MSC_VER)) \ | ||
| 21 | && 0) | ||
| 22 | /* [[noreturn]] is not practically usable, because with it the syntax | ||
| 23 | extern _Noreturn void func (...); | ||
| 24 | would not be valid; such a declaration would only be valid with 'extern' | ||
| 25 | and '_Noreturn' swapped, or without the 'extern' keyword. However, some | ||
| 26 | AIX system header files and several gnulib header files use precisely | ||
| 27 | this syntax with 'extern'. */ | ||
| 28 | # define _Noreturn [[noreturn]] | ||
| 29 | # elif (defined __clang__ && __clang_major__ < 16 \ | ||
| 30 | && defined _GL_WORK_AROUND_LLVM_BUG_59792) | ||
| 31 | /* Compile with -D_GL_WORK_AROUND_LLVM_BUG_59792 to work around | ||
| 32 | that rare LLVM bug, though you may get many false-alarm warnings. */ | ||
| 33 | # define _Noreturn | ||
| 34 | # elif ((!defined __cplusplus || defined __clang__) \ | ||
| 35 | && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ | ||
| 36 | || (!defined __STRICT_ANSI__ \ | ||
| 37 | && (4 < __GNUC__ + (7 <= __GNUC_MINOR__) \ | ||
| 38 | || (defined __apple_build_version__ \ | ||
| 39 | ? 6000000 <= __apple_build_version__ \ | ||
| 40 | : 3 < __clang_major__ + (5 <= __clang_minor__)))))) | ||
| 41 | /* _Noreturn works as-is. */ | 32 | /* _Noreturn works as-is. */ |
| 42 | # elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \ | 33 | # elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \ |
| 43 | || 0x5110 <= __SUNPRO_C) | 34 | || 0x5110 <= __SUNPRO_C) |
| 35 | /* Prefer __attribute__ ((__noreturn__)) to plain _Noreturn even if the | ||
| 36 | latter works, as 'gcc -std=gnu99 -Wpedantic' warns about _Noreturn. */ | ||
| 44 | # define _Noreturn __attribute__ ((__noreturn__)) | 37 | # define _Noreturn __attribute__ ((__noreturn__)) |
| 45 | # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) | 38 | # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) |
| 46 | # define _Noreturn __declspec (noreturn) | 39 | # define _Noreturn __declspec (noreturn) |
diff --git a/gl/af_alg.c b/gl/af_alg.c index 6fd08c28..cfa96954 100644 --- a/gl/af_alg.c +++ b/gl/af_alg.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* af_alg.c - Compute message digests from file streams and buffers. | 1 | /* af_alg.c - Compute message digests from file streams and buffers. |
| 2 | Copyright (C) 2018-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2018-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/af_alg.h b/gl/af_alg.h index ed933e12..236659bc 100644 --- a/gl/af_alg.h +++ b/gl/af_alg.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* af_alg.h - Compute message digests from file streams and buffers. | 1 | /* af_alg.h - Compute message digests from file streams and buffers. |
| 2 | Copyright (C) 2018-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2018-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/alloca.in.h b/gl/alloca.in.h index 6aa47df8..afb00caf 100644 --- a/gl/alloca.in.h +++ b/gl/alloca.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Memory allocation on the stack. | 1 | /* Memory allocation on the stack. |
| 2 | 2 | ||
| 3 | Copyright (C) 1995, 1999, 2001-2004, 2006-2024 Free Software Foundation, | 3 | Copyright (C) 1995, 1999, 2001-2004, 2006-2025 Free Software Foundation, |
| 4 | Inc. | 4 | Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/arg-nonnull.h b/gl/arg-nonnull.h index 46c711ca..747bb413 100644 --- a/gl/arg-nonnull.h +++ b/gl/arg-nonnull.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* A C macro for declaring that specific arguments must not be NULL. | 1 | /* A C macro for declaring that specific arguments must not be NULL. |
| 2 | Copyright (C) 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify it | 4 | This program is free software: you can redistribute it and/or modify it |
| 5 | under the terms of the GNU Lesser General Public License as published | 5 | under the terms of the GNU Lesser General Public License as published |
diff --git a/gl/arpa_inet.c b/gl/arpa_inet.c new file mode 100644 index 00000000..fae7c241 --- /dev/null +++ b/gl/arpa_inet.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Inline functions for <arpa/inet.h>. | ||
| 2 | |||
| 3 | Copyright (C) 2024-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | #define _GL_ARPA_INET_INLINE _GL_EXTERN_INLINE | ||
| 21 | #include <arpa/inet.h> | ||
diff --git a/gl/arpa_inet.in.h b/gl/arpa_inet.in.h index 523a448c..d7417bfd 100644 --- a/gl/arpa_inet.in.h +++ b/gl/arpa_inet.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A GNU-like <arpa/inet.h>. | 1 | /* A GNU-like <arpa/inet.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2005-2006, 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2005-2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -60,6 +60,53 @@ | |||
| 60 | # include <ws2tcpip.h> | 60 | # include <ws2tcpip.h> |
| 61 | #endif | 61 | #endif |
| 62 | 62 | ||
| 63 | #if !(@HAVE_DECL_HTONL@ || @HAVE_DECL_HTONS@ || @HAVE_DECL_NTOHL@ || @HAVE_DECL_NTOHS@) | ||
| 64 | # include <endian.h> | ||
| 65 | #endif | ||
| 66 | |||
| 67 | _GL_INLINE_HEADER_BEGIN | ||
| 68 | #ifndef _GL_ARPA_INET_INLINE | ||
| 69 | # define _GL_ARPA_INET_INLINE _GL_INLINE | ||
| 70 | #endif | ||
| 71 | |||
| 72 | |||
| 73 | /* Host to network byte order. */ | ||
| 74 | |||
| 75 | #if !@HAVE_DECL_HTONS@ | ||
| 76 | _GL_ARPA_INET_INLINE uint16_t | ||
| 77 | htons (uint16_t value) | ||
| 78 | { | ||
| 79 | return htobe16 (value); | ||
| 80 | } | ||
| 81 | #endif | ||
| 82 | |||
| 83 | #if !@HAVE_DECL_HTONL@ | ||
| 84 | _GL_ARPA_INET_INLINE uint32_t | ||
| 85 | htonl (uint32_t value) | ||
| 86 | { | ||
| 87 | return htobe32 (value); | ||
| 88 | } | ||
| 89 | #endif | ||
| 90 | |||
| 91 | /* Network to host byte order. */ | ||
| 92 | |||
| 93 | #if !@HAVE_DECL_NTOHS@ | ||
| 94 | _GL_ARPA_INET_INLINE uint16_t | ||
| 95 | ntohs (uint16_t value) | ||
| 96 | { | ||
| 97 | return htobe16 (value); | ||
| 98 | } | ||
| 99 | #endif | ||
| 100 | |||
| 101 | #if !@HAVE_DECL_NTOHL@ | ||
| 102 | _GL_ARPA_INET_INLINE uint32_t | ||
| 103 | ntohl (uint32_t value) | ||
| 104 | { | ||
| 105 | return htobe32 (value); | ||
| 106 | } | ||
| 107 | #endif | ||
| 108 | |||
| 109 | |||
| 63 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | 110 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ |
| 64 | 111 | ||
| 65 | /* The definition of _GL_ARG_NONNULL is copied here. */ | 112 | /* The definition of _GL_ARG_NONNULL is copied here. */ |
| @@ -90,7 +137,7 @@ | |||
| 90 | # endif | 137 | # endif |
| 91 | _GL_FUNCDECL_RPL (inet_ntop, const char *, | 138 | _GL_FUNCDECL_RPL (inet_ntop, const char *, |
| 92 | (int af, const void *restrict src, | 139 | (int af, const void *restrict src, |
| 93 | char *restrict dst, socklen_t cnt) | 140 | char *restrict dst, socklen_t cnt), |
| 94 | _GL_ARG_NONNULL ((2, 3))); | 141 | _GL_ARG_NONNULL ((2, 3))); |
| 95 | _GL_CXXALIAS_RPL (inet_ntop, const char *, | 142 | _GL_CXXALIAS_RPL (inet_ntop, const char *, |
| 96 | (int af, const void *restrict src, | 143 | (int af, const void *restrict src, |
| @@ -99,7 +146,7 @@ _GL_CXXALIAS_RPL (inet_ntop, const char *, | |||
| 99 | # if !@HAVE_DECL_INET_NTOP@ | 146 | # if !@HAVE_DECL_INET_NTOP@ |
| 100 | _GL_FUNCDECL_SYS (inet_ntop, const char *, | 147 | _GL_FUNCDECL_SYS (inet_ntop, const char *, |
| 101 | (int af, const void *restrict src, | 148 | (int af, const void *restrict src, |
| 102 | char *restrict dst, socklen_t cnt) | 149 | char *restrict dst, socklen_t cnt), |
| 103 | _GL_ARG_NONNULL ((2, 3))); | 150 | _GL_ARG_NONNULL ((2, 3))); |
| 104 | # endif | 151 | # endif |
| 105 | /* Need to cast, because on NonStop Kernel, the fourth parameter is | 152 | /* Need to cast, because on NonStop Kernel, the fourth parameter is |
| @@ -126,14 +173,14 @@ _GL_WARN_ON_USE (inet_ntop, "inet_ntop is unportable - " | |||
| 126 | # define inet_pton rpl_inet_pton | 173 | # define inet_pton rpl_inet_pton |
| 127 | # endif | 174 | # endif |
| 128 | _GL_FUNCDECL_RPL (inet_pton, int, | 175 | _GL_FUNCDECL_RPL (inet_pton, int, |
| 129 | (int af, const char *restrict src, void *restrict dst) | 176 | (int af, const char *restrict src, void *restrict dst), |
| 130 | _GL_ARG_NONNULL ((2, 3))); | 177 | _GL_ARG_NONNULL ((2, 3))); |
| 131 | _GL_CXXALIAS_RPL (inet_pton, int, | 178 | _GL_CXXALIAS_RPL (inet_pton, int, |
| 132 | (int af, const char *restrict src, void *restrict dst)); | 179 | (int af, const char *restrict src, void *restrict dst)); |
| 133 | # else | 180 | # else |
| 134 | # if !@HAVE_DECL_INET_PTON@ | 181 | # if !@HAVE_DECL_INET_PTON@ |
| 135 | _GL_FUNCDECL_SYS (inet_pton, int, | 182 | _GL_FUNCDECL_SYS (inet_pton, int, |
| 136 | (int af, const char *restrict src, void *restrict dst) | 183 | (int af, const char *restrict src, void *restrict dst), |
| 137 | _GL_ARG_NONNULL ((2, 3))); | 184 | _GL_ARG_NONNULL ((2, 3))); |
| 138 | # endif | 185 | # endif |
| 139 | _GL_CXXALIAS_SYS (inet_pton, int, | 186 | _GL_CXXALIAS_SYS (inet_pton, int, |
| @@ -150,6 +197,7 @@ _GL_WARN_ON_USE (inet_pton, "inet_pton is unportable - " | |||
| 150 | # endif | 197 | # endif |
| 151 | #endif | 198 | #endif |
| 152 | 199 | ||
| 200 | _GL_INLINE_HEADER_END | ||
| 153 | 201 | ||
| 154 | #endif /* _@GUARD_PREFIX@_ARPA_INET_H */ | 202 | #endif /* _@GUARD_PREFIX@_ARPA_INET_H */ |
| 155 | #endif /* _@GUARD_PREFIX@_ARPA_INET_H */ | 203 | #endif /* _@GUARD_PREFIX@_ARPA_INET_H */ |
diff --git a/gl/asnprintf.c b/gl/asnprintf.c index a6c09bc2..0488b6be 100644 --- a/gl/asnprintf.c +++ b/gl/asnprintf.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Formatted output to strings. | 1 | /* Formatted output to strings. |
| 2 | Copyright (C) 1999, 2002, 2006, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2002, 2006, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/asprintf.c b/gl/asprintf.c index b0c33478..336700be 100644 --- a/gl/asprintf.c +++ b/gl/asprintf.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Formatted output to strings. | 1 | /* Formatted output to strings. |
| 2 | Copyright (C) 1999, 2002, 2006-2007, 2009-2024 Free Software Foundation, | 2 | Copyright (C) 1999, 2002, 2006-2007, 2009-2025 Free Software Foundation, |
| 3 | Inc. | 3 | Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/assert.in.h b/gl/assert.in.h index 6e4995e1..87339abc 100644 --- a/gl/assert.in.h +++ b/gl/assert.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Substitute for and wrapper around <assert.h> | 1 | /* Substitute for and wrapper around <assert.h> |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/attribute.h b/gl/attribute.h index 710341ba..c85412d9 100644 --- a/gl/attribute.h +++ b/gl/attribute.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* ATTRIBUTE_* macros for using attributes in GCC and similar compilers | 1 | /* ATTRIBUTE_* macros for using attributes in GCC and similar compilers |
| 2 | 2 | ||
| 3 | Copyright 2020-2024 Free Software Foundation, Inc. | 3 | Copyright 2020-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -20,12 +20,50 @@ | |||
| 20 | /* Provide public ATTRIBUTE_* names for the private _GL_ATTRIBUTE_* | 20 | /* Provide public ATTRIBUTE_* names for the private _GL_ATTRIBUTE_* |
| 21 | macros used within Gnulib. */ | 21 | macros used within Gnulib. */ |
| 22 | 22 | ||
| 23 | /* These attributes can be placed in two ways: | 23 | /* The placement of these attributes depends on the kind of declaration |
| 24 | - At the start of a declaration (i.e. even before storage-class | 24 | and, in some cases, also on the programming language (C vs. C++). |
| 25 | specifiers!); then they apply to all entities that are declared | 25 | |
| 26 | by the declaration. | 26 | In function declarations and function definitions: |
| 27 | - Immediately after the name of an entity being declared by the | 27 | |
| 28 | declaration; then they apply to that entity only. */ | 28 | * ATTRIBUTE_NOTHROW must come after the parameter list. |
| 29 | |||
| 30 | * The macros | ||
| 31 | ATTRIBUTE_CONST | ||
| 32 | ATTRIBUTE_PURE | ||
| 33 | DEPRECATED | ||
| 34 | MAYBE_UNUSED | ||
| 35 | NODISCARD | ||
| 36 | REPRODUCIBLE | ||
| 37 | UNSEQUENCED | ||
| 38 | must come before the return type, and more precisely: | ||
| 39 | - In a function declaration/definition without a storage-class | ||
| 40 | specifier: at the beginning of the declaration/definition. | ||
| 41 | - In a function declaration/definition with a storage-class | ||
| 42 | specifier: | ||
| 43 | - In C: before the storage-class specifier. | ||
| 44 | - In C++: between the storage-class specifier and the return type. | ||
| 45 | |||
| 46 | * The other macros can be placed | ||
| 47 | - Either | ||
| 48 | - In a function declaration/definition without a storage-class | ||
| 49 | specifier: at the beginning of the declaration/definition. | ||
| 50 | - In a function declaration/definition with a storage-class | ||
| 51 | specifier: between the storage-class specifier and the return | ||
| 52 | type. | ||
| 53 | - Or, in a function declaration: | ||
| 54 | after the parameter list, | ||
| 55 | ∙ but after ATTRIBUTE_NOTHROW if present. | ||
| 56 | |||
| 57 | In other declarations, such as variable declarations: | ||
| 58 | |||
| 59 | * Either | ||
| 60 | - In C: before the storage-class specifier. | ||
| 61 | - In C++: between the storage-class specifier and the return type. | ||
| 62 | Then they apply to all entities that are declared by the declaration. | ||
| 63 | |||
| 64 | * Or immediately after the name of an entity being declared by the | ||
| 65 | declaration. Then they apply to that entity only. | ||
| 66 | */ | ||
| 29 | 67 | ||
| 30 | #ifndef _GL_ATTRIBUTE_H | 68 | #ifndef _GL_ATTRIBUTE_H |
| 31 | #define _GL_ATTRIBUTE_H | 69 | #define _GL_ATTRIBUTE_H |
| @@ -48,9 +86,10 @@ | |||
| 48 | _GL_ATTRIBUTE_FALLTHROUGH, _GL_ATTRIBUTE_FORMAT, _GL_ATTRIBUTE_LEAF, | 86 | _GL_ATTRIBUTE_FALLTHROUGH, _GL_ATTRIBUTE_FORMAT, _GL_ATTRIBUTE_LEAF, |
| 49 | _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_MAY_ALIAS, _GL_ATTRIBUTE_MAYBE_UNUSED, | 87 | _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_MAY_ALIAS, _GL_ATTRIBUTE_MAYBE_UNUSED, |
| 50 | _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOINLINE, _GL_ATTRIBUTE_NONNULL, | 88 | _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOINLINE, _GL_ATTRIBUTE_NONNULL, |
| 51 | _GL_ATTRIBUTE_NONSTRING, _GL_ATTRIBUTE_NOTHROW, _GL_ATTRIBUTE_PACKED, | 89 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO, _GL_ATTRIBUTE_NONSTRING, |
| 52 | _GL_ATTRIBUTE_PURE, _GL_ATTRIBUTE_RETURNS_NONNULL, | 90 | _GL_ATTRIBUTE_NOTHROW, _GL_ATTRIBUTE_PACKED, _GL_ATTRIBUTE_PURE, |
| 53 | _GL_ATTRIBUTE_SENTINEL. */ | 91 | _GL_ATTRIBUTE_REPRODUCIBLE, _GL_ATTRIBUTE_RETURNS_NONNULL, |
| 92 | _GL_ATTRIBUTE_SENTINEL, _GL_ATTRIBUTE_UNSEQUENCED. */ | ||
| 54 | #if !_GL_CONFIG_H_INCLUDED | 93 | #if !_GL_CONFIG_H_INCLUDED |
| 55 | #error "Please include config.h first." | 94 | #error "Please include config.h first." |
| 56 | #endif | 95 | #endif |
| @@ -88,7 +127,7 @@ | |||
| 88 | is the size of the returned memory block. | 127 | is the size of the returned memory block. |
| 89 | ATTRIBUTE_ALLOC_SIZE ((M, N)) - Multiply the Mth and Nth arguments | 128 | ATTRIBUTE_ALLOC_SIZE ((M, N)) - Multiply the Mth and Nth arguments |
| 90 | to determine the size of the returned memory block. */ | 129 | to determine the size of the returned memory block. */ |
| 91 | /* Applies to: function, pointer to function, function types. */ | 130 | /* Applies to: functions, pointer to functions, function types. */ |
| 92 | #define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args) | 131 | #define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args) |
| 93 | 132 | ||
| 94 | /* ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers | 133 | /* ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers |
| @@ -132,6 +171,12 @@ | |||
| 132 | /* Applies to: functions. */ | 171 | /* Applies to: functions. */ |
| 133 | #define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL (args) | 172 | #define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL (args) |
| 134 | 173 | ||
| 174 | /* ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) - Argument NP (a pointer) | ||
| 175 | must not be NULL if the argument NI (an integer) is != 0. */ | ||
| 176 | /* Applies to: functions. */ | ||
| 177 | #define ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (np, ni) | ||
| 178 | |||
| 179 | |||
| 135 | /* The function's return value is a non-NULL pointer. */ | 180 | /* The function's return value is a non-NULL pointer. */ |
| 136 | /* Applies to: functions. */ | 181 | /* Applies to: functions. */ |
| 137 | #define ATTRIBUTE_RETURNS_NONNULL _GL_ATTRIBUTE_RETURNS_NONNULL | 182 | #define ATTRIBUTE_RETURNS_NONNULL _GL_ATTRIBUTE_RETURNS_NONNULL |
| @@ -170,7 +215,7 @@ | |||
| 170 | /* Attributes regarding debugging information emitted by the compiler. */ | 215 | /* Attributes regarding debugging information emitted by the compiler. */ |
| 171 | 216 | ||
| 172 | /* Omit the function from stack traces when debugging. */ | 217 | /* Omit the function from stack traces when debugging. */ |
| 173 | /* Applies to: function. */ | 218 | /* Applies to: functions. */ |
| 174 | #define ATTRIBUTE_ARTIFICIAL _GL_ATTRIBUTE_ARTIFICIAL | 219 | #define ATTRIBUTE_ARTIFICIAL _GL_ATTRIBUTE_ARTIFICIAL |
| 175 | 220 | ||
| 176 | /* Make the entity visible to debuggers etc., even with '-fwhole-program'. */ | 221 | /* Make the entity visible to debuggers etc., even with '-fwhole-program'. */ |
| @@ -192,25 +237,68 @@ | |||
| 192 | 237 | ||
| 193 | /* Always inline the function, and report an error if the compiler | 238 | /* Always inline the function, and report an error if the compiler |
| 194 | cannot inline. */ | 239 | cannot inline. */ |
| 195 | /* Applies to: function. */ | 240 | /* Applies to: functions. */ |
| 196 | #define ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE | 241 | #define ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE |
| 197 | 242 | ||
| 198 | /* It is OK for a compiler to omit duplicate calls with the same arguments. | 243 | /* It is OK for a compiler to move calls to the function and to omit |
| 244 | calls to the function if another call has the same arguments or the | ||
| 245 | result is not used. | ||
| 199 | This attribute is safe for a function that neither depends on | 246 | This attribute is safe for a function that neither depends on |
| 200 | nor affects observable state, and always returns exactly once - | 247 | nor affects state, and always returns exactly once - |
| 201 | e.g., does not loop forever, and does not call longjmp. | 248 | e.g., does not raise an exception, call longjmp, or loop forever. |
| 202 | (This attribute is stricter than ATTRIBUTE_PURE.) */ | 249 | (This attribute is stricter than ATTRIBUTE_PURE because the |
| 250 | function cannot observe state. It is stricter than UNSEQUENCED | ||
| 251 | because the function must return exactly once and cannot depend on | ||
| 252 | state addressed by its arguments.) */ | ||
| 203 | /* Applies to: functions. */ | 253 | /* Applies to: functions. */ |
| 204 | #define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST | 254 | #define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST |
| 205 | 255 | ||
| 206 | /* It is OK for a compiler to omit duplicate calls with the same | 256 | /* It is OK for a compiler to move calls to the function and to omit duplicate |
| 207 | arguments if observable state is not changed between calls. | 257 | calls to the function with the same arguments, so long as the state |
| 208 | This attribute is safe for a function that does not affect | 258 | addressed by its arguments is the same. |
| 209 | observable state, and always returns exactly once. | 259 | This attribute is safe for a function that is effectless, idempotent, |
| 210 | (This attribute is looser than ATTRIBUTE_CONST.) */ | 260 | stateless, and independent; see ISO C 23 § 6.7.12.7 for a definition of |
| 261 | these terms. | ||
| 262 | (This attribute is stricter than REPRODUCIBLE because the function | ||
| 263 | must be stateless and independent. It is looser than ATTRIBUTE_CONST | ||
| 264 | because the function need not return exactly once and can depend | ||
| 265 | on state addressed by its arguments.) | ||
| 266 | See also <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2956.htm> and | ||
| 267 | <https://stackoverflow.com/questions/76847905/>. | ||
| 268 | ATTENTION! Efforts are underway to change the meaning of this attribute. | ||
| 269 | See <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3424.htm>. */ | ||
| 270 | /* Applies to: functions, pointer to functions, function type. */ | ||
| 271 | #define UNSEQUENCED _GL_ATTRIBUTE_UNSEQUENCED | ||
| 272 | |||
| 273 | /* It is OK for a compiler to move calls to the function and to omit | ||
| 274 | calls to the function if another call has the same arguments or the | ||
| 275 | result is not used, and if observable state is the same. | ||
| 276 | This attribute is safe for a function that does not affect observable state | ||
| 277 | and always returns exactly once. | ||
| 278 | (This attribute is looser than ATTRIBUTE_CONST because the function | ||
| 279 | can depend on observable state. It is stricter than REPRODUCIBLE | ||
| 280 | because the function must return exactly once and cannot affect | ||
| 281 | state addressed by its arguments.) */ | ||
| 211 | /* Applies to: functions. */ | 282 | /* Applies to: functions. */ |
| 212 | #define ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE | 283 | #define ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE |
| 213 | 284 | ||
| 285 | /* It is OK for a compiler to move calls to the function and to omit duplicate | ||
| 286 | calls to the function with the same arguments, so long as the state | ||
| 287 | addressed by its arguments is the same and is updated in time for | ||
| 288 | the rest of the program. | ||
| 289 | This attribute is safe for a function that is effectless and idempotent; see | ||
| 290 | ISO C 23 § 6.7.12.7 for a definition of these terms. | ||
| 291 | (This attribute is looser than UNSEQUENCED because the function need | ||
| 292 | not be stateless and idempotent. It is looser than ATTRIBUTE_PURE | ||
| 293 | because the function need not return exactly once and can affect | ||
| 294 | state addressed by its arguments.) | ||
| 295 | See also <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2956.htm> and | ||
| 296 | <https://stackoverflow.com/questions/76847905/>. | ||
| 297 | ATTENTION! Efforts are underway to change the meaning of this attribute. | ||
| 298 | See <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3424.htm>. */ | ||
| 299 | /* Applies to: functions, pointer to functions, function type. */ | ||
| 300 | #define REPRODUCIBLE _GL_ATTRIBUTE_REPRODUCIBLE | ||
| 301 | |||
| 214 | /* The function is rarely executed. */ | 302 | /* The function is rarely executed. */ |
| 215 | /* Applies to: functions. */ | 303 | /* Applies to: functions. */ |
| 216 | #define ATTRIBUTE_COLD _GL_ATTRIBUTE_COLD | 304 | #define ATTRIBUTE_COLD _GL_ATTRIBUTE_COLD |
diff --git a/gl/base64.c b/gl/base64.c index c8b3b76b..8a0edd4a 100644 --- a/gl/base64.c +++ b/gl/base64.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* base64.c -- Encode binary data using printable characters. | 1 | /* base64.c -- Encode binary data using printable characters. |
| 2 | Copyright (C) 1999-2001, 2004-2006, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1999-2001, 2004-2006, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -48,7 +48,7 @@ | |||
| 48 | /* Get imalloc. */ | 48 | /* Get imalloc. */ |
| 49 | #include <ialloc.h> | 49 | #include <ialloc.h> |
| 50 | 50 | ||
| 51 | #include <intprops.h> | 51 | #include <stdckdint.h> |
| 52 | 52 | ||
| 53 | #include <string.h> | 53 | #include <string.h> |
| 54 | 54 | ||
| @@ -59,7 +59,7 @@ to_uchar (char ch) | |||
| 59 | return ch; | 59 | return ch; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | static const char b64c[64] = | 62 | static const char b64c[64] _GL_ATTRIBUTE_NONSTRING = |
| 63 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 63 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 64 | 64 | ||
| 65 | /* Base64 encode IN array of size INLEN into OUT array. OUT needs | 65 | /* Base64 encode IN array of size INLEN into OUT array. OUT needs |
| @@ -148,7 +148,7 @@ base64_encode_alloc (const char *in, idx_t inlen, char **out) | |||
| 148 | Treat negative INLEN as overflow, for better compatibility with | 148 | Treat negative INLEN as overflow, for better compatibility with |
| 149 | pre-2021-08-27 API, which used size_t. */ | 149 | pre-2021-08-27 API, which used size_t. */ |
| 150 | idx_t in_over_3 = inlen / 3 + (inlen % 3 != 0), outlen; | 150 | idx_t in_over_3 = inlen / 3 + (inlen % 3 != 0), outlen; |
| 151 | if (! INT_MULTIPLY_OK (in_over_3, 4, &outlen) || inlen < 0) | 151 | if (ckd_mul (&outlen, in_over_3, 4) || inlen < 0) |
| 152 | { | 152 | { |
| 153 | *out = NULL; | 153 | *out = NULL; |
| 154 | return 0; | 154 | return 0; |
diff --git a/gl/base64.h b/gl/base64.h index 7691f6c4..cdafdac9 100644 --- a/gl/base64.h +++ b/gl/base64.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* base64.h -- Encode binary data using printable characters. | 1 | /* base64.h -- Encode binary data using printable characters. |
| 2 | Copyright (C) 2004-2006, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2004-2006, 2009-2025 Free Software Foundation, Inc. |
| 3 | Written by Simon Josefsson. | 3 | Written by Simon Josefsson. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <idx.h> | 27 | #include <idx.h> |
| 28 | 28 | ||
| 29 | /* Pacify GCC in isubase64. */ | 29 | /* Pacify GCC in isubase64. */ |
| 30 | #if defined __GNUC__ && 4 < __GNUC__ + (3 <= __GNUC_MINOR__) | 30 | #if 4 < __GNUC__ + (3 <= __GNUC_MINOR__) && !defined __clang__ |
| 31 | # pragma GCC diagnostic ignored "-Wtype-limits" | 31 | # pragma GCC diagnostic ignored "-Wtype-limits" |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
diff --git a/gl/basename-lgpl.c b/gl/basename-lgpl.c index 256f8460..2aecb0dd 100644 --- a/gl/basename-lgpl.c +++ b/gl/basename-lgpl.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* basename.c -- return the last element in a file name | 1 | /* basename.c -- return the last element in a file name |
| 2 | 2 | ||
| 3 | Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2024 Free Software | 3 | Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/basename-lgpl.h b/gl/basename-lgpl.h index 2a56be98..120bd1cf 100644 --- a/gl/basename-lgpl.h +++ b/gl/basename-lgpl.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Extract the last component (base name) of a file name. | 1 | /* Extract the last component (base name) of a file name. |
| 2 | 2 | ||
| 3 | Copyright (C) 1998, 2001, 2003-2006, 2009-2024 Free Software Foundation, | 3 | Copyright (C) 1998, 2001, 2003-2006, 2009-2025 Free Software Foundation, |
| 4 | Inc. | 4 | Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/basename.c b/gl/basename.c index c5a6bdc9..9d2852d4 100644 --- a/gl/basename.c +++ b/gl/basename.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* basename.c -- return the last element in a file name | 1 | /* basename.c -- return the last element in a file name |
| 2 | 2 | ||
| 3 | Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2024 Free Software | 3 | Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This program is free software: you can redistribute it and/or modify | 6 | This program is free software: you can redistribute it and/or modify |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Convert unibyte character to wide character. | 1 | /* Convert unibyte character to wide character. |
| 2 | Copyright (C) 2008, 2010-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008, 2010-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/byteswap.c b/gl/byteswap.c new file mode 100644 index 00000000..97f7fc9e --- /dev/null +++ b/gl/byteswap.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Inline functions for <byteswap.h>. | ||
| 2 | |||
| 3 | Copyright 2024-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | #define _GL_BYTESWAP_INLINE _GL_EXTERN_INLINE | ||
| 21 | #include <byteswap.h> | ||
diff --git a/gl/byteswap.in.h b/gl/byteswap.in.h index 8e49efad..6b4fbabf 100644 --- a/gl/byteswap.in.h +++ b/gl/byteswap.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* byteswap.h - Byte swapping | 1 | /* byteswap.h - Byte swapping |
| 2 | Copyright (C) 2005, 2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005, 2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | Written by Oskar Liljeblad <oskar@osk.mine.nu>, 2005. | 3 | Written by Oskar Liljeblad <oskar@osk.mine.nu>, 2005. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -16,29 +16,103 @@ | |||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
| 17 | 17 | ||
| 18 | #ifndef _GL_BYTESWAP_H | 18 | #ifndef _GL_BYTESWAP_H |
| 19 | #define _GL_BYTESWAP_H | 19 | #define _GL_BYTESWAP_H 1 |
| 20 | |||
| 21 | /* This file uses _GL_INLINE. */ | ||
| 22 | #if !_GL_CONFIG_H_INCLUDED | ||
| 23 | #error "Please include config.h first." | ||
| 24 | #endif | ||
| 25 | |||
| 26 | /* Define this now, rather than after including stdint.h, in case | ||
| 27 | stdint.h recursively includes us. This is for Gnulib endian.h. */ | ||
| 28 | #ifndef _GL_BYTESWAP_INLINE | ||
| 29 | # define _GL_BYTESWAP_INLINE _GL_INLINE | ||
| 30 | #endif | ||
| 31 | |||
| 32 | #include <stdint.h> | ||
| 33 | |||
| 34 | _GL_INLINE_HEADER_BEGIN | ||
| 35 | |||
| 36 | #ifdef __cplusplus | ||
| 37 | extern "C" { | ||
| 38 | #endif | ||
| 39 | |||
| 40 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) | ||
| 41 | # define _GL_BYTESWAP_HAS_BUILTIN_BSWAP16 true | ||
| 42 | #elif defined __has_builtin | ||
| 43 | # if __has_builtin (__builtin_bswap16) | ||
| 44 | # define _GL_BYTESWAP_HAS_BUILTIN_BSWAP16 true | ||
| 45 | # endif | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) | ||
| 49 | # define _GL_BYTESWAP_HAS_BUILTIN_BSWAP32 true | ||
| 50 | # define _GL_BYTESWAP_HAS_BUILTIN_BSWAP64 true | ||
| 51 | #elif defined __has_builtin | ||
| 52 | # if __has_builtin (__builtin_bswap32) | ||
| 53 | # define _GL_BYTESWAP_HAS_BUILTIN_BSWAP32 true | ||
| 54 | # endif | ||
| 55 | # if __has_builtin (__builtin_bswap64) | ||
| 56 | # define _GL_BYTESWAP_HAS_BUILTIN_BSWAP64 true | ||
| 57 | # endif | ||
| 58 | #endif | ||
| 20 | 59 | ||
| 21 | /* Given an unsigned 16-bit argument X, return the value corresponding to | 60 | /* Given an unsigned 16-bit argument X, return the value corresponding to |
| 22 | X with reversed byte order. */ | 61 | X with reversed byte order. */ |
| 23 | #define bswap_16(x) ((((x) & 0x00FF) << 8) | \ | 62 | _GL_BYTESWAP_INLINE uint_least16_t |
| 24 | (((x) & 0xFF00) >> 8)) | 63 | bswap_16 (uint_least16_t x) |
| 64 | { | ||
| 65 | #ifdef _GL_BYTESWAP_HAS_BUILTIN_BSWAP16 | ||
| 66 | return __builtin_bswap16 (x); | ||
| 67 | #else | ||
| 68 | uint_fast16_t mask = 0xff; | ||
| 69 | return ( (x & mask << 8 * 1) >> 8 * 1 | ||
| 70 | | (x & mask << 8 * 0) << 8 * 1); | ||
| 71 | #endif | ||
| 72 | } | ||
| 25 | 73 | ||
| 26 | /* Given an unsigned 32-bit argument X, return the value corresponding to | 74 | /* Given an unsigned 32-bit argument X, return the value corresponding to |
| 27 | X with reversed byte order. */ | 75 | X with reversed byte order. */ |
| 28 | #define bswap_32(x) ((((x) & 0x000000FF) << 24) | \ | 76 | _GL_BYTESWAP_INLINE uint_least32_t |
| 29 | (((x) & 0x0000FF00) << 8) | \ | 77 | bswap_32 (uint_least32_t x) |
| 30 | (((x) & 0x00FF0000) >> 8) | \ | 78 | { |
| 31 | (((x) & 0xFF000000) >> 24)) | 79 | #ifdef _GL_BYTESWAP_HAS_BUILTIN_BSWAP32 |
| 80 | return __builtin_bswap32 (x); | ||
| 81 | #else | ||
| 82 | uint_fast32_t mask = 0xff; | ||
| 83 | return ( (x & mask << 8 * 3) >> 8 * 3 | ||
| 84 | | (x & mask << 8 * 2) >> 8 * 1 | ||
| 85 | | (x & mask << 8 * 1) << 8 * 1 | ||
| 86 | | (x & mask << 8 * 0) << 8 * 3); | ||
| 87 | #endif | ||
| 88 | } | ||
| 32 | 89 | ||
| 90 | #ifdef UINT_LEAST64_MAX | ||
| 33 | /* Given an unsigned 64-bit argument X, return the value corresponding to | 91 | /* Given an unsigned 64-bit argument X, return the value corresponding to |
| 34 | X with reversed byte order. */ | 92 | X with reversed byte order. */ |
| 35 | #define bswap_64(x) ((((x) & 0x00000000000000FFULL) << 56) | \ | 93 | _GL_BYTESWAP_INLINE uint_least64_t |
| 36 | (((x) & 0x000000000000FF00ULL) << 40) | \ | 94 | bswap_64 (uint_least64_t x) |
| 37 | (((x) & 0x0000000000FF0000ULL) << 24) | \ | 95 | { |
| 38 | (((x) & 0x00000000FF000000ULL) << 8) | \ | 96 | # ifdef _GL_BYTESWAP_HAS_BUILTIN_BSWAP64 |
| 39 | (((x) & 0x000000FF00000000ULL) >> 8) | \ | 97 | return __builtin_bswap64 (x); |
| 40 | (((x) & 0x0000FF0000000000ULL) >> 24) | \ | 98 | # else |
| 41 | (((x) & 0x00FF000000000000ULL) >> 40) | \ | 99 | uint_fast64_t mask = 0xff; |
| 42 | (((x) & 0xFF00000000000000ULL) >> 56)) | 100 | return ( (x & mask << 8 * 7) >> 8 * 7 |
| 101 | | (x & mask << 8 * 6) >> 8 * 5 | ||
| 102 | | (x & mask << 8 * 5) >> 8 * 3 | ||
| 103 | | (x & mask << 8 * 4) >> 8 * 1 | ||
| 104 | | (x & mask << 8 * 3) << 8 * 1 | ||
| 105 | | (x & mask << 8 * 2) << 8 * 3 | ||
| 106 | | (x & mask << 8 * 1) << 8 * 5 | ||
| 107 | | (x & mask << 8 * 0) << 8 * 7); | ||
| 108 | # endif | ||
| 109 | } | ||
| 110 | #endif | ||
| 111 | |||
| 112 | #ifdef __cplusplus | ||
| 113 | } | ||
| 114 | #endif | ||
| 115 | |||
| 116 | _GL_INLINE_HEADER_END | ||
| 43 | 117 | ||
| 44 | #endif /* _GL_BYTESWAP_H */ | 118 | #endif /* _GL_BYTESWAP_H */ |
diff --git a/gl/c++defs.h b/gl/c++defs.h index eb66967b..df98a5ae 100644 --- a/gl/c++defs.h +++ b/gl/c++defs.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* C++ compatible function declaration macros. | 1 | /* C++ compatible function declaration macros. |
| 2 | Copyright (C) 2010-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2010-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify it | 4 | This program is free software: you can redistribute it and/or modify it |
| 5 | under the terms of the GNU Lesser General Public License as published | 5 | under the terms of the GNU Lesser General Public License as published |
| @@ -93,11 +93,27 @@ | |||
| 93 | # define _GL_EXTERN_C extern | 93 | # define _GL_EXTERN_C extern |
| 94 | #endif | 94 | #endif |
| 95 | 95 | ||
| 96 | /* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes); | 96 | /* _GL_EXTERN_C_FUNC declaration; |
| 97 | performs the declaration of a function with C linkage. */ | ||
| 98 | #if defined __cplusplus | ||
| 99 | # define _GL_EXTERN_C_FUNC extern "C" | ||
| 100 | #else | ||
| 101 | /* In C mode, omit the 'extern' keyword, because attributes in bracket syntax | ||
| 102 | are not allowed between 'extern' and the return type (see gnulib-common.m4). | ||
| 103 | */ | ||
| 104 | # define _GL_EXTERN_C_FUNC | ||
| 105 | #endif | ||
| 106 | |||
| 107 | /* _GL_FUNCDECL_RPL (func, rettype, parameters, [attributes]); | ||
| 97 | declares a replacement function, named rpl_func, with the given prototype, | 108 | declares a replacement function, named rpl_func, with the given prototype, |
| 98 | consisting of return type, parameters, and attributes. | 109 | consisting of return type, parameters, and attributes. |
| 99 | Example: | 110 | Although attributes are optional, the comma before them is required |
| 100 | _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) | 111 | for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW, |
| 112 | if needed, must be placed after the _GL_FUNCDECL_RPL invocation, | ||
| 113 | at the end of the declaration. | ||
| 114 | Examples: | ||
| 115 | _GL_FUNCDECL_RPL (free, void, (void *ptr), ) _GL_ATTRIBUTE_NOTHROW; | ||
| 116 | _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...), | ||
| 101 | _GL_ARG_NONNULL ((1))); | 117 | _GL_ARG_NONNULL ((1))); |
| 102 | 118 | ||
| 103 | Note: Attributes, such as _GL_ATTRIBUTE_DEPRECATED, are supported in front | 119 | Note: Attributes, such as _GL_ATTRIBUTE_DEPRECATED, are supported in front |
| @@ -106,20 +122,24 @@ | |||
| 106 | [[...]] extern "C" <declaration>; | 122 | [[...]] extern "C" <declaration>; |
| 107 | is invalid syntax in C++.) | 123 | is invalid syntax in C++.) |
| 108 | */ | 124 | */ |
| 109 | #define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \ | 125 | #define _GL_FUNCDECL_RPL(func,rettype,parameters,...) \ |
| 110 | _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes) | 126 | _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters, __VA_ARGS__) |
| 111 | #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \ | 127 | #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \ |
| 112 | _GL_EXTERN_C rettype rpl_func parameters_and_attributes | 128 | _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters |
| 113 | 129 | ||
| 114 | /* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes); | 130 | /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]); |
| 115 | declares the system function, named func, with the given prototype, | 131 | declares the system function, named func, with the given prototype, |
| 116 | consisting of return type, parameters, and attributes. | 132 | consisting of return type, parameters, and attributes. |
| 117 | Example: | 133 | Although attributes are optional, the comma before them is required |
| 118 | _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...) | 134 | for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW, |
| 119 | _GL_ARG_NONNULL ((1))); | 135 | if needed, must be placed after the _GL_FUNCDECL_RPL invocation, |
| 136 | at the end of the declaration. | ||
| 137 | Examples: | ||
| 138 | _GL_FUNCDECL_SYS (getumask, mode_t, (void), ) _GL_ATTRIBUTE_NOTHROW; | ||
| 139 | _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD); | ||
| 120 | */ | 140 | */ |
| 121 | #define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \ | 141 | #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \ |
| 122 | _GL_EXTERN_C rettype func parameters_and_attributes | 142 | _GL_EXTERN_C_FUNC __VA_ARGS__ rettype func parameters |
| 123 | 143 | ||
| 124 | /* _GL_CXXALIAS_RPL (func, rettype, parameters); | 144 | /* _GL_CXXALIAS_RPL (func, rettype, parameters); |
| 125 | declares a C++ alias called GNULIB_NAMESPACE::func | 145 | declares a C++ alias called GNULIB_NAMESPACE::func |
| @@ -297,7 +317,7 @@ | |||
| 297 | _GL_WARN_ON_USE (func, \ | 317 | _GL_WARN_ON_USE (func, \ |
| 298 | "The symbol ::" #func " refers to the system function. " \ | 318 | "The symbol ::" #func " refers to the system function. " \ |
| 299 | "Use " #namespace "::" #func " instead.") | 319 | "Use " #namespace "::" #func " instead.") |
| 300 | # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING | 320 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING |
| 301 | # define _GL_CXXALIASWARN_2(func,namespace) \ | 321 | # define _GL_CXXALIASWARN_2(func,namespace) \ |
| 302 | extern __typeof__ (func) func | 322 | extern __typeof__ (func) func |
| 303 | # else | 323 | # else |
diff --git a/gl/c-ctype.c b/gl/c-ctype.c new file mode 100644 index 00000000..ecf2c083 --- /dev/null +++ b/gl/c-ctype.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Character handling in C locale. | ||
| 2 | |||
| 3 | Copyright (C) 2003-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | #define C_CTYPE_INLINE _GL_EXTERN_INLINE | ||
| 21 | #include "c-ctype.h" | ||
diff --git a/gl/c-ctype.h b/gl/c-ctype.h new file mode 100644 index 00000000..39063142 --- /dev/null +++ b/gl/c-ctype.h | |||
| @@ -0,0 +1,366 @@ | |||
| 1 | /* Character handling in C locale. | ||
| 2 | |||
| 3 | These functions work like the corresponding functions in <ctype.h>, | ||
| 4 | except that they have the C (POSIX) locale hardwired, whereas the | ||
| 5 | <ctype.h> functions' behaviour depends on the current locale set via | ||
| 6 | setlocale. | ||
| 7 | |||
| 8 | Copyright (C) 2000-2003, 2006, 2008-2025 Free Software Foundation, Inc. | ||
| 9 | |||
| 10 | This file is free software: you can redistribute it and/or modify | ||
| 11 | it under the terms of the GNU Lesser General Public License as | ||
| 12 | published by the Free Software Foundation; either version 2.1 of the | ||
| 13 | License, or (at your option) any later version. | ||
| 14 | |||
| 15 | This file is distributed in the hope that it will be useful, | ||
| 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | GNU Lesser General Public License for more details. | ||
| 19 | |||
| 20 | You should have received a copy of the GNU Lesser General Public License | ||
| 21 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 22 | |||
| 23 | #ifndef C_CTYPE_H | ||
| 24 | #define C_CTYPE_H | ||
| 25 | |||
| 26 | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ | ||
| 27 | #if !_GL_CONFIG_H_INCLUDED | ||
| 28 | #error "Please include config.h first." | ||
| 29 | #endif | ||
| 30 | |||
| 31 | _GL_INLINE_HEADER_BEGIN | ||
| 32 | #ifndef C_CTYPE_INLINE | ||
| 33 | # define C_CTYPE_INLINE _GL_INLINE | ||
| 34 | #endif | ||
| 35 | |||
| 36 | #ifdef __cplusplus | ||
| 37 | extern "C" { | ||
| 38 | #endif | ||
| 39 | |||
| 40 | |||
| 41 | /* The functions defined in this file assume the "C" locale and a character | ||
| 42 | set without diacritics (ASCII-US or EBCDIC-US or something like that). | ||
| 43 | Even if the "C" locale on a particular system is an extension of the ASCII | ||
| 44 | character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it | ||
| 45 | is ISO-8859-1), the functions in this file recognize only the ASCII | ||
| 46 | characters. */ | ||
| 47 | |||
| 48 | |||
| 49 | #if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ | ||
| 50 | && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ | ||
| 51 | && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ | ||
| 52 | && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ | ||
| 53 | && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ | ||
| 54 | && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ | ||
| 55 | && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ | ||
| 56 | && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ | ||
| 57 | && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ | ||
| 58 | && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ | ||
| 59 | && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ | ||
| 60 | && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ | ||
| 61 | && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ | ||
| 62 | && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ | ||
| 63 | && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ | ||
| 64 | && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ | ||
| 65 | && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ | ||
| 66 | && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ | ||
| 67 | && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ | ||
| 68 | && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ | ||
| 69 | && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ | ||
| 70 | && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ | ||
| 71 | && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) | ||
| 72 | /* The character set is ASCII or one of its variants or extensions, not EBCDIC. | ||
| 73 | Testing the value of '\n' and '\r' is not relevant. */ | ||
| 74 | # define C_CTYPE_ASCII 1 | ||
| 75 | #elif ! (' ' == '\x40' && '0' == '\xf0' \ | ||
| 76 | && 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \ | ||
| 77 | && 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2') | ||
| 78 | # error "Only ASCII and EBCDIC are supported" | ||
| 79 | #endif | ||
| 80 | |||
| 81 | #if 'A' < 0 | ||
| 82 | # error "EBCDIC and char is signed -- not supported" | ||
| 83 | #endif | ||
| 84 | |||
| 85 | /* Cases for control characters. */ | ||
| 86 | |||
| 87 | #define _C_CTYPE_CNTRL \ | ||
| 88 | case '\a': case '\b': case '\f': case '\n': \ | ||
| 89 | case '\r': case '\t': case '\v': \ | ||
| 90 | _C_CTYPE_OTHER_CNTRL | ||
| 91 | |||
| 92 | /* ASCII control characters other than those with \-letter escapes. */ | ||
| 93 | |||
| 94 | #if C_CTYPE_ASCII | ||
| 95 | # define _C_CTYPE_OTHER_CNTRL \ | ||
| 96 | case '\x00': case '\x01': case '\x02': case '\x03': \ | ||
| 97 | case '\x04': case '\x05': case '\x06': case '\x0e': \ | ||
| 98 | case '\x0f': case '\x10': case '\x11': case '\x12': \ | ||
| 99 | case '\x13': case '\x14': case '\x15': case '\x16': \ | ||
| 100 | case '\x17': case '\x18': case '\x19': case '\x1a': \ | ||
| 101 | case '\x1b': case '\x1c': case '\x1d': case '\x1e': \ | ||
| 102 | case '\x1f': case '\x7f' | ||
| 103 | #else | ||
| 104 | /* Use EBCDIC code page 1047's assignments for ASCII control chars; | ||
| 105 | assume all EBCDIC code pages agree about these assignments. */ | ||
| 106 | # define _C_CTYPE_OTHER_CNTRL \ | ||
| 107 | case '\x00': case '\x01': case '\x02': case '\x03': \ | ||
| 108 | case '\x07': case '\x0e': case '\x0f': case '\x10': \ | ||
| 109 | case '\x11': case '\x12': case '\x13': case '\x18': \ | ||
| 110 | case '\x19': case '\x1c': case '\x1d': case '\x1e': \ | ||
| 111 | case '\x1f': case '\x26': case '\x27': case '\x2d': \ | ||
| 112 | case '\x2e': case '\x32': case '\x37': case '\x3c': \ | ||
| 113 | case '\x3d': case '\x3f' | ||
| 114 | #endif | ||
| 115 | |||
| 116 | /* Cases for lowercase hex letters, and lowercase letters, all offset by N. */ | ||
| 117 | |||
| 118 | #define _C_CTYPE_LOWER_A_THRU_F_N(N) \ | ||
| 119 | case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \ | ||
| 120 | case 'e' + (N): case 'f' + (N) | ||
| 121 | #define _C_CTYPE_LOWER_N(N) \ | ||
| 122 | _C_CTYPE_LOWER_A_THRU_F_N(N): \ | ||
| 123 | case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \ | ||
| 124 | case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \ | ||
| 125 | case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \ | ||
| 126 | case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \ | ||
| 127 | case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N) | ||
| 128 | |||
| 129 | /* Cases for hex letters, digits, lower, punct, and upper. */ | ||
| 130 | |||
| 131 | #define _C_CTYPE_A_THRU_F \ | ||
| 132 | _C_CTYPE_LOWER_A_THRU_F_N (0): \ | ||
| 133 | _C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a') | ||
| 134 | #define _C_CTYPE_DIGIT \ | ||
| 135 | case '0': case '1': case '2': case '3': \ | ||
| 136 | case '4': case '5': case '6': case '7': \ | ||
| 137 | case '8': case '9' | ||
| 138 | #define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0) | ||
| 139 | #define _C_CTYPE_PUNCT \ | ||
| 140 | case '!': case '"': case '#': case '$': \ | ||
| 141 | case '%': case '&': case '\'': case '(': \ | ||
| 142 | case ')': case '*': case '+': case ',': \ | ||
| 143 | case '-': case '.': case '/': case ':': \ | ||
| 144 | case ';': case '<': case '=': case '>': \ | ||
| 145 | case '?': case '@': case '[': case '\\': \ | ||
| 146 | case ']': case '^': case '_': case '`': \ | ||
| 147 | case '{': case '|': case '}': case '~' | ||
| 148 | #define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a') | ||
| 149 | |||
| 150 | |||
| 151 | /* Function definitions. */ | ||
| 152 | |||
| 153 | /* Unlike the functions in <ctype.h>, which require an argument in the range | ||
| 154 | of the 'unsigned char' type, the functions here operate on values that are | ||
| 155 | in the 'unsigned char' range or in the 'char' range. In other words, | ||
| 156 | when you have a 'char' value, you need to cast it before using it as | ||
| 157 | argument to a <ctype.h> function: | ||
| 158 | |||
| 159 | const char *s = ...; | ||
| 160 | if (isalpha ((unsigned char) *s)) ... | ||
| 161 | |||
| 162 | but you don't need to cast it for the functions defined in this file: | ||
| 163 | |||
| 164 | const char *s = ...; | ||
| 165 | if (c_isalpha (*s)) ... | ||
| 166 | */ | ||
| 167 | |||
| 168 | C_CTYPE_INLINE bool | ||
| 169 | c_isalnum (int c) | ||
| 170 | { | ||
| 171 | switch (c) | ||
| 172 | { | ||
| 173 | _C_CTYPE_DIGIT: | ||
| 174 | _C_CTYPE_LOWER: | ||
| 175 | _C_CTYPE_UPPER: | ||
| 176 | return true; | ||
| 177 | default: | ||
| 178 | return false; | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | C_CTYPE_INLINE bool | ||
| 183 | c_isalpha (int c) | ||
| 184 | { | ||
| 185 | switch (c) | ||
| 186 | { | ||
| 187 | _C_CTYPE_LOWER: | ||
| 188 | _C_CTYPE_UPPER: | ||
| 189 | return true; | ||
| 190 | default: | ||
| 191 | return false; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | |||
| 195 | /* The function isascii is not locale dependent. | ||
| 196 | Its use in EBCDIC is questionable. */ | ||
| 197 | C_CTYPE_INLINE bool | ||
| 198 | c_isascii (int c) | ||
| 199 | { | ||
| 200 | switch (c) | ||
| 201 | { | ||
| 202 | case ' ': | ||
| 203 | _C_CTYPE_CNTRL: | ||
| 204 | _C_CTYPE_DIGIT: | ||
| 205 | _C_CTYPE_LOWER: | ||
| 206 | _C_CTYPE_PUNCT: | ||
| 207 | _C_CTYPE_UPPER: | ||
| 208 | return true; | ||
| 209 | default: | ||
| 210 | return false; | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | C_CTYPE_INLINE bool | ||
| 215 | c_isblank (int c) | ||
| 216 | { | ||
| 217 | return c == ' ' || c == '\t'; | ||
| 218 | } | ||
| 219 | |||
| 220 | C_CTYPE_INLINE bool | ||
| 221 | c_iscntrl (int c) | ||
| 222 | { | ||
| 223 | switch (c) | ||
| 224 | { | ||
| 225 | _C_CTYPE_CNTRL: | ||
| 226 | return true; | ||
| 227 | default: | ||
| 228 | return false; | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | C_CTYPE_INLINE bool | ||
| 233 | c_isdigit (int c) | ||
| 234 | { | ||
| 235 | switch (c) | ||
| 236 | { | ||
| 237 | _C_CTYPE_DIGIT: | ||
| 238 | return true; | ||
| 239 | default: | ||
| 240 | return false; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | C_CTYPE_INLINE bool | ||
| 245 | c_isgraph (int c) | ||
| 246 | { | ||
| 247 | switch (c) | ||
| 248 | { | ||
| 249 | _C_CTYPE_DIGIT: | ||
| 250 | _C_CTYPE_LOWER: | ||
| 251 | _C_CTYPE_PUNCT: | ||
| 252 | _C_CTYPE_UPPER: | ||
| 253 | return true; | ||
| 254 | default: | ||
| 255 | return false; | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | C_CTYPE_INLINE bool | ||
| 260 | c_islower (int c) | ||
| 261 | { | ||
| 262 | switch (c) | ||
| 263 | { | ||
| 264 | _C_CTYPE_LOWER: | ||
| 265 | return true; | ||
| 266 | default: | ||
| 267 | return false; | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | C_CTYPE_INLINE bool | ||
| 272 | c_isprint (int c) | ||
| 273 | { | ||
| 274 | switch (c) | ||
| 275 | { | ||
| 276 | case ' ': | ||
| 277 | _C_CTYPE_DIGIT: | ||
| 278 | _C_CTYPE_LOWER: | ||
| 279 | _C_CTYPE_PUNCT: | ||
| 280 | _C_CTYPE_UPPER: | ||
| 281 | return true; | ||
| 282 | default: | ||
| 283 | return false; | ||
| 284 | } | ||
| 285 | } | ||
| 286 | |||
| 287 | C_CTYPE_INLINE bool | ||
| 288 | c_ispunct (int c) | ||
| 289 | { | ||
| 290 | switch (c) | ||
| 291 | { | ||
| 292 | _C_CTYPE_PUNCT: | ||
| 293 | return true; | ||
| 294 | default: | ||
| 295 | return false; | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | C_CTYPE_INLINE bool | ||
| 300 | c_isspace (int c) | ||
| 301 | { | ||
| 302 | switch (c) | ||
| 303 | { | ||
| 304 | case ' ': case '\t': case '\n': case '\v': case '\f': case '\r': | ||
| 305 | return true; | ||
| 306 | default: | ||
| 307 | return false; | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | C_CTYPE_INLINE bool | ||
| 312 | c_isupper (int c) | ||
| 313 | { | ||
| 314 | switch (c) | ||
| 315 | { | ||
| 316 | _C_CTYPE_UPPER: | ||
| 317 | return true; | ||
| 318 | default: | ||
| 319 | return false; | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | C_CTYPE_INLINE bool | ||
| 324 | c_isxdigit (int c) | ||
| 325 | { | ||
| 326 | switch (c) | ||
| 327 | { | ||
| 328 | _C_CTYPE_DIGIT: | ||
| 329 | _C_CTYPE_A_THRU_F: | ||
| 330 | return true; | ||
| 331 | default: | ||
| 332 | return false; | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | C_CTYPE_INLINE int | ||
| 337 | c_tolower (int c) | ||
| 338 | { | ||
| 339 | switch (c) | ||
| 340 | { | ||
| 341 | _C_CTYPE_UPPER: | ||
| 342 | return c - 'A' + 'a'; | ||
| 343 | default: | ||
| 344 | return c; | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | C_CTYPE_INLINE int | ||
| 349 | c_toupper (int c) | ||
| 350 | { | ||
| 351 | switch (c) | ||
| 352 | { | ||
| 353 | _C_CTYPE_LOWER: | ||
| 354 | return c - 'a' + 'A'; | ||
| 355 | default: | ||
| 356 | return c; | ||
| 357 | } | ||
| 358 | } | ||
| 359 | |||
| 360 | #ifdef __cplusplus | ||
| 361 | } | ||
| 362 | #endif | ||
| 363 | |||
| 364 | _GL_INLINE_HEADER_END | ||
| 365 | |||
| 366 | #endif /* C_CTYPE_H */ | ||
diff --git a/gl/c32is-impl.h b/gl/c32is-impl.h new file mode 100644 index 00000000..8366035d --- /dev/null +++ b/gl/c32is-impl.h | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | /* Test whether a 32-bit wide character belongs to a specific character class. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, 2020. */ | ||
| 18 | |||
| 19 | #include <wchar.h> | ||
| 20 | #include <wctype.h> | ||
| 21 | |||
| 22 | #ifdef __CYGWIN__ | ||
| 23 | # include <cygwin/version.h> | ||
| 24 | #endif | ||
| 25 | |||
| 26 | #if GNULIB_defined_mbstate_t | ||
| 27 | # include "localcharset.h" | ||
| 28 | # include "streq.h" | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #if GL_CHAR32_T_IS_UNICODE | ||
| 32 | # include "lc-charset-unicode.h" | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #include "unictype.h" | ||
| 36 | |||
| 37 | #if _GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t | ||
| 38 | _GL_EXTERN_INLINE | ||
| 39 | #endif | ||
| 40 | int | ||
| 41 | FUNC (wint_t wc) | ||
| 42 | { | ||
| 43 | /* The char32_t encoding of a multibyte character is defined by the way | ||
| 44 | mbrtoc32() is defined. */ | ||
| 45 | |||
| 46 | #if GNULIB_defined_mbstate_t /* AIX, IRIX */ | ||
| 47 | /* mbrtoc32() is defined on top of mbtowc() for the non-UTF-8 locales | ||
| 48 | and directly for the UTF-8 locales. */ | ||
| 49 | if (wc != WEOF) | ||
| 50 | { | ||
| 51 | const char *encoding = locale_charset (); | ||
| 52 | if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) | ||
| 53 | return UCS_FUNC (wc); | ||
| 54 | else | ||
| 55 | return WCHAR_FUNC (wc); | ||
| 56 | } | ||
| 57 | else | ||
| 58 | return 0; | ||
| 59 | |||
| 60 | #elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, Android */ | ||
| 61 | /* mbrtoc32() is essentially defined by the system libc. */ | ||
| 62 | |||
| 63 | # if _GL_WCHAR_T_IS_UCS4 | ||
| 64 | /* The char32_t encoding of a multibyte character is known to be the same as | ||
| 65 | the wchar_t encoding. */ | ||
| 66 | return WCHAR_FUNC (wc); | ||
| 67 | # else | ||
| 68 | /* The char32_t encoding of a multibyte character is known to be UCS-4, | ||
| 69 | different from the wchar_t encoding. */ | ||
| 70 | if (wc != WEOF) | ||
| 71 | return UCS_FUNC (wc); | ||
| 72 | else | ||
| 73 | return 0; | ||
| 74 | # endif | ||
| 75 | |||
| 76 | #elif _GL_SMALL_WCHAR_T /* Cygwin, mingw, MSVC */ | ||
| 77 | /* The wchar_t encoding is UTF-16. | ||
| 78 | The char32_t encoding is UCS-4. */ | ||
| 79 | |||
| 80 | # if defined __CYGWIN__ && CYGWIN_VERSION_DLL_MAJOR >= 1007 | ||
| 81 | /* As an extension to POSIX, the iswalnum() function of Cygwin >= 1.7 | ||
| 82 | supports also wc arguments outside the Unicode BMP, that is, outside | ||
| 83 | the 'wchar_t' range. See | ||
| 84 | <https://lists.gnu.org/archive/html/bug-gnulib/2011-02/msg00019.html> | ||
| 85 | = <https://cygwin.com/ml/cygwin/2011-02/msg00044.html>. */ | ||
| 86 | return WCHAR_FUNC (wc); | ||
| 87 | # else | ||
| 88 | if (wc == WEOF || wc == (wchar_t) wc) | ||
| 89 | /* wc is in the range for the isw* functions. */ | ||
| 90 | return WCHAR_FUNC (wc); | ||
| 91 | else | ||
| 92 | return UCS_FUNC (wc); | ||
| 93 | # endif | ||
| 94 | |||
| 95 | #else /* macOS, FreeBSD, NetBSD, OpenBSD, HP-UX, Solaris, Minix, Android */ | ||
| 96 | /* char32_t and wchar_t are equivalent. */ | ||
| 97 | static_assert (sizeof (char32_t) == sizeof (wchar_t)); | ||
| 98 | |||
| 99 | # if GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION | ||
| 100 | return UCS_FUNC (wc); | ||
| 101 | # else | ||
| 102 | return WCHAR_FUNC (wc); | ||
| 103 | # endif | ||
| 104 | #endif | ||
| 105 | } | ||
diff --git a/gl/c32isalnum.c b/gl/c32isalnum.c new file mode 100644 index 00000000..7d0ebcf5 --- /dev/null +++ b/gl/c32isalnum.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being alphanumeric. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISALNUM | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32isalnum | ||
| 24 | #define WCHAR_FUNC iswalnum | ||
| 25 | #define UCS_FUNC uc_is_alnum | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32isalpha.c b/gl/c32isalpha.c new file mode 100644 index 00000000..308fd76a --- /dev/null +++ b/gl/c32isalpha.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being alphabetic. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISALPHA | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32isalpha | ||
| 24 | #define WCHAR_FUNC iswalpha | ||
| 25 | #define UCS_FUNC uc_is_alpha | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32isblank.c b/gl/c32isblank.c new file mode 100644 index 00000000..1a03c2db --- /dev/null +++ b/gl/c32isblank.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being blank. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISBLANK | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32isblank | ||
| 24 | #define WCHAR_FUNC iswblank | ||
| 25 | #define UCS_FUNC uc_is_blank | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32iscntrl.c b/gl/c32iscntrl.c new file mode 100644 index 00000000..1d004087 --- /dev/null +++ b/gl/c32iscntrl.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being a control character. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISCNTRL | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32iscntrl | ||
| 24 | #define WCHAR_FUNC iswcntrl | ||
| 25 | #define UCS_FUNC uc_is_cntrl | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32isdigit.c b/gl/c32isdigit.c new file mode 100644 index 00000000..7d3bda81 --- /dev/null +++ b/gl/c32isdigit.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being a digit. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISDIGIT | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32isdigit | ||
| 24 | #define WCHAR_FUNC iswdigit | ||
| 25 | #define UCS_FUNC uc_is_digit | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32isgraph.c b/gl/c32isgraph.c new file mode 100644 index 00000000..8b68ae39 --- /dev/null +++ b/gl/c32isgraph.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being graphic. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISGRAPH | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32isgraph | ||
| 24 | #define WCHAR_FUNC iswgraph | ||
| 25 | #define UCS_FUNC uc_is_graph | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32islower.c b/gl/c32islower.c new file mode 100644 index 00000000..1ce08cf4 --- /dev/null +++ b/gl/c32islower.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being lowercase. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISLOWER | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32islower | ||
| 24 | #define WCHAR_FUNC iswlower | ||
| 25 | #define UCS_FUNC uc_is_lower | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32isprint.c b/gl/c32isprint.c new file mode 100644 index 00000000..d47ce1f8 --- /dev/null +++ b/gl/c32isprint.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being printable. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISPRINT | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32isprint | ||
| 24 | #define WCHAR_FUNC iswprint | ||
| 25 | #define UCS_FUNC uc_is_print | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32ispunct.c b/gl/c32ispunct.c new file mode 100644 index 00000000..41ac3d70 --- /dev/null +++ b/gl/c32ispunct.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being a punctuation or symbol character. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISPUNCT | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32ispunct | ||
| 24 | #define WCHAR_FUNC iswpunct | ||
| 25 | #define UCS_FUNC uc_is_punct | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32isspace.c b/gl/c32isspace.c new file mode 100644 index 00000000..2393142b --- /dev/null +++ b/gl/c32isspace.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being white-space. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISSPACE | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32isspace | ||
| 24 | #define WCHAR_FUNC iswspace | ||
| 25 | #define UCS_FUNC uc_is_space | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32isupper.c b/gl/c32isupper.c new file mode 100644 index 00000000..bfe4a148 --- /dev/null +++ b/gl/c32isupper.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being uppercase. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISUPPER | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32isupper | ||
| 24 | #define WCHAR_FUNC iswupper | ||
| 25 | #define UCS_FUNC uc_is_upper | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32isxdigit.c b/gl/c32isxdigit.c new file mode 100644 index 00000000..b38d7f1f --- /dev/null +++ b/gl/c32isxdigit.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Test 32-bit wide character for being a hexadecimal digit. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32ISXDIGIT | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32isxdigit | ||
| 24 | #define WCHAR_FUNC iswxdigit | ||
| 25 | #define UCS_FUNC uc_is_xdigit | ||
| 26 | #include "c32is-impl.h" | ||
diff --git a/gl/c32to-impl.h b/gl/c32to-impl.h new file mode 100644 index 00000000..a63a25b6 --- /dev/null +++ b/gl/c32to-impl.h | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | /* Case mapping of a 32-bit wide character. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, 2023. */ | ||
| 18 | |||
| 19 | #include <wchar.h> | ||
| 20 | #include <wctype.h> | ||
| 21 | |||
| 22 | #if GNULIB_defined_mbstate_t | ||
| 23 | # include "localcharset.h" | ||
| 24 | # include "streq.h" | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #if GL_CHAR32_T_IS_UNICODE | ||
| 28 | # include "lc-charset-unicode.h" | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #include "unicase.h" | ||
| 32 | |||
| 33 | #if _GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t | ||
| 34 | _GL_EXTERN_INLINE | ||
| 35 | #endif | ||
| 36 | wint_t | ||
| 37 | FUNC (wint_t wc) | ||
| 38 | { | ||
| 39 | /* The char32_t encoding of a multibyte character is defined by the way | ||
| 40 | mbrtoc32() is defined. */ | ||
| 41 | |||
| 42 | #if GNULIB_defined_mbstate_t /* AIX, IRIX */ | ||
| 43 | /* mbrtoc32() is defined on top of mbtowc() for the non-UTF-8 locales | ||
| 44 | and directly for the UTF-8 locales. */ | ||
| 45 | if (wc != WEOF) | ||
| 46 | { | ||
| 47 | const char *encoding = locale_charset (); | ||
| 48 | if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) | ||
| 49 | return UCS_FUNC (wc); | ||
| 50 | else | ||
| 51 | return WCHAR_FUNC (wc); | ||
| 52 | } | ||
| 53 | else | ||
| 54 | return wc; | ||
| 55 | |||
| 56 | #elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, Android */ | ||
| 57 | /* mbrtoc32() is essentially defined by the system libc. */ | ||
| 58 | |||
| 59 | # if _GL_WCHAR_T_IS_UCS4 | ||
| 60 | /* The char32_t encoding of a multibyte character is known to be the same as | ||
| 61 | the wchar_t encoding. */ | ||
| 62 | return WCHAR_FUNC (wc); | ||
| 63 | # else | ||
| 64 | /* The char32_t encoding of a multibyte character is known to be UCS-4, | ||
| 65 | different from the wchar_t encoding. */ | ||
| 66 | if (wc != WEOF) | ||
| 67 | return UCS_FUNC (wc); | ||
| 68 | else | ||
| 69 | return wc; | ||
| 70 | # endif | ||
| 71 | |||
| 72 | #elif _GL_SMALL_WCHAR_T /* Cygwin, mingw, MSVC */ | ||
| 73 | /* The wchar_t encoding is UTF-16. | ||
| 74 | The char32_t encoding is UCS-4. */ | ||
| 75 | |||
| 76 | # if defined _WIN32 && !defined __CYGWIN__ | ||
| 77 | /* On native Windows, in the UTF-8 locale, towlower and towupper are | ||
| 78 | lacking (at least) the mappings for ISO-8859-1 characters, such as | ||
| 79 | 0x00C9 <-> 0x00E9. Since it is expensive to test whether the locale | ||
| 80 | encoding is UTF-8, ignore the system's WCHAR_FUNC altogether. */ | ||
| 81 | if (wc != WEOF) | ||
| 82 | return UCS_FUNC (wc); | ||
| 83 | else | ||
| 84 | return wc; | ||
| 85 | # else | ||
| 86 | if (wc == WEOF || wc == (wchar_t) wc) | ||
| 87 | /* wc is in the range for the tow* functions. */ | ||
| 88 | return WCHAR_FUNC (wc); | ||
| 89 | else | ||
| 90 | return UCS_FUNC (wc); | ||
| 91 | # endif | ||
| 92 | |||
| 93 | #else /* macOS, FreeBSD, NetBSD, OpenBSD, HP-UX, Solaris, Minix, Android */ | ||
| 94 | /* char32_t and wchar_t are equivalent. */ | ||
| 95 | static_assert (sizeof (char32_t) == sizeof (wchar_t)); | ||
| 96 | |||
| 97 | # if GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION | ||
| 98 | return UCS_FUNC (wc); | ||
| 99 | # else | ||
| 100 | return WCHAR_FUNC (wc); | ||
| 101 | # endif | ||
| 102 | #endif | ||
| 103 | } | ||
diff --git a/gl/c32tolower.c b/gl/c32tolower.c new file mode 100644 index 00000000..a0b0523f --- /dev/null +++ b/gl/c32tolower.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Map a 32-bit wide character to lowercase. | ||
| 2 | Copyright (C) 2023-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define IN_C32TOLOWER | ||
| 20 | /* Specification. */ | ||
| 21 | #include <uchar.h> | ||
| 22 | |||
| 23 | #define FUNC c32tolower | ||
| 24 | #define WCHAR_FUNC towlower | ||
| 25 | #define UCS_FUNC uc_tolower | ||
| 26 | #include "c32to-impl.h" | ||
diff --git a/gl/c32width.c b/gl/c32width.c new file mode 100644 index 00000000..442a432c --- /dev/null +++ b/gl/c32width.c | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /* Determine the number of screen columns needed for a 32-bit wide character. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, 2023. */ | ||
| 18 | |||
| 19 | #include <config.h> | ||
| 20 | |||
| 21 | #define IN_C32WIDTH | ||
| 22 | /* Specification. */ | ||
| 23 | #include <uchar.h> | ||
| 24 | |||
| 25 | #include <wchar.h> | ||
| 26 | |||
| 27 | #ifdef __CYGWIN__ | ||
| 28 | # include <cygwin/version.h> | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #if GNULIB_defined_mbstate_t | ||
| 32 | # include "streq.h" | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #include "localcharset.h" | ||
| 36 | |||
| 37 | #if GL_CHAR32_T_IS_UNICODE | ||
| 38 | # include "lc-charset-unicode.h" | ||
| 39 | #endif | ||
| 40 | |||
| 41 | #include "uniwidth.h" | ||
| 42 | |||
| 43 | #if _GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t | ||
| 44 | _GL_EXTERN_INLINE | ||
| 45 | #endif | ||
| 46 | int | ||
| 47 | c32width (char32_t wc) | ||
| 48 | { | ||
| 49 | /* The char32_t encoding of a multibyte character is defined by the way | ||
| 50 | mbrtoc32() is defined. */ | ||
| 51 | |||
| 52 | #if GNULIB_defined_mbstate_t /* AIX, IRIX */ | ||
| 53 | /* mbrtoc32() is defined on top of mbtowc() for the non-UTF-8 locales | ||
| 54 | and directly for the UTF-8 locales. */ | ||
| 55 | const char *encoding = locale_charset (); | ||
| 56 | if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) | ||
| 57 | return uc_width (wc, encoding); | ||
| 58 | else | ||
| 59 | return wcwidth (wc); | ||
| 60 | |||
| 61 | #elif HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB /* glibc, Android */ | ||
| 62 | /* mbrtoc32() is essentially defined by the system libc. */ | ||
| 63 | |||
| 64 | # if _GL_WCHAR_T_IS_UCS4 | ||
| 65 | /* The char32_t encoding of a multibyte character is known to be the same as | ||
| 66 | the wchar_t encoding. */ | ||
| 67 | return wcwidth (wc); | ||
| 68 | # else | ||
| 69 | /* The char32_t encoding of a multibyte character is known to be UCS-4, | ||
| 70 | different from the wchar_t encoding. */ | ||
| 71 | return uc_width (wc, locale_charset ()); | ||
| 72 | # endif | ||
| 73 | |||
| 74 | #elif _GL_SMALL_WCHAR_T /* Cygwin, mingw, MSVC */ | ||
| 75 | /* The wchar_t encoding is UTF-16. | ||
| 76 | The char32_t encoding is UCS-4. */ | ||
| 77 | |||
| 78 | # if defined __CYGWIN__ && CYGWIN_VERSION_DLL_MAJOR >= 1007 && 0 | ||
| 79 | /* As an extension to POSIX, the wcwidth() function of Cygwin >= 1.7 | ||
| 80 | supports also wc arguments outside the Unicode BMP, that is, outside | ||
| 81 | the 'wchar_t' range. See | ||
| 82 | <https://www.cygwin.com/cgit/newlib-cygwin/commit/?id=098a75dc51caa98f369d98a9809d773bc45329aa>. | ||
| 83 | But the resulting values for these characters are not of good quality. */ | ||
| 84 | return wcwidth (wc); | ||
| 85 | # else | ||
| 86 | if (wc == (wchar_t) wc) | ||
| 87 | /* wc is in the range for the wcwidth function. */ | ||
| 88 | return wcwidth (wc); | ||
| 89 | else | ||
| 90 | return uc_width (wc, locale_charset ()); | ||
| 91 | # endif | ||
| 92 | |||
| 93 | #else /* macOS, FreeBSD, NetBSD, OpenBSD, HP-UX, Solaris, Minix, Android */ | ||
| 94 | /* char32_t and wchar_t are equivalent. */ | ||
| 95 | static_assert (sizeof (char32_t) == sizeof (wchar_t)); | ||
| 96 | |||
| 97 | # if GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION | ||
| 98 | return uc_width (wc, locale_charset ()); | ||
| 99 | # endif | ||
| 100 | return wcwidth (wc); | ||
| 101 | #endif | ||
| 102 | } | ||
diff --git a/gl/calloc.c b/gl/calloc.c index 81dfd3ef..5258c5de 100644 --- a/gl/calloc.c +++ b/gl/calloc.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* calloc() function that is glibc compatible. | 1 | /* calloc() function that is glibc compatible. |
| 2 | This wrapper function is required at least on Tru64 UNIX 5.1 and mingw. | 2 | This wrapper function is required at least on Tru64 UNIX 5.1 and mingw. |
| 3 | Copyright (C) 2004-2007, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2004-2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -17,17 +17,15 @@ | |||
| 17 | 17 | ||
| 18 | /* written by Jim Meyering and Bruno Haible */ | 18 | /* written by Jim Meyering and Bruno Haible */ |
| 19 | 19 | ||
| 20 | /* Ensure that we call the system's calloc() below. */ | ||
| 21 | #define _GL_USE_STDLIB_ALLOC 1 | ||
| 20 | #include <config.h> | 22 | #include <config.h> |
| 21 | 23 | ||
| 22 | /* Specification. */ | 24 | /* Specification. */ |
| 23 | #include <stdlib.h> | 25 | #include <stdlib.h> |
| 24 | 26 | ||
| 25 | #include <errno.h> | 27 | #include <errno.h> |
| 26 | 28 | #include <stdckdint.h> | |
| 27 | #include "xalloc-oversized.h" | ||
| 28 | |||
| 29 | /* Call the system's calloc below. */ | ||
| 30 | #undef calloc | ||
| 31 | 29 | ||
| 32 | /* Allocate and zero-fill an NxS-byte block of memory from the heap, | 30 | /* Allocate and zero-fill an NxS-byte block of memory from the heap, |
| 33 | even if N or S is zero. */ | 31 | even if N or S is zero. */ |
| @@ -35,14 +33,19 @@ | |||
| 35 | void * | 33 | void * |
| 36 | rpl_calloc (size_t n, size_t s) | 34 | rpl_calloc (size_t n, size_t s) |
| 37 | { | 35 | { |
| 36 | #if !HAVE_MALLOC_0_NONNULL | ||
| 38 | if (n == 0 || s == 0) | 37 | if (n == 0 || s == 0) |
| 39 | n = s = 1; | 38 | n = s = 1; |
| 39 | #endif | ||
| 40 | 40 | ||
| 41 | if (xalloc_oversized (n, s)) | 41 | #if !HAVE_MALLOC_PTRDIFF |
| 42 | ptrdiff_t signed_n; | ||
| 43 | if (ckd_mul (&signed_n, n, s)) | ||
| 42 | { | 44 | { |
| 43 | errno = ENOMEM; | 45 | errno = ENOMEM; |
| 44 | return NULL; | 46 | return NULL; |
| 45 | } | 47 | } |
| 48 | #endif | ||
| 46 | 49 | ||
| 47 | void *result = calloc (n, s); | 50 | void *result = calloc (n, s); |
| 48 | 51 | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 1992-2024 Free Software Foundation, Inc. | 1 | /* Copyright (C) 1992-2025 Free Software Foundation, Inc. |
| 2 | Copyright The GNU Toolchain Authors. | 2 | Copyright The GNU Toolchain Authors. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| @@ -83,7 +83,7 @@ | |||
| 83 | # define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct | 83 | # define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct |
| 84 | # define __NTHNL(fct) __attribute__ ((__nothrow__)) fct | 84 | # define __NTHNL(fct) __attribute__ ((__nothrow__)) fct |
| 85 | # else | 85 | # else |
| 86 | # if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4) | 86 | # if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major__ >= 4) |
| 87 | # if __cplusplus >= 201103L | 87 | # if __cplusplus >= 201103L |
| 88 | # define __THROW noexcept (true) | 88 | # define __THROW noexcept (true) |
| 89 | # else | 89 | # else |
| @@ -277,10 +277,10 @@ | |||
| 277 | */ | 277 | */ |
| 278 | #endif | 278 | #endif |
| 279 | 279 | ||
| 280 | /* GCC and clang have various useful declarations that can be made with | 280 | /* GCC, clang, and compatible compilers have various useful declarations |
| 281 | the '__attribute__' syntax. All of the ways we use this do fine if | 281 | that can be made with the '__attribute__' syntax. All of the ways we use |
| 282 | they are omitted for compilers that don't understand it. */ | 282 | this do fine if they are omitted for compilers that don't understand it. */ |
| 283 | #if !(defined __GNUC__ || defined __clang__) | 283 | #if !(defined __GNUC__ || defined __clang__ || defined __TINYC__) |
| 284 | # define __attribute__(xyz) /* Ignore */ | 284 | # define __attribute__(xyz) /* Ignore */ |
| 285 | #endif | 285 | #endif |
| 286 | 286 | ||
| @@ -482,7 +482,7 @@ | |||
| 482 | run in pedantic mode if the uses are carefully marked using the | 482 | run in pedantic mode if the uses are carefully marked using the |
| 483 | `__extension__' keyword. But this is not generally available before | 483 | `__extension__' keyword. But this is not generally available before |
| 484 | version 2.8. */ | 484 | version 2.8. */ |
| 485 | #if !(__GNUC_PREREQ (2,8) || defined __clang__) | 485 | #if ! (__GNUC_PREREQ (2,8) || defined __clang__ || 0x5150 <= __SUNPRO_C) |
| 486 | # define __extension__ /* Ignore */ | 486 | # define __extension__ /* Ignore */ |
| 487 | #endif | 487 | #endif |
| 488 | 488 | ||
| @@ -497,7 +497,7 @@ | |||
| 497 | # endif | 497 | # endif |
| 498 | #endif | 498 | #endif |
| 499 | 499 | ||
| 500 | /* ISO C99 also allows to declare arrays as non-overlapping. The syntax is | 500 | /* ISO C99 also allows declaring arrays as non-overlapping. The syntax is |
| 501 | array_name[restrict] | 501 | array_name[restrict] |
| 502 | GCC 3.1 and clang support this. | 502 | GCC 3.1 and clang support this. |
| 503 | This syntax is not usable in C++ mode. */ | 503 | This syntax is not usable in C++ mode. */ |
diff --git a/gl/cloexec.c b/gl/cloexec.c index cdb0d740..8ab5591f 100644 --- a/gl/cloexec.c +++ b/gl/cloexec.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* cloexec.c - set or clear the close-on-exec descriptor flag | 1 | /* cloexec.c - set or clear the close-on-exec descriptor flag |
| 2 | 2 | ||
| 3 | Copyright (C) 1991, 2004-2006, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1991, 2004-2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/cloexec.h b/gl/cloexec.h index a7944d6d..0eb9fa09 100644 --- a/gl/cloexec.h +++ b/gl/cloexec.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* cloexec.c - set or clear the close-on-exec descriptor flag | 1 | /* cloexec.c - set or clear the close-on-exec descriptor flag |
| 2 | 2 | ||
| 3 | Copyright (C) 2004, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2004, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* close replacement. | 1 | /* close replacement. |
| 2 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/dirname-lgpl.c b/gl/dirname-lgpl.c index 8333c0eb..9e0ec565 100644 --- a/gl/dirname-lgpl.c +++ b/gl/dirname-lgpl.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* dirname.c -- return all but the last element in a file name | 1 | /* dirname.c -- return all but the last element in a file name |
| 2 | 2 | ||
| 3 | Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2024 Free Software | 3 | Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/dirname.c b/gl/dirname.c index 393ec1b4..e747fcaf 100644 --- a/gl/dirname.c +++ b/gl/dirname.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* dirname.c -- return all but the last element in a file name | 1 | /* dirname.c -- return all but the last element in a file name |
| 2 | 2 | ||
| 3 | Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2024 Free Software | 3 | Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This program is free software: you can redistribute it and/or modify | 6 | This program is free software: you can redistribute it and/or modify |
diff --git a/gl/dirname.h b/gl/dirname.h index 33935ba9..d4d03f66 100644 --- a/gl/dirname.h +++ b/gl/dirname.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Take file names apart into directory and base names. | 1 | /* Take file names apart into directory and base names. |
| 2 | 2 | ||
| 3 | Copyright (C) 1998, 2001, 2003-2006, 2009-2024 Free Software Foundation, | 3 | Copyright (C) 1998, 2001, 2003-2006, 2009-2025 Free Software Foundation, |
| 4 | Inc. | 4 | Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Duplicate an open file descriptor to a specified file descriptor. | 1 | /* Duplicate an open file descriptor to a specified file descriptor. |
| 2 | 2 | ||
| 3 | Copyright (C) 1999, 2004-2007, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1999, 2004-2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/dynarray.h b/gl/dynarray.h index 8940e81b..74471ea2 100644 --- a/gl/dynarray.h +++ b/gl/dynarray.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Type-safe arrays which grow dynamically. | 1 | /* Type-safe arrays which grow dynamically. |
| 2 | Copyright 2021-2024 Free Software Foundation, Inc. | 2 | Copyright 2021-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/errno.in.h b/gl/errno.in.h index aa658e62..ba5dd371 100644 --- a/gl/errno.in.h +++ b/gl/errno.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A POSIX-like <errno.h>. | 1 | /* A POSIX-like <errno.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -133,7 +133,7 @@ | |||
| 133 | 133 | ||
| 134 | /* These are intentionally the same values as the WSA* error numbers, defined | 134 | /* These are intentionally the same values as the WSA* error numbers, defined |
| 135 | in <winsock2.h>. */ | 135 | in <winsock2.h>. */ |
| 136 | # define ESOCKTNOSUPPORT 10044 /* not required by POSIX */ | 136 | # define ESOCKTNOSUPPORT 10044 |
| 137 | # define EPFNOSUPPORT 10046 /* not required by POSIX */ | 137 | # define EPFNOSUPPORT 10046 /* not required by POSIX */ |
| 138 | # define ESHUTDOWN 10058 /* not required by POSIX */ | 138 | # define ESHUTDOWN 10058 /* not required by POSIX */ |
| 139 | # define ETOOMANYREFS 10059 /* not required by POSIX */ | 139 | # define ETOOMANYREFS 10059 /* not required by POSIX */ |
| @@ -270,10 +270,17 @@ | |||
| 270 | # define GNULIB_defined_ENOTRECOVERABLE 1 | 270 | # define GNULIB_defined_ENOTRECOVERABLE 1 |
| 271 | # endif | 271 | # endif |
| 272 | 272 | ||
| 273 | /* On LynxOS, the macro EILSEQ is not defined. */ | ||
| 273 | # ifndef EILSEQ | 274 | # ifndef EILSEQ |
| 274 | # define EILSEQ 2015 | 275 | # define EILSEQ 2015 |
| 275 | # define GNULIB_defined_EILSEQ 1 | 276 | # define GNULIB_defined_EILSEQ 1 |
| 276 | # endif | 277 | # endif |
| 277 | 278 | ||
| 279 | /* On Haiku, the macro ESOCKTNOSUPPORT is not defined. */ | ||
| 280 | # ifndef ESOCKTNOSUPPORT | ||
| 281 | # define ESOCKTNOSUPPORT 2016 | ||
| 282 | # define GNULIB_defined_ESOCKTNOSUPPORT 1 | ||
| 283 | # endif | ||
| 284 | |||
| 278 | #endif /* _@GUARD_PREFIX@_ERRNO_H */ | 285 | #endif /* _@GUARD_PREFIX@_ERRNO_H */ |
| 279 | #endif /* _@GUARD_PREFIX@_ERRNO_H */ | 286 | #endif /* _@GUARD_PREFIX@_ERRNO_H */ |
| @@ -1,25 +1,32 @@ | |||
| 1 | /* Error handler for noninteractive utilities | 1 | /* Error handler for noninteractive utilities |
| 2 | Copyright (C) 1990-1998, 2000-2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1990-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | The GNU C Library is free software; you can redistribute it and/or |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | modify it under the terms of the GNU Lesser General Public |
| 7 | published by the Free Software Foundation; either version 2.1 of the | 7 | License as published by the Free Software Foundation; either |
| 8 | License, or (at your option) any later version. | 8 | version 2.1 of the License, or (at your option) any later version. |
| 9 | 9 | ||
| 10 | This file is distributed in the hope that it will be useful, | 10 | The GNU C Library is distributed in the hope that it will be useful, |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | GNU Lesser General Public License for more details. | 13 | Lesser General Public License for more details. |
| 14 | 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public License | 15 | You should have received a copy of the GNU Lesser General Public |
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | 16 | License along with the GNU C Library; if not, see |
| 17 | <https://www.gnu.org/licenses/>. */ | ||
| 17 | 18 | ||
| 18 | /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ | 19 | /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ |
| 19 | 20 | ||
| 20 | #if !_LIBC | 21 | #if !_LIBC |
| 21 | # include <config.h> | 22 | # include <config.h> |
| 22 | # define _GL_NO_INLINE_ERROR | 23 | # define _GL_NO_INLINE_ERROR |
| 24 | # define __error_internal(status, err, fmt, args, flags) \ | ||
| 25 | verror (status, err, fmt, args) | ||
| 26 | # define __error_at_line_internal(status, err, file, line, fmt, args, flags) \ | ||
| 27 | verror_at_line (status, err, file, line, fmt, args) | ||
| 28 | # define error_tail(status, err, fmt, args, flags) \ | ||
| 29 | error_tail (status, err, fmt, args) | ||
| 23 | #endif | 30 | #endif |
| 24 | 31 | ||
| 25 | #include <error.h> | 32 | #include <error.h> |
| @@ -31,7 +38,7 @@ | |||
| 31 | 38 | ||
| 32 | #if !_LIBC && ENABLE_NLS | 39 | #if !_LIBC && ENABLE_NLS |
| 33 | # include "gettext.h" | 40 | # include "gettext.h" |
| 34 | # define _(msgid) gettext (msgid) | 41 | # define _(msgid) dgettext ("gnulib", msgid) |
| 35 | #endif | 42 | #endif |
| 36 | 43 | ||
| 37 | #ifdef _LIBC | 44 | #ifdef _LIBC |
| @@ -85,7 +92,7 @@ extern void __error_at_line (int status, int errnum, const char *file_name, | |||
| 85 | # undef putc | 92 | # undef putc |
| 86 | # define putc(c, fp) _IO_putc (c, fp) | 93 | # define putc(c, fp) _IO_putc (c, fp) |
| 87 | 94 | ||
| 88 | # include <bits/libc-lock.h> | 95 | # include <libc-lock.h> |
| 89 | 96 | ||
| 90 | #else /* not _LIBC */ | 97 | #else /* not _LIBC */ |
| 91 | 98 | ||
| @@ -123,6 +130,13 @@ int strerror_r (int errnum, char *buf, size_t buflen); | |||
| 123 | # if GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r | 130 | # if GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r |
| 124 | # define __strerror_r strerror_r | 131 | # define __strerror_r strerror_r |
| 125 | # endif /* GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r */ | 132 | # endif /* GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r */ |
| 133 | |||
| 134 | # if GNULIB_defined_verror | ||
| 135 | # undef verror | ||
| 136 | # endif | ||
| 137 | # if GNULIB_defined_verror_at_line | ||
| 138 | # undef verror_at_line | ||
| 139 | # endif | ||
| 126 | #endif /* not _LIBC */ | 140 | #endif /* not _LIBC */ |
| 127 | 141 | ||
| 128 | #if !_LIBC | 142 | #if !_LIBC |
| @@ -151,8 +165,8 @@ flush_stdout (void) | |||
| 151 | #if !_LIBC | 165 | #if !_LIBC |
| 152 | int stdout_fd; | 166 | int stdout_fd; |
| 153 | 167 | ||
| 154 | # if GNULIB_FREOPEN_SAFER | 168 | # if GNULIB_FREOPEN_SAFER || GNULIB_XSTDOPEN |
| 155 | /* Use of gnulib's freopen-safer module normally ensures that | 169 | /* Gnulib's freopen-safer and/or xstdopen modules normally ensure that |
| 156 | fileno (stdout) == 1 | 170 | fileno (stdout) == 1 |
| 157 | whenever stdout is open. */ | 171 | whenever stdout is open. */ |
| 158 | stdout_fd = STDOUT_FILENO; | 172 | stdout_fd = STDOUT_FILENO; |
| @@ -183,7 +197,7 @@ print_errno_message (int errnum) | |||
| 183 | if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) | 197 | if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) |
| 184 | s = errbuf; | 198 | s = errbuf; |
| 185 | else | 199 | else |
| 186 | s = 0; | 200 | s = NULL; |
| 187 | # endif | 201 | # endif |
| 188 | #else | 202 | #else |
| 189 | s = strerror (errnum); | 203 | s = strerror (errnum); |
| @@ -202,75 +216,18 @@ print_errno_message (int errnum) | |||
| 202 | } | 216 | } |
| 203 | 217 | ||
| 204 | static void _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3)) | 218 | static void _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3)) |
| 205 | error_tail (int status, int errnum, const char *message, va_list args) | 219 | error_tail (int status, int errnum, const char *message, va_list args, |
| 220 | unsigned int mode_flags) | ||
| 206 | { | 221 | { |
| 207 | #if _LIBC | 222 | #if _LIBC |
| 208 | if (_IO_fwide (stderr, 0) > 0) | 223 | int ret = __vfxprintf (stderr, message, args, mode_flags); |
| 209 | { | 224 | if (ret < 0 && errno == ENOMEM && _IO_fwide (stderr, 0) > 0) |
| 210 | size_t len = strlen (message) + 1; | 225 | /* Leave a trace in case the heap allocation of the message string |
| 211 | wchar_t *wmessage = NULL; | 226 | failed. */ |
| 212 | mbstate_t st; | 227 | fputws_unlocked (L"out of memory\n", stderr); |
| 213 | size_t res; | 228 | #else |
| 214 | const char *tmp; | 229 | vfprintf (stderr, message, args); |
| 215 | bool use_malloc = false; | ||
| 216 | |||
| 217 | while (1) | ||
| 218 | { | ||
| 219 | if (__libc_use_alloca (len * sizeof (wchar_t))) | ||
| 220 | wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); | ||
| 221 | else | ||
| 222 | { | ||
| 223 | if (!use_malloc) | ||
| 224 | wmessage = NULL; | ||
| 225 | |||
| 226 | wchar_t *p = (wchar_t *) realloc (wmessage, | ||
| 227 | len * sizeof (wchar_t)); | ||
| 228 | if (p == NULL) | ||
| 229 | { | ||
| 230 | free (wmessage); | ||
| 231 | fputws_unlocked (L"out of memory\n", stderr); | ||
| 232 | return; | ||
| 233 | } | ||
| 234 | wmessage = p; | ||
| 235 | use_malloc = true; | ||
| 236 | } | ||
| 237 | |||
| 238 | memset (&st, '\0', sizeof (st)); | ||
| 239 | tmp = message; | ||
| 240 | |||
| 241 | res = mbsrtowcs (wmessage, &tmp, len, &st); | ||
| 242 | if (res != len) | ||
| 243 | break; | ||
| 244 | |||
| 245 | if (__builtin_expect (len >= SIZE_MAX / sizeof (wchar_t) / 2, 0)) | ||
| 246 | { | ||
| 247 | /* This really should not happen if everything is fine. */ | ||
| 248 | res = (size_t) -1; | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | |||
| 252 | len *= 2; | ||
| 253 | } | ||
| 254 | |||
| 255 | if (res == (size_t) -1) | ||
| 256 | { | ||
| 257 | /* The string cannot be converted. */ | ||
| 258 | if (use_malloc) | ||
| 259 | { | ||
| 260 | free (wmessage); | ||
| 261 | use_malloc = false; | ||
| 262 | } | ||
| 263 | wmessage = (wchar_t *) L"???"; | ||
| 264 | } | ||
| 265 | |||
| 266 | __vfwprintf (stderr, wmessage, args); | ||
| 267 | |||
| 268 | if (use_malloc) | ||
| 269 | free (wmessage); | ||
| 270 | } | ||
| 271 | else | ||
| 272 | #endif | 230 | #endif |
| 273 | vfprintf (stderr, message, args); | ||
| 274 | 231 | ||
| 275 | ++error_message_count; | 232 | ++error_message_count; |
| 276 | if (errnum) | 233 | if (errnum) |
| @@ -291,16 +248,14 @@ error_tail (int status, int errnum, const char *message, va_list args) | |||
| 291 | If ERRNUM is nonzero, print its corresponding system error message. | 248 | If ERRNUM is nonzero, print its corresponding system error message. |
| 292 | Exit with status STATUS if it is nonzero. */ | 249 | Exit with status STATUS if it is nonzero. */ |
| 293 | void | 250 | void |
| 294 | error (int status, int errnum, const char *message, ...) | 251 | __error_internal (int status, int errnum, const char *message, |
| 252 | va_list args, unsigned int mode_flags) | ||
| 295 | { | 253 | { |
| 296 | va_list args; | 254 | #if defined _LIBC |
| 297 | |||
| 298 | #if defined _LIBC && defined __libc_ptf_call | ||
| 299 | /* We do not want this call to be cut short by a thread | 255 | /* We do not want this call to be cut short by a thread |
| 300 | cancellation. Therefore disable cancellation for now. */ | 256 | cancellation. Therefore disable cancellation for now. */ |
| 301 | int state = PTHREAD_CANCEL_ENABLE; | 257 | int state = PTHREAD_CANCEL_ENABLE; |
| 302 | __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), | 258 | __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state); |
| 303 | 0); | ||
| 304 | #endif | 259 | #endif |
| 305 | 260 | ||
| 306 | flush_stdout (); | 261 | flush_stdout (); |
| @@ -318,28 +273,32 @@ error (int status, int errnum, const char *message, ...) | |||
| 318 | #endif | 273 | #endif |
| 319 | } | 274 | } |
| 320 | 275 | ||
| 321 | va_start (args, message); | 276 | error_tail (status, errnum, message, args, mode_flags); |
| 322 | error_tail (status, errnum, message, args); | ||
| 323 | va_end (args); | ||
| 324 | 277 | ||
| 325 | #ifdef _LIBC | 278 | #ifdef _LIBC |
| 326 | _IO_funlockfile (stderr); | 279 | _IO_funlockfile (stderr); |
| 327 | # ifdef __libc_ptf_call | 280 | __pthread_setcancelstate (state, NULL); |
| 328 | __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); | ||
| 329 | # endif | ||
| 330 | #endif | 281 | #endif |
| 331 | } | 282 | } |
| 283 | |||
| 284 | void | ||
| 285 | error (int status, int errnum, const char *message, ...) | ||
| 286 | { | ||
| 287 | va_list ap; | ||
| 288 | va_start (ap, message); | ||
| 289 | __error_internal (status, errnum, message, ap, 0); | ||
| 290 | va_end (ap); | ||
| 291 | } | ||
| 332 | 292 | ||
| 333 | /* Sometimes we want to have at most one error per line. This | 293 | /* Sometimes we want to have at most one error per line. This |
| 334 | variable controls whether this mode is selected or not. */ | 294 | variable controls whether this mode is selected or not. */ |
| 335 | int error_one_per_line; | 295 | int error_one_per_line; |
| 336 | 296 | ||
| 337 | void | 297 | void |
| 338 | error_at_line (int status, int errnum, const char *file_name, | 298 | __error_at_line_internal (int status, int errnum, const char *file_name, |
| 339 | unsigned int line_number, const char *message, ...) | 299 | unsigned int line_number, const char *message, |
| 300 | va_list args, unsigned int mode_flags) | ||
| 340 | { | 301 | { |
| 341 | va_list args; | ||
| 342 | |||
| 343 | if (error_one_per_line) | 302 | if (error_one_per_line) |
| 344 | { | 303 | { |
| 345 | static const char *old_file_name; | 304 | static const char *old_file_name; |
| @@ -358,12 +317,11 @@ error_at_line (int status, int errnum, const char *file_name, | |||
| 358 | old_line_number = line_number; | 317 | old_line_number = line_number; |
| 359 | } | 318 | } |
| 360 | 319 | ||
| 361 | #if defined _LIBC && defined __libc_ptf_call | 320 | #if defined _LIBC |
| 362 | /* We do not want this call to be cut short by a thread | 321 | /* We do not want this call to be cut short by a thread |
| 363 | cancellation. Therefore disable cancellation for now. */ | 322 | cancellation. Therefore disable cancellation for now. */ |
| 364 | int state = PTHREAD_CANCEL_ENABLE; | 323 | int state = PTHREAD_CANCEL_ENABLE; |
| 365 | __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), | 324 | __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state); |
| 366 | 0); | ||
| 367 | #endif | 325 | #endif |
| 368 | 326 | ||
| 369 | flush_stdout (); | 327 | flush_stdout (); |
| @@ -389,18 +347,25 @@ error_at_line (int status, int errnum, const char *file_name, | |||
| 389 | file_name, line_number); | 347 | file_name, line_number); |
| 390 | #endif | 348 | #endif |
| 391 | 349 | ||
| 392 | va_start (args, message); | 350 | error_tail (status, errnum, message, args, mode_flags); |
| 393 | error_tail (status, errnum, message, args); | ||
| 394 | va_end (args); | ||
| 395 | 351 | ||
| 396 | #ifdef _LIBC | 352 | #ifdef _LIBC |
| 397 | _IO_funlockfile (stderr); | 353 | _IO_funlockfile (stderr); |
| 398 | # ifdef __libc_ptf_call | 354 | __pthread_setcancelstate (state, NULL); |
| 399 | __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); | ||
| 400 | # endif | ||
| 401 | #endif | 355 | #endif |
| 402 | } | 356 | } |
| 403 | 357 | ||
| 358 | void | ||
| 359 | error_at_line (int status, int errnum, const char *file_name, | ||
| 360 | unsigned int line_number, const char *message, ...) | ||
| 361 | { | ||
| 362 | va_list ap; | ||
| 363 | va_start (ap, message); | ||
| 364 | __error_at_line_internal (status, errnum, file_name, line_number, | ||
| 365 | message, ap, 0); | ||
| 366 | va_end (ap); | ||
| 367 | } | ||
| 368 | |||
| 404 | #ifdef _LIBC | 369 | #ifdef _LIBC |
| 405 | /* Make the weak alias. */ | 370 | /* Make the weak alias. */ |
| 406 | # undef error | 371 | # undef error |
diff --git a/gl/error.in.h b/gl/error.in.h index 51f8cafd..6c512ec8 100644 --- a/gl/error.in.h +++ b/gl/error.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Declarations for error-reporting functions. | 1 | /* Declarations for error-reporting functions. |
| 2 | Copyright (C) 1995-1997, 2003, 2006, 2008-2024 Free Software Foundation, | 2 | Copyright (C) 1995-1997, 2003, 2006, 2008-2025 Free Software Foundation, |
| 3 | Inc. | 3 | Inc. |
| 4 | This file is part of the GNU C Library. | 4 | This file is part of the GNU C Library. |
| 5 | 5 | ||
| @@ -23,20 +23,23 @@ | |||
| 23 | or error_at_line(...) invocations. */ | 23 | or error_at_line(...) invocations. */ |
| 24 | 24 | ||
| 25 | /* The include_next requires a split double-inclusion guard. */ | 25 | /* The include_next requires a split double-inclusion guard. */ |
| 26 | #if @HAVE_ERROR_H@ | 26 | #if @HAVE_ERROR_H@ && !defined __MINGW32__ |
| 27 | # @INCLUDE_NEXT@ @NEXT_ERROR_H@ | 27 | # @INCLUDE_NEXT@ @NEXT_ERROR_H@ |
| 28 | #endif | 28 | #endif |
| 29 | 29 | ||
| 30 | #ifndef _@GUARD_PREFIX@_ERROR_H | 30 | #ifndef _@GUARD_PREFIX@_ERROR_H |
| 31 | #define _@GUARD_PREFIX@_ERROR_H | 31 | #define _@GUARD_PREFIX@_ERROR_H |
| 32 | 32 | ||
| 33 | /* This file uses _GL_ATTRIBUTE_ALWAYS_INLINE, _GL_ATTRIBUTE_FORMAT, | 33 | /* This file uses _GL_ATTRIBUTE_ALWAYS_INLINE, _GL_ATTRIBUTE_COLD, |
| 34 | _GL_ATTRIBUTE_MAYBE_UNUSED. */ | 34 | _GL_ATTRIBUTE_FORMAT, _GL_ATTRIBUTE_MAYBE_UNUSED. */ |
| 35 | #if !_GL_CONFIG_H_INCLUDED | 35 | #if !_GL_CONFIG_H_INCLUDED |
| 36 | #error "Please include config.h first." | 36 | #error "Please include config.h first." |
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | /* Get 'unreachable'. */ | 39 | /* Get va_list. */ |
| 40 | #include <stdarg.h> | ||
| 41 | |||
| 42 | /* Get 'gl_unreachable'. */ | ||
| 40 | #include <stddef.h> | 43 | #include <stddef.h> |
| 41 | 44 | ||
| 42 | /* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM. */ | 45 | /* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, _GL_ATTRIBUTE_SPEC_PRINTF_SYSTEM. */ |
| @@ -54,11 +57,11 @@ | |||
| 54 | It evaluates its arguments only once. | 57 | It evaluates its arguments only once. |
| 55 | Test case: Compile copy-file.c with "gcc -Wimplicit-fallthrough". */ | 58 | Test case: Compile copy-file.c with "gcc -Wimplicit-fallthrough". */ |
| 56 | #if defined __GNUC__ || defined __clang__ | 59 | #if defined __GNUC__ || defined __clang__ |
| 57 | /* Use 'unreachable' to tell the compiler when the function call does not | 60 | /* Use 'gl_unreachable' to tell the compiler when the function call does not |
| 58 | return. */ | 61 | return. */ |
| 59 | # define __gl_error_call1(function, status, ...) \ | 62 | # define __gl_error_call1(function, status, ...) \ |
| 60 | ((function) (status, __VA_ARGS__), \ | 63 | ((function) (status, __VA_ARGS__), \ |
| 61 | (status) != 0 ? unreachable () : (void) 0) | 64 | (status) != 0 ? gl_unreachable () : (void) 0) |
| 62 | /* If STATUS is a not a constant, the function call may or may not return; | 65 | /* If STATUS is a not a constant, the function call may or may not return; |
| 63 | therefore -Wimplicit-fallthrough will produce a warning. Use a compound | 66 | therefore -Wimplicit-fallthrough will produce a warning. Use a compound |
| 64 | statement in order to evaluate STATUS only once. | 67 | statement in order to evaluate STATUS only once. |
| @@ -92,7 +95,8 @@ extern "C" { | |||
| 92 | # define error rpl_error | 95 | # define error rpl_error |
| 93 | # endif | 96 | # endif |
| 94 | _GL_FUNCDECL_RPL (error, void, | 97 | _GL_FUNCDECL_RPL (error, void, |
| 95 | (int __status, int __errnum, const char *__format, ...) | 98 | (int __status, int __errnum, const char *__format, ...), |
| 99 | _GL_ATTRIBUTE_COLD | ||
| 96 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4))); | 100 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4))); |
| 97 | _GL_CXXALIAS_RPL (error, void, | 101 | _GL_CXXALIAS_RPL (error, void, |
| 98 | (int __status, int __errnum, const char *__format, ...)); | 102 | (int __status, int __errnum, const char *__format, ...)); |
| @@ -104,7 +108,8 @@ _GL_CXXALIAS_RPL (error, void, | |||
| 104 | #else | 108 | #else |
| 105 | # if ! @HAVE_ERROR@ | 109 | # if ! @HAVE_ERROR@ |
| 106 | _GL_FUNCDECL_SYS (error, void, | 110 | _GL_FUNCDECL_SYS (error, void, |
| 107 | (int __status, int __errnum, const char *__format, ...) | 111 | (int __status, int __errnum, const char *__format, ...), |
| 112 | _GL_ATTRIBUTE_COLD | ||
| 108 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4))); | 113 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4))); |
| 109 | # endif | 114 | # endif |
| 110 | _GL_CXXALIAS_SYS (error, void, | 115 | _GL_CXXALIAS_SYS (error, void, |
| @@ -117,7 +122,7 @@ _GL_CXXALIAS_SYS (error, void, | |||
| 117 | # pragma GCC diagnostic ignored "-Wattributes" | 122 | # pragma GCC diagnostic ignored "-Wattributes" |
| 118 | _GL_ATTRIBUTE_MAYBE_UNUSED | 123 | _GL_ATTRIBUTE_MAYBE_UNUSED |
| 119 | static void | 124 | static void |
| 120 | _GL_ATTRIBUTE_ALWAYS_INLINE | 125 | _GL_ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_COLD |
| 121 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4)) | 126 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 3, 4)) |
| 122 | _gl_inline_error (int __status, int __errnum, const char *__format, ...) | 127 | _gl_inline_error (int __status, int __errnum, const char *__format, ...) |
| 123 | { | 128 | { |
| @@ -147,7 +152,8 @@ _GL_CXXALIASWARN (error); | |||
| 147 | # endif | 152 | # endif |
| 148 | _GL_FUNCDECL_RPL (error_at_line, void, | 153 | _GL_FUNCDECL_RPL (error_at_line, void, |
| 149 | (int __status, int __errnum, const char *__filename, | 154 | (int __status, int __errnum, const char *__filename, |
| 150 | unsigned int __lineno, const char *__format, ...) | 155 | unsigned int __lineno, const char *__format, ...), |
| 156 | _GL_ATTRIBUTE_COLD | ||
| 151 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6))); | 157 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6))); |
| 152 | _GL_CXXALIAS_RPL (error_at_line, void, | 158 | _GL_CXXALIAS_RPL (error_at_line, void, |
| 153 | (int __status, int __errnum, const char *__filename, | 159 | (int __status, int __errnum, const char *__filename, |
| @@ -161,7 +167,8 @@ _GL_CXXALIAS_RPL (error_at_line, void, | |||
| 161 | # if ! @HAVE_ERROR_AT_LINE@ | 167 | # if ! @HAVE_ERROR_AT_LINE@ |
| 162 | _GL_FUNCDECL_SYS (error_at_line, void, | 168 | _GL_FUNCDECL_SYS (error_at_line, void, |
| 163 | (int __status, int __errnum, const char *__filename, | 169 | (int __status, int __errnum, const char *__filename, |
| 164 | unsigned int __lineno, const char *__format, ...) | 170 | unsigned int __lineno, const char *__format, ...), |
| 171 | _GL_ATTRIBUTE_COLD | ||
| 165 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6))); | 172 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6))); |
| 166 | # endif | 173 | # endif |
| 167 | _GL_CXXALIAS_SYS (error_at_line, void, | 174 | _GL_CXXALIAS_SYS (error_at_line, void, |
| @@ -175,7 +182,7 @@ _GL_CXXALIAS_SYS (error_at_line, void, | |||
| 175 | # pragma GCC diagnostic ignored "-Wattributes" | 182 | # pragma GCC diagnostic ignored "-Wattributes" |
| 176 | _GL_ATTRIBUTE_MAYBE_UNUSED | 183 | _GL_ATTRIBUTE_MAYBE_UNUSED |
| 177 | static void | 184 | static void |
| 178 | _GL_ATTRIBUTE_ALWAYS_INLINE | 185 | _GL_ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_COLD |
| 179 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6)) | 186 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_ERROR, 5, 6)) |
| 180 | _gl_inline_error_at_line (int __status, int __errnum, const char *__filename, | 187 | _gl_inline_error_at_line (int __status, int __errnum, const char *__filename, |
| 181 | unsigned int __lineno, const char *__format, ...) | 188 | unsigned int __lineno, const char *__format, ...) |
| @@ -196,6 +203,44 @@ _gl_inline_error_at_line (int __status, int __errnum, const char *__filename, | |||
| 196 | #endif | 203 | #endif |
| 197 | _GL_CXXALIASWARN (error_at_line); | 204 | _GL_CXXALIASWARN (error_at_line); |
| 198 | 205 | ||
| 206 | /* Print a message with 'vfprintf (stderr, FORMAT, ARGS)'; | ||
| 207 | if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). | ||
| 208 | If STATUS is nonzero, terminate the program with 'exit (STATUS)'. | ||
| 209 | Use the globals error_print_progname and error_message_count similarly | ||
| 210 | to error(). */ | ||
| 211 | |||
| 212 | extern void verror (int __status, int __errnum, const char *__format, | ||
| 213 | va_list __args) | ||
| 214 | _GL_ATTRIBUTE_COLD | ||
| 215 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 0)); | ||
| 216 | #ifndef _GL_NO_INLINE_ERROR | ||
| 217 | # ifndef verror | ||
| 218 | # define verror(status, ...) \ | ||
| 219 | __gl_error_call (verror, status, __VA_ARGS__) | ||
| 220 | # define GNULIB_defined_verror 1 | ||
| 221 | # endif | ||
| 222 | #endif | ||
| 223 | |||
| 224 | /* Print a message with 'vfprintf (stderr, FORMAT, ARGS)'; | ||
| 225 | if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). | ||
| 226 | If STATUS is nonzero, terminate the program with 'exit (STATUS)'. | ||
| 227 | If FNAME is not NULL, prepend the message with "FNAME:LINENO:". | ||
| 228 | Use the globals error_print_progname, error_message_count, and | ||
| 229 | error_one_per_line similarly to error_at_line(). */ | ||
| 230 | |||
| 231 | extern void verror_at_line (int __status, int __errnum, const char *__fname, | ||
| 232 | unsigned int __lineno, const char *__format, | ||
| 233 | va_list __args) | ||
| 234 | _GL_ATTRIBUTE_COLD | ||
| 235 | _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 5, 0)); | ||
| 236 | #ifdef _GL_NO_INLINE_ERROR | ||
| 237 | # ifndef verror_at_line | ||
| 238 | # define verror_at_line(status, ...) \ | ||
| 239 | __gl_error_call (verror_at_line, status, __VA_ARGS__) | ||
| 240 | # define GNULIB_defined_verror_at_line 1 | ||
| 241 | # endif | ||
| 242 | #endif | ||
| 243 | |||
| 199 | /* If NULL, error will flush stdout, then print on stderr the program | 244 | /* If NULL, error will flush stdout, then print on stderr the program |
| 200 | name, a colon and a space. Otherwise, error will call this | 245 | name, a colon and a space. Otherwise, error will call this |
| 201 | function without parameters instead. */ | 246 | function without parameters instead. */ |
diff --git a/gl/exitfail.c b/gl/exitfail.c index 8a5962e8..5b37c10b 100644 --- a/gl/exitfail.c +++ b/gl/exitfail.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Failure exit status | 1 | /* Failure exit status |
| 2 | 2 | ||
| 3 | Copyright (C) 2002-2003, 2005-2007, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2002-2003, 2005-2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/exitfail.h b/gl/exitfail.h index fa264b5c..9d6b1528 100644 --- a/gl/exitfail.h +++ b/gl/exitfail.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Failure exit status | 1 | /* Failure exit status |
| 2 | 2 | ||
| 3 | Copyright (C) 2002, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2002, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Provide file descriptor control. | 1 | /* Provide file descriptor control. |
| 2 | 2 | ||
| 3 | Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -29,8 +29,7 @@ | |||
| 29 | #include <unistd.h> | 29 | #include <unistd.h> |
| 30 | 30 | ||
| 31 | #ifdef __KLIBC__ | 31 | #ifdef __KLIBC__ |
| 32 | # define INCL_DOS | 32 | # include <emx/io.h> |
| 33 | # include <os2.h> | ||
| 34 | #endif | 33 | #endif |
| 35 | 34 | ||
| 36 | #if defined _WIN32 && ! defined __CYGWIN__ | 35 | #if defined _WIN32 && ! defined __CYGWIN__ |
| @@ -562,7 +561,8 @@ klibc_fcntl (int fd, int action, /* arg */...) | |||
| 562 | if (result == -1 && (errno == EPERM || errno == ENOTSUP) | 561 | if (result == -1 && (errno == EPERM || errno == ENOTSUP) |
| 563 | && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode)) | 562 | && !fstat (fd, &sbuf) && S_ISDIR (sbuf.st_mode)) |
| 564 | { | 563 | { |
| 565 | ULONG ulMode; | 564 | PLIBCFH pFH; |
| 565 | unsigned fFlags; | ||
| 566 | 566 | ||
| 567 | switch (action) | 567 | switch (action) |
| 568 | { | 568 | { |
| @@ -574,34 +574,41 @@ klibc_fcntl (int fd, int action, /* arg */...) | |||
| 574 | result = dup2 (fd, arg); | 574 | result = dup2 (fd, arg); |
| 575 | break; | 575 | break; |
| 576 | 576 | ||
| 577 | /* Using underlying APIs is right ? */ | ||
| 578 | case F_GETFD: | 577 | case F_GETFD: |
| 579 | if (DosQueryFHState (fd, &ulMode)) | 578 | pFH = __libc_FH (fd); |
| 580 | break; | 579 | if (!pFH) |
| 580 | { | ||
| 581 | errno = EBADF; | ||
| 582 | break; | ||
| 583 | } | ||
| 581 | 584 | ||
| 582 | result = (ulMode & OPEN_FLAGS_NOINHERIT) ? FD_CLOEXEC : 0; | 585 | result = (pFH->fFlags & ((FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT ) |
| 586 | | O_NOINHERIT)) ? FD_CLOEXEC : 0; | ||
| 583 | break; | 587 | break; |
| 584 | 588 | ||
| 585 | case F_SETFD: | 589 | case F_SETFD: |
| 586 | if (arg & ~FD_CLOEXEC) | 590 | if (arg & ~FD_CLOEXEC) |
| 587 | break; | 591 | break; |
| 588 | 592 | ||
| 589 | if (DosQueryFHState (fd, &ulMode)) | 593 | pFH = __libc_FH (fd); |
| 590 | break; | 594 | if (!pFH) |
| 595 | { | ||
| 596 | errno = EBADF; | ||
| 597 | break; | ||
| 598 | } | ||
| 591 | 599 | ||
| 600 | fFlags = pFH->fFlags; | ||
| 592 | if (arg & FD_CLOEXEC) | 601 | if (arg & FD_CLOEXEC) |
| 593 | ulMode |= OPEN_FLAGS_NOINHERIT; | 602 | fFlags |= (FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT) | O_NOINHERIT; |
| 594 | else | 603 | else |
| 595 | ulMode &= ~OPEN_FLAGS_NOINHERIT; | 604 | fFlags &= ~((FD_CLOEXEC << __LIBC_FH_FDFLAGS_SHIFT) | O_NOINHERIT); |
| 596 | |||
| 597 | /* Filter supported flags. */ | ||
| 598 | ulMode &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | ||
| 599 | | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT); | ||
| 600 | 605 | ||
| 601 | if (DosSetFHState (fd, ulMode)) | 606 | result = __libc_FHSetFlags (pFH, fd, fFlags); |
| 602 | break; | 607 | if (result < 0) |
| 603 | 608 | { | |
| 604 | result = 0; | 609 | errno = -result; |
| 610 | result = -1; | ||
| 611 | } | ||
| 605 | break; | 612 | break; |
| 606 | 613 | ||
| 607 | case F_GETFL: | 614 | case F_GETFL: |
diff --git a/gl/fcntl.in.h b/gl/fcntl.in.h index eea3b954..c5068ed4 100644 --- a/gl/fcntl.in.h +++ b/gl/fcntl.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Like <fcntl.h>, but with non-working flags defined to 0. | 1 | /* Like <fcntl.h>, but with non-working flags defined to 0. |
| 2 | 2 | ||
| 3 | Copyright (C) 2006-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -22,8 +22,12 @@ | |||
| 22 | #endif | 22 | #endif |
| 23 | @PRAGMA_COLUMNS@ | 23 | @PRAGMA_COLUMNS@ |
| 24 | 24 | ||
| 25 | #if defined __need_system_fcntl_h | 25 | #if defined __need_system_fcntl_h || defined _@GUARD_PREFIX@_ALREADY_INCLUDING_FCNTL_H |
| 26 | /* Special invocation convention. */ | 26 | /* Special invocation convention: |
| 27 | - On Haiku we have a sequence of nested includes | ||
| 28 | <fcntl.h> -> <unistd.h> -> <fcntl.h> | ||
| 29 | In this situation, GNULIB_defined_O_NONBLOCK gets defined before the | ||
| 30 | system's definition of O_NONBLOCK is processed. */ | ||
| 27 | 31 | ||
| 28 | /* Needed before <sys/stat.h>. | 32 | /* Needed before <sys/stat.h>. |
| 29 | May also define off_t to a 64-bit type on native Windows. */ | 33 | May also define off_t to a 64-bit type on native Windows. */ |
| @@ -50,8 +54,11 @@ | |||
| 50 | 54 | ||
| 51 | #ifndef _@GUARD_PREFIX@_FCNTL_H | 55 | #ifndef _@GUARD_PREFIX@_FCNTL_H |
| 52 | 56 | ||
| 57 | #define _@GUARD_PREFIX@_ALREADY_INCLUDING_FCNTL_H | ||
| 58 | |||
| 53 | /* Needed before <sys/stat.h>. | 59 | /* Needed before <sys/stat.h>. |
| 54 | May also define off_t to a 64-bit type on native Windows. */ | 60 | May also define off_t to a 64-bit type on native Windows. |
| 61 | Also defines off64_t on macOS, NetBSD, OpenBSD, MSVC, Cygwin, Haiku. */ | ||
| 55 | #include <sys/types.h> | 62 | #include <sys/types.h> |
| 56 | /* On some systems other than glibc, <sys/stat.h> is a prerequisite of | 63 | /* On some systems other than glibc, <sys/stat.h> is a prerequisite of |
| 57 | <fcntl.h>. On glibc systems, we would like to avoid namespace pollution. | 64 | <fcntl.h>. On glibc systems, we would like to avoid namespace pollution. |
| @@ -71,6 +78,8 @@ | |||
| 71 | # include <io.h> | 78 | # include <io.h> |
| 72 | #endif | 79 | #endif |
| 73 | 80 | ||
| 81 | #undef _@GUARD_PREFIX@_ALREADY_INCLUDING_FCNTL_H | ||
| 82 | |||
| 74 | #ifndef _@GUARD_PREFIX@_FCNTL_H | 83 | #ifndef _@GUARD_PREFIX@_FCNTL_H |
| 75 | #define _@GUARD_PREFIX@_FCNTL_H | 84 | #define _@GUARD_PREFIX@_FCNTL_H |
| 76 | 85 | ||
| @@ -99,7 +108,7 @@ | |||
| 99 | # undef creat | 108 | # undef creat |
| 100 | # define creat rpl_creat | 109 | # define creat rpl_creat |
| 101 | # endif | 110 | # endif |
| 102 | _GL_FUNCDECL_RPL (creat, int, (const char *filename, mode_t mode) | 111 | _GL_FUNCDECL_RPL (creat, int, (const char *filename, mode_t mode), |
| 103 | _GL_ARG_NONNULL ((1))); | 112 | _GL_ARG_NONNULL ((1))); |
| 104 | _GL_CXXALIAS_RPL (creat, int, (const char *filename, mode_t mode)); | 113 | _GL_CXXALIAS_RPL (creat, int, (const char *filename, mode_t mode)); |
| 105 | # elif defined _WIN32 && !defined __CYGWIN__ | 114 | # elif defined _WIN32 && !defined __CYGWIN__ |
| @@ -140,14 +149,14 @@ _GL_CXXALIASWARN (creat); | |||
| 140 | # undef fcntl | 149 | # undef fcntl |
| 141 | # define fcntl rpl_fcntl | 150 | # define fcntl rpl_fcntl |
| 142 | # endif | 151 | # endif |
| 143 | _GL_FUNCDECL_RPL (fcntl, int, (int fd, int action, ...)); | 152 | _GL_FUNCDECL_RPL (fcntl, int, (int fd, int action, ...), ); |
| 144 | _GL_CXXALIAS_RPL (fcntl, int, (int fd, int action, ...)); | 153 | _GL_CXXALIAS_RPL (fcntl, int, (int fd, int action, ...)); |
| 145 | # if !GNULIB_defined_rpl_fcntl | 154 | # if !GNULIB_defined_rpl_fcntl |
| 146 | # define GNULIB_defined_rpl_fcntl 1 | 155 | # define GNULIB_defined_rpl_fcntl 1 |
| 147 | # endif | 156 | # endif |
| 148 | # else | 157 | # else |
| 149 | # if !@HAVE_FCNTL@ | 158 | # if !@HAVE_FCNTL@ |
| 150 | _GL_FUNCDECL_SYS (fcntl, int, (int fd, int action, ...)); | 159 | _GL_FUNCDECL_SYS (fcntl, int, (int fd, int action, ...), ); |
| 151 | # if !GNULIB_defined_fcntl | 160 | # if !GNULIB_defined_fcntl |
| 152 | # define GNULIB_defined_fcntl 1 | 161 | # define GNULIB_defined_fcntl 1 |
| 153 | # endif | 162 | # endif |
| @@ -169,7 +178,7 @@ _GL_WARN_ON_USE (fcntl, "fcntl is not always POSIX compliant - " | |||
| 169 | # undef open | 178 | # undef open |
| 170 | # define open rpl_open | 179 | # define open rpl_open |
| 171 | # endif | 180 | # endif |
| 172 | _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) | 181 | _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...), |
| 173 | _GL_ARG_NONNULL ((1))); | 182 | _GL_ARG_NONNULL ((1))); |
| 174 | _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); | 183 | _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); |
| 175 | # elif defined _WIN32 && !defined __CYGWIN__ | 184 | # elif defined _WIN32 && !defined __CYGWIN__ |
| @@ -200,7 +209,9 @@ _GL_WARN_ON_USE (open, "open is not always POSIX compliant - " | |||
| 200 | # undef open | 209 | # undef open |
| 201 | # define open _open | 210 | # define open _open |
| 202 | # endif | 211 | # endif |
| 203 | _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...)); | 212 | /* Need to cast, because in MSVC the parameter list of _open as a C++ function |
| 213 | is (const char *, int, int = 0). */ | ||
| 214 | _GL_CXXALIAS_MDA_CAST (open, int, (const char *filename, int flags, ...)); | ||
| 204 | # else | 215 | # else |
| 205 | _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); | 216 | _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); |
| 206 | # endif | 217 | # endif |
| @@ -216,14 +227,14 @@ _GL_CXXALIASWARN (open); | |||
| 216 | # define openat rpl_openat | 227 | # define openat rpl_openat |
| 217 | # endif | 228 | # endif |
| 218 | _GL_FUNCDECL_RPL (openat, int, | 229 | _GL_FUNCDECL_RPL (openat, int, |
| 219 | (int fd, char const *file, int flags, /* mode_t mode */ ...) | 230 | (int fd, char const *file, int flags, /* mode_t mode */ ...), |
| 220 | _GL_ARG_NONNULL ((2))); | 231 | _GL_ARG_NONNULL ((2))); |
| 221 | _GL_CXXALIAS_RPL (openat, int, | 232 | _GL_CXXALIAS_RPL (openat, int, |
| 222 | (int fd, char const *file, int flags, /* mode_t mode */ ...)); | 233 | (int fd, char const *file, int flags, /* mode_t mode */ ...)); |
| 223 | # else | 234 | # else |
| 224 | # if !@HAVE_OPENAT@ | 235 | # if !@HAVE_OPENAT@ |
| 225 | _GL_FUNCDECL_SYS (openat, int, | 236 | _GL_FUNCDECL_SYS (openat, int, |
| 226 | (int fd, char const *file, int flags, /* mode_t mode */ ...) | 237 | (int fd, char const *file, int flags, /* mode_t mode */ ...), |
| 227 | _GL_ARG_NONNULL ((2))); | 238 | _GL_ARG_NONNULL ((2))); |
| 228 | # endif | 239 | # endif |
| 229 | _GL_CXXALIAS_SYS (openat, int, | 240 | _GL_CXXALIAS_SYS (openat, int, |
| @@ -304,7 +315,7 @@ _GL_WARN_ON_USE (openat, "openat is not portable - " | |||
| 304 | #endif | 315 | #endif |
| 305 | 316 | ||
| 306 | #ifndef O_DIRECTORY | 317 | #ifndef O_DIRECTORY |
| 307 | # define O_DIRECTORY 0 | 318 | # define O_DIRECTORY 0x20000000 /* Try to not collide with system O_* flags. */ |
| 308 | #endif | 319 | #endif |
| 309 | 320 | ||
| 310 | #ifndef O_DSYNC | 321 | #ifndef O_DSYNC |
| @@ -368,8 +379,12 @@ _GL_WARN_ON_USE (openat, "openat is not portable - " | |||
| 368 | # define O_RSYNC 0 | 379 | # define O_RSYNC 0 |
| 369 | #endif | 380 | #endif |
| 370 | 381 | ||
| 382 | #if defined O_SEARCH && defined O_PATH && O_SEARCH == O_PATH | ||
| 383 | # undef O_SEARCH /* musl mistakenly #defines O_SEARCH to O_PATH. */ | ||
| 384 | #endif | ||
| 385 | |||
| 371 | #ifndef O_SEARCH | 386 | #ifndef O_SEARCH |
| 372 | # define O_SEARCH O_RDONLY /* This is often close enough in older systems. */ | 387 | # define O_SEARCH O_RDONLY /* Often close enough in non-POSIX systems. */ |
| 373 | #endif | 388 | #endif |
| 374 | 389 | ||
| 375 | #ifndef O_SYNC | 390 | #ifndef O_SYNC |
diff --git a/gl/fd-hook.c b/gl/fd-hook.c index 75bbe49c..4a5014eb 100644 --- a/gl/fd-hook.c +++ b/gl/fd-hook.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Hook for making file descriptor functions close(), ioctl() extensible. | 1 | /* Hook for making file descriptor functions close(), ioctl() extensible. |
| 2 | Copyright (C) 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2009. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2009. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/fd-hook.h b/gl/fd-hook.h index 2150460b..a960eaf3 100644 --- a/gl/fd-hook.h +++ b/gl/fd-hook.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Hook for making file descriptor functions close(), ioctl() extensible. | 1 | /* Hook for making file descriptor functions close(), ioctl() extensible. |
| 2 | Copyright (C) 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/fflush.c b/gl/fflush.c index 36cc14d1..d8619082 100644 --- a/gl/fflush.c +++ b/gl/fflush.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* fflush.c -- allow flushing input streams | 1 | /* fflush.c -- allow flushing input streams |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -33,12 +33,15 @@ | |||
| 33 | 33 | ||
| 34 | #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 | 34 | #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 |
| 35 | /* GNU libc, BeOS, Haiku, Linux libc5 */ | 35 | /* GNU libc, BeOS, Haiku, Linux libc5 */ |
| 36 | # if !defined __HAIKU__ | ||
| 37 | # define fp_ fp | ||
| 38 | # endif | ||
| 36 | 39 | ||
| 37 | /* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */ | 40 | /* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */ |
| 38 | static void | 41 | static void |
| 39 | clear_ungetc_buffer_preserving_position (FILE *fp) | 42 | clear_ungetc_buffer_preserving_position (FILE *fp) |
| 40 | { | 43 | { |
| 41 | if (fp->_flags & _IO_IN_BACKUP) | 44 | if (fp_->_flags & _IO_IN_BACKUP) |
| 42 | /* _IO_free_backup_area is a bit complicated. Simply call fseek. */ | 45 | /* _IO_free_backup_area is a bit complicated. Simply call fseek. */ |
| 43 | fseeko (fp, 0, SEEK_CUR); | 46 | fseeko (fp, 0, SEEK_CUR); |
| 44 | } | 47 | } |
| @@ -50,7 +53,7 @@ static void | |||
| 50 | clear_ungetc_buffer (FILE *fp) | 53 | clear_ungetc_buffer (FILE *fp) |
| 51 | { | 54 | { |
| 52 | # if defined __sferror || defined __DragonFly__ || defined __ANDROID__ | 55 | # if defined __sferror || defined __DragonFly__ || defined __ANDROID__ |
| 53 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 56 | /* FreeBSD, NetBSD, OpenBSD <= 7.7, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 54 | if (HASUB (fp)) | 57 | if (HASUB (fp)) |
| 55 | { | 58 | { |
| 56 | fp_->_p += fp_->_r; | 59 | fp_->_p += fp_->_r; |
| @@ -75,7 +78,7 @@ clear_ungetc_buffer (FILE *fp) | |||
| 75 | /* GNU libc, BeOS, Haiku, Linux libc5 */ | 78 | /* GNU libc, BeOS, Haiku, Linux libc5 */ |
| 76 | 79 | ||
| 77 | # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT | 80 | # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT |
| 78 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 81 | /* FreeBSD, NetBSD, OpenBSD <= 7.7, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 79 | 82 | ||
| 80 | static int | 83 | static int |
| 81 | disable_seek_optimization (FILE *fp) | 84 | disable_seek_optimization (FILE *fp) |
| @@ -98,7 +101,7 @@ update_fpos_cache (_GL_ATTRIBUTE_MAYBE_UNUSED FILE *fp, | |||
| 98 | _GL_ATTRIBUTE_MAYBE_UNUSED off_t pos) | 101 | _GL_ATTRIBUTE_MAYBE_UNUSED off_t pos) |
| 99 | { | 102 | { |
| 100 | # if defined __sferror || defined __DragonFly__ || defined __ANDROID__ | 103 | # if defined __sferror || defined __DragonFly__ || defined __ANDROID__ |
| 101 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 104 | /* FreeBSD, NetBSD, OpenBSD <= 7.7, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 102 | # if defined __CYGWIN__ || defined __ANDROID__ | 105 | # if defined __CYGWIN__ || defined __ANDROID__ |
| 103 | /* fp_->_offset is typed as an integer. */ | 106 | /* fp_->_offset is typed as an integer. */ |
| 104 | fp_->_offset = pos; | 107 | fp_->_offset = pos; |
| @@ -203,7 +206,7 @@ rpl_fflush (FILE *stream) | |||
| 203 | } | 206 | } |
| 204 | 207 | ||
| 205 | # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT | 208 | # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT |
| 206 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 209 | /* FreeBSD, NetBSD, OpenBSD <= 7.7, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 207 | 210 | ||
| 208 | { | 211 | { |
| 209 | /* Disable seek optimization for the next fseeko call. This tells the | 212 | /* Disable seek optimization for the next fseeko call. This tells the |
diff --git a/gl/filename.h b/gl/filename.h index 4f0f0fbc..e353363e 100644 --- a/gl/filename.h +++ b/gl/filename.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Basic filename support macros. | 1 | /* Basic filename support macros. |
| 2 | Copyright (C) 2001-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
diff --git a/gl/float+.h b/gl/float+.h index 104f477f..37381146 100644 --- a/gl/float+.h +++ b/gl/float+.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Supplemental information about the floating-point formats. | 1 | /* Supplemental information about the floating-point formats. |
| 2 | Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2007. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2007. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Auxiliary definitions for <float.h>. | 1 | /* Auxiliary definitions for <float.h>. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -20,14 +20,101 @@ | |||
| 20 | /* Specification. */ | 20 | /* Specification. */ |
| 21 | #include <float.h> | 21 | #include <float.h> |
| 22 | 22 | ||
| 23 | #if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ | 23 | #if GNULIB_defined_long_double_union |
| 24 | # if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ | ||
| 24 | const union gl_long_double_union gl_LDBL_MAX = | 25 | const union gl_long_double_union gl_LDBL_MAX = |
| 25 | { { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL } }; | 26 | { { DBL_MAX, DBL_MAX / 0x1p53 } }; |
| 26 | #elif defined __i386__ | 27 | # elif defined __i386__ |
| 27 | const union gl_long_double_union gl_LDBL_MAX = | 28 | const union gl_long_double_union gl_LDBL_MAX = |
| 28 | { { 0xFFFFFFFF, 0xFFFFFFFF, 32766 } }; | 29 | { { 0xFFFFFFFF, 0xFFFFFFFF, 32766 } }; |
| 29 | #else | 30 | # endif |
| 31 | # if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__) | ||
| 32 | /* We can't even simply evaluate the formula (LDBL_MIN / 9223372036854775808.0L) | ||
| 33 | at run time, because it would require BEGIN_LONG_DOUBLE_ROUNDING / | ||
| 34 | END_LONG_DOUBLE_ROUNDING invocations. It simpler to just write down the | ||
| 35 | representation of LDBL_TRUE_MIN, based on | ||
| 36 | <https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format>. */ | ||
| 37 | const union gl_long_double_union gl_LDBL_TRUE_MIN = | ||
| 38 | { { 0x00000001, 0x00000000, 0 } }; | ||
| 39 | # endif | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #if GNULIB_defined_FLT_SNAN | ||
| 43 | /* Define like memory_positive_SNaNf(), see signed-snan.h and snan.h, | ||
| 44 | or like setpayloadsigf() with an arbitrary payload. */ | ||
| 45 | gl_FLT_SNAN_t gl_FLT_SNAN = | ||
| 46 | # if FLT_MANT_DIG == 24 | ||
| 47 | # if defined __hppa || (defined __mips__ && !MIPS_NAN2008_FLOAT) || defined __sh__ | ||
| 48 | /* sign bit: 0, 8 exponent bits: all 1, next bit: 1, payload: 0b10...0 */ | ||
| 49 | { { 0x7FE00000U } } | ||
| 50 | # else | ||
| 51 | /* sign bit: 0, 8 exponent bits: all 1, next bit: 0, payload: 0b10...0 */ | ||
| 52 | { { 0x7FA00000U } } | ||
| 53 | # endif | ||
| 54 | # endif | ||
| 55 | ; | ||
| 56 | #endif | ||
| 57 | |||
| 58 | #if GNULIB_defined_DBL_SNAN | ||
| 59 | /* Define like memory_positive_SNaNd(), see signed-snan.h and snan.h, | ||
| 60 | or like setpayloadsig() with an arbitrary payload. */ | ||
| 61 | gl_DBL_SNAN_t gl_DBL_SNAN = | ||
| 62 | # if DBL_MANT_DIG == 53 | ||
| 63 | # if defined __hppa || (defined __mips__ && !MIPS_NAN2008_FLOAT) || defined __sh__ | ||
| 64 | /* sign bit: 0, 11 exponent bits: all 1, next bit: 1, payload: 0b10...0 */ | ||
| 65 | { { 0x7FFC000000000000ULL } } | ||
| 66 | # else | ||
| 67 | /* sign bit: 0, 11 exponent bits: all 1, next bit: 0, payload: 0b10...0 */ | ||
| 68 | { { 0x7FF4000000000000ULL } } | ||
| 69 | # endif | ||
| 70 | # endif | ||
| 71 | ; | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #if GNULIB_defined_LDBL_SNAN | ||
| 75 | # ifdef WORDS_BIGENDIAN | ||
| 76 | # define TWO(hi,lo) { hi, lo } | ||
| 77 | # else | ||
| 78 | # define TWO(hi,lo) { lo, hi } | ||
| 79 | # endif | ||
| 80 | /* Define like memory_positive_SNaNl(), see signed-snan.h and snan.h, | ||
| 81 | or like setpayloadsigl() with an arbitrary payload. */ | ||
| 82 | gl_LDBL_SNAN_t gl_LDBL_SNAN = | ||
| 83 | # if LDBL_MANT_DIG == 53 /* on arm, hppa, mips, sh, but also MSVC */ | ||
| 84 | # if defined __hppa || (defined __mips__ && !MIPS_NAN2008_FLOAT) || defined __sh__ | ||
| 85 | /* sign bit: 0, 11 exponent bits: all 1, next bit: 1, payload: 0b10...0 */ | ||
| 86 | { { 0x7FFC000000000000ULL } } | ||
| 87 | # else | ||
| 88 | /* sign bit: 0, 11 exponent bits: all 1, next bit: 0, payload: 0b10...0 */ | ||
| 89 | { { 0x7FF4000000000000ULL } } | ||
| 90 | # endif | ||
| 91 | # elif LDBL_MANT_DIG == 64 /* on i386, x86_64, ia64, m68k */ | ||
| 92 | # if defined __m68k__ | ||
| 93 | /* sign bit: 0, 15 exponent bits: all 1, 16 gap bits: all 0, | ||
| 94 | always=1 bit: 1, next bit: 0, payload: 0b10...0 */ | ||
| 95 | { { 0x7FFF0000ULL, 0xA0000000ULL, 0x00000000ULL } } | ||
| 96 | # else | ||
| 97 | /* sign bit: 0, 15 exponent bits: all 1, always=1 bit: 1, next bit: 0, payload: 0b10...0 | ||
| 98 | (see <https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format>) */ | ||
| 99 | { TWO (0x00007FFFULL, 0xA000000000000000ULL) } | ||
| 100 | # endif | ||
| 101 | # elif LDBL_MANT_DIG == 106 /* on powerpc, powerpc64, powerpc64le */ | ||
| 102 | /* most-significant double: | ||
| 103 | sign bit: 0, 11 exponent bits: all 1, next bit: 0, payload: 0b10...0, | ||
| 104 | least-significant double: 0.0 */ | ||
| 105 | { { 0x7FF4000000000000ULL, 0ULL } } | ||
| 106 | # elif LDBL_MANT_DIG == 113 /* on alpha, arm64, loongarch64, mips64, riscv64, s390x, sparc64 */ | ||
| 107 | # if (defined __mips__ && !MIPS_NAN2008_FLOAT) | ||
| 108 | /* sign bit: 0, 15 exponent bits: all 1, next bit: 1, payload: 0b10...0 */ | ||
| 109 | { TWO (0x7FFFC00000000000ULL, 0ULL) } | ||
| 110 | # else | ||
| 111 | /* sign bit: 0, 15 exponent bits: all 1, next bit: 0, payload: 0b10...0 */ | ||
| 112 | { TWO (0x7FFF400000000000ULL, 0ULL) } | ||
| 113 | # endif | ||
| 114 | # endif | ||
| 115 | ; | ||
| 116 | #endif | ||
| 117 | |||
| 30 | /* This declaration is solely to ensure that after preprocessing | 118 | /* This declaration is solely to ensure that after preprocessing |
| 31 | this file is never empty. */ | 119 | this file is never empty. */ |
| 32 | typedef int dummy; | 120 | typedef int dummy; |
| 33 | #endif | ||
diff --git a/gl/float.in.h b/gl/float.in.h index 73e8d406..d75a06e7 100644 --- a/gl/float.in.h +++ b/gl/float.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A correct <float.h>. | 1 | /* A correct <float.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -28,6 +28,8 @@ | |||
| 28 | #ifndef _@GUARD_PREFIX@_FLOAT_H | 28 | #ifndef _@GUARD_PREFIX@_FLOAT_H |
| 29 | #define _@GUARD_PREFIX@_FLOAT_H | 29 | #define _@GUARD_PREFIX@_FLOAT_H |
| 30 | 30 | ||
| 31 | /* ============================ ISO C99 support ============================ */ | ||
| 32 | |||
| 31 | /* 'long double' properties. */ | 33 | /* 'long double' properties. */ |
| 32 | 34 | ||
| 33 | #if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) | 35 | #if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) |
| @@ -111,44 +113,38 @@ extern const union gl_long_double_union gl_LDBL_MAX; | |||
| 111 | # define LDBL_MAX_10_EXP 4932 | 113 | # define LDBL_MAX_10_EXP 4932 |
| 112 | #endif | 114 | #endif |
| 113 | 115 | ||
| 114 | /* On AIX 7.1 with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX are | 116 | /* On PowerPC with gcc 15 when using __ibm128 long double, the value of |
| 115 | wrong. | 117 | LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX, and LDBL_NORM_MAX are wrong. */ |
| 116 | On Linux/PowerPC with gcc 4.4, the value of LDBL_MAX is wrong. */ | 118 | #if (defined _ARCH_PPC && LDBL_MANT_DIG == 106 \ |
| 117 | #if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__ | 119 | && defined __GNUC__) |
| 118 | # undef LDBL_MIN_EXP | 120 | # undef LDBL_MIN_EXP |
| 119 | # define LDBL_MIN_EXP DBL_MIN_EXP | 121 | # define LDBL_MIN_EXP DBL_MIN_EXP |
| 120 | # undef LDBL_MIN_10_EXP | 122 | # undef LDBL_MIN_10_EXP |
| 121 | # define LDBL_MIN_10_EXP DBL_MIN_10_EXP | 123 | # define LDBL_MIN_10_EXP DBL_MIN_10_EXP |
| 122 | # undef LDBL_MIN | 124 | # undef LDBL_MIN |
| 123 | # define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ | 125 | # define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ |
| 124 | #endif | ||
| 125 | #if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ | ||
| 126 | # undef LDBL_MAX | 126 | # undef LDBL_MAX |
| 127 | /* LDBL_MAX is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xFFFFFFFF }. | 127 | /* LDBL_MAX is 2**1024 - 2**918, represented as: { 0x7FEFFFFF, 0xFFFFFFFF, |
| 128 | It is not easy to define: | 128 | 0x7C9FFFFF, 0xFFFFFFFF }. |
| 129 | #define LDBL_MAX 1.79769313486231580793728971405302307166e308L | 129 | |
| 130 | is too small, whereas | 130 | Do not write it as a constant expression, as GCC would likely treat |
| 131 | #define LDBL_MAX 1.79769313486231580793728971405302307167e308L | 131 | that as infinity due to the vagaries of this platform's funky arithmetic. |
| 132 | is too large. Apparently a bug in GCC decimal-to-binary conversion. | 132 | Instead, define it through a reference to an external variable. |
| 133 | Also, I can't get values larger than | 133 | Like the following, but using a union to avoid type mismatches: |
| 134 | #define LDBL63 ((long double) (1ULL << 63)) | ||
| 135 | #define LDBL882 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) | ||
| 136 | #define LDBL945 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) | ||
| 137 | #define LDBL1008 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) | ||
| 138 | #define LDBL_MAX (LDBL1008 * 65535.0L + LDBL945 * (long double) 9223372036821221375ULL + LDBL882 * (long double) 4611686018427387904ULL) | ||
| 139 | which is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xF8000000 }. | ||
| 140 | So, define it like this through a reference to an external variable | ||
| 141 | 134 | ||
| 142 | const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }; | 135 | const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / 0x1p53 }; |
| 143 | extern const long double LDBL_MAX; | 136 | extern const long double LDBL_MAX; |
| 144 | 137 | ||
| 145 | or through a pointer cast | 138 | The following alternative would not work as well when GCC is optimizing: |
| 146 | 139 | ||
| 147 | #define LDBL_MAX \ | 140 | #define LDBL_MAX (*(long double const *) (double[]) |
| 148 | (*(const long double *) (double[]) { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }) | 141 | { DBL_MAX, DBL_MAX / 0x1p53 }) |
| 149 | 142 | ||
| 150 | Unfortunately, this is not a constant expression, and the latter expression | 143 | The following alternative would require GCC 6 or later: |
| 151 | does not work well when GCC is optimizing.. */ | 144 | |
| 145 | #define LDBL_MAX __builtin_pack_longdouble (DBL_MAX, DBL_MAX / 0x1p53) | ||
| 146 | |||
| 147 | Unfortunately none of the alternatives are constant expressions. */ | ||
| 152 | # if !GNULIB_defined_long_double_union | 148 | # if !GNULIB_defined_long_double_union |
| 153 | union gl_long_double_union | 149 | union gl_long_double_union |
| 154 | { | 150 | { |
| @@ -159,6 +155,8 @@ union gl_long_double_union | |||
| 159 | # endif | 155 | # endif |
| 160 | extern const union gl_long_double_union gl_LDBL_MAX; | 156 | extern const union gl_long_double_union gl_LDBL_MAX; |
| 161 | # define LDBL_MAX (gl_LDBL_MAX.ld) | 157 | # define LDBL_MAX (gl_LDBL_MAX.ld) |
| 158 | # undef LDBL_NORM_MAX | ||
| 159 | # define LDBL_NORM_MAX LDBL_MAX | ||
| 162 | #endif | 160 | #endif |
| 163 | 161 | ||
| 164 | /* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong. | 162 | /* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong. |
| @@ -179,6 +177,175 @@ extern const union gl_long_double_union gl_LDBL_MAX; | |||
| 179 | # endif | 177 | # endif |
| 180 | #endif | 178 | #endif |
| 181 | 179 | ||
| 180 | /* On PowerPC platforms, 'long double' has a double-double representation. | ||
| 181 | Up to ISO C 17, this was outside the scope of ISO C because it can represent | ||
| 182 | numbers with mantissas of the form 1.<52 bits><many zeroes><52 bits>, such as | ||
| 183 | 1.0L + 4.94065645841246544176568792868221e-324L = 1 + 2^-1074; see | ||
| 184 | ISO C 17 § 5.2.4.2.2.(3). | ||
| 185 | In ISO C 23, wording has been included that makes this 'long double' | ||
| 186 | representation compliant; see ISO C 23 § 5.2.5.3.3.(8)-(9). In this setting, | ||
| 187 | numbers with mantissas of the form 1.<52 bits><many zeroes><52 bits> are | ||
| 188 | called "unnormalized". And since LDBL_EPSILON must be normalized (per | ||
| 189 | ISO C 23 § 5.2.5.3.3.(33)), it must be 2^-105. */ | ||
| 190 | #if defined __powerpc__ && LDBL_MANT_DIG == 106 | ||
| 191 | # undef LDBL_EPSILON | ||
| 192 | # define LDBL_EPSILON 2.46519032881566189191165176650870696773e-32L /* 2^-105 */ | ||
| 193 | #endif | ||
| 194 | |||
| 195 | /* ============================ ISO C11 support ============================ */ | ||
| 196 | |||
| 197 | /* 'float' properties */ | ||
| 198 | |||
| 199 | #ifndef FLT_HAS_SUBNORM | ||
| 200 | # define FLT_HAS_SUBNORM 1 | ||
| 201 | #endif | ||
| 202 | #ifndef FLT_DECIMAL_DIG | ||
| 203 | /* FLT_MANT_DIG = 24 => FLT_DECIMAL_DIG = 9 */ | ||
| 204 | # define FLT_DECIMAL_DIG ((int)(FLT_MANT_DIG * 0.3010299956639812 + 2)) | ||
| 205 | #endif | ||
| 206 | #if defined _AIX && !defined __GNUC__ | ||
| 207 | /* On AIX, the value of FLT_TRUE_MIN in /usr/include/float.h is a 'double', | ||
| 208 | not a 'float'. */ | ||
| 209 | # undef FLT_TRUE_MIN | ||
| 210 | #endif | ||
| 211 | #ifndef FLT_TRUE_MIN | ||
| 212 | /* FLT_MIN / 2^(FLT_MANT_DIG-1) */ | ||
| 213 | # define FLT_TRUE_MIN (FLT_MIN / 8388608.0f) | ||
| 214 | #endif | ||
| 215 | |||
| 216 | /* 'double' properties */ | ||
| 217 | |||
| 218 | #ifndef DBL_HAS_SUBNORM | ||
| 219 | # define DBL_HAS_SUBNORM 1 | ||
| 220 | #endif | ||
| 221 | #ifndef DBL_DECIMAL_DIG | ||
| 222 | /* DBL_MANT_DIG = 53 => DBL_DECIMAL_DIG = 17 */ | ||
| 223 | # define DBL_DECIMAL_DIG ((int)(DBL_MANT_DIG * 0.3010299956639812 + 2)) | ||
| 224 | #endif | ||
| 225 | #ifndef DBL_TRUE_MIN | ||
| 226 | /* DBL_MIN / 2^(DBL_MANT_DIG-1) */ | ||
| 227 | # define DBL_TRUE_MIN (DBL_MIN / 4503599627370496.0) | ||
| 228 | #endif | ||
| 229 | |||
| 230 | /* 'long double' properties */ | ||
| 231 | |||
| 232 | #ifndef LDBL_HAS_SUBNORM | ||
| 233 | # define LDBL_HAS_SUBNORM 1 | ||
| 234 | #endif | ||
| 235 | #ifndef LDBL_DECIMAL_DIG | ||
| 236 | /* LDBL_MANT_DIG = 53 => LDBL_DECIMAL_DIG = 17 */ | ||
| 237 | /* LDBL_MANT_DIG = 64 => LDBL_DECIMAL_DIG = 21 */ | ||
| 238 | /* LDBL_MANT_DIG = 106 => LDBL_DECIMAL_DIG = 33 */ | ||
| 239 | /* LDBL_MANT_DIG = 113 => LDBL_DECIMAL_DIG = 36 */ | ||
| 240 | # define LDBL_DECIMAL_DIG ((int)(LDBL_MANT_DIG * 0.3010299956639812 + 2)) | ||
| 241 | #endif | ||
| 242 | #ifndef LDBL_TRUE_MIN | ||
| 243 | /* LDBL_MIN / 2^(LDBL_MANT_DIG-1) */ | ||
| 244 | # if LDBL_MANT_DIG == 53 | ||
| 245 | # define LDBL_TRUE_MIN (LDBL_MIN / 4503599627370496.0L) | ||
| 246 | # elif LDBL_MANT_DIG == 64 | ||
| 247 | # if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__) | ||
| 248 | /* Work around FreeBSD/x86 problem mentioned above. */ | ||
| 249 | extern const union gl_long_double_union gl_LDBL_TRUE_MIN; | ||
| 250 | # define LDBL_TRUE_MIN (gl_LDBL_TRUE_MIN.ld) | ||
| 251 | # else | ||
| 252 | # define LDBL_TRUE_MIN (LDBL_MIN / 9223372036854775808.0L) | ||
| 253 | # endif | ||
| 254 | # elif LDBL_MANT_DIG == 106 | ||
| 255 | # define LDBL_TRUE_MIN (LDBL_MIN / 40564819207303340847894502572032.0L) | ||
| 256 | # elif LDBL_MANT_DIG == 113 | ||
| 257 | # define LDBL_TRUE_MIN (LDBL_MIN / 5192296858534827628530496329220096.0L) | ||
| 258 | # endif | ||
| 259 | #endif | ||
| 260 | |||
| 261 | /* ============================ ISO C23 support ============================ */ | ||
| 262 | |||
| 263 | /* 'float' properties */ | ||
| 264 | |||
| 265 | #ifndef FLT_IS_IEC_60559 | ||
| 266 | # if defined __m68k__ | ||
| 267 | # define FLT_IS_IEC_60559 0 | ||
| 268 | # else | ||
| 269 | # define FLT_IS_IEC_60559 1 | ||
| 270 | # endif | ||
| 271 | #endif | ||
| 272 | #ifndef FLT_NORM_MAX | ||
| 273 | # define FLT_NORM_MAX FLT_MAX | ||
| 274 | #endif | ||
| 275 | #ifndef FLT_SNAN | ||
| 276 | /* For sh, beware of <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111814>. */ | ||
| 277 | # if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ | ||
| 278 | # define FLT_SNAN __builtin_nansf ("") | ||
| 279 | # else | ||
| 280 | typedef union { unsigned int word[1]; float value; } gl_FLT_SNAN_t; | ||
| 281 | extern gl_FLT_SNAN_t gl_FLT_SNAN; | ||
| 282 | # define FLT_SNAN (gl_FLT_SNAN.value) | ||
| 283 | # define GNULIB_defined_FLT_SNAN 1 | ||
| 284 | # endif | ||
| 285 | #endif | ||
| 286 | |||
| 287 | /* 'double' properties */ | ||
| 288 | |||
| 289 | #ifndef DBL_IS_IEC_60559 | ||
| 290 | # if defined __m68k__ | ||
| 291 | # define DBL_IS_IEC_60559 0 | ||
| 292 | # else | ||
| 293 | # define DBL_IS_IEC_60559 1 | ||
| 294 | # endif | ||
| 295 | #endif | ||
| 296 | #ifndef DBL_NORM_MAX | ||
| 297 | # define DBL_NORM_MAX DBL_MAX | ||
| 298 | #endif | ||
| 299 | #ifndef DBL_SNAN | ||
| 300 | /* For sh, beware of <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111814>. */ | ||
| 301 | # if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ | ||
| 302 | # define DBL_SNAN __builtin_nans ("") | ||
| 303 | # else | ||
| 304 | typedef union { unsigned long long word[1]; double value; } gl_DBL_SNAN_t; | ||
| 305 | extern gl_DBL_SNAN_t gl_DBL_SNAN; | ||
| 306 | # define DBL_SNAN (gl_DBL_SNAN.value) | ||
| 307 | # define GNULIB_defined_DBL_SNAN 1 | ||
| 308 | # endif | ||
| 309 | #endif | ||
| 310 | |||
| 311 | /* 'long double' properties */ | ||
| 312 | |||
| 313 | #ifndef LDBL_IS_IEC_60559 | ||
| 314 | # if defined __m68k__ | ||
| 315 | # define LDBL_IS_IEC_60559 0 | ||
| 316 | # elif LDBL_MANT_DIG == 53 || LDBL_MANT_DIG == 113 | ||
| 317 | # define LDBL_IS_IEC_60559 1 | ||
| 318 | # else | ||
| 319 | # define LDBL_IS_IEC_60559 0 | ||
| 320 | # endif | ||
| 321 | #endif | ||
| 322 | #ifndef LDBL_NORM_MAX | ||
| 323 | # ifdef __LDBL_NORM_MAX__ | ||
| 324 | # define LDBL_NORM_MAX __LDBL_NORM_MAX__ | ||
| 325 | # else | ||
| 326 | # define LDBL_NORM_MAX LDBL_MAX | ||
| 327 | # endif | ||
| 328 | #endif | ||
| 329 | #ifndef LDBL_SNAN | ||
| 330 | /* For sh, beware of <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111814>. */ | ||
| 331 | # if ((__GNUC__ + (__GNUC_MINOR__ >= 3) > 3) || defined __clang__) && !defined __sh__ | ||
| 332 | # define LDBL_SNAN __builtin_nansl ("") | ||
| 333 | # else | ||
| 334 | # if LDBL_MANT_DIG == 53 | ||
| 335 | typedef union { unsigned long long word[1]; long double value; } gl_LDBL_SNAN_t; | ||
| 336 | # elif defined __m68k__ | ||
| 337 | typedef union { unsigned int word[3]; long double value; } gl_LDBL_SNAN_t; | ||
| 338 | # else | ||
| 339 | typedef union { unsigned long long word[2]; long double value; } gl_LDBL_SNAN_t; | ||
| 340 | # endif | ||
| 341 | extern gl_LDBL_SNAN_t gl_LDBL_SNAN; | ||
| 342 | # define LDBL_SNAN (gl_LDBL_SNAN.value) | ||
| 343 | # define GNULIB_defined_LDBL_SNAN 1 | ||
| 344 | # endif | ||
| 345 | #endif | ||
| 346 | |||
| 347 | /* ================================= Other ================================= */ | ||
| 348 | |||
| 182 | #if @REPLACE_ITOLD@ | 349 | #if @REPLACE_ITOLD@ |
| 183 | /* Pull in a function that fixes the 'int' to 'long double' conversion | 350 | /* Pull in a function that fixes the 'int' to 'long double' conversion |
| 184 | of glibc 2.7. */ | 351 | of glibc 2.7. */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Round towards negative infinity. | 1 | /* Round towards negative infinity. |
| 2 | Copyright (C) 2007, 2010-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2010-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/floorf.c b/gl/floorf.c index f9785d0c..d210c297 100644 --- a/gl/floorf.c +++ b/gl/floorf.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Round towards negative infinity. | 1 | /* Round towards negative infinity. |
| 2 | Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Open a stream to a file. | 1 | /* Open a stream to a file. |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -19,12 +19,12 @@ | |||
| 19 | /* If the user's config.h happens to include <stdio.h>, let it include only | 19 | /* If the user's config.h happens to include <stdio.h>, let it include only |
| 20 | the system's <stdio.h> here, so that orig_fopen doesn't recurse to | 20 | the system's <stdio.h> here, so that orig_fopen doesn't recurse to |
| 21 | rpl_fopen. */ | 21 | rpl_fopen. */ |
| 22 | #define _GL_ALREADY_INCLUDING_STDIO_H | 22 | #define _GL_SKIP_GNULIB_STDIO_H |
| 23 | #include <config.h> | 23 | #include <config.h> |
| 24 | 24 | ||
| 25 | /* Get the original definition of fopen. It might be defined as a macro. */ | 25 | /* Get the original definition of fopen. It might be defined as a macro. */ |
| 26 | #include <stdio.h> | 26 | #include <stdio.h> |
| 27 | #undef _GL_ALREADY_INCLUDING_STDIO_H | 27 | #undef _GL_SKIP_GNULIB_STDIO_H |
| 28 | 28 | ||
| 29 | static FILE * | 29 | static FILE * |
| 30 | orig_fopen (const char *filename, const char *mode) | 30 | orig_fopen (const char *filename, const char *mode) |
diff --git a/gl/fpurge.c b/gl/fpurge.c index 52a3dcef..0b69da3f 100644 --- a/gl/fpurge.c +++ b/gl/fpurge.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Flushing buffers of a FILE stream. | 1 | /* Flushing buffers of a FILE stream. |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -37,7 +37,7 @@ fpurge (FILE *fp) | |||
| 37 | /* The __fpurge function does not have a return value. */ | 37 | /* The __fpurge function does not have a return value. */ |
| 38 | return 0; | 38 | return 0; |
| 39 | 39 | ||
| 40 | #elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin >= 1.7 */ | 40 | #elif HAVE_FPURGE /* FreeBSD, NetBSD, 2.0 <= OpenBSD <= 7.7, DragonFly, Mac OS X, Cygwin >= 1.7 */ |
| 41 | 41 | ||
| 42 | /* Call the system's fpurge function. */ | 42 | /* Call the system's fpurge function. */ |
| 43 | # undef fpurge | 43 | # undef fpurge |
| @@ -46,7 +46,7 @@ fpurge (FILE *fp) | |||
| 46 | # endif | 46 | # endif |
| 47 | int result = fpurge (fp); | 47 | int result = fpurge (fp); |
| 48 | # if defined __sferror || defined __DragonFly__ || defined __ANDROID__ | 48 | # if defined __sferror || defined __DragonFly__ || defined __ANDROID__ |
| 49 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 49 | /* FreeBSD, NetBSD, OpenBSD <= 7.7, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 50 | if (result == 0) | 50 | if (result == 0) |
| 51 | /* Correct the invariants that fpurge broke. | 51 | /* Correct the invariants that fpurge broke. |
| 52 | <stdio.h> on BSD systems says: | 52 | <stdio.h> on BSD systems says: |
| @@ -76,7 +76,7 @@ fpurge (FILE *fp) | |||
| 76 | } | 76 | } |
| 77 | return 0; | 77 | return 0; |
| 78 | # elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ | 78 | # elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ |
| 79 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 79 | /* FreeBSD, NetBSD, OpenBSD < 2.0, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 80 | fp_->_p = fp_->_bf._base; | 80 | fp_->_p = fp_->_bf._base; |
| 81 | fp_->_r = 0; | 81 | fp_->_r = 0; |
| 82 | fp_->_w = ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ | 82 | fp_->_w = ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ |
diff --git a/gl/freading.c b/gl/freading.c index c80d9aa8..6a60d6b3 100644 --- a/gl/freading.c +++ b/gl/freading.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Retrieve information about a FILE stream. | 1 | /* Retrieve information about a FILE stream. |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -25,6 +25,10 @@ | |||
| 25 | <https://sourceware.org/bugzilla/show_bug.cgi?id=4359> */ | 25 | <https://sourceware.org/bugzilla/show_bug.cgi?id=4359> */ |
| 26 | #if !(HAVE___FREADING && (!defined __GLIBC__ || defined __UCLIBC__ || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))) | 26 | #if !(HAVE___FREADING && (!defined __GLIBC__ || defined __UCLIBC__ || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))) |
| 27 | 27 | ||
| 28 | /* This code is not compiled on systems that have a working __freading function, | ||
| 29 | namely glibc >= 2.7, OpenBSD >= 7.6, Solaris >= 7, UnixWare >= 7.1.4.MP4, | ||
| 30 | Cygwin >= 1.7.34, Android API >= 28, musl libc, Haiku >= hrev58760. */ | ||
| 31 | |||
| 28 | bool | 32 | bool |
| 29 | freading (FILE *fp) | 33 | freading (FILE *fp) |
| 30 | { | 34 | { |
| @@ -37,7 +41,7 @@ freading (FILE *fp) | |||
| 37 | || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0 | 41 | || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0 |
| 38 | && fp->_IO_read_base != NULL)); | 42 | && fp->_IO_read_base != NULL)); |
| 39 | # elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ | 43 | # elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ |
| 40 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin < 1.7.34, Minix 3, Android */ | 44 | /* FreeBSD, NetBSD, OpenBSD < 7.6, DragonFly, Mac OS X, Cygwin < 1.7.34, Minix 3, Android */ |
| 41 | return (fp_->_flags & __SRD) != 0; | 45 | return (fp_->_flags & __SRD) != 0; |
| 42 | # elif defined __EMX__ /* emx+gcc */ | 46 | # elif defined __EMX__ /* emx+gcc */ |
| 43 | return (fp->_flags & _IOREAD) != 0; | 47 | return (fp->_flags & _IOREAD) != 0; |
diff --git a/gl/freading.h b/gl/freading.h index 943354f5..405a651e 100644 --- a/gl/freading.h +++ b/gl/freading.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Retrieve information about a FILE stream. | 1 | /* Retrieve information about a FILE stream. |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Make free() preserve errno. | 1 | /* Make free() preserve errno. |
| 2 | 2 | ||
| 3 | Copyright (C) 2003, 2006, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2003, 2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* An fseek() function that, together with fflush(), is POSIX compliant. | 1 | /* An fseek() function that, together with fflush(), is POSIX compliant. |
| 2 | Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/fseeko.c b/gl/fseeko.c index 2c3b053a..ecd2f83a 100644 --- a/gl/fseeko.c +++ b/gl/fseeko.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* An fseeko() function that, together with fflush(), is POSIX compliant. | 1 | /* An fseeko() function that, together with fflush(), is POSIX compliant. |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -48,12 +48,15 @@ fseeko (FILE *fp, off_t offset, int whence) | |||
| 48 | 48 | ||
| 49 | /* These tests are based on fpurge.c. */ | 49 | /* These tests are based on fpurge.c. */ |
| 50 | #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 | 50 | #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 |
| 51 | # if !defined __HAIKU__ | ||
| 52 | # define fp_ fp | ||
| 53 | # endif | ||
| 51 | /* GNU libc, BeOS, Haiku, Linux libc5 */ | 54 | /* GNU libc, BeOS, Haiku, Linux libc5 */ |
| 52 | if (fp->_IO_read_end == fp->_IO_read_ptr | 55 | if (fp_->_IO_read_end == fp_->_IO_read_ptr |
| 53 | && fp->_IO_write_ptr == fp->_IO_write_base | 56 | && fp_->_IO_write_ptr == fp_->_IO_write_base |
| 54 | && fp->_IO_save_base == NULL) | 57 | && fp_->_IO_save_base == NULL) |
| 55 | #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ | 58 | #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ |
| 56 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 59 | /* FreeBSD, NetBSD, OpenBSD <= 7.7, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 57 | # if defined __SL64 && defined __SCLE /* Cygwin */ | 60 | # if defined __SL64 && defined __SCLE /* Cygwin */ |
| 58 | if ((fp->_flags & __SL64) == 0) | 61 | if ((fp->_flags & __SL64) == 0) |
| 59 | { | 62 | { |
| @@ -101,6 +104,9 @@ fseeko (FILE *fp, off_t offset, int whence) | |||
| 101 | #elif defined EPLAN9 /* Plan9 */ | 104 | #elif defined EPLAN9 /* Plan9 */ |
| 102 | if (fp->rp == fp->buf | 105 | if (fp->rp == fp->buf |
| 103 | && fp->wp == fp->buf) | 106 | && fp->wp == fp->buf) |
| 107 | #elif defined __OpenBSD__ && !defined __sferror /* OpenBSD >= 7.8 */ | ||
| 108 | /* fseeko and fflush work as advertised. */ | ||
| 109 | if (0) | ||
| 104 | #elif FUNC_FFLUSH_STDIN < 0 && 200809 <= _POSIX_VERSION | 110 | #elif FUNC_FFLUSH_STDIN < 0 && 200809 <= _POSIX_VERSION |
| 105 | /* Cross-compiling to some other system advertising conformance to | 111 | /* Cross-compiling to some other system advertising conformance to |
| 106 | POSIX.1-2008 or later. Assume fseeko and fflush work as advertised. | 112 | POSIX.1-2008 or later. Assume fseeko and fflush work as advertised. |
| @@ -118,7 +124,7 @@ fseeko (FILE *fp, off_t offset, int whence) | |||
| 118 | if (pos == -1) | 124 | if (pos == -1) |
| 119 | { | 125 | { |
| 120 | #if defined __sferror || defined __DragonFly__ || defined __ANDROID__ | 126 | #if defined __sferror || defined __DragonFly__ || defined __ANDROID__ |
| 121 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 127 | /* FreeBSD, NetBSD, OpenBSD <= 7.7, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 122 | fp_->_flags &= ~__SOFF; | 128 | fp_->_flags &= ~__SOFF; |
| 123 | #endif | 129 | #endif |
| 124 | return -1; | 130 | return -1; |
| @@ -126,10 +132,10 @@ fseeko (FILE *fp, off_t offset, int whence) | |||
| 126 | 132 | ||
| 127 | #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 | 133 | #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 |
| 128 | /* GNU libc, BeOS, Haiku, Linux libc5 */ | 134 | /* GNU libc, BeOS, Haiku, Linux libc5 */ |
| 129 | fp->_flags &= ~_IO_EOF_SEEN; | 135 | fp_->_flags &= ~_IO_EOF_SEEN; |
| 130 | fp->_offset = pos; | 136 | fp_->_offset = pos; |
| 131 | #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ | 137 | #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ |
| 132 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 138 | /* FreeBSD, NetBSD, OpenBSD <= 7.7, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 133 | # if defined __CYGWIN__ || (defined __NetBSD__ && __NetBSD_Version__ >= 600000000) || defined __minix | 139 | # if defined __CYGWIN__ || (defined __NetBSD__ && __NetBSD_Version__ >= 600000000) || defined __minix |
| 134 | /* fp_->_offset is typed as an integer. */ | 140 | /* fp_->_offset is typed as an integer. */ |
| 135 | fp_->_offset = pos; | 141 | fp_->_offset = pos; |
diff --git a/gl/fseterr.c b/gl/fseterr.c new file mode 100644 index 00000000..a01ef2af --- /dev/null +++ b/gl/fseterr.c | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | /* Set the error indicator of a stream. | ||
| 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | /* Specification. */ | ||
| 20 | #include "fseterr.h" | ||
| 21 | |||
| 22 | #include <errno.h> | ||
| 23 | |||
| 24 | #include "stdio-impl.h" | ||
| 25 | |||
| 26 | /* This file is not used on systems that have the __fseterr function, | ||
| 27 | namely OpenBSD >= 7.6, musl libc, Haiku >= hrev58760. */ | ||
| 28 | |||
| 29 | void | ||
| 30 | fseterr (FILE *fp) | ||
| 31 | { | ||
| 32 | /* Most systems provide FILE as a struct and the necessary bitmask in | ||
| 33 | <stdio.h>, because they need it for implementing getc() and putc() as | ||
| 34 | fast macros. */ | ||
| 35 | #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 | ||
| 36 | /* GNU libc, BeOS, Haiku, Linux libc5 */ | ||
| 37 | fp->_flags |= _IO_ERR_SEEN; | ||
| 38 | #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ | ||
| 39 | /* FreeBSD, NetBSD, OpenBSD < 7.6, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | ||
| 40 | fp_->_flags |= __SERR; | ||
| 41 | #elif defined __EMX__ /* emx+gcc */ | ||
| 42 | fp->_flags |= _IOERR; | ||
| 43 | #elif defined __minix /* Minix */ | ||
| 44 | fp->_flags |= _IOERR; | ||
| 45 | #elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, UnixWare, mingw, MSVC, NonStop Kernel, OpenVMS */ | ||
| 46 | fp_->_flag |= _IOERR; | ||
| 47 | #elif defined __UCLIBC__ /* uClibc */ | ||
| 48 | fp->__modeflags |= __FLAG_ERROR; | ||
| 49 | #elif defined __QNX__ /* QNX */ | ||
| 50 | fp->_Mode |= 0x200 /* _MERR */; | ||
| 51 | #elif defined __MINT__ /* Atari FreeMiNT */ | ||
| 52 | fp->__error = 1; | ||
| 53 | #elif defined EPLAN9 /* Plan9 */ | ||
| 54 | if (fp->state != 0 /* CLOSED */) | ||
| 55 | fp->state = 5 /* ERR */; | ||
| 56 | #elif 0 /* unknown */ | ||
| 57 | /* Portable fallback, based on an idea by Rich Felker. | ||
| 58 | Wow! 6 system calls for something that is just a bit operation! | ||
| 59 | Not activated on any system, because there is no way to repair FP when | ||
| 60 | the sequence of system calls fails, and library code should not call | ||
| 61 | abort(). */ | ||
| 62 | int saved_errno; | ||
| 63 | int fd; | ||
| 64 | int fd2; | ||
| 65 | |||
| 66 | saved_errno = errno; | ||
| 67 | fflush (fp); | ||
| 68 | fd = fileno (fp); | ||
| 69 | fd2 = dup (fd); | ||
| 70 | if (fd2 >= 0) | ||
| 71 | { | ||
| 72 | close (fd); | ||
| 73 | fputc ('\0', fp); /* This should set the error indicator. */ | ||
| 74 | fflush (fp); /* Or this. */ | ||
| 75 | if (dup2 (fd2, fd) < 0) | ||
| 76 | /* Whee... we botched the stream and now cannot restore it! */ | ||
| 77 | abort (); | ||
| 78 | close (fd2); | ||
| 79 | } | ||
| 80 | errno = saved_errno; | ||
| 81 | #else | ||
| 82 | #error "Please port gnulib fseterr.c to your platform! Look at the definitions of ferror and clearerr on your system, then report this to bug-gnulib." | ||
| 83 | #endif | ||
| 84 | } | ||
diff --git a/gl/fseterr.h b/gl/fseterr.h new file mode 100644 index 00000000..57c30ef3 --- /dev/null +++ b/gl/fseterr.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* Set the error indicator of a stream. | ||
| 2 | Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #ifndef _FSETERR_H | ||
| 18 | #define _FSETERR_H | ||
| 19 | |||
| 20 | /* This file uses HAVE___FSETERR. */ | ||
| 21 | #if !_GL_CONFIG_H_INCLUDED | ||
| 22 | #error "Please include config.h first." | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #include <stdio.h> | ||
| 26 | |||
| 27 | /* Set the error indicator of the stream FP. | ||
| 28 | The "error indicator" is set when an I/O operation on the stream fails, and | ||
| 29 | is cleared (together with the "end-of-file" indicator) by clearerr (FP). */ | ||
| 30 | |||
| 31 | #if HAVE___FSETERR /* musl libc */ | ||
| 32 | |||
| 33 | /* Haiku has __fseterr but does not declare it. */ | ||
| 34 | # if defined __HAIKU__ | ||
| 35 | extern void __fseterr (FILE *fp); | ||
| 36 | # endif | ||
| 37 | |||
| 38 | # include <stdio_ext.h> | ||
| 39 | # define fseterr(fp) __fseterr (fp) | ||
| 40 | |||
| 41 | #else | ||
| 42 | |||
| 43 | # ifdef __cplusplus | ||
| 44 | extern "C" { | ||
| 45 | # endif | ||
| 46 | |||
| 47 | extern void fseterr (FILE *fp); | ||
| 48 | |||
| 49 | # ifdef __cplusplus | ||
| 50 | } | ||
| 51 | # endif | ||
| 52 | |||
| 53 | #endif | ||
| 54 | |||
| 55 | #endif /* _FSETERR_H */ | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* fstat() replacement. | 1 | /* fstat() replacement. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/fsusage.c b/gl/fsusage.c index 97d0eef7..e26bda88 100644 --- a/gl/fsusage.c +++ b/gl/fsusage.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* fsusage.c -- return space usage of mounted file systems | 1 | /* fsusage.c -- return space usage of mounted file systems |
| 2 | 2 | ||
| 3 | Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2024 Free Software | 3 | Copyright (C) 1991-1992, 1996, 1998-1999, 2002-2006, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/fsusage.h b/gl/fsusage.h index da878590..00d9067e 100644 --- a/gl/fsusage.h +++ b/gl/fsusage.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* fsusage.h -- declarations for file system space usage info | 1 | /* fsusage.h -- declarations for file system space usage info |
| 2 | 2 | ||
| 3 | Copyright (C) 1991-1992, 1997, 2003-2006, 2009-2024 Free Software | 3 | Copyright (C) 1991-1992, 1997, 2003-2006, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* An ftell() function that works around platform bugs. | 1 | /* An ftell() function that works around platform bugs. |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/ftello.c b/gl/ftello.c index 64119aab..b0a20bf3 100644 --- a/gl/ftello.c +++ b/gl/ftello.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* An ftello() function that works around platform bugs. | 1 | /* An ftello() function that works around platform bugs. |
| 2 | Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -20,7 +20,7 @@ | |||
| 20 | #include <stdio.h> | 20 | #include <stdio.h> |
| 21 | 21 | ||
| 22 | #include <errno.h> | 22 | #include <errno.h> |
| 23 | #include "intprops.h" | 23 | #include <stdckdint.h> |
| 24 | 24 | ||
| 25 | /* Get lseek. */ | 25 | /* Get lseek. */ |
| 26 | #include <unistd.h> | 26 | #include <unistd.h> |
| @@ -34,7 +34,10 @@ ftello (FILE *fp) | |||
| 34 | # undef ftell | 34 | # undef ftell |
| 35 | # define ftello ftell | 35 | # define ftello ftell |
| 36 | #endif | 36 | #endif |
| 37 | #if _GL_WINDOWS_64_BIT_OFF_T | 37 | #if (defined _WIN32 && !defined __CYGWIN__) \ |
| 38 | /* We need to test _FILE_OFFSET_BITS for mingw-w64 */ \ | ||
| 39 | /* and _GL_WINDOWS_64_BIT_OFF_T for MSVC. */ \ | ||
| 40 | && (_FILE_OFFSET_BITS == 64 || _GL_WINDOWS_64_BIT_OFF_T) | ||
| 38 | # undef ftello | 41 | # undef ftello |
| 39 | # if HAVE__FTELLI64 /* msvc, mingw64 */ | 42 | # if HAVE__FTELLI64 /* msvc, mingw64 */ |
| 40 | # define ftello _ftelli64 | 43 | # define ftello _ftelli64 |
| @@ -97,7 +100,7 @@ ftello (FILE *fp) | |||
| 97 | 100 | ||
| 98 | /* Compute pos + buffered, with overflow check. */ | 101 | /* Compute pos + buffered, with overflow check. */ |
| 99 | off_t sum; | 102 | off_t sum; |
| 100 | if (! INT_ADD_OK (pos, buffered, &sum)) | 103 | if (ckd_add (&sum, pos, buffered)) |
| 101 | { | 104 | { |
| 102 | errno = EOVERFLOW; | 105 | errno = EOVERFLOW; |
| 103 | return -1; | 106 | return -1; |
diff --git a/gl/gai_strerror.c b/gl/gai_strerror.c index 37092e29..9c5f1419 100644 --- a/gl/gai_strerror.c +++ b/gl/gai_strerror.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 1997, 2001-2002, 2004-2006, 2008-2024 Free Software | 1 | /* Copyright (C) 1997, 2001-2002, 2004-2006, 2008-2025 Free Software |
| 2 | Foundation, Inc. | 2 | Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Contributed by Philip Blundell <pjb27@cam.ac.uk>, 1997. | 4 | Contributed by Philip Blundell <pjb27@cam.ac.uk>, 1997. |
| @@ -27,8 +27,8 @@ | |||
| 27 | # include <libintl.h> | 27 | # include <libintl.h> |
| 28 | #else | 28 | #else |
| 29 | # include "gettext.h" | 29 | # include "gettext.h" |
| 30 | # define _(String) gettext (String) | 30 | # define _(msgid) dgettext ("gnulib", msgid) |
| 31 | # define N_(String) String | 31 | # define N_(msgid) msgid |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | #if HAVE_DECL_GAI_STRERROR | 34 | #if HAVE_DECL_GAI_STRERROR |
diff --git a/gl/getaddrinfo.c b/gl/getaddrinfo.c index bf5d61f3..a8c45c21 100644 --- a/gl/getaddrinfo.c +++ b/gl/getaddrinfo.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Get address information (partial implementation). | 1 | /* Get address information (partial implementation). |
| 2 | Copyright (C) 1997, 2001-2002, 2004-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1997, 2001-2002, 2004-2025 Free Software Foundation, Inc. |
| 3 | Contributed by Simon Josefsson <simon@josefsson.org>. | 3 | Contributed by Simon Josefsson <simon@josefsson.org>. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -40,8 +40,8 @@ | |||
| 40 | #include <stdio.h> | 40 | #include <stdio.h> |
| 41 | 41 | ||
| 42 | #include "gettext.h" | 42 | #include "gettext.h" |
| 43 | #define _(String) gettext (String) | 43 | #define _(msgid) dgettext ("gnulib", msgid) |
| 44 | #define N_(String) String | 44 | #define N_(msgid) msgid |
| 45 | 45 | ||
| 46 | /* BeOS has AF_INET, but not PF_INET. */ | 46 | /* BeOS has AF_INET, but not PF_INET. */ |
| 47 | #ifndef PF_INET | 47 | #ifndef PF_INET |
| @@ -54,7 +54,7 @@ | |||
| 54 | 54 | ||
| 55 | #if HAVE_GETADDRINFO | 55 | #if HAVE_GETADDRINFO |
| 56 | 56 | ||
| 57 | /* Override with cdecl calling convention. */ | 57 | /* Override with cdecl calling convention and mingw fix. */ |
| 58 | 58 | ||
| 59 | int | 59 | int |
| 60 | getaddrinfo (const char *restrict nodename, | 60 | getaddrinfo (const char *restrict nodename, |
| @@ -63,6 +63,10 @@ getaddrinfo (const char *restrict nodename, | |||
| 63 | struct addrinfo **restrict res) | 63 | struct addrinfo **restrict res) |
| 64 | # undef getaddrinfo | 64 | # undef getaddrinfo |
| 65 | { | 65 | { |
| 66 | if (hints && (hints->ai_flags & AI_NUMERICSERV) != 0 | ||
| 67 | && servname && !(*servname >= '0' && *servname <= '9')) | ||
| 68 | return EAI_NONAME; | ||
| 69 | |||
| 66 | return getaddrinfo (nodename, servname, hints, res); | 70 | return getaddrinfo (nodename, servname, hints, res); |
| 67 | } | 71 | } |
| 68 | 72 | ||
| @@ -169,16 +173,43 @@ validate_family (int family) | |||
| 169 | { | 173 | { |
| 170 | /* FIXME: Support more families. */ | 174 | /* FIXME: Support more families. */ |
| 171 | # if HAVE_IPV4 | 175 | # if HAVE_IPV4 |
| 172 | if (family == PF_INET) | 176 | if (family == PF_INET) |
| 173 | return true; | 177 | return true; |
| 174 | # endif | 178 | # endif |
| 175 | # if HAVE_IPV6 | 179 | # if HAVE_IPV6 |
| 176 | if (family == PF_INET6) | 180 | if (family == PF_INET6) |
| 177 | return true; | 181 | return true; |
| 178 | # endif | 182 | # endif |
| 179 | if (family == PF_UNSPEC) | 183 | if (family == PF_UNSPEC) |
| 180 | return true; | 184 | return true; |
| 181 | return false; | 185 | return false; |
| 186 | } | ||
| 187 | |||
| 188 | static bool | ||
| 189 | is_numeric_host (const char *host, int family) | ||
| 190 | { | ||
| 191 | # if HAVE_IPV4 | ||
| 192 | if (family == PF_INET || family == PF_UNSPEC) | ||
| 193 | { | ||
| 194 | /* glibc supports IPv4 addresses in numbers-and-dots notation, that is, | ||
| 195 | also hexadecimal and octal number formats and formats that don't | ||
| 196 | require all four bytes to be explicitly written, via inet_aton(). | ||
| 197 | But POSIX doesn't require support for these legacy formats. Therefore | ||
| 198 | we are free to use inet_pton() instead of inet_aton(). */ | ||
| 199 | struct in_addr addr; | ||
| 200 | if (inet_pton (AF_INET, host, &addr)) | ||
| 201 | return true; | ||
| 202 | } | ||
| 203 | # endif | ||
| 204 | # if HAVE_IPV6 | ||
| 205 | if (family == PF_INET6 || family == PF_UNSPEC) | ||
| 206 | { | ||
| 207 | struct in6_addr addr; | ||
| 208 | if (inet_pton (AF_INET6, host, &addr)) | ||
| 209 | return true; | ||
| 210 | } | ||
| 211 | # endif | ||
| 212 | return false; | ||
| 182 | } | 213 | } |
| 183 | 214 | ||
| 184 | /* Translate name of a service location and/or a service name to set of | 215 | /* Translate name of a service location and/or a service name to set of |
| @@ -210,10 +241,17 @@ getaddrinfo (const char *restrict nodename, | |||
| 210 | 241 | ||
| 211 | # ifdef WINDOWS_NATIVE | 242 | # ifdef WINDOWS_NATIVE |
| 212 | if (use_win32_p ()) | 243 | if (use_win32_p ()) |
| 213 | return getaddrinfo_ptr (nodename, servname, hints, res); | 244 | { |
| 245 | if (hints && (hints->ai_flags & AI_NUMERICSERV) != 0 | ||
| 246 | && servname && !(*servname >= '0' && *servname <= '9')) | ||
| 247 | return EAI_NONAME; | ||
| 248 | return getaddrinfo_ptr (nodename, servname, hints, res); | ||
| 249 | } | ||
| 214 | # endif | 250 | # endif |
| 215 | 251 | ||
| 216 | if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE))) | 252 | if (hints |
| 253 | && (hints->ai_flags | ||
| 254 | & ~(AI_CANONNAME | AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV))) | ||
| 217 | /* FIXME: Support more flags. */ | 255 | /* FIXME: Support more flags. */ |
| 218 | return EAI_BADFLAGS; | 256 | return EAI_BADFLAGS; |
| 219 | 257 | ||
| @@ -225,12 +263,18 @@ getaddrinfo (const char *restrict nodename, | |||
| 225 | /* FIXME: Support other socktype. */ | 263 | /* FIXME: Support other socktype. */ |
| 226 | return EAI_SOCKTYPE; /* FIXME: Better return code? */ | 264 | return EAI_SOCKTYPE; /* FIXME: Better return code? */ |
| 227 | 265 | ||
| 228 | if (!nodename) | 266 | if (nodename != NULL) |
| 267 | { | ||
| 268 | if (hints && (hints->ai_flags & AI_NUMERICHOST) != 0 | ||
| 269 | && !is_numeric_host (nodename, hints->ai_family)) | ||
| 270 | return EAI_NONAME; | ||
| 271 | } | ||
| 272 | else | ||
| 229 | { | 273 | { |
| 230 | if (!(hints->ai_flags & AI_PASSIVE)) | 274 | if (!(hints->ai_flags & AI_PASSIVE)) |
| 231 | return EAI_NONAME; | 275 | return EAI_NONAME; |
| 232 | 276 | ||
| 233 | # ifdef HAVE_IPV6 | 277 | # if HAVE_IPV6 |
| 234 | nodename = (hints->ai_family == AF_INET6) ? "::" : "0.0.0.0"; | 278 | nodename = (hints->ai_family == AF_INET6) ? "::" : "0.0.0.0"; |
| 235 | # else | 279 | # else |
| 236 | nodename = "0.0.0.0"; | 280 | nodename = "0.0.0.0"; |
diff --git a/gl/getdelim.c b/gl/getdelim.c index 58063b15..2576d376 100644 --- a/gl/getdelim.c +++ b/gl/getdelim.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* getdelim.c --- Implementation of replacement getdelim function. | 1 | /* getdelim.c --- Implementation of replacement getdelim function. |
| 2 | Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2024 Free Software | 2 | Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2025 Free Software |
| 3 | Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/getdtablesize.c b/gl/getdtablesize.c index 762c100b..b98fbb70 100644 --- a/gl/getdtablesize.c +++ b/gl/getdtablesize.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* getdtablesize() function: Return maximum possible file descriptor value + 1. | 1 | /* getdtablesize() function: Return maximum possible file descriptor value + 1. |
| 2 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/gethostname.c b/gl/gethostname.c index c075b6df..8f0ceafc 100644 --- a/gl/gethostname.c +++ b/gl/gethostname.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* gethostname emulation for SysV and POSIX.1. | 1 | /* gethostname emulation for SysV and POSIX.1. |
| 2 | 2 | ||
| 3 | Copyright (C) 1992, 2003, 2006, 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1992, 2003, 2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/getline.c b/gl/getline.c index 2d03b646..0921dd95 100644 --- a/gl/getline.c +++ b/gl/getline.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* getline.c --- Implementation of replacement getline function. | 1 | /* getline.c --- Implementation of replacement getline function. |
| 2 | Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/getloadavg.c b/gl/getloadavg.c index c940e4c7..752ec1f5 100644 --- a/gl/getloadavg.c +++ b/gl/getloadavg.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Get the system load averages. | 1 | /* Get the system load averages. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2024 Free Software | 3 | Copyright (C) 1985-1989, 1991-1995, 1997, 1999-2000, 2003-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | NOTE: The canonical source of this file is maintained with gnulib. | 6 | NOTE: The canonical source of this file is maintained with gnulib. |
| @@ -47,8 +47,6 @@ | |||
| 47 | N_NAME_POINTER The nlist n_name element is a pointer, | 47 | N_NAME_POINTER The nlist n_name element is a pointer, |
| 48 | not an array. | 48 | not an array. |
| 49 | HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'. | 49 | HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'. |
| 50 | LINUX_LDAV_FILE [__linux__, __ANDROID__, __CYGWIN__]: File | ||
| 51 | containing load averages. | ||
| 52 | 50 | ||
| 53 | Specific system predefines this file uses, aside from setting | 51 | Specific system predefines this file uses, aside from setting |
| 54 | default values if not emacs: | 52 | default values if not emacs: |
| @@ -65,8 +63,7 @@ | |||
| 65 | UMAX4_3 | 63 | UMAX4_3 |
| 66 | VMS | 64 | VMS |
| 67 | _WIN32 Native Windows (possibly also defined on Cygwin) | 65 | _WIN32 Native Windows (possibly also defined on Cygwin) |
| 68 | __linux__, __ANDROID__ Linux: assumes /proc file system mounted. | 66 | __linux__, __ANDROID__ Linux: assumes sysinfo() call. |
| 69 | Support from Michael K. Johnson. | ||
| 70 | __CYGWIN__ Cygwin emulates linux /proc/loadavg. | 67 | __CYGWIN__ Cygwin emulates linux /proc/loadavg. |
| 71 | __NetBSD__ NetBSD: assumes /kern file system mounted. | 68 | __NetBSD__ NetBSD: assumes /kern file system mounted. |
| 72 | 69 | ||
| @@ -108,10 +105,10 @@ | |||
| 108 | # endif | 105 | # endif |
| 109 | 106 | ||
| 110 | /* Same issues as for NeXT apply to the HURD-based GNU system. */ | 107 | /* Same issues as for NeXT apply to the HURD-based GNU system. */ |
| 111 | # ifdef __GNU__ | 108 | # if defined __gnu_hurd__ || defined NeXT |
| 112 | # undef BSD | 109 | # undef BSD |
| 113 | # undef FSCALE | 110 | # undef FSCALE |
| 114 | # endif /* __GNU__ */ | 111 | # endif /* __gnu_hurd__ || NeXT */ |
| 115 | 112 | ||
| 116 | /* Set values that are different from the defaults, which are | 113 | /* Set values that are different from the defaults, which are |
| 117 | set a little farther down with #ifndef. */ | 114 | set a little farther down with #ifndef. */ |
| @@ -143,7 +140,7 @@ | |||
| 143 | # define SUNOS_5 | 140 | # define SUNOS_5 |
| 144 | # endif | 141 | # endif |
| 145 | 142 | ||
| 146 | # if defined (__osf__) && (defined (__alpha) || defined (__alpha__)) | 143 | # if defined (__osf__) && defined (__alpha) |
| 147 | # define OSF_ALPHA | 144 | # define OSF_ALPHA |
| 148 | # include <sys/mbuf.h> | 145 | # include <sys/mbuf.h> |
| 149 | # include <sys/socket.h> | 146 | # include <sys/socket.h> |
| @@ -312,8 +309,7 @@ | |||
| 312 | # endif | 309 | # endif |
| 313 | # endif | 310 | # endif |
| 314 | 311 | ||
| 315 | # if defined (__GNU__) && !defined (NeXT) | 312 | # if defined __gnu_hurd__ && !defined NeXT |
| 316 | /* Note that NeXT Openstep defines __GNU__ even though it should not. */ | ||
| 317 | /* GNU system acts much like NeXT, for load average purposes, | 313 | /* GNU system acts much like NeXT, for load average purposes, |
| 318 | but not exactly. */ | 314 | but not exactly. */ |
| 319 | # define NeXT | 315 | # define NeXT |
| @@ -358,6 +354,11 @@ | |||
| 358 | # include <sys/dg_sys_info.h> | 354 | # include <sys/dg_sys_info.h> |
| 359 | # endif | 355 | # endif |
| 360 | 356 | ||
| 357 | # if defined __linux__ || defined __ANDROID__ | ||
| 358 | # include <sys/param.h> | ||
| 359 | # include <sys/sysinfo.h> | ||
| 360 | # endif | ||
| 361 | |||
| 361 | # if (defined __linux__ || defined __ANDROID__ \ | 362 | # if (defined __linux__ || defined __ANDROID__ \ |
| 362 | || defined __CYGWIN__ || defined SUNOS_5 \ | 363 | || defined __CYGWIN__ || defined SUNOS_5 \ |
| 363 | || (defined LOAD_AVE_TYPE && ! defined __VMS)) | 364 | || (defined LOAD_AVE_TYPE && ! defined __VMS)) |
| @@ -498,20 +499,33 @@ getloadavg (double loadavg[], int nelem) | |||
| 498 | } | 499 | } |
| 499 | # endif | 500 | # endif |
| 500 | 501 | ||
| 501 | # if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__ || defined __CYGWIN__) | 502 | # if (!defined LDAV_DONE \ |
| 502 | /* Linux without glibc, Android, Cygwin */ | 503 | && (defined __ANDROID__ ? 13 <= __ANDROID_API__ : defined __linux__)) |
| 504 | /* non-Android Linux without glibc, Android 3.2+, Cygwin */ | ||
| 503 | # define LDAV_DONE | 505 | # define LDAV_DONE |
| 504 | # undef LOAD_AVE_TYPE | 506 | # undef LOAD_AVE_TYPE |
| 505 | 507 | ||
| 506 | # ifndef LINUX_LDAV_FILE | 508 | { |
| 507 | # define LINUX_LDAV_FILE "/proc/loadavg" | 509 | struct sysinfo info; |
| 508 | # endif | 510 | if (sysinfo (&info) < 0) |
| 511 | return -1; | ||
| 512 | loadavg[0] = info.loads[0] / (double)(1U << SI_LOAD_SHIFT); | ||
| 513 | loadavg[1] = info.loads[1] / (double)(1U << SI_LOAD_SHIFT); | ||
| 514 | loadavg[2] = info.loads[2] / (double)(1U << SI_LOAD_SHIFT); | ||
| 515 | elem = 3; | ||
| 516 | } | ||
| 517 | # endif /* __ANDROID__ ? 13 <= __ANDROID_API__ : __linux__ */ | ||
| 518 | |||
| 519 | # if !defined (LDAV_DONE) && defined __CYGWIN__ | ||
| 520 | /* Cygwin */ | ||
| 521 | # define LDAV_DONE | ||
| 522 | # undef LOAD_AVE_TYPE | ||
| 509 | 523 | ||
| 510 | char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; | 524 | char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; |
| 511 | char const *ptr = ldavgbuf; | 525 | char const *ptr = ldavgbuf; |
| 512 | int fd, count, saved_errno; | 526 | int fd, count, saved_errno; |
| 513 | 527 | ||
| 514 | fd = open (LINUX_LDAV_FILE, O_RDONLY | O_CLOEXEC); | 528 | fd = open ("/proc/loadavg", O_RDONLY | O_CLOEXEC); |
| 515 | if (fd == -1) | 529 | if (fd == -1) |
| 516 | return -1; | 530 | return -1; |
| 517 | count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); | 531 | count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); |
| @@ -554,7 +568,7 @@ getloadavg (double loadavg[], int nelem) | |||
| 554 | 568 | ||
| 555 | return elem; | 569 | return elem; |
| 556 | 570 | ||
| 557 | # endif /* __linux__ || __ANDROID__ || __CYGWIN__ */ | 571 | # endif /* __CYGWIN__ */ |
| 558 | 572 | ||
| 559 | # if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */ | 573 | # if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */ |
| 560 | # define LDAV_DONE | 574 | # define LDAV_DONE |
diff --git a/gl/getopt-cdefs.in.h b/gl/getopt-cdefs.in.h index a1d304d4..3a5d06be 100644 --- a/gl/getopt-cdefs.in.h +++ b/gl/getopt-cdefs.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* getopt-on-non-glibc compatibility macros. | 1 | /* getopt-on-non-glibc compatibility macros. |
| 2 | Copyright (C) 1989-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1989-2025 Free Software Foundation, Inc. |
| 3 | This file is part of gnulib. | 3 | This file is part of gnulib. |
| 4 | Unlike most of the getopt implementation, it is NOT shared | 4 | Unlike most of the getopt implementation, it is NOT shared |
| 5 | with the GNU C Library. | 5 | with the GNU C Library. |
| @@ -46,10 +46,14 @@ | |||
| 46 | # endif | 46 | # endif |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #if defined __clang__ | ||
| 50 | /* clang really only groks GNU C 4.2, regardless of its value of __GNUC__. */ | ||
| 51 | # undef __GNUC_PREREQ | ||
| 52 | # define __GNUC_PREREQ(maj, min) ((maj) < 4 + ((min) <= 2)) | ||
| 53 | #endif | ||
| 49 | #ifndef __GNUC_PREREQ | 54 | #ifndef __GNUC_PREREQ |
| 50 | # if defined __GNUC__ && defined __GNUC_VERSION__ | 55 | # if defined __GNUC__ && defined __GNUC_MINOR__ |
| 51 | # define __GNUC_PREREQ(maj, min) \ | 56 | # define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= __GNUC_MINOR__)) |
| 52 | ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) | ||
| 53 | # else | 57 | # else |
| 54 | # define __GNUC_PREREQ(maj, min) 0 | 58 | # define __GNUC_PREREQ(maj, min) 0 |
| 55 | # endif | 59 | # endif |
diff --git a/gl/getopt-core.h b/gl/getopt-core.h index 12d09a25..51ac213d 100644 --- a/gl/getopt-core.h +++ b/gl/getopt-core.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Declarations for getopt (basic, portable features only). | 1 | /* Declarations for getopt (basic, portable features only). |
| 2 | Copyright (C) 1989-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1989-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library and is also part of gnulib. | 3 | This file is part of the GNU C Library and is also part of gnulib. |
| 4 | Patches to this file should be submitted to both projects. | 4 | Patches to this file should be submitted to both projects. |
| 5 | 5 | ||
diff --git a/gl/getopt-ext.h b/gl/getopt-ext.h index e4b499d4..92b66a3b 100644 --- a/gl/getopt-ext.h +++ b/gl/getopt-ext.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Declarations for getopt (GNU extensions). | 1 | /* Declarations for getopt (GNU extensions). |
| 2 | Copyright (C) 1989-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1989-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library and is also part of gnulib. | 3 | This file is part of the GNU C Library and is also part of gnulib. |
| 4 | Patches to this file should be submitted to both projects. | 4 | Patches to this file should be submitted to both projects. |
| 5 | 5 | ||
diff --git a/gl/getopt-pfx-core.h b/gl/getopt-pfx-core.h index 78b7816a..7c5ea094 100644 --- a/gl/getopt-pfx-core.h +++ b/gl/getopt-pfx-core.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* getopt (basic, portable features) gnulib wrapper header. | 1 | /* getopt (basic, portable features) gnulib wrapper header. |
| 2 | Copyright (C) 1989-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1989-2025 Free Software Foundation, Inc. |
| 3 | This file is part of gnulib. | 3 | This file is part of gnulib. |
| 4 | Unlike most of the getopt implementation, it is NOT shared | 4 | Unlike most of the getopt implementation, it is NOT shared |
| 5 | with the GNU C Library. | 5 | with the GNU C Library. |
| @@ -31,6 +31,16 @@ | |||
| 31 | functions and variables. Renaming avoids problems with some | 31 | functions and variables. Renaming avoids problems with some |
| 32 | compilers and linkers. */ | 32 | compilers and linkers. */ |
| 33 | #ifdef __GETOPT_PREFIX | 33 | #ifdef __GETOPT_PREFIX |
| 34 | |||
| 35 | /* Include platform-dependent header files that may declare getopt() and | ||
| 36 | friends. */ | ||
| 37 | # if defined _AIX || defined __hpux || defined __sun || defined __QNX__ | ||
| 38 | # include <stdio.h> | ||
| 39 | # endif | ||
| 40 | # if defined MUSL_LIBC || (defined __FreeBSD__ || defined __DragonFly__) || defined __NetBSD__ || defined __OpenBSD__ || (defined __APPLE__ && defined __MACH__) || defined _AIX || defined __sun || defined __minix || defined __HAIKU__ | ||
| 41 | # include <unistd.h> | ||
| 42 | # endif | ||
| 43 | |||
| 34 | # ifndef __GETOPT_ID | 44 | # ifndef __GETOPT_ID |
| 35 | # define __GETOPT_CONCAT(x, y) x ## y | 45 | # define __GETOPT_CONCAT(x, y) x ## y |
| 36 | # define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) | 46 | # define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) |
diff --git a/gl/getopt-pfx-ext.h b/gl/getopt-pfx-ext.h index f001c11e..a61c68c7 100644 --- a/gl/getopt-pfx-ext.h +++ b/gl/getopt-pfx-ext.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* getopt (GNU extensions) gnulib wrapper header. | 1 | /* getopt (GNU extensions) gnulib wrapper header. |
| 2 | Copyright (C) 1989-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1989-2025 Free Software Foundation, Inc. |
| 3 | This file is part of gnulib. | 3 | This file is part of gnulib. |
| 4 | Unlike most of the getopt implementation, it is NOT shared | 4 | Unlike most of the getopt implementation, it is NOT shared |
| 5 | with the GNU C Library. | 5 | with the GNU C Library. |
| @@ -38,11 +38,9 @@ | |||
| 38 | # endif | 38 | # endif |
| 39 | # undef getopt_long | 39 | # undef getopt_long |
| 40 | # undef getopt_long_only | 40 | # undef getopt_long_only |
| 41 | # undef option | ||
| 42 | # undef _getopt_internal | 41 | # undef _getopt_internal |
| 43 | # define getopt_long __GETOPT_ID (getopt_long) | 42 | # define getopt_long __GETOPT_ID (getopt_long) |
| 44 | # define getopt_long_only __GETOPT_ID (getopt_long_only) | 43 | # define getopt_long_only __GETOPT_ID (getopt_long_only) |
| 45 | # define option __GETOPT_ID (option) | ||
| 46 | # define _getopt_internal __GETOPT_ID (getopt_internal) | 44 | # define _getopt_internal __GETOPT_ID (getopt_internal) |
| 47 | 45 | ||
| 48 | /* The system's getopt.h may have already included getopt-ext.h to | 46 | /* The system's getopt.h may have already included getopt-ext.h to |
diff --git a/gl/getopt.c b/gl/getopt.c index f66f119e..6b155e6c 100644 --- a/gl/getopt.c +++ b/gl/getopt.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Getopt for GNU. | 1 | /* Getopt for GNU. |
| 2 | Copyright (C) 1987-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1987-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library and is also part of gnulib. | 3 | This file is part of the GNU C Library and is also part of gnulib. |
| 4 | Patches to this file should be submitted to both projects. | 4 | Patches to this file should be submitted to both projects. |
| 5 | 5 | ||
| @@ -42,7 +42,7 @@ | |||
| 42 | # define funlockfile(fp) _IO_funlockfile (fp) | 42 | # define funlockfile(fp) _IO_funlockfile (fp) |
| 43 | #else | 43 | #else |
| 44 | # include "gettext.h" | 44 | # include "gettext.h" |
| 45 | # define _(msgid) gettext (msgid) | 45 | # define _(msgid) dgettext ("gnulib", msgid) |
| 46 | /* When used standalone, flockfile and funlockfile might not be | 46 | /* When used standalone, flockfile and funlockfile might not be |
| 47 | available. */ | 47 | available. */ |
| 48 | # if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \ | 48 | # if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \ |
| @@ -723,7 +723,7 @@ _getopt_internal (int argc, char **argv, const char *optstring, | |||
| 723 | return result; | 723 | return result; |
| 724 | } | 724 | } |
| 725 | 725 | ||
| 726 | /* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt. | 726 | /* glibc gets a LSB-compliant getopt and a POSIX-compliant __posix_getopt. |
| 727 | Standalone applications just get a POSIX-compliant getopt. | 727 | Standalone applications just get a POSIX-compliant getopt. |
| 728 | POSIX and LSB both require these functions to take 'char *const *argv' | 728 | POSIX and LSB both require these functions to take 'char *const *argv' |
| 729 | even though this is incorrect (because of the permutation). */ | 729 | even though this is incorrect (because of the permutation). */ |
| @@ -732,7 +732,7 @@ _getopt_internal (int argc, char **argv, const char *optstring, | |||
| 732 | NAME (int argc, char *const *argv, const char *optstring) \ | 732 | NAME (int argc, char *const *argv, const char *optstring) \ |
| 733 | { \ | 733 | { \ |
| 734 | return _getopt_internal (argc, (char **)argv, optstring, \ | 734 | return _getopt_internal (argc, (char **)argv, optstring, \ |
| 735 | 0, 0, 0, POSIXLY_CORRECT); \ | 735 | NULL, NULL, 0, POSIXLY_CORRECT); \ |
| 736 | } | 736 | } |
| 737 | 737 | ||
| 738 | #ifdef _LIBC | 738 | #ifdef _LIBC |
diff --git a/gl/getopt.in.h b/gl/getopt.in.h index c2411a75..4a87a2d5 100644 --- a/gl/getopt.in.h +++ b/gl/getopt.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Declarations for getopt. | 1 | /* Declarations for getopt. |
| 2 | Copyright (C) 1989-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1989-2025 Free Software Foundation, Inc. |
| 3 | This file is part of gnulib. | 3 | This file is part of gnulib. |
| 4 | Unlike most of the getopt implementation, it is NOT shared | 4 | Unlike most of the getopt implementation, it is NOT shared |
| 5 | with the GNU C Library, which supplies a different version of | 5 | with the GNU C Library, which supplies a different version of |
| @@ -30,7 +30,12 @@ | |||
| 30 | <getopt.h>; our definitions will be present soon enough. */ | 30 | <getopt.h>; our definitions will be present soon enough. */ |
| 31 | #if @HAVE_GETOPT_H@ | 31 | #if @HAVE_GETOPT_H@ |
| 32 | # define _GL_SYSTEM_GETOPT | 32 | # define _GL_SYSTEM_GETOPT |
| 33 | /* Rename the system's 'struct option' to 'struct sys_option', | ||
| 34 | so that we don't have to rename ours to 'struct rpl_option' | ||
| 35 | (which would cause significant trouble in C++ mode). */ | ||
| 36 | # define option sys_option | ||
| 33 | # @INCLUDE_NEXT@ @NEXT_GETOPT_H@ | 37 | # @INCLUDE_NEXT@ @NEXT_GETOPT_H@ |
| 38 | # undef option | ||
| 34 | # undef _GL_SYSTEM_GETOPT | 39 | # undef _GL_SYSTEM_GETOPT |
| 35 | #endif | 40 | #endif |
| 36 | 41 | ||
diff --git a/gl/getopt1.c b/gl/getopt1.c index c42d29f8..c8566845 100644 --- a/gl/getopt1.c +++ b/gl/getopt1.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* getopt_long and getopt_long_only entry points for GNU getopt. | 1 | /* getopt_long and getopt_long_only entry points for GNU getopt. |
| 2 | Copyright (C) 1987-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1987-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library and is also part of gnulib. | 3 | This file is part of the GNU C Library and is also part of gnulib. |
| 4 | Patches to this file should be submitted to both projects. | 4 | Patches to this file should be submitted to both projects. |
| 5 | 5 | ||
diff --git a/gl/getopt_int.h b/gl/getopt_int.h index c00c0b69..94c1945c 100644 --- a/gl/getopt_int.h +++ b/gl/getopt_int.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Internal declarations for getopt. | 1 | /* Internal declarations for getopt. |
| 2 | Copyright (C) 1989-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1989-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library and is also part of gnulib. | 3 | This file is part of the GNU C Library and is also part of gnulib. |
| 4 | Patches to this file should be submitted to both projects. | 4 | Patches to this file should be submitted to both projects. |
| 5 | 5 | ||
diff --git a/gl/getprogname.c b/gl/getprogname.c index 392a9a2f..4fe7c90d 100644 --- a/gl/getprogname.c +++ b/gl/getprogname.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Program name management. | 1 | /* Program name management. |
| 2 | Copyright (C) 2016-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2016-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify | 4 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as published by | 5 | it under the terms of the GNU Lesser General Public License as published by |
diff --git a/gl/getprogname.h b/gl/getprogname.h index bee1c1a2..ee9bb286 100644 --- a/gl/getprogname.h +++ b/gl/getprogname.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Program name management. | 1 | /* Program name management. |
| 2 | Copyright (C) 2016-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2016-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify | 4 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as published by | 5 | it under the terms of the GNU Lesser General Public License as published by |
diff --git a/gl/gettext.h b/gl/gettext.h index 39d5ae4d..0650abc9 100644 --- a/gl/gettext.h +++ b/gl/gettext.h | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* Convenience header for conditional use of GNU <libintl.h>. | 1 | /* Convenience header for conditional use of GNU <libintl.h>. |
| 2 | Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2024 Free Software | 2 | Copyright (C) 1995-2025 Free Software Foundation, Inc. |
| 3 | Foundation, Inc. | ||
| 4 | 3 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -18,6 +17,7 @@ | |||
| 18 | #ifndef _LIBGETTEXT_H | 17 | #ifndef _LIBGETTEXT_H |
| 19 | #define _LIBGETTEXT_H 1 | 18 | #define _LIBGETTEXT_H 1 |
| 20 | 19 | ||
| 20 | |||
| 21 | /* NLS can be disabled through the configure --disable-nls option | 21 | /* NLS can be disabled through the configure --disable-nls option |
| 22 | or through "#define ENABLE NLS 0" before including this file. */ | 22 | or through "#define ENABLE NLS 0" before including this file. */ |
| 23 | #if defined ENABLE_NLS && ENABLE_NLS | 23 | #if defined ENABLE_NLS && ENABLE_NLS |
| @@ -45,32 +45,90 @@ | |||
| 45 | as well because people using "gettext.h" will not include <libintl.h>, | 45 | as well because people using "gettext.h" will not include <libintl.h>, |
| 46 | and also including <libintl.h> would fail on SunOS 4, whereas <locale.h> | 46 | and also including <libintl.h> would fail on SunOS 4, whereas <locale.h> |
| 47 | is OK. */ | 47 | is OK. */ |
| 48 | #if defined(__sun) | 48 | # if defined(__sun) |
| 49 | # include <locale.h> | 49 | # include <locale.h> |
| 50 | #endif | 50 | # endif |
| 51 | 51 | ||
| 52 | /* Many header files from the libstdc++ coming with g++ 3.3 or newer include | 52 | /* Many header files from the libstdc++ coming with g++ 3.3 or newer include |
| 53 | <libintl.h>, which chokes if dcgettext is defined as a macro. So include | 53 | <libintl.h>, which chokes if dcgettext is defined as a macro. So include |
| 54 | it now, to make later inclusions of <libintl.h> a NOP. */ | 54 | it now, to make later inclusions of <libintl.h> a NOP. */ |
| 55 | #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) | 55 | # if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) |
| 56 | # include <cstdlib> | 56 | # include <cstdlib> |
| 57 | # if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H | 57 | # if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H |
| 58 | # include <libintl.h> | 58 | # include <libintl.h> |
| 59 | # endif | ||
| 59 | # endif | 60 | # endif |
| 60 | #endif | ||
| 61 | 61 | ||
| 62 | /* Disabled NLS. | 62 | /* Disabled NLS. */ |
| 63 | The casts to 'const char *' serve the purpose of producing warnings | 63 | # if defined __GNUC__ && !defined __clang__ && !defined __cplusplus |
| 64 | for invalid uses of the value returned from these functions. | 64 | /* Use inline functions, to avoid warnings |
| 65 | On pre-ANSI systems without 'const', the config.h file is supposed to | 65 | warning: format not a string literal and no format arguments |
| 66 | contain "#define const". */ | 66 | that don't occur with enabled NLS. */ |
| 67 | # undef gettext | 67 | /* The return type 'const char *' serves the purpose of producing warnings |
| 68 | # define gettext(Msgid) ((const char *) (Msgid)) | 68 | for invalid uses of the value returned from these functions. */ |
| 69 | # undef dgettext | 69 | # if __GNUC__ >= 9 |
| 70 | # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) | 70 | # pragma GCC diagnostic push |
| 71 | # undef dcgettext | 71 | # pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" |
| 72 | # define dcgettext(Domainname, Msgid, Category) \ | 72 | # endif |
| 73 | ((void) (Category), dgettext (Domainname, Msgid)) | 73 | # if __GNUC__ + (__GNUC_MINOR__ >= 2) > 4 |
| 74 | __attribute__ ((__always_inline__, __gnu_inline__)) | ||
| 75 | # else | ||
| 76 | __attribute__ ((__always_inline__)) | ||
| 77 | # endif | ||
| 78 | extern inline | ||
| 79 | # if !defined(__sun) | ||
| 80 | const | ||
| 81 | # endif | ||
| 82 | char * | ||
| 83 | gettext (const char *msgid) | ||
| 84 | { | ||
| 85 | return msgid; | ||
| 86 | } | ||
| 87 | # if __GNUC__ + (__GNUC_MINOR__ >= 2) > 4 | ||
| 88 | __attribute__ ((__always_inline__, __gnu_inline__)) | ||
| 89 | # else | ||
| 90 | __attribute__ ((__always_inline__)) | ||
| 91 | # endif | ||
| 92 | extern inline | ||
| 93 | # if !defined(__sun) | ||
| 94 | const | ||
| 95 | # endif | ||
| 96 | char * | ||
| 97 | dgettext (const char *domain, const char *msgid) | ||
| 98 | { | ||
| 99 | (void) domain; | ||
| 100 | return msgid; | ||
| 101 | } | ||
| 102 | # if __GNUC__ + (__GNUC_MINOR__ >= 2) > 4 | ||
| 103 | __attribute__ ((__always_inline__, __gnu_inline__)) | ||
| 104 | # else | ||
| 105 | __attribute__ ((__always_inline__)) | ||
| 106 | # endif | ||
| 107 | extern inline | ||
| 108 | # if !defined(__sun) | ||
| 109 | const | ||
| 110 | # endif | ||
| 111 | char * | ||
| 112 | dcgettext (const char *domain, const char *msgid, int category) | ||
| 113 | { | ||
| 114 | (void) domain; | ||
| 115 | (void) category; | ||
| 116 | return msgid; | ||
| 117 | } | ||
| 118 | # if __GNUC__ >= 9 | ||
| 119 | # pragma GCC diagnostic pop | ||
| 120 | # endif | ||
| 121 | # else | ||
| 122 | /* The casts to 'const char *' serve the purpose of producing warnings | ||
| 123 | for invalid uses of the value returned from these functions. */ | ||
| 124 | # undef gettext | ||
| 125 | # define gettext(Msgid) ((const char *) (Msgid)) | ||
| 126 | # undef dgettext | ||
| 127 | # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) | ||
| 128 | # undef dcgettext | ||
| 129 | # define dcgettext(Domainname, Msgid, Category) \ | ||
| 130 | ((void) (Category), dgettext (Domainname, Msgid)) | ||
| 131 | # endif | ||
| 74 | # undef ngettext | 132 | # undef ngettext |
| 75 | # define ngettext(Msgid1, Msgid2, N) \ | 133 | # define ngettext(Msgid1, Msgid2, N) \ |
| 76 | ((N) == 1 \ | 134 | ((N) == 1 \ |
| @@ -93,12 +151,14 @@ | |||
| 93 | 151 | ||
| 94 | #endif | 152 | #endif |
| 95 | 153 | ||
| 154 | |||
| 96 | /* Prefer gnulib's setlocale override over libintl's setlocale override. */ | 155 | /* Prefer gnulib's setlocale override over libintl's setlocale override. */ |
| 97 | #ifdef GNULIB_defined_setlocale | 156 | #ifdef GNULIB_defined_setlocale |
| 98 | # undef setlocale | 157 | # undef setlocale |
| 99 | # define setlocale rpl_setlocale | 158 | # define setlocale rpl_setlocale |
| 100 | #endif | 159 | #endif |
| 101 | 160 | ||
| 161 | |||
| 102 | /* A pseudo function call that serves as a marker for the automated | 162 | /* A pseudo function call that serves as a marker for the automated |
| 103 | extraction of messages, but does not call gettext(). The run-time | 163 | extraction of messages, but does not call gettext(). The run-time |
| 104 | translation is done at a different place in the code. | 164 | translation is done at a different place in the code. |
| @@ -108,6 +168,7 @@ | |||
| 108 | initializer for static 'char[]' or 'const char[]' variables. */ | 168 | initializer for static 'char[]' or 'const char[]' variables. */ |
| 109 | #define gettext_noop(String) String | 169 | #define gettext_noop(String) String |
| 110 | 170 | ||
| 171 | |||
| 111 | /* The separator between msgctxt and msgid in a .mo file. */ | 172 | /* The separator between msgctxt and msgid in a .mo file. */ |
| 112 | #define GETTEXT_CONTEXT_GLUE "\004" | 173 | #define GETTEXT_CONTEXT_GLUE "\004" |
| 113 | 174 | ||
| @@ -115,6 +176,9 @@ | |||
| 115 | MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be | 176 | MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be |
| 116 | short and rarely need to change. | 177 | short and rarely need to change. |
| 117 | The letter 'p' stands for 'particular' or 'special'. */ | 178 | The letter 'p' stands for 'particular' or 'special'. */ |
| 179 | |||
| 180 | #include <locale.h> /* for LC_MESSAGES */ | ||
| 181 | |||
| 118 | #ifdef DEFAULT_TEXT_DOMAIN | 182 | #ifdef DEFAULT_TEXT_DOMAIN |
| 119 | # define pgettext(Msgctxt, Msgid) \ | 183 | # define pgettext(Msgctxt, Msgid) \ |
| 120 | pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) | 184 | pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) |
| @@ -178,11 +242,12 @@ npgettext_aux (const char *domain, | |||
| 178 | return translation; | 242 | return translation; |
| 179 | } | 243 | } |
| 180 | 244 | ||
| 245 | |||
| 181 | /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID | 246 | /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID |
| 182 | can be arbitrary expressions. But for string literals these macros are | 247 | can be arbitrary expressions. But for string literals these macros are |
| 183 | less efficient than those above. */ | 248 | less efficient than those above. */ |
| 184 | 249 | ||
| 185 | #include <string.h> | 250 | #include <string.h> /* for memcpy */ |
| 186 | 251 | ||
| 187 | /* GNULIB_NO_VLA can be defined to disable use of VLAs even if supported. | 252 | /* GNULIB_NO_VLA can be defined to disable use of VLAs even if supported. |
| 188 | This relates to the -Wvla and -Wvla-larger-than warnings, enabled in | 253 | This relates to the -Wvla and -Wvla-larger-than warnings, enabled in |
| @@ -199,7 +264,7 @@ npgettext_aux (const char *domain, | |||
| 199 | #endif | 264 | #endif |
| 200 | 265 | ||
| 201 | #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS | 266 | #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS |
| 202 | #include <stdlib.h> | 267 | # include <stdlib.h> /* for malloc, free */ |
| 203 | #endif | 268 | #endif |
| 204 | 269 | ||
| 205 | #define pgettext_expr(Msgctxt, Msgid) \ | 270 | #define pgettext_expr(Msgctxt, Msgid) \ |
| @@ -297,4 +362,5 @@ dcnpgettext_expr (const char *domain, | |||
| 297 | return (n == 1 ? msgid : msgid_plural); | 362 | return (n == 1 ? msgid : msgid_plural); |
| 298 | } | 363 | } |
| 299 | 364 | ||
| 365 | |||
| 300 | #endif /* _LIBGETTEXT_H */ | 366 | #endif /* _LIBGETTEXT_H */ |
diff --git a/gl/gl_openssl.h b/gl/gl_openssl.h index 06864732..dea70c1c 100644 --- a/gl/gl_openssl.h +++ b/gl/gl_openssl.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Wrap openssl crypto hash routines in gnulib interface. -*- coding: utf-8 -*- | 1 | /* Wrap openssl crypto hash routines in gnulib interface. -*- coding: utf-8 -*- |
| 2 | 2 | ||
| 3 | Copyright (C) 2013-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2013-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/glthread/lock.c b/gl/glthread/lock.c index 6661ad6a..dace4fda 100644 --- a/gl/glthread/lock.c +++ b/gl/glthread/lock.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Locking in multithreaded situations. | 1 | /* Locking in multithreaded situations. |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -240,8 +240,6 @@ glthread_recursive_lock_destroy (gl_recursive_lock_t *lock) | |||
| 240 | return 0; | 240 | return 0; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 244 | |||
| 245 | #endif | 243 | #endif |
| 246 | 244 | ||
| 247 | /* ========================================================================= */ | 245 | /* ========================================================================= */ |
| @@ -271,7 +269,7 @@ glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock) | |||
| 271 | /* Note: PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP is the only value that | 269 | /* Note: PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP is the only value that |
| 272 | causes the writer to be preferred. PTHREAD_RWLOCK_PREFER_WRITER_NP does not | 270 | causes the writer to be preferred. PTHREAD_RWLOCK_PREFER_WRITER_NP does not |
| 273 | do this; see | 271 | do this; see |
| 274 | http://man7.org/linux/man-pages/man3/pthread_rwlockattr_setkind_np.3.html */ | 272 | https://man7.org/linux/man-pages/man3/pthread_rwlockattr_setkind_np.3.html */ |
| 275 | err = pthread_rwlockattr_setkind_np (&attributes, | 273 | err = pthread_rwlockattr_setkind_np (&attributes, |
| 276 | PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); | 274 | PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); |
| 277 | if (err == 0) | 275 | if (err == 0) |
| @@ -698,46 +696,6 @@ glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock) | |||
| 698 | 696 | ||
| 699 | # endif | 697 | # endif |
| 700 | 698 | ||
| 701 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 702 | |||
| 703 | static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT; | ||
| 704 | |||
| 705 | int | ||
| 706 | glthread_once_singlethreaded (pthread_once_t *once_control) | ||
| 707 | { | ||
| 708 | /* We don't know whether pthread_once_t is an integer type, a floating-point | ||
| 709 | type, a pointer type, or a structure type. */ | ||
| 710 | char *firstbyte = (char *)once_control; | ||
| 711 | if (*firstbyte == *(const char *)&fresh_once) | ||
| 712 | { | ||
| 713 | /* First time use of once_control. Invert the first byte. */ | ||
| 714 | *firstbyte = ~ *(const char *)&fresh_once; | ||
| 715 | return 1; | ||
| 716 | } | ||
| 717 | else | ||
| 718 | return 0; | ||
| 719 | } | ||
| 720 | |||
| 721 | # if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) | ||
| 722 | |||
| 723 | int | ||
| 724 | glthread_once_multithreaded (pthread_once_t *once_control, | ||
| 725 | void (*init_function) (void)) | ||
| 726 | { | ||
| 727 | int err = pthread_once (once_control, init_function); | ||
| 728 | if (err == ENOSYS) | ||
| 729 | { | ||
| 730 | /* This happens on FreeBSD 11: The pthread_once function in libc returns | ||
| 731 | ENOSYS. */ | ||
| 732 | if (glthread_once_singlethreaded (once_control)) | ||
| 733 | init_function (); | ||
| 734 | return 0; | ||
| 735 | } | ||
| 736 | return err; | ||
| 737 | } | ||
| 738 | |||
| 739 | # endif | ||
| 740 | |||
| 741 | #endif | 699 | #endif |
| 742 | 700 | ||
| 743 | /* ========================================================================= */ | 701 | /* ========================================================================= */ |
diff --git a/gl/glthread/lock.h b/gl/glthread/lock.h index 2d5cb320..d6ccc202 100644 --- a/gl/glthread/lock.h +++ b/gl/glthread/lock.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Locking in multithreaded situations. | 1 | /* Locking in multithreaded situations. |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -64,13 +64,6 @@ | |||
| 64 | Taking the lock: err = glthread_recursive_lock_lock (&name); | 64 | Taking the lock: err = glthread_recursive_lock_lock (&name); |
| 65 | Releasing the lock: err = glthread_recursive_lock_unlock (&name); | 65 | Releasing the lock: err = glthread_recursive_lock_unlock (&name); |
| 66 | De-initialization: err = glthread_recursive_lock_destroy (&name); | 66 | De-initialization: err = glthread_recursive_lock_destroy (&name); |
| 67 | |||
| 68 | Once-only execution: | ||
| 69 | Type: gl_once_t | ||
| 70 | Initializer: gl_once_define(extern, name) | ||
| 71 | Execution: gl_once (name, initfunction); | ||
| 72 | Equivalent functions with control of error handling: | ||
| 73 | Execution: err = glthread_once (&name, initfunction); | ||
| 74 | */ | 67 | */ |
| 75 | 68 | ||
| 76 | 69 | ||
| @@ -88,17 +81,9 @@ | |||
| 88 | #include <errno.h> | 81 | #include <errno.h> |
| 89 | #include <stdlib.h> | 82 | #include <stdlib.h> |
| 90 | 83 | ||
| 91 | #if !defined c11_threads_in_use | 84 | #include "glthread/once.h" |
| 92 | # if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC | 85 | |
| 93 | # define c11_threads_in_use() 1 | 86 | /* c11_threads_in_use() is defined in glthread/once.h. */ |
| 94 | # elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK | ||
| 95 | # include <threads.h> | ||
| 96 | # pragma weak thrd_exit | ||
| 97 | # define c11_threads_in_use() (thrd_exit != NULL) | ||
| 98 | # else | ||
| 99 | # define c11_threads_in_use() 0 | ||
| 100 | # endif | ||
| 101 | #endif | ||
| 102 | 87 | ||
| 103 | /* ========================================================================= */ | 88 | /* ========================================================================= */ |
| 104 | 89 | ||
| @@ -195,14 +180,6 @@ extern int glthread_recursive_lock_lock (gl_recursive_lock_t *lock); | |||
| 195 | extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); | 180 | extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); |
| 196 | extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); | 181 | extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); |
| 197 | 182 | ||
| 198 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 199 | |||
| 200 | typedef once_flag gl_once_t; | ||
| 201 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 202 | STORAGECLASS once_flag NAME = ONCE_FLAG_INIT; | ||
| 203 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 204 | (call_once (ONCE_CONTROL, INITFUNCTION), 0) | ||
| 205 | |||
| 206 | # ifdef __cplusplus | 183 | # ifdef __cplusplus |
| 207 | } | 184 | } |
| 208 | # endif | 185 | # endif |
| @@ -221,80 +198,7 @@ typedef once_flag gl_once_t; | |||
| 221 | extern "C" { | 198 | extern "C" { |
| 222 | # endif | 199 | # endif |
| 223 | 200 | ||
| 224 | # if PTHREAD_IN_USE_DETECTION_HARD | 201 | /* pthread_in_use() is defined in glthread/once.h. */ |
| 225 | |||
| 226 | /* The pthread_in_use() detection needs to be done at runtime. */ | ||
| 227 | # define pthread_in_use() \ | ||
| 228 | glthread_in_use () | ||
| 229 | extern int glthread_in_use (void); | ||
| 230 | |||
| 231 | # endif | ||
| 232 | |||
| 233 | # if USE_POSIX_THREADS_WEAK | ||
| 234 | |||
| 235 | /* Use weak references to the POSIX threads library. */ | ||
| 236 | |||
| 237 | /* Weak references avoid dragging in external libraries if the other parts | ||
| 238 | of the program don't use them. Here we use them, because we don't want | ||
| 239 | every program that uses libintl to depend on libpthread. This assumes | ||
| 240 | that libpthread would not be loaded after libintl; i.e. if libintl is | ||
| 241 | loaded first, by an executable that does not depend on libpthread, and | ||
| 242 | then a module is dynamically loaded that depends on libpthread, libintl | ||
| 243 | will not be multithread-safe. */ | ||
| 244 | |||
| 245 | /* The way to test at runtime whether libpthread is present is to test | ||
| 246 | whether a function pointer's value, such as &pthread_mutex_init, is | ||
| 247 | non-NULL. However, some versions of GCC have a bug through which, in | ||
| 248 | PIC mode, &foo != NULL always evaluates to true if there is a direct | ||
| 249 | call to foo(...) in the same function. To avoid this, we test the | ||
| 250 | address of a function in libpthread that we don't use. */ | ||
| 251 | |||
| 252 | # pragma weak pthread_mutex_init | ||
| 253 | # pragma weak pthread_mutex_lock | ||
| 254 | # pragma weak pthread_mutex_unlock | ||
| 255 | # pragma weak pthread_mutex_destroy | ||
| 256 | # pragma weak pthread_rwlock_init | ||
| 257 | # pragma weak pthread_rwlock_rdlock | ||
| 258 | # pragma weak pthread_rwlock_wrlock | ||
| 259 | # pragma weak pthread_rwlock_unlock | ||
| 260 | # pragma weak pthread_rwlock_destroy | ||
| 261 | # pragma weak pthread_once | ||
| 262 | # pragma weak pthread_cond_init | ||
| 263 | # pragma weak pthread_cond_wait | ||
| 264 | # pragma weak pthread_cond_signal | ||
| 265 | # pragma weak pthread_cond_broadcast | ||
| 266 | # pragma weak pthread_cond_destroy | ||
| 267 | # pragma weak pthread_mutexattr_init | ||
| 268 | # pragma weak pthread_mutexattr_settype | ||
| 269 | # pragma weak pthread_mutexattr_destroy | ||
| 270 | # pragma weak pthread_rwlockattr_init | ||
| 271 | # if __GNU_LIBRARY__ > 1 | ||
| 272 | # pragma weak pthread_rwlockattr_setkind_np | ||
| 273 | # endif | ||
| 274 | # pragma weak pthread_rwlockattr_destroy | ||
| 275 | # ifndef pthread_self | ||
| 276 | # pragma weak pthread_self | ||
| 277 | # endif | ||
| 278 | |||
| 279 | # if !PTHREAD_IN_USE_DETECTION_HARD | ||
| 280 | /* Considering all platforms with USE_POSIX_THREADS_WEAK, only few symbols | ||
| 281 | can be used to determine whether libpthread is in use. These are: | ||
| 282 | pthread_mutexattr_gettype | ||
| 283 | pthread_rwlockattr_destroy | ||
| 284 | pthread_rwlockattr_init | ||
| 285 | */ | ||
| 286 | # pragma weak pthread_mutexattr_gettype | ||
| 287 | # define pthread_in_use() \ | ||
| 288 | (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) | ||
| 289 | # endif | ||
| 290 | |||
| 291 | # else | ||
| 292 | |||
| 293 | # if !PTHREAD_IN_USE_DETECTION_HARD | ||
| 294 | # define pthread_in_use() 1 | ||
| 295 | # endif | ||
| 296 | |||
| 297 | # endif | ||
| 298 | 202 | ||
| 299 | /* -------------------------- gl_lock_t datatype -------------------------- */ | 203 | /* -------------------------- gl_lock_t datatype -------------------------- */ |
| 300 | 204 | ||
| @@ -510,26 +414,6 @@ extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *l | |||
| 510 | 414 | ||
| 511 | # endif | 415 | # endif |
| 512 | 416 | ||
| 513 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 514 | |||
| 515 | typedef pthread_once_t gl_once_t; | ||
| 516 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 517 | STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; | ||
| 518 | # if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK | ||
| 519 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 520 | (pthread_in_use () \ | ||
| 521 | ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ | ||
| 522 | : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) | ||
| 523 | # else | ||
| 524 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 525 | (pthread_in_use () \ | ||
| 526 | ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ | ||
| 527 | : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) | ||
| 528 | extern int glthread_once_multithreaded (pthread_once_t *once_control, | ||
| 529 | void (*init_function) (void)); | ||
| 530 | # endif | ||
| 531 | extern int glthread_once_singlethreaded (pthread_once_t *once_control); | ||
| 532 | |||
| 533 | # ifdef __cplusplus | 417 | # ifdef __cplusplus |
| 534 | } | 418 | } |
| 535 | # endif | 419 | # endif |
| @@ -546,7 +430,6 @@ extern int glthread_once_singlethreaded (pthread_once_t *once_control); | |||
| 546 | # include "windows-mutex.h" | 430 | # include "windows-mutex.h" |
| 547 | # include "windows-rwlock.h" | 431 | # include "windows-rwlock.h" |
| 548 | # include "windows-recmutex.h" | 432 | # include "windows-recmutex.h" |
| 549 | # include "windows-once.h" | ||
| 550 | 433 | ||
| 551 | # ifdef __cplusplus | 434 | # ifdef __cplusplus |
| 552 | extern "C" { | 435 | extern "C" { |
| @@ -619,14 +502,6 @@ typedef glwthread_recmutex_t gl_recursive_lock_t; | |||
| 619 | # define glthread_recursive_lock_destroy(LOCK) \ | 502 | # define glthread_recursive_lock_destroy(LOCK) \ |
| 620 | glwthread_recmutex_destroy (LOCK) | 503 | glwthread_recmutex_destroy (LOCK) |
| 621 | 504 | ||
| 622 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 623 | |||
| 624 | typedef glwthread_once_t gl_once_t; | ||
| 625 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 626 | STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT; | ||
| 627 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 628 | (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0) | ||
| 629 | |||
| 630 | # ifdef __cplusplus | 505 | # ifdef __cplusplus |
| 631 | } | 506 | } |
| 632 | # endif | 507 | # endif |
| @@ -670,14 +545,6 @@ typedef int gl_recursive_lock_t; | |||
| 670 | # define glthread_recursive_lock_unlock(NAME) 0 | 545 | # define glthread_recursive_lock_unlock(NAME) 0 |
| 671 | # define glthread_recursive_lock_destroy(NAME) 0 | 546 | # define glthread_recursive_lock_destroy(NAME) 0 |
| 672 | 547 | ||
| 673 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 674 | |||
| 675 | typedef int gl_once_t; | ||
| 676 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 677 | STORAGECLASS gl_once_t NAME = 0; | ||
| 678 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 679 | (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0) | ||
| 680 | |||
| 681 | #endif | 548 | #endif |
| 682 | 549 | ||
| 683 | /* ========================================================================= */ | 550 | /* ========================================================================= */ |
| @@ -784,16 +651,6 @@ typedef int gl_once_t; | |||
| 784 | } \ | 651 | } \ |
| 785 | while (0) | 652 | while (0) |
| 786 | 653 | ||
| 787 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 788 | |||
| 789 | #define gl_once(NAME, INITFUNCTION) \ | ||
| 790 | do \ | ||
| 791 | { \ | ||
| 792 | if (glthread_once (&NAME, INITFUNCTION)) \ | ||
| 793 | abort (); \ | ||
| 794 | } \ | ||
| 795 | while (0) | ||
| 796 | |||
| 797 | /* ========================================================================= */ | 654 | /* ========================================================================= */ |
| 798 | 655 | ||
| 799 | #endif /* _LOCK_H */ | 656 | #endif /* _LOCK_H */ |
diff --git a/gl/glthread/once.c b/gl/glthread/once.c new file mode 100644 index 00000000..53211af8 --- /dev/null +++ b/gl/glthread/once.c | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | /* Once-only initialization in multithreaded situations. | ||
| 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, 2005. | ||
| 18 | Based on GCC's gthr-posix.h, gthr-posix95.h. */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | |||
| 22 | #include "glthread/once.h" | ||
| 23 | |||
| 24 | /* ========================================================================= */ | ||
| 25 | |||
| 26 | #if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS | ||
| 27 | |||
| 28 | #endif | ||
| 29 | |||
| 30 | /* ========================================================================= */ | ||
| 31 | |||
| 32 | #if USE_POSIX_THREADS | ||
| 33 | |||
| 34 | static const pthread_once_t fresh_once = PTHREAD_ONCE_INIT; | ||
| 35 | |||
| 36 | int | ||
| 37 | glthread_once_singlethreaded (pthread_once_t *once_control) | ||
| 38 | { | ||
| 39 | /* We don't know whether pthread_once_t is an integer type, a floating-point | ||
| 40 | type, a pointer type, or a structure type. */ | ||
| 41 | char *firstbyte = (char *)once_control; | ||
| 42 | if (*firstbyte == *(const char *)&fresh_once) | ||
| 43 | { | ||
| 44 | /* First time use of once_control. Invert the first byte. */ | ||
| 45 | *firstbyte = ~ *(const char *)&fresh_once; | ||
| 46 | return 1; | ||
| 47 | } | ||
| 48 | else | ||
| 49 | return 0; | ||
| 50 | } | ||
| 51 | |||
| 52 | # if !(PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK) | ||
| 53 | |||
| 54 | int | ||
| 55 | glthread_once_multithreaded (pthread_once_t *once_control, | ||
| 56 | void (*init_function) (void)) | ||
| 57 | { | ||
| 58 | int err = pthread_once (once_control, init_function); | ||
| 59 | if (err == ENOSYS) | ||
| 60 | { | ||
| 61 | /* This happens on FreeBSD 11: The pthread_once function in libc returns | ||
| 62 | ENOSYS. */ | ||
| 63 | if (glthread_once_singlethreaded (once_control)) | ||
| 64 | init_function (); | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | return err; | ||
| 68 | } | ||
| 69 | |||
| 70 | # endif | ||
| 71 | |||
| 72 | #endif | ||
| 73 | |||
| 74 | /* ========================================================================= */ | ||
| 75 | |||
| 76 | #if USE_WINDOWS_THREADS | ||
| 77 | |||
| 78 | #endif | ||
| 79 | |||
| 80 | /* ========================================================================= */ | ||
diff --git a/gl/glthread/once.h b/gl/glthread/once.h new file mode 100644 index 00000000..943bd7a2 --- /dev/null +++ b/gl/glthread/once.h | |||
| @@ -0,0 +1,272 @@ | |||
| 1 | /* Once-only initialization in multithreaded situations. | ||
| 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, 2005. | ||
| 18 | Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h. */ | ||
| 19 | |||
| 20 | /* This file contains once-only initialization primitives for use with a given | ||
| 21 | thread library. | ||
| 22 | It does not contain primitives for creating threads or for other | ||
| 23 | synchronization primitives. | ||
| 24 | |||
| 25 | Once-only execution: | ||
| 26 | Type: gl_once_t | ||
| 27 | Initializer: gl_once_define(extern, name) | ||
| 28 | Execution: gl_once (name, initfunction); | ||
| 29 | Equivalent functions with control of error handling: | ||
| 30 | Execution: err = glthread_once (&name, initfunction); | ||
| 31 | */ | ||
| 32 | |||
| 33 | |||
| 34 | #ifndef _ONCE_H | ||
| 35 | #define _ONCE_H | ||
| 36 | |||
| 37 | /* This file uses HAVE_THREADS_H. */ | ||
| 38 | #if !_GL_CONFIG_H_INCLUDED | ||
| 39 | #error "Please include config.h first." | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #include <errno.h> | ||
| 43 | #include <stdlib.h> | ||
| 44 | |||
| 45 | #if !defined c11_threads_in_use | ||
| 46 | # if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC | ||
| 47 | # define c11_threads_in_use() 1 | ||
| 48 | # elif HAVE_THREADS_H && USE_POSIX_THREADS_WEAK | ||
| 49 | # include <threads.h> | ||
| 50 | # pragma weak thrd_exit | ||
| 51 | # define c11_threads_in_use() (thrd_exit != NULL) | ||
| 52 | # else | ||
| 53 | # define c11_threads_in_use() 0 | ||
| 54 | # endif | ||
| 55 | #endif | ||
| 56 | |||
| 57 | /* ========================================================================= */ | ||
| 58 | |||
| 59 | #if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS | ||
| 60 | |||
| 61 | /* Use the ISO C threads library. */ | ||
| 62 | |||
| 63 | # include <threads.h> | ||
| 64 | |||
| 65 | # ifdef __cplusplus | ||
| 66 | extern "C" { | ||
| 67 | # endif | ||
| 68 | |||
| 69 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 70 | |||
| 71 | typedef once_flag gl_once_t; | ||
| 72 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 73 | STORAGECLASS once_flag NAME = ONCE_FLAG_INIT; | ||
| 74 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 75 | (call_once (ONCE_CONTROL, INITFUNCTION), 0) | ||
| 76 | |||
| 77 | # ifdef __cplusplus | ||
| 78 | } | ||
| 79 | # endif | ||
| 80 | |||
| 81 | #endif | ||
| 82 | |||
| 83 | /* ========================================================================= */ | ||
| 84 | |||
| 85 | #if USE_POSIX_THREADS | ||
| 86 | |||
| 87 | /* Use the POSIX threads library. */ | ||
| 88 | |||
| 89 | # include <pthread.h> | ||
| 90 | |||
| 91 | # ifdef __cplusplus | ||
| 92 | extern "C" { | ||
| 93 | # endif | ||
| 94 | |||
| 95 | # if PTHREAD_IN_USE_DETECTION_HARD | ||
| 96 | |||
| 97 | /* The pthread_in_use() detection needs to be done at runtime. */ | ||
| 98 | # define pthread_in_use() \ | ||
| 99 | glthread_in_use () | ||
| 100 | extern int glthread_in_use (void); | ||
| 101 | |||
| 102 | # endif | ||
| 103 | |||
| 104 | # if USE_POSIX_THREADS_WEAK | ||
| 105 | |||
| 106 | /* Use weak references to the POSIX threads library. */ | ||
| 107 | |||
| 108 | /* Weak references avoid dragging in external libraries if the other parts | ||
| 109 | of the program don't use them. Here we use them, because we don't want | ||
| 110 | every program that uses libintl to depend on libpthread. This assumes | ||
| 111 | that libpthread would not be loaded after libintl; i.e. if libintl is | ||
| 112 | loaded first, by an executable that does not depend on libpthread, and | ||
| 113 | then a module is dynamically loaded that depends on libpthread, libintl | ||
| 114 | will not be multithread-safe. */ | ||
| 115 | |||
| 116 | /* The way to test at runtime whether libpthread is present is to test | ||
| 117 | whether a function pointer's value, such as &pthread_mutex_init, is | ||
| 118 | non-NULL. However, some versions of GCC have a bug through which, in | ||
| 119 | PIC mode, &foo != NULL always evaluates to true if there is a direct | ||
| 120 | call to foo(...) in the same function. To avoid this, we test the | ||
| 121 | address of a function in libpthread that we don't use. */ | ||
| 122 | |||
| 123 | # pragma weak pthread_mutex_init | ||
| 124 | # pragma weak pthread_mutex_lock | ||
| 125 | # pragma weak pthread_mutex_unlock | ||
| 126 | # pragma weak pthread_mutex_destroy | ||
| 127 | /* Work around clang bug <https://github.com/llvm/llvm-project/issues/104670> */ | ||
| 128 | # ifndef pthread_rwlock_init | ||
| 129 | # pragma weak pthread_rwlock_init | ||
| 130 | # endif | ||
| 131 | # pragma weak pthread_rwlock_rdlock | ||
| 132 | # pragma weak pthread_rwlock_wrlock | ||
| 133 | # pragma weak pthread_rwlock_unlock | ||
| 134 | # pragma weak pthread_rwlock_destroy | ||
| 135 | # pragma weak pthread_once | ||
| 136 | # pragma weak pthread_cond_init | ||
| 137 | # pragma weak pthread_cond_wait | ||
| 138 | # pragma weak pthread_cond_signal | ||
| 139 | # pragma weak pthread_cond_broadcast | ||
| 140 | # pragma weak pthread_cond_destroy | ||
| 141 | # pragma weak pthread_mutexattr_init | ||
| 142 | # pragma weak pthread_mutexattr_settype | ||
| 143 | # pragma weak pthread_mutexattr_destroy | ||
| 144 | /* Work around clang bug <https://github.com/llvm/llvm-project/issues/104670> */ | ||
| 145 | # ifndef pthread_rwlockattr_init | ||
| 146 | # pragma weak pthread_rwlockattr_init | ||
| 147 | # endif | ||
| 148 | # if __GNU_LIBRARY__ > 1 | ||
| 149 | # pragma weak pthread_rwlockattr_setkind_np | ||
| 150 | # endif | ||
| 151 | # pragma weak pthread_rwlockattr_destroy | ||
| 152 | # ifndef pthread_self | ||
| 153 | # pragma weak pthread_self | ||
| 154 | # endif | ||
| 155 | |||
| 156 | # if !PTHREAD_IN_USE_DETECTION_HARD | ||
| 157 | /* Considering all platforms with USE_POSIX_THREADS_WEAK, only few symbols | ||
| 158 | can be used to determine whether libpthread is in use. These are: | ||
| 159 | pthread_mutexattr_gettype | ||
| 160 | pthread_rwlockattr_destroy | ||
| 161 | pthread_rwlockattr_init | ||
| 162 | */ | ||
| 163 | # pragma weak pthread_mutexattr_gettype | ||
| 164 | # define pthread_in_use() \ | ||
| 165 | (pthread_mutexattr_gettype != NULL || c11_threads_in_use ()) | ||
| 166 | # endif | ||
| 167 | |||
| 168 | # else | ||
| 169 | |||
| 170 | # if !PTHREAD_IN_USE_DETECTION_HARD | ||
| 171 | # define pthread_in_use() 1 | ||
| 172 | # endif | ||
| 173 | |||
| 174 | # endif | ||
| 175 | |||
| 176 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 177 | |||
| 178 | typedef pthread_once_t gl_once_t; | ||
| 179 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 180 | STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; | ||
| 181 | # if PTHREAD_IN_USE_DETECTION_HARD || USE_POSIX_THREADS_WEAK | ||
| 182 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 183 | (pthread_in_use () \ | ||
| 184 | ? pthread_once (ONCE_CONTROL, INITFUNCTION) \ | ||
| 185 | : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) | ||
| 186 | # else | ||
| 187 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 188 | (pthread_in_use () \ | ||
| 189 | ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION) \ | ||
| 190 | : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0)) | ||
| 191 | extern int glthread_once_multithreaded (pthread_once_t *once_control, | ||
| 192 | void (*init_function) (void)); | ||
| 193 | # endif | ||
| 194 | extern int glthread_once_singlethreaded (pthread_once_t *once_control); | ||
| 195 | |||
| 196 | # ifdef __cplusplus | ||
| 197 | } | ||
| 198 | # endif | ||
| 199 | |||
| 200 | #endif | ||
| 201 | |||
| 202 | /* ========================================================================= */ | ||
| 203 | |||
| 204 | #if USE_WINDOWS_THREADS | ||
| 205 | |||
| 206 | # define WIN32_LEAN_AND_MEAN /* avoid including junk */ | ||
| 207 | # include <windows.h> | ||
| 208 | |||
| 209 | # include "windows-once.h" | ||
| 210 | |||
| 211 | # ifdef __cplusplus | ||
| 212 | extern "C" { | ||
| 213 | # endif | ||
| 214 | |||
| 215 | /* We can use CRITICAL_SECTION directly, rather than the native Windows Event, | ||
| 216 | Mutex, Semaphore types, because | ||
| 217 | - we need only to synchronize inside a single process (address space), | ||
| 218 | not inter-process locking, | ||
| 219 | - we don't need to support trylock operations. (TryEnterCriticalSection | ||
| 220 | does not work on Windows 95/98/ME. Packages that need trylock usually | ||
| 221 | define their own mutex type.) */ | ||
| 222 | |||
| 223 | /* There is no way to statically initialize a CRITICAL_SECTION. It needs | ||
| 224 | to be done lazily, once only. For this we need spinlocks. */ | ||
| 225 | |||
| 226 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 227 | |||
| 228 | typedef glwthread_once_t gl_once_t; | ||
| 229 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 230 | STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT; | ||
| 231 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 232 | (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0) | ||
| 233 | |||
| 234 | # ifdef __cplusplus | ||
| 235 | } | ||
| 236 | # endif | ||
| 237 | |||
| 238 | #endif | ||
| 239 | |||
| 240 | /* ========================================================================= */ | ||
| 241 | |||
| 242 | #if !(USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS) | ||
| 243 | |||
| 244 | /* Provide dummy implementation if threads are not supported. */ | ||
| 245 | |||
| 246 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 247 | |||
| 248 | typedef int gl_once_t; | ||
| 249 | # define gl_once_define(STORAGECLASS, NAME) \ | ||
| 250 | STORAGECLASS gl_once_t NAME = 0; | ||
| 251 | # define glthread_once(ONCE_CONTROL, INITFUNCTION) \ | ||
| 252 | (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0) | ||
| 253 | |||
| 254 | #endif | ||
| 255 | |||
| 256 | /* ========================================================================= */ | ||
| 257 | |||
| 258 | /* Macros with built-in error handling. */ | ||
| 259 | |||
| 260 | /* -------------------------- gl_once_t datatype -------------------------- */ | ||
| 261 | |||
| 262 | #define gl_once(NAME, INITFUNCTION) \ | ||
| 263 | do \ | ||
| 264 | { \ | ||
| 265 | if (glthread_once (&NAME, INITFUNCTION)) \ | ||
| 266 | abort (); \ | ||
| 267 | } \ | ||
| 268 | while (0) | ||
| 269 | |||
| 270 | /* ========================================================================= */ | ||
| 271 | |||
| 272 | #endif /* _ONCE_H */ | ||
diff --git a/gl/glthread/threadlib.c b/gl/glthread/threadlib.c index 7a776768..a6f7688b 100644 --- a/gl/glthread/threadlib.c +++ b/gl/glthread/threadlib.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Multithreading primitives. | 1 | /* Multithreading primitives. |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/hard-locale.c b/gl/hard-locale.c index 653c5809..767906d1 100644 --- a/gl/hard-locale.c +++ b/gl/hard-locale.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* hard-locale.c -- Determine whether a locale is hard. | 1 | /* hard-locale.c -- Determine whether a locale is hard. |
| 2 | 2 | ||
| 3 | Copyright (C) 1997-1999, 2002-2004, 2006-2007, 2009-2024 Free Software | 3 | Copyright (C) 1997-1999, 2002-2004, 2006-2007, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/hard-locale.h b/gl/hard-locale.h index 5d40e522..29808da6 100644 --- a/gl/hard-locale.h +++ b/gl/hard-locale.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Determine whether a locale is hard. | 1 | /* Determine whether a locale is hard. |
| 2 | 2 | ||
| 3 | Copyright (C) 1999, 2003-2004, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1999, 2003-2004, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/ialloc.c b/gl/ialloc.c index 8564a15b..881c8f04 100644 --- a/gl/ialloc.c +++ b/gl/ialloc.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* malloc with idx_t rather than size_t | 1 | /* malloc with idx_t rather than size_t |
| 2 | 2 | ||
| 3 | Copyright 2021-2024 Free Software Foundation, Inc. | 3 | Copyright 2021-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/ialloc.h b/gl/ialloc.h index 2aa94ae7..8bf5dd12 100644 --- a/gl/ialloc.h +++ b/gl/ialloc.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* ialloc.h -- malloc with idx_t rather than size_t | 1 | /* ialloc.h -- malloc with idx_t rather than size_t |
| 2 | 2 | ||
| 3 | Copyright 2021-2024 Free Software Foundation, Inc. | 3 | Copyright 2021-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -29,9 +29,6 @@ | |||
| 29 | #include <errno.h> | 29 | #include <errno.h> |
| 30 | #include <stdint.h> | 30 | #include <stdint.h> |
| 31 | #include <stdlib.h> | 31 | #include <stdlib.h> |
| 32 | #if defined __CHERI_PURE_CAPABILITY__ | ||
| 33 | # include <cheri.h> | ||
| 34 | #endif | ||
| 35 | 32 | ||
| 36 | _GL_INLINE_HEADER_BEGIN | 33 | _GL_INLINE_HEADER_BEGIN |
| 37 | #ifndef IALLOC_INLINE | 34 | #ifndef IALLOC_INLINE |
| @@ -68,19 +65,7 @@ IALLOC_INLINE | |||
| 68 | void * | 65 | void * |
| 69 | irealloc (void *p, idx_t s) | 66 | irealloc (void *p, idx_t s) |
| 70 | { | 67 | { |
| 71 | if (s <= SIZE_MAX) | 68 | return s <= SIZE_MAX ? realloc (p, s) : _gl_alloc_nomem (); |
| 72 | { | ||
| 73 | /* Work around GNU realloc glitch by treating a zero size as if it | ||
| 74 | were 1, so that returning NULL is equivalent to failing. */ | ||
| 75 | p = realloc (p, s | !s); | ||
| 76 | #if defined __CHERI_PURE_CAPABILITY__ | ||
| 77 | if (p != NULL) | ||
| 78 | p = cheri_bounds_set (p, s); | ||
| 79 | #endif | ||
| 80 | return p; | ||
| 81 | } | ||
| 82 | else | ||
| 83 | return _gl_alloc_nomem (); | ||
| 84 | } | 69 | } |
| 85 | 70 | ||
| 86 | /* icalloc (num, size) is like calloc (num, size). | 71 | /* icalloc (num, size) is like calloc (num, size). |
| @@ -112,23 +97,9 @@ icalloc (idx_t n, idx_t s) | |||
| 112 | IALLOC_INLINE void * | 97 | IALLOC_INLINE void * |
| 113 | ireallocarray (void *p, idx_t n, idx_t s) | 98 | ireallocarray (void *p, idx_t n, idx_t s) |
| 114 | { | 99 | { |
| 115 | if (n <= SIZE_MAX && s <= SIZE_MAX) | 100 | return (n <= SIZE_MAX && s <= SIZE_MAX |
| 116 | { | 101 | ? reallocarray (p, n, s) |
| 117 | /* Work around GNU reallocarray glitch by treating a zero size as if | 102 | : _gl_alloc_nomem ()); |
| 118 | it were 1, so that returning NULL is equivalent to failing. */ | ||
| 119 | size_t nx = n; | ||
| 120 | size_t sx = s; | ||
| 121 | if (n == 0 || s == 0) | ||
| 122 | nx = sx = 1; | ||
| 123 | p = reallocarray (p, nx, sx); | ||
| 124 | #if defined __CHERI_PURE_CAPABILITY__ | ||
| 125 | if (p != NULL && (n == 0 || s == 0)) | ||
| 126 | p = cheri_bounds_set (p, 0); | ||
| 127 | #endif | ||
| 128 | return p; | ||
| 129 | } | ||
| 130 | else | ||
| 131 | return _gl_alloc_nomem (); | ||
| 132 | } | 103 | } |
| 133 | 104 | ||
| 134 | #ifdef __cplusplus | 105 | #ifdef __cplusplus |
diff --git a/gl/idpriv-droptemp.c b/gl/idpriv-droptemp.c index eb882dea..ecaab836 100644 --- a/gl/idpriv-droptemp.c +++ b/gl/idpriv-droptemp.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Dropping uid/gid privileges of the current process temporarily. | 1 | /* Dropping uid/gid privileges of the current process temporarily. |
| 2 | Copyright (C) 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify | 4 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
| @@ -25,18 +25,18 @@ | |||
| 25 | 25 | ||
| 26 | /* The privileged uid and gid that the process had earlier. */ | 26 | /* The privileged uid and gid that the process had earlier. */ |
| 27 | #if HAVE_GETUID | 27 | #if HAVE_GETUID |
| 28 | static int saved_uid = -1; | 28 | static uid_t saved_uid = -1; |
| 29 | #endif | 29 | #endif |
| 30 | #if HAVE_GETGID | 30 | #if HAVE_GETGID |
| 31 | static int saved_gid = -1; | 31 | static gid_t saved_gid = -1; |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | int | 34 | int |
| 35 | idpriv_temp_drop (void) | 35 | idpriv_temp_drop (void) |
| 36 | { | 36 | { |
| 37 | #if HAVE_GETEUID && HAVE_GETEGID && (HAVE_SETRESUID || HAVE_SETREUID) && (HAVE_SETRESGID || HAVE_SETREGID) | 37 | #if HAVE_GETEUID && HAVE_GETEGID && (HAVE_SETRESUID || HAVE_SETREUID) && (HAVE_SETRESGID || HAVE_SETREGID) |
| 38 | int uid = getuid (); | 38 | uid_t uid = getuid (); |
| 39 | int gid = getgid (); | 39 | gid_t gid = getgid (); |
| 40 | 40 | ||
| 41 | /* Find out about the privileged uid and gid at the first call. */ | 41 | /* Find out about the privileged uid and gid at the first call. */ |
| 42 | if (saved_uid == -1) | 42 | if (saved_uid == -1) |
| @@ -124,8 +124,8 @@ int | |||
| 124 | idpriv_temp_restore (void) | 124 | idpriv_temp_restore (void) |
| 125 | { | 125 | { |
| 126 | #if HAVE_GETEUID && HAVE_GETEGID && (HAVE_SETRESUID || HAVE_SETREUID) && (HAVE_SETRESGID || HAVE_SETREGID) | 126 | #if HAVE_GETEUID && HAVE_GETEGID && (HAVE_SETRESUID || HAVE_SETREUID) && (HAVE_SETRESGID || HAVE_SETREGID) |
| 127 | int uid = getuid (); | 127 | uid_t uid = getuid (); |
| 128 | int gid = getgid (); | 128 | gid_t gid = getgid (); |
| 129 | 129 | ||
| 130 | if (saved_uid == -1 || saved_gid == -1) | 130 | if (saved_uid == -1 || saved_gid == -1) |
| 131 | /* Caller error: idpriv_temp_drop was never invoked. */ | 131 | /* Caller error: idpriv_temp_drop was never invoked. */ |
diff --git a/gl/idpriv.h b/gl/idpriv.h index a3ae5926..f4f8158e 100644 --- a/gl/idpriv.h +++ b/gl/idpriv.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Dropping uid/gid privileges of the current process. | 1 | /* Dropping uid/gid privileges of the current process. |
| 2 | Copyright (C) 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify | 4 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* A type for indices and sizes. | 1 | /* A type for indices and sizes. |
| 2 | Copyright (C) 2020-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
diff --git a/gl/inet_ntop.c b/gl/inet_ntop.c index 0a4ba20e..df3d9512 100644 --- a/gl/inet_ntop.c +++ b/gl/inet_ntop.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* inet_ntop.c -- convert IPv4 and IPv6 addresses from binary to text form | 1 | /* inet_ntop.c -- convert IPv4 and IPv6 addresses from binary to text form |
| 2 | 2 | ||
| 3 | Copyright (C) 2005-2006, 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2005-2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -117,7 +117,7 @@ inet_ntop (int af, const void *restrict src, | |||
| 117 | * 'dst' (as a const) | 117 | * 'dst' (as a const) |
| 118 | * notes: | 118 | * notes: |
| 119 | * (1) uses no statics | 119 | * (1) uses no statics |
| 120 | * (2) takes a u_char* not an in_addr as input | 120 | * (2) takes a 'unsigned char *' not an in_addr as input |
| 121 | * author: | 121 | * author: |
| 122 | * Paul Vixie, 1996. | 122 | * Paul Vixie, 1996. |
| 123 | */ | 123 | */ |
diff --git a/gl/inet_pton.c b/gl/inet_pton.c new file mode 100644 index 00000000..74d55c43 --- /dev/null +++ b/gl/inet_pton.c | |||
| @@ -0,0 +1,268 @@ | |||
| 1 | /* inet_pton.c -- convert IPv4 and IPv6 addresses from text to binary form | ||
| 2 | |||
| 3 | Copyright (C) 2006, 2008-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * Copyright (c) 1996,1999 by Internet Software Consortium. | ||
| 20 | * | ||
| 21 | * Permission to use, copy, modify, and distribute this software for any | ||
| 22 | * purpose with or without fee is hereby granted, provided that the above | ||
| 23 | * copyright notice and this permission notice appear in all copies. | ||
| 24 | * | ||
| 25 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||
| 26 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||
| 27 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||
| 28 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
| 29 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
| 30 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
| 31 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
| 32 | * SOFTWARE. | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include <config.h> | ||
| 36 | |||
| 37 | /* Specification. */ | ||
| 38 | #include <arpa/inet.h> | ||
| 39 | |||
| 40 | #if HAVE_DECL_INET_PTON | ||
| 41 | |||
| 42 | # undef inet_pton | ||
| 43 | |||
| 44 | int | ||
| 45 | rpl_inet_pton (int af, const char *restrict src, void *restrict dst) | ||
| 46 | { | ||
| 47 | return inet_pton (af, src, dst); | ||
| 48 | } | ||
| 49 | |||
| 50 | #else | ||
| 51 | |||
| 52 | # include <c-ctype.h> | ||
| 53 | # include <string.h> | ||
| 54 | # include <errno.h> | ||
| 55 | |||
| 56 | # define NS_INADDRSZ 4 | ||
| 57 | # define NS_IN6ADDRSZ 16 | ||
| 58 | # define NS_INT16SZ 2 | ||
| 59 | |||
| 60 | /* | ||
| 61 | * WARNING: Don't even consider trying to compile this on a system where | ||
| 62 | * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. | ||
| 63 | */ | ||
| 64 | |||
| 65 | static int inet_pton4 (const char *src, unsigned char *dst); | ||
| 66 | # if HAVE_IPV6 | ||
| 67 | static int inet_pton6 (const char *src, unsigned char *dst); | ||
| 68 | # endif | ||
| 69 | |||
| 70 | /* int | ||
| 71 | * inet_pton(af, src, dst) | ||
| 72 | * convert from presentation format (which usually means ASCII printable) | ||
| 73 | * to network format (which is usually some kind of binary format). | ||
| 74 | * return: | ||
| 75 | * 1 if the address was valid for the specified address family | ||
| 76 | * 0 if the address wasn't valid ('dst' is untouched in this case) | ||
| 77 | * -1 if some other error occurred ('dst' is untouched in this case, too) | ||
| 78 | * author: | ||
| 79 | * Paul Vixie, 1996. | ||
| 80 | */ | ||
| 81 | int | ||
| 82 | inet_pton (int af, const char *restrict src, void *restrict dst) | ||
| 83 | { | ||
| 84 | switch (af) | ||
| 85 | { | ||
| 86 | case AF_INET: | ||
| 87 | return (inet_pton4 (src, dst)); | ||
| 88 | |||
| 89 | # if HAVE_IPV6 | ||
| 90 | case AF_INET6: | ||
| 91 | return (inet_pton6 (src, dst)); | ||
| 92 | # endif | ||
| 93 | |||
| 94 | default: | ||
| 95 | errno = EAFNOSUPPORT; | ||
| 96 | return (-1); | ||
| 97 | } | ||
| 98 | /* NOTREACHED */ | ||
| 99 | } | ||
| 100 | |||
| 101 | /* int | ||
| 102 | * inet_pton4(src, dst) | ||
| 103 | * like inet_aton() but without all the hexadecimal, octal (with the | ||
| 104 | * exception of 0) and shorthand. | ||
| 105 | * return: | ||
| 106 | * 1 if 'src' is a valid dotted quad, else 0. | ||
| 107 | * notice: | ||
| 108 | * does not touch 'dst' unless it's returning 1. | ||
| 109 | * author: | ||
| 110 | * Paul Vixie, 1996. | ||
| 111 | */ | ||
| 112 | static int | ||
| 113 | inet_pton4 (const char *restrict src, unsigned char *restrict dst) | ||
| 114 | { | ||
| 115 | int saw_digit, octets, ch; | ||
| 116 | unsigned char tmp[NS_INADDRSZ], *tp; | ||
| 117 | |||
| 118 | saw_digit = 0; | ||
| 119 | octets = 0; | ||
| 120 | *(tp = tmp) = 0; | ||
| 121 | while ((ch = *src++) != '\0') | ||
| 122 | { | ||
| 123 | |||
| 124 | if (ch >= '0' && ch <= '9') | ||
| 125 | { | ||
| 126 | unsigned new = *tp * 10 + (ch - '0'); | ||
| 127 | |||
| 128 | if (saw_digit && *tp == 0) | ||
| 129 | return (0); | ||
| 130 | if (new > 255) | ||
| 131 | return (0); | ||
| 132 | *tp = new; | ||
| 133 | if (!saw_digit) | ||
| 134 | { | ||
| 135 | if (++octets > 4) | ||
| 136 | return (0); | ||
| 137 | saw_digit = 1; | ||
| 138 | } | ||
| 139 | } | ||
| 140 | else if (ch == '.' && saw_digit) | ||
| 141 | { | ||
| 142 | if (octets == 4) | ||
| 143 | return (0); | ||
| 144 | *++tp = 0; | ||
| 145 | saw_digit = 0; | ||
| 146 | } | ||
| 147 | else | ||
| 148 | return (0); | ||
| 149 | } | ||
| 150 | if (octets < 4) | ||
| 151 | return (0); | ||
| 152 | memcpy (dst, tmp, NS_INADDRSZ); | ||
| 153 | return (1); | ||
| 154 | } | ||
| 155 | |||
| 156 | # if HAVE_IPV6 | ||
| 157 | |||
| 158 | /* int | ||
| 159 | * inet_pton6(src, dst) | ||
| 160 | * convert presentation level address to network order binary form. | ||
| 161 | * return: | ||
| 162 | * 1 if 'src' is a valid [RFC1884 2.2] address, else 0. | ||
| 163 | * notice: | ||
| 164 | * (1) does not touch 'dst' unless it's returning 1. | ||
| 165 | * (2) :: in a full address is silently ignored. | ||
| 166 | * credit: | ||
| 167 | * inspired by Mark Andrews. | ||
| 168 | * author: | ||
| 169 | * Paul Vixie, 1996. | ||
| 170 | */ | ||
| 171 | static int | ||
| 172 | inet_pton6 (const char *restrict src, unsigned char *restrict dst) | ||
| 173 | { | ||
| 174 | static const char xdigits[] = "0123456789abcdef"; | ||
| 175 | unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; | ||
| 176 | const char *curtok; | ||
| 177 | int ch, saw_xdigit; | ||
| 178 | unsigned val; | ||
| 179 | |||
| 180 | tp = memset (tmp, '\0', NS_IN6ADDRSZ); | ||
| 181 | endp = tp + NS_IN6ADDRSZ; | ||
| 182 | colonp = NULL; | ||
| 183 | /* Leading :: requires some special handling. */ | ||
| 184 | if (*src == ':') | ||
| 185 | if (*++src != ':') | ||
| 186 | return (0); | ||
| 187 | curtok = src; | ||
| 188 | saw_xdigit = 0; | ||
| 189 | val = 0; | ||
| 190 | while ((ch = c_tolower (*src++)) != '\0') | ||
| 191 | { | ||
| 192 | const char *pch; | ||
| 193 | |||
| 194 | pch = strchr (xdigits, ch); | ||
| 195 | if (pch != NULL) | ||
| 196 | { | ||
| 197 | val <<= 4; | ||
| 198 | val |= (pch - xdigits); | ||
| 199 | if (val > 0xffff) | ||
| 200 | return (0); | ||
| 201 | saw_xdigit = 1; | ||
| 202 | continue; | ||
| 203 | } | ||
| 204 | if (ch == ':') | ||
| 205 | { | ||
| 206 | curtok = src; | ||
| 207 | if (!saw_xdigit) | ||
| 208 | { | ||
| 209 | if (colonp) | ||
| 210 | return (0); | ||
| 211 | colonp = tp; | ||
| 212 | continue; | ||
| 213 | } | ||
| 214 | else if (*src == '\0') | ||
| 215 | { | ||
| 216 | return (0); | ||
| 217 | } | ||
| 218 | if (tp + NS_INT16SZ > endp) | ||
| 219 | return (0); | ||
| 220 | *tp++ = (unsigned char) (val >> 8) & 0xff; | ||
| 221 | *tp++ = (unsigned char) val & 0xff; | ||
| 222 | saw_xdigit = 0; | ||
| 223 | val = 0; | ||
| 224 | continue; | ||
| 225 | } | ||
| 226 | if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && | ||
| 227 | inet_pton4 (curtok, tp) > 0) | ||
| 228 | { | ||
| 229 | tp += NS_INADDRSZ; | ||
| 230 | saw_xdigit = 0; | ||
| 231 | break; /* '\0' was seen by inet_pton4(). */ | ||
| 232 | } | ||
| 233 | return (0); | ||
| 234 | } | ||
| 235 | if (saw_xdigit) | ||
| 236 | { | ||
| 237 | if (tp + NS_INT16SZ > endp) | ||
| 238 | return (0); | ||
| 239 | *tp++ = (unsigned char) (val >> 8) & 0xff; | ||
| 240 | *tp++ = (unsigned char) val & 0xff; | ||
| 241 | } | ||
| 242 | if (colonp != NULL) | ||
| 243 | { | ||
| 244 | /* | ||
| 245 | * Since some memmove()'s erroneously fail to handle | ||
| 246 | * overlapping regions, we'll do the shift by hand. | ||
| 247 | */ | ||
| 248 | const int n = tp - colonp; | ||
| 249 | int i; | ||
| 250 | |||
| 251 | if (tp == endp) | ||
| 252 | return (0); | ||
| 253 | for (i = 1; i <= n; i++) | ||
| 254 | { | ||
| 255 | endp[-i] = colonp[n - i]; | ||
| 256 | colonp[n - i] = 0; | ||
| 257 | } | ||
| 258 | tp = endp; | ||
| 259 | } | ||
| 260 | if (tp != endp) | ||
| 261 | return (0); | ||
| 262 | memcpy (dst, tmp, NS_IN6ADDRSZ); | ||
| 263 | return (1); | ||
| 264 | } | ||
| 265 | |||
| 266 | # endif | ||
| 267 | |||
| 268 | #endif | ||
diff --git a/gl/intprops-internal.h b/gl/intprops-internal.h index b5ba8d7c..7ace0cdd 100644 --- a/gl/intprops-internal.h +++ b/gl/intprops-internal.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* intprops-internal.h -- properties of integer types not visible to users | 1 | /* intprops-internal.h -- properties of integer types not visible to users |
| 2 | 2 | ||
| 3 | Copyright (C) 2001-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2001-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software: you can redistribute it and/or modify it | 5 | This program is free software: you can redistribute it and/or modify it |
| 6 | under the terms of the GNU Lesser General Public License as published | 6 | under the terms of the GNU Lesser General Public License as published |
| @@ -21,7 +21,7 @@ | |||
| 21 | #include <limits.h> | 21 | #include <limits.h> |
| 22 | 22 | ||
| 23 | /* Pacify GCC 13.2 in some calls to _GL_EXPR_SIGNED. */ | 23 | /* Pacify GCC 13.2 in some calls to _GL_EXPR_SIGNED. */ |
| 24 | #if defined __GNUC__ && 4 < __GNUC__ + (3 <= __GNUC_MINOR__) | 24 | #if 4 < __GNUC__ + (3 <= __GNUC_MINOR__) && !defined __clang__ |
| 25 | # pragma GCC diagnostic ignored "-Wtype-limits" | 25 | # pragma GCC diagnostic ignored "-Wtype-limits" |
| 26 | #endif | 26 | #endif |
| 27 | 27 | ||
| @@ -77,10 +77,11 @@ | |||
| 77 | 77 | ||
| 78 | /* Does the __typeof__ keyword work? This could be done by | 78 | /* Does the __typeof__ keyword work? This could be done by |
| 79 | 'configure', but for now it's easier to do it by hand. */ | 79 | 'configure', but for now it's easier to do it by hand. */ |
| 80 | #if (2 <= __GNUC__ \ | 80 | #if ((defined __GNUC__ && 2 <= __GNUC__) \ |
| 81 | || (4 <= __clang_major__) \ | 81 | || (defined __clang_major__ && 4 <= __clang_major__) \ |
| 82 | || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \ | 82 | || (defined __IBMC__ && 1210 <= __IBMC__ && defined __IBM__TYPEOF__) \ |
| 83 | || (0x5110 <= __SUNPRO_C && !__STDC__)) | 83 | || (defined __SUNPRO_C && 0x5110 <= __SUNPRO_C && !__STDC__) \ |
| 84 | || (defined _MSC_VER && 1939 <= _MSC_VER)) | ||
| 84 | # define _GL_HAVE___TYPEOF__ 1 | 85 | # define _GL_HAVE___TYPEOF__ 1 |
| 85 | #else | 86 | #else |
| 86 | # define _GL_HAVE___TYPEOF__ 0 | 87 | # define _GL_HAVE___TYPEOF__ 0 |
| @@ -119,8 +120,8 @@ | |||
| 119 | #endif | 120 | #endif |
| 120 | 121 | ||
| 121 | /* True if __builtin_mul_overflow (A, B, P) works when P is non-null. */ | 122 | /* True if __builtin_mul_overflow (A, B, P) works when P is non-null. */ |
| 122 | #if defined __clang_major__ && __clang_major__ < 14 | 123 | #if defined __clang_major__ && __clang_major__ < 21 |
| 123 | /* Work around Clang bug <https://bugs.llvm.org/show_bug.cgi?id=16404>. */ | 124 | /* Work around Clang bug <https://github.com/llvm/llvm-project/issues/16778>. */ |
| 124 | # define _GL_HAS_BUILTIN_MUL_OVERFLOW 0 | 125 | # define _GL_HAS_BUILTIN_MUL_OVERFLOW 0 |
| 125 | #else | 126 | #else |
| 126 | # define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW | 127 | # define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW |
| @@ -163,7 +164,7 @@ | |||
| 163 | #if _GL_HAS_BUILTIN_MUL_OVERFLOW | 164 | #if _GL_HAS_BUILTIN_MUL_OVERFLOW |
| 164 | # if ((9 < __GNUC__ + (3 <= __GNUC_MINOR__) \ | 165 | # if ((9 < __GNUC__ + (3 <= __GNUC_MINOR__) \ |
| 165 | || (__GNUC__ == 8 && 4 <= __GNUC_MINOR__)) \ | 166 | || (__GNUC__ == 8 && 4 <= __GNUC_MINOR__)) \ |
| 166 | && !defined __EDG__) | 167 | && !defined __clang__ && !defined __EDG__) |
| 167 | # define _GL_INT_MULTIPLY_WRAPV(a, b, r) __builtin_mul_overflow (a, b, r) | 168 | # define _GL_INT_MULTIPLY_WRAPV(a, b, r) __builtin_mul_overflow (a, b, r) |
| 168 | # else | 169 | # else |
| 169 | /* Work around GCC bug 91450. */ | 170 | /* Work around GCC bug 91450. */ |
| @@ -182,13 +183,13 @@ | |||
| 182 | _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW) | 183 | _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW) |
| 183 | #endif | 184 | #endif |
| 184 | 185 | ||
| 185 | /* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See: | 186 | /* Nonzero if this compiler has GCC bug 68193 or Clang bug 25764. See: |
| 186 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193 | 187 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193 |
| 187 | https://llvm.org/bugs/show_bug.cgi?id=25390 | 188 | https://github.com/llvm/llvm-project/issues/25764 |
| 188 | For now, assume all versions of GCC-like compilers generate bogus | 189 | For now, assume GCC < 14 and all Clang versions generate bogus |
| 189 | warnings for _Generic. This matters only for compilers that | 190 | warnings for _Generic. This matters only for compilers that |
| 190 | lack relevant builtins. */ | 191 | lack relevant builtins. */ |
| 191 | #if __GNUC__ || defined __clang__ | 192 | #if (__GNUC__ && __GNUC__ < 14) || defined __clang__ |
| 192 | # define _GL__GENERIC_BOGUS 1 | 193 | # define _GL__GENERIC_BOGUS 1 |
| 193 | #else | 194 | #else |
| 194 | # define _GL__GENERIC_BOGUS 0 | 195 | # define _GL__GENERIC_BOGUS 0 |
diff --git a/gl/intprops.h b/gl/intprops.h index 43734f34..2f9fa0a0 100644 --- a/gl/intprops.h +++ b/gl/intprops.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* intprops.h -- properties of integer types | 1 | /* intprops.h -- properties of integer types |
| 2 | 2 | ||
| 3 | Copyright (C) 2001-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2001-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software: you can redistribute it and/or modify it | 5 | This program is free software: you can redistribute it and/or modify it |
| 6 | under the terms of the GNU Lesser General Public License as published | 6 | under the terms of the GNU Lesser General Public License as published |
| @@ -34,6 +34,14 @@ | |||
| 34 | signed or floating type. Do not evaluate E. */ | 34 | signed or floating type. Do not evaluate E. */ |
| 35 | #define EXPR_SIGNED(e) _GL_EXPR_SIGNED (e) | 35 | #define EXPR_SIGNED(e) _GL_EXPR_SIGNED (e) |
| 36 | 36 | ||
| 37 | /* The same value as as the arithmetic expression E, but with E's type | ||
| 38 | after integer promotions. For example, if E is of type 'enum {A, B}' | ||
| 39 | then 'switch (INT_PROMOTE (E))' pacifies gcc -Wswitch-enum if some | ||
| 40 | enum values are deliberately omitted from the switch's cases. | ||
| 41 | Here, unary + is safer than a cast or inline function, as unary + | ||
| 42 | does only integer promotions and is disallowed on pointers. */ | ||
| 43 | #define INT_PROMOTE(e) (+ (e)) | ||
| 44 | |||
| 37 | 45 | ||
| 38 | /* Minimum and maximum values for integer types and expressions. */ | 46 | /* Minimum and maximum values for integer types and expressions. */ |
| 39 | 47 | ||
diff --git a/gl/inttypes.in.h b/gl/inttypes.in.h index b9ab8a4b..5520ebc5 100644 --- a/gl/inttypes.in.h +++ b/gl/inttypes.in.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 2006-2024 Free Software Foundation, Inc. | 1 | /* Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 2 | Written by Paul Eggert, Bruno Haible, Derek Price. | 2 | Written by Paul Eggert, Bruno Haible, Derek Price. |
| 3 | This file is part of gnulib. | 3 | This file is part of gnulib. |
| 4 | 4 | ||
| @@ -913,11 +913,11 @@ extern "C" { | |||
| 913 | # undef imaxabs | 913 | # undef imaxabs |
| 914 | # define imaxabs rpl_imaxabs | 914 | # define imaxabs rpl_imaxabs |
| 915 | # endif | 915 | # endif |
| 916 | _GL_FUNCDECL_RPL (imaxabs, intmax_t, (intmax_t x)); | 916 | _GL_FUNCDECL_RPL (imaxabs, intmax_t, (intmax_t x), ); |
| 917 | _GL_CXXALIAS_RPL (imaxabs, intmax_t, (intmax_t x)); | 917 | _GL_CXXALIAS_RPL (imaxabs, intmax_t, (intmax_t x)); |
| 918 | # else | 918 | # else |
| 919 | # if !@HAVE_DECL_IMAXABS@ | 919 | # if !@HAVE_DECL_IMAXABS@ |
| 920 | _GL_FUNCDECL_SYS (imaxabs, intmax_t, (intmax_t x)); | 920 | _GL_FUNCDECL_SYS (imaxabs, intmax_t, (intmax_t x), ); |
| 921 | # endif | 921 | # endif |
| 922 | _GL_CXXALIAS_SYS (imaxabs, intmax_t, (intmax_t x)); | 922 | _GL_CXXALIAS_SYS (imaxabs, intmax_t, (intmax_t x)); |
| 923 | # endif | 923 | # endif |
| @@ -944,11 +944,11 @@ typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t; | |||
| 944 | # undef imaxdiv | 944 | # undef imaxdiv |
| 945 | # define imaxdiv rpl_imaxdiv | 945 | # define imaxdiv rpl_imaxdiv |
| 946 | # endif | 946 | # endif |
| 947 | _GL_FUNCDECL_RPL (imaxdiv, imaxdiv_t, (intmax_t numer, intmax_t denom)); | 947 | _GL_FUNCDECL_RPL (imaxdiv, imaxdiv_t, (intmax_t numer, intmax_t denom), ); |
| 948 | _GL_CXXALIAS_RPL (imaxdiv, imaxdiv_t, (intmax_t numer, intmax_t denom)); | 948 | _GL_CXXALIAS_RPL (imaxdiv, imaxdiv_t, (intmax_t numer, intmax_t denom)); |
| 949 | # else | 949 | # else |
| 950 | # if !@HAVE_DECL_IMAXDIV@ | 950 | # if !@HAVE_DECL_IMAXDIV@ |
| 951 | _GL_FUNCDECL_SYS (imaxdiv, imaxdiv_t, (intmax_t numer, intmax_t denom)); | 951 | _GL_FUNCDECL_SYS (imaxdiv, imaxdiv_t, (intmax_t numer, intmax_t denom), ); |
| 952 | # endif | 952 | # endif |
| 953 | _GL_CXXALIAS_SYS (imaxdiv, imaxdiv_t, (intmax_t numer, intmax_t denom)); | 953 | _GL_CXXALIAS_SYS (imaxdiv, imaxdiv_t, (intmax_t numer, intmax_t denom)); |
| 954 | # endif | 954 | # endif |
| @@ -970,7 +970,7 @@ _GL_WARN_ON_USE (imaxdiv, "imaxdiv is unportable - " | |||
| 970 | # define strtoimax rpl_strtoimax | 970 | # define strtoimax rpl_strtoimax |
| 971 | # endif | 971 | # endif |
| 972 | _GL_FUNCDECL_RPL (strtoimax, intmax_t, | 972 | _GL_FUNCDECL_RPL (strtoimax, intmax_t, |
| 973 | (const char *restrict, char **restrict, int) | 973 | (const char *restrict, char **restrict, int), |
| 974 | _GL_ARG_NONNULL ((1))); | 974 | _GL_ARG_NONNULL ((1))); |
| 975 | _GL_CXXALIAS_RPL (strtoimax, intmax_t, | 975 | _GL_CXXALIAS_RPL (strtoimax, intmax_t, |
| 976 | (const char *restrict, char **restrict, int)); | 976 | (const char *restrict, char **restrict, int)); |
| @@ -978,7 +978,7 @@ _GL_CXXALIAS_RPL (strtoimax, intmax_t, | |||
| 978 | # if !@HAVE_DECL_STRTOIMAX@ | 978 | # if !@HAVE_DECL_STRTOIMAX@ |
| 979 | # undef strtoimax | 979 | # undef strtoimax |
| 980 | _GL_FUNCDECL_SYS (strtoimax, intmax_t, | 980 | _GL_FUNCDECL_SYS (strtoimax, intmax_t, |
| 981 | (const char *restrict, char **restrict, int) | 981 | (const char *restrict, char **restrict, int), |
| 982 | _GL_ARG_NONNULL ((1))); | 982 | _GL_ARG_NONNULL ((1))); |
| 983 | # endif | 983 | # endif |
| 984 | _GL_CXXALIAS_SYS (strtoimax, intmax_t, | 984 | _GL_CXXALIAS_SYS (strtoimax, intmax_t, |
| @@ -1000,7 +1000,7 @@ _GL_WARN_ON_USE (strtoimax, "strtoimax is unportable - " | |||
| 1000 | # define strtoumax rpl_strtoumax | 1000 | # define strtoumax rpl_strtoumax |
| 1001 | # endif | 1001 | # endif |
| 1002 | _GL_FUNCDECL_RPL (strtoumax, uintmax_t, | 1002 | _GL_FUNCDECL_RPL (strtoumax, uintmax_t, |
| 1003 | (const char *restrict, char **restrict, int) | 1003 | (const char *restrict, char **restrict, int), |
| 1004 | _GL_ARG_NONNULL ((1))); | 1004 | _GL_ARG_NONNULL ((1))); |
| 1005 | _GL_CXXALIAS_RPL (strtoumax, uintmax_t, | 1005 | _GL_CXXALIAS_RPL (strtoumax, uintmax_t, |
| 1006 | (const char *restrict, char **restrict, int)); | 1006 | (const char *restrict, char **restrict, int)); |
| @@ -1008,7 +1008,7 @@ _GL_CXXALIAS_RPL (strtoumax, uintmax_t, | |||
| 1008 | # if !@HAVE_DECL_STRTOUMAX@ | 1008 | # if !@HAVE_DECL_STRTOUMAX@ |
| 1009 | # undef strtoumax | 1009 | # undef strtoumax |
| 1010 | _GL_FUNCDECL_SYS (strtoumax, uintmax_t, | 1010 | _GL_FUNCDECL_SYS (strtoumax, uintmax_t, |
| 1011 | (const char *restrict, char **restrict, int) | 1011 | (const char *restrict, char **restrict, int), |
| 1012 | _GL_ARG_NONNULL ((1))); | 1012 | _GL_ARG_NONNULL ((1))); |
| 1013 | # endif | 1013 | # endif |
| 1014 | _GL_CXXALIAS_SYS (strtoumax, uintmax_t, | 1014 | _GL_CXXALIAS_SYS (strtoumax, uintmax_t, |
diff --git a/gl/iswblank.c b/gl/iswblank.c index f699850a..6e361f43 100644 --- a/gl/iswblank.c +++ b/gl/iswblank.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Test wide character for being blank. | 1 | /* Test wide character for being blank. |
| 2 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/iswctype-impl.h b/gl/iswctype-impl.h index 999f220c..c87e00ff 100644 --- a/gl/iswctype-impl.h +++ b/gl/iswctype-impl.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Test whether a wide character has a given property. | 1 | /* Test whether a wide character has a given property. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/iswctype.c b/gl/iswctype.c index f4e6f015..576e93e4 100644 --- a/gl/iswctype.c +++ b/gl/iswctype.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Test whether a wide character has a given property. | 1 | /* Test whether a wide character has a given property. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/iswdigit.c b/gl/iswdigit.c index 57363ab8..6bba487b 100644 --- a/gl/iswdigit.c +++ b/gl/iswdigit.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Test wide character for being a digit. | 1 | /* Test wide character for being a digit. |
| 2 | Copyright (C) 2020-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/iswpunct.c b/gl/iswpunct.c index c7cb28b5..2b9258a9 100644 --- a/gl/iswpunct.c +++ b/gl/iswpunct.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Test wide character for being a punctuation or symbol character. | 1 | /* Test wide character for being a punctuation or symbol character. |
| 2 | Copyright (C) 2023-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2023-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/iswxdigit.c b/gl/iswxdigit.c index d32e3b0f..e154ac80 100644 --- a/gl/iswxdigit.c +++ b/gl/iswxdigit.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Test wide character for being a hexadecimal digit. | 1 | /* Test wide character for being a hexadecimal digit. |
| 2 | Copyright (C) 2020-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Replacement for 'int' to 'long double' conversion routine. | 1 | /* Replacement for 'int' to 'long double' conversion routine. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/langinfo.in.h b/gl/langinfo.in.h index febbd25f..e16c95b3 100644 --- a/gl/langinfo.in.h +++ b/gl/langinfo.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Substitute for and wrapper around <langinfo.h>. | 1 | /* Substitute for and wrapper around <langinfo.h>. |
| 2 | Copyright (C) 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -115,6 +115,18 @@ typedef int nl_item; | |||
| 115 | # define ABMON_10 (ABMON_1 + 9) | 115 | # define ABMON_10 (ABMON_1 + 9) |
| 116 | # define ABMON_11 (ABMON_1 + 10) | 116 | # define ABMON_11 (ABMON_1 + 10) |
| 117 | # define ABMON_12 (ABMON_1 + 11) | 117 | # define ABMON_12 (ABMON_1 + 11) |
| 118 | # define ABALTMON_1 10220 | ||
| 119 | # define ABALTMON_2 (ABALTMON_1 + 1) | ||
| 120 | # define ABALTMON_3 (ABALTMON_1 + 2) | ||
| 121 | # define ABALTMON_4 (ABALTMON_1 + 3) | ||
| 122 | # define ABALTMON_5 (ABALTMON_1 + 4) | ||
| 123 | # define ABALTMON_6 (ABALTMON_1 + 5) | ||
| 124 | # define ABALTMON_7 (ABALTMON_1 + 6) | ||
| 125 | # define ABALTMON_8 (ABALTMON_1 + 7) | ||
| 126 | # define ABALTMON_9 (ABALTMON_1 + 8) | ||
| 127 | # define ABALTMON_10 (ABALTMON_1 + 9) | ||
| 128 | # define ABALTMON_11 (ABALTMON_1 + 10) | ||
| 129 | # define ABALTMON_12 (ABALTMON_1 + 11) | ||
| 118 | # define ERA 10047 | 130 | # define ERA 10047 |
| 119 | # define ERA_D_FMT 10048 | 131 | # define ERA_D_FMT 10048 |
| 120 | # define ERA_D_T_FMT 10049 | 132 | # define ERA_D_T_FMT 10049 |
| @@ -171,6 +183,37 @@ typedef int nl_item; | |||
| 171 | # define GNULIB_defined_ALTMON 1 | 183 | # define GNULIB_defined_ALTMON 1 |
| 172 | # endif | 184 | # endif |
| 173 | 185 | ||
| 186 | # if !@HAVE_LANGINFO_ABALTMON@ | ||
| 187 | # if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 27 | ||
| 188 | # define ABALTMON_1 _NL_ABALTMON_1 | ||
| 189 | # define ABALTMON_2 _NL_ABALTMON_2 | ||
| 190 | # define ABALTMON_3 _NL_ABALTMON_3 | ||
| 191 | # define ABALTMON_4 _NL_ABALTMON_4 | ||
| 192 | # define ABALTMON_5 _NL_ABALTMON_5 | ||
| 193 | # define ABALTMON_6 _NL_ABALTMON_6 | ||
| 194 | # define ABALTMON_7 _NL_ABALTMON_7 | ||
| 195 | # define ABALTMON_8 _NL_ABALTMON_8 | ||
| 196 | # define ABALTMON_9 _NL_ABALTMON_9 | ||
| 197 | # define ABALTMON_10 _NL_ABALTMON_10 | ||
| 198 | # define ABALTMON_11 _NL_ABALTMON_11 | ||
| 199 | # define ABALTMON_12 _NL_ABALTMON_12 | ||
| 200 | # else | ||
| 201 | # define ABALTMON_1 10220 | ||
| 202 | # define ABALTMON_2 (ABALTMON_1 + 1) | ||
| 203 | # define ABALTMON_3 (ABALTMON_1 + 2) | ||
| 204 | # define ABALTMON_4 (ABALTMON_1 + 3) | ||
| 205 | # define ABALTMON_5 (ABALTMON_1 + 4) | ||
| 206 | # define ABALTMON_6 (ABALTMON_1 + 5) | ||
| 207 | # define ABALTMON_7 (ABALTMON_1 + 6) | ||
| 208 | # define ABALTMON_8 (ABALTMON_1 + 7) | ||
| 209 | # define ABALTMON_9 (ABALTMON_1 + 8) | ||
| 210 | # define ABALTMON_10 (ABALTMON_1 + 9) | ||
| 211 | # define ABALTMON_11 (ABALTMON_1 + 10) | ||
| 212 | # define ABALTMON_12 (ABALTMON_1 + 11) | ||
| 213 | # define GNULIB_defined_ABALTMON 1 | ||
| 214 | # endif | ||
| 215 | # endif | ||
| 216 | |||
| 174 | # if !@HAVE_LANGINFO_ERA@ | 217 | # if !@HAVE_LANGINFO_ERA@ |
| 175 | # define ERA 10047 | 218 | # define ERA 10047 |
| 176 | # define ERA_D_FMT 10048 | 219 | # define ERA_D_FMT 10048 |
| @@ -205,11 +248,11 @@ typedef int nl_item; | |||
| 205 | # undef nl_langinfo | 248 | # undef nl_langinfo |
| 206 | # define nl_langinfo rpl_nl_langinfo | 249 | # define nl_langinfo rpl_nl_langinfo |
| 207 | # endif | 250 | # endif |
| 208 | _GL_FUNCDECL_RPL (nl_langinfo, char *, (nl_item item)); | 251 | _GL_FUNCDECL_RPL (nl_langinfo, char *, (nl_item item), ); |
| 209 | _GL_CXXALIAS_RPL (nl_langinfo, char *, (nl_item item)); | 252 | _GL_CXXALIAS_RPL (nl_langinfo, char *, (nl_item item)); |
| 210 | # else | 253 | # else |
| 211 | # if !@HAVE_NL_LANGINFO@ | 254 | # if !@HAVE_NL_LANGINFO@ |
| 212 | _GL_FUNCDECL_SYS (nl_langinfo, char *, (nl_item item)); | 255 | _GL_FUNCDECL_SYS (nl_langinfo, char *, (nl_item item), ); |
| 213 | # endif | 256 | # endif |
| 214 | _GL_CXXALIAS_SYS (nl_langinfo, char *, (nl_item item)); | 257 | _GL_CXXALIAS_SYS (nl_langinfo, char *, (nl_item item)); |
| 215 | # endif | 258 | # endif |
diff --git a/gl/lc-charset-dispatch.c b/gl/lc-charset-dispatch.c index e2f8b2f5..91ab6d72 100644 --- a/gl/lc-charset-dispatch.c +++ b/gl/lc-charset-dispatch.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Dispatching based on the current locale's character encoding. | 1 | /* Dispatching based on the current locale's character encoding. |
| 2 | Copyright (C) 2018-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2018-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/lc-charset-dispatch.h b/gl/lc-charset-dispatch.h index 4c1cf5f1..554137b6 100644 --- a/gl/lc-charset-dispatch.h +++ b/gl/lc-charset-dispatch.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Dispatching based on the current locale's character encoding. | 1 | /* Dispatching based on the current locale's character encoding. |
| 2 | Copyright (C) 2018-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2018-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/libc-config.h b/gl/libc-config.h index 70114608..33da9cf1 100644 --- a/gl/libc-config.h +++ b/gl/libc-config.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* System definitions for code taken from the GNU C Library | 1 | /* System definitions for code taken from the GNU C Library |
| 2 | 2 | ||
| 3 | Copyright 2017-2024 Free Software Foundation, Inc. | 3 | Copyright 2017-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software; you can redistribute it and/or | 5 | This program is free software; you can redistribute it and/or |
| 6 | modify it under the terms of the GNU Lesser General Public | 6 | modify it under the terms of the GNU Lesser General Public |
| @@ -48,6 +48,11 @@ | |||
| 48 | 48 | ||
| 49 | /* From glibc <features.h>. */ | 49 | /* From glibc <features.h>. */ |
| 50 | 50 | ||
| 51 | #if defined __clang__ | ||
| 52 | /* clang really only groks GNU C 4.2, regardless of its value of __GNUC__. */ | ||
| 53 | # undef __GNUC_PREREQ | ||
| 54 | # define __GNUC_PREREQ(maj, min) ((maj) < 4 + ((min) <= 2)) | ||
| 55 | #endif | ||
| 51 | #ifndef __GNUC_PREREQ | 56 | #ifndef __GNUC_PREREQ |
| 52 | # if defined __GNUC__ && defined __GNUC_MINOR__ | 57 | # if defined __GNUC__ && defined __GNUC_MINOR__ |
| 53 | # define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= __GNUC_MINOR__)) | 58 | # define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= __GNUC_MINOR__)) |
diff --git a/gl/limits.in.h b/gl/limits.in.h index c65eb4c1..c33c59e1 100644 --- a/gl/limits.in.h +++ b/gl/limits.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A GNU-like <limits.h>. | 1 | /* A GNU-like <limits.h>. |
| 2 | 2 | ||
| 3 | Copyright 2016-2024 Free Software Foundation, Inc. | 3 | Copyright 2016-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -20,7 +20,7 @@ | |||
| 20 | #endif | 20 | #endif |
| 21 | @PRAGMA_COLUMNS@ | 21 | @PRAGMA_COLUMNS@ |
| 22 | 22 | ||
| 23 | #if defined _GL_ALREADY_INCLUDING_LIMITS_H | 23 | #if defined _@GUARD_PREFIX@_ALREADY_INCLUDING_LIMITS_H |
| 24 | /* Special invocation convention: | 24 | /* Special invocation convention: |
| 25 | On Haiku/x86_64, we have a sequence of nested includes | 25 | On Haiku/x86_64, we have a sequence of nested includes |
| 26 | <limits.h> -> <syslimits.h> -> <limits.h>. | 26 | <limits.h> -> <syslimits.h> -> <limits.h>. |
| @@ -34,12 +34,12 @@ | |||
| 34 | 34 | ||
| 35 | #ifndef _@GUARD_PREFIX@_LIMITS_H | 35 | #ifndef _@GUARD_PREFIX@_LIMITS_H |
| 36 | 36 | ||
| 37 | # define _GL_ALREADY_INCLUDING_LIMITS_H | 37 | # define _@GUARD_PREFIX@_ALREADY_INCLUDING_LIMITS_H |
| 38 | 38 | ||
| 39 | /* The include_next requires a split double-inclusion guard. */ | 39 | /* The include_next requires a split double-inclusion guard. */ |
| 40 | # @INCLUDE_NEXT@ @NEXT_LIMITS_H@ | 40 | # @INCLUDE_NEXT@ @NEXT_LIMITS_H@ |
| 41 | 41 | ||
| 42 | # undef _GL_ALREADY_INCLUDING_LIMITS_H | 42 | # undef _@GUARD_PREFIX@_ALREADY_INCLUDING_LIMITS_H |
| 43 | 43 | ||
| 44 | #ifndef _@GUARD_PREFIX@_LIMITS_H | 44 | #ifndef _@GUARD_PREFIX@_LIMITS_H |
| 45 | #define _@GUARD_PREFIX@_LIMITS_H | 45 | #define _@GUARD_PREFIX@_LIMITS_H |
diff --git a/gl/localcharset.c b/gl/localcharset.c index 93c4baa4..32f6f78e 100644 --- a/gl/localcharset.c +++ b/gl/localcharset.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Determine a canonical name for the current locale's character encoding. | 1 | /* Determine a canonical name for the current locale's character encoding. |
| 2 | 2 | ||
| 3 | Copyright (C) 2000-2006, 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2000-2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -380,7 +380,7 @@ static const struct table_entry alias_table[] = | |||
| 380 | # if defined OS2 /* OS/2 */ | 380 | # if defined OS2 /* OS/2 */ |
| 381 | /* The list of encodings is taken from "List of OS/2 Codepages" | 381 | /* The list of encodings is taken from "List of OS/2 Codepages" |
| 382 | by Alex Taylor: | 382 | by Alex Taylor: |
| 383 | <http://altsan.org/os2/toolkits/uls/index.html#codepages>. | 383 | <https://altsan.org/os2/toolkits/uls/index.html#codepages>. |
| 384 | See also "__convcp() of kLIBC": | 384 | See also "__convcp() of kLIBC": |
| 385 | <https://github.com/bitwiseworks/libc/blob/master/src/emx/src/lib/locale/__convcp.c>. */ | 385 | <https://github.com/bitwiseworks/libc/blob/master/src/emx/src/lib/locale/__convcp.c>. */ |
| 386 | { "CP1004", "CP1252" }, | 386 | { "CP1004", "CP1252" }, |
| @@ -939,8 +939,10 @@ locale_charset (void) | |||
| 939 | sprintf (buf, "CP%u", GetACP ()); | 939 | sprintf (buf, "CP%u", GetACP ()); |
| 940 | } | 940 | } |
| 941 | /* For a locale name such as "French_France.65001", in Windows 10, | 941 | /* For a locale name such as "French_France.65001", in Windows 10, |
| 942 | setlocale now returns "French_France.utf8" instead. */ | 942 | setlocale now returns "French_France.utf8" instead, or in the UTF-8 |
| 943 | if (strcmp (buf + 2, "65001") == 0 || strcmp (buf + 2, "utf8") == 0) | 943 | environment (with modern system settings) "fr_FR.UTF-8". */ |
| 944 | if (strcmp (buf + 2, "65001") == 0 || strcmp (buf + 2, "utf8") == 0 | ||
| 945 | || strcmp (buf + 2, "UTF-8") == 0) | ||
| 944 | codeset = "UTF-8"; | 946 | codeset = "UTF-8"; |
| 945 | else | 947 | else |
| 946 | { | 948 | { |
diff --git a/gl/localcharset.h b/gl/localcharset.h index 47214024..25e6d099 100644 --- a/gl/localcharset.h +++ b/gl/localcharset.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Determine a canonical name for the current locale's character encoding. | 1 | /* Determine a canonical name for the current locale's character encoding. |
| 2 | Copyright (C) 2000-2003, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2000-2003, 2009-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU CHARSET Library. | 3 | This file is part of the GNU CHARSET Library. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/locale.in.h b/gl/locale.in.h index 1b11a41c..34f8c5b6 100644 --- a/gl/locale.in.h +++ b/gl/locale.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* A POSIX <locale.h>. | 1 | /* A POSIX <locale.h>. |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -20,7 +20,7 @@ | |||
| 20 | @PRAGMA_COLUMNS@ | 20 | @PRAGMA_COLUMNS@ |
| 21 | 21 | ||
| 22 | #if (defined _WIN32 && !defined __CYGWIN__ && defined __need_locale_t) \ | 22 | #if (defined _WIN32 && !defined __CYGWIN__ && defined __need_locale_t) \ |
| 23 | || defined _GL_ALREADY_INCLUDING_LOCALE_H | 23 | || defined _@GUARD_PREFIX@_ALREADY_INCLUDING_LOCALE_H |
| 24 | 24 | ||
| 25 | /* Special invocation convention: | 25 | /* Special invocation convention: |
| 26 | - Inside mingw header files, | 26 | - Inside mingw header files, |
| @@ -34,12 +34,12 @@ | |||
| 34 | 34 | ||
| 35 | #ifndef _@GUARD_PREFIX@_LOCALE_H | 35 | #ifndef _@GUARD_PREFIX@_LOCALE_H |
| 36 | 36 | ||
| 37 | #define _GL_ALREADY_INCLUDING_LOCALE_H | 37 | #define _@GUARD_PREFIX@_ALREADY_INCLUDING_LOCALE_H |
| 38 | 38 | ||
| 39 | /* The include_next requires a split double-inclusion guard. */ | 39 | /* The include_next requires a split double-inclusion guard. */ |
| 40 | #@INCLUDE_NEXT@ @NEXT_LOCALE_H@ | 40 | #@INCLUDE_NEXT@ @NEXT_LOCALE_H@ |
| 41 | 41 | ||
| 42 | #undef _GL_ALREADY_INCLUDING_LOCALE_H | 42 | #undef _@GUARD_PREFIX@_ALREADY_INCLUDING_LOCALE_H |
| 43 | 43 | ||
| 44 | #ifndef _@GUARD_PREFIX@_LOCALE_H | 44 | #ifndef _@GUARD_PREFIX@_LOCALE_H |
| 45 | #define _@GUARD_PREFIX@_LOCALE_H | 45 | #define _@GUARD_PREFIX@_LOCALE_H |
| @@ -69,6 +69,85 @@ | |||
| 69 | # define LC_MESSAGES 1729 | 69 | # define LC_MESSAGES 1729 |
| 70 | #endif | 70 | #endif |
| 71 | 71 | ||
| 72 | #if !@HAVE_LOCALE_T@ | ||
| 73 | # if !defined GNULIB_defined_locale_t | ||
| 74 | /* The values of the POSIX-standardized LC_* macros are: | ||
| 75 | |||
| 76 | LC_COLLATE LC_CTYPE LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME | ||
| 77 | |||
| 78 | glibc, Solaris, 3 0 5 4 1 2 | ||
| 79 | Android | ||
| 80 | macOS, *BSD 1 2 6 3 4 5 | ||
| 81 | native Windows 1 2 1729 3 4 5 | ||
| 82 | |||
| 83 | We map these to the log2(LC_*_MASK) values, chosen to be compatible with | ||
| 84 | later releases of the same operating system. */ | ||
| 85 | # if defined __APPLE__ && defined __MACH__ /* macOS */ | ||
| 86 | /* LC_COLLATE LC_CTYPE LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME | ||
| 87 | |||
| 88 | category 1 2 6 3 4 5 | ||
| 89 | log2(LC_*_MASK) 0 1 2 3 4 5 | ||
| 90 | */ | ||
| 91 | # define gl_log2_lc_mask(category) ((0x2543100 >> (4 * (category))) & 0xf) | ||
| 92 | # elif defined __FreeBSD__ || defined __DragonFly__ /* FreeBSD */ | ||
| 93 | /* LC_COLLATE LC_CTYPE LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME | ||
| 94 | |||
| 95 | category 1 2 6 3 4 5 | ||
| 96 | log2(LC_*_MASK) 0 1 5 2 3 4 | ||
| 97 | */ | ||
| 98 | # define gl_log2_lc_mask(category) ((category) - 1) | ||
| 99 | # elif defined _WIN32 && !defined __CYGWIN__ /* native Windows */ | ||
| 100 | # define gl_log2_lc_mask(category) \ | ||
| 101 | ((category) == LC_MESSAGES ? 0 : (category)) | ||
| 102 | # else /* glibc, Solaris, Android, NetBSD, OpenBSD */ | ||
| 103 | # define gl_log2_lc_mask(category) (category) | ||
| 104 | # endif | ||
| 105 | /* From there we map them to array indices 0..5. */ | ||
| 106 | # if (gl_log2_lc_mask (LC_COLLATE) == 0 || gl_log2_lc_mask (LC_CTYPE) == 0 \ | ||
| 107 | || gl_log2_lc_mask (LC_MESSAGES) == 0) | ||
| 108 | /* glibc, Solaris, Android, macOS, FreeBSD, native Windows */ | ||
| 109 | # define gl_log2_lcmask_to_index(c) (c) | ||
| 110 | # define gl_index_to_log2_lcmask(i) (i) | ||
| 111 | # else | ||
| 112 | /* NetBSD, OpenBSD */ | ||
| 113 | # define gl_log2_lcmask_to_index(c) ((c) - 1) | ||
| 114 | # define gl_index_to_log2_lcmask(i) ((i) + 1) | ||
| 115 | # endif | ||
| 116 | /* Define the LC_*_MASK macros. */ | ||
| 117 | # define LC_COLLATE_MASK (1 << gl_log2_lc_mask (LC_COLLATE)) | ||
| 118 | # define LC_CTYPE_MASK (1 << gl_log2_lc_mask (LC_CTYPE)) | ||
| 119 | # define LC_MESSAGES_MASK (1 << gl_log2_lc_mask (LC_MESSAGES)) | ||
| 120 | # define LC_MONETARY_MASK (1 << gl_log2_lc_mask (LC_MONETARY)) | ||
| 121 | # define LC_NUMERIC_MASK (1 << gl_log2_lc_mask (LC_NUMERIC)) | ||
| 122 | # define LC_TIME_MASK (1 << gl_log2_lc_mask (LC_TIME)) | ||
| 123 | # define LC_ALL_MASK \ | ||
| 124 | (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | LC_MONETARY_MASK \ | ||
| 125 | | LC_NUMERIC_MASK | LC_TIME_MASK) | ||
| 126 | /* Now define the locale_t type. */ | ||
| 127 | struct gl_locale_category_t | ||
| 128 | { | ||
| 129 | char *name; | ||
| 130 | bool is_c_locale; | ||
| 131 | # if @HAVE_WINDOWS_LOCALE_T@ | ||
| 132 | /* Use the native Windows '_locale_t' type. | ||
| 133 | Documentation: | ||
| 134 | <https://learn.microsoft.com/en-us/cpp/c-runtime-library/locale> | ||
| 135 | This field is NULL if is_c_locale is true. But don't use this NULL value, | ||
| 136 | since for the native Windows *_l functions a null _locale_t means to use | ||
| 137 | the global locale. */ | ||
| 138 | _locale_t system_locale; | ||
| 139 | # endif | ||
| 140 | }; | ||
| 141 | struct gl_locale_t | ||
| 142 | { | ||
| 143 | struct gl_locale_category_t category[6]; | ||
| 144 | }; | ||
| 145 | typedef struct gl_locale_t *locale_t; | ||
| 146 | # define LC_GLOBAL_LOCALE ((locale_t)(-1)) | ||
| 147 | # define GNULIB_defined_locale_t 1 | ||
| 148 | # endif | ||
| 149 | #endif | ||
| 150 | |||
| 72 | /* On native Windows with MSVC, 'struct lconv' lacks the members int_p_* and | 151 | /* On native Windows with MSVC, 'struct lconv' lacks the members int_p_* and |
| 73 | int_n_*. Instead of overriding 'struct lconv', merely define these member | 152 | int_n_*. Instead of overriding 'struct lconv', merely define these member |
| 74 | names as macros. This avoids trouble in C++ mode. */ | 153 | names as macros. This avoids trouble in C++ mode. */ |
| @@ -83,7 +162,8 @@ | |||
| 83 | 162 | ||
| 84 | /* Bionic libc's 'struct lconv' is just a dummy. */ | 163 | /* Bionic libc's 'struct lconv' is just a dummy. */ |
| 85 | #if @REPLACE_STRUCT_LCONV@ | 164 | #if @REPLACE_STRUCT_LCONV@ |
| 86 | # define lconv rpl_lconv | 165 | # if !defined GNULIB_defined_struct_lconv |
| 166 | # define lconv rpl_lconv | ||
| 87 | struct lconv | 167 | struct lconv |
| 88 | { | 168 | { |
| 89 | /* All 'char *' are actually 'const char *'. */ | 169 | /* All 'char *' are actually 'const char *'. */ |
| @@ -160,6 +240,8 @@ struct lconv | |||
| 160 | number. */ | 240 | number. */ |
| 161 | char int_n_sep_by_space; | 241 | char int_n_sep_by_space; |
| 162 | }; | 242 | }; |
| 243 | # define GNULIB_defined_struct_lconv 1 | ||
| 244 | # endif | ||
| 163 | #endif | 245 | #endif |
| 164 | 246 | ||
| 165 | #if @GNULIB_LOCALECONV@ | 247 | #if @GNULIB_LOCALECONV@ |
| @@ -168,7 +250,7 @@ struct lconv | |||
| 168 | # undef localeconv | 250 | # undef localeconv |
| 169 | # define localeconv rpl_localeconv | 251 | # define localeconv rpl_localeconv |
| 170 | # endif | 252 | # endif |
| 171 | _GL_FUNCDECL_RPL (localeconv, struct lconv *, (void)); | 253 | _GL_FUNCDECL_RPL (localeconv, struct lconv *, (void), ); |
| 172 | _GL_CXXALIAS_RPL (localeconv, struct lconv *, (void)); | 254 | _GL_CXXALIAS_RPL (localeconv, struct lconv *, (void)); |
| 173 | # else | 255 | # else |
| 174 | _GL_CXXALIAS_SYS (localeconv, struct lconv *, (void)); | 256 | _GL_CXXALIAS_SYS (localeconv, struct lconv *, (void)); |
| @@ -177,8 +259,10 @@ _GL_CXXALIAS_SYS (localeconv, struct lconv *, (void)); | |||
| 177 | _GL_CXXALIASWARN (localeconv); | 259 | _GL_CXXALIASWARN (localeconv); |
| 178 | # endif | 260 | # endif |
| 179 | #elif @REPLACE_STRUCT_LCONV@ | 261 | #elif @REPLACE_STRUCT_LCONV@ |
| 180 | # undef localeconv | 262 | # if !GNULIB_LOCALECONV |
| 181 | # define localeconv localeconv_used_without_requesting_gnulib_module_localeconv | 263 | # undef localeconv |
| 264 | # define localeconv localeconv_used_without_requesting_gnulib_module_localeconv | ||
| 265 | # endif | ||
| 182 | #elif defined GNULIB_POSIXCHECK | 266 | #elif defined GNULIB_POSIXCHECK |
| 183 | # undef localeconv | 267 | # undef localeconv |
| 184 | # if HAVE_RAW_DECL_LOCALECONV | 268 | # if HAVE_RAW_DECL_LOCALECONV |
| @@ -195,7 +279,7 @@ _GL_WARN_ON_USE (localeconv, | |||
| 195 | # define setlocale rpl_setlocale | 279 | # define setlocale rpl_setlocale |
| 196 | # define GNULIB_defined_setlocale 1 | 280 | # define GNULIB_defined_setlocale 1 |
| 197 | # endif | 281 | # endif |
| 198 | _GL_FUNCDECL_RPL (setlocale, char *, (int category, const char *locale)); | 282 | _GL_FUNCDECL_RPL (setlocale, char *, (int category, const char *locale), ); |
| 199 | _GL_CXXALIAS_RPL (setlocale, char *, (int category, const char *locale)); | 283 | _GL_CXXALIAS_RPL (setlocale, char *, (int category, const char *locale)); |
| 200 | # else | 284 | # else |
| 201 | _GL_CXXALIAS_SYS (setlocale, char *, (int category, const char *locale)); | 285 | _GL_CXXALIAS_SYS (setlocale, char *, (int category, const char *locale)); |
| @@ -216,7 +300,7 @@ _GL_WARN_ON_USE (setlocale, "setlocale works differently on native Windows - " | |||
| 216 | # include "setlocale_null.h" | 300 | # include "setlocale_null.h" |
| 217 | #endif | 301 | #endif |
| 218 | 302 | ||
| 219 | #if /*@GNULIB_NEWLOCALE@ ||*/ (@GNULIB_LOCALENAME_UNSAFE@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_NEWLOCALE@) | 303 | #if @GNULIB_NEWLOCALE@ || (@GNULIB_GETLOCALENAME_L_UNSAFE@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_NEWLOCALE@) |
| 220 | # if @REPLACE_NEWLOCALE@ | 304 | # if @REPLACE_NEWLOCALE@ |
| 221 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 305 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 222 | # undef newlocale | 306 | # undef newlocale |
| @@ -224,24 +308,22 @@ _GL_WARN_ON_USE (setlocale, "setlocale works differently on native Windows - " | |||
| 224 | # define GNULIB_defined_newlocale 1 | 308 | # define GNULIB_defined_newlocale 1 |
| 225 | # endif | 309 | # endif |
| 226 | _GL_FUNCDECL_RPL (newlocale, locale_t, | 310 | _GL_FUNCDECL_RPL (newlocale, locale_t, |
| 227 | (int category_mask, const char *name, locale_t base) | 311 | (int category_mask, const char *name, locale_t base), |
| 228 | _GL_ARG_NONNULL ((2))); | 312 | _GL_ARG_NONNULL ((2))); |
| 229 | _GL_CXXALIAS_RPL (newlocale, locale_t, | 313 | _GL_CXXALIAS_RPL (newlocale, locale_t, |
| 230 | (int category_mask, const char *name, locale_t base)); | 314 | (int category_mask, const char *name, locale_t base)); |
| 231 | # else | 315 | # else |
| 232 | # if @HAVE_NEWLOCALE@ | 316 | # if !@HAVE_NEWLOCALE@ |
| 317 | _GL_FUNCDECL_SYS (newlocale, locale_t, | ||
| 318 | (int category_mask, const char *name, locale_t base), | ||
| 319 | _GL_ARG_NONNULL ((2))); | ||
| 320 | # endif | ||
| 233 | _GL_CXXALIAS_SYS (newlocale, locale_t, | 321 | _GL_CXXALIAS_SYS (newlocale, locale_t, |
| 234 | (int category_mask, const char *name, locale_t base)); | 322 | (int category_mask, const char *name, locale_t base)); |
| 235 | # endif | ||
| 236 | # endif | 323 | # endif |
| 237 | # if __GLIBC__ >= 2 && @HAVE_NEWLOCALE@ | 324 | # if __GLIBC__ >= 2 |
| 238 | _GL_CXXALIASWARN (newlocale); | 325 | _GL_CXXALIASWARN (newlocale); |
| 239 | # endif | 326 | # endif |
| 240 | # if @HAVE_NEWLOCALE@ || @REPLACE_NEWLOCALE@ | ||
| 241 | # ifndef HAVE_WORKING_NEWLOCALE | ||
| 242 | # define HAVE_WORKING_NEWLOCALE 1 | ||
| 243 | # endif | ||
| 244 | # endif | ||
| 245 | #elif defined GNULIB_POSIXCHECK | 327 | #elif defined GNULIB_POSIXCHECK |
| 246 | # undef newlocale | 328 | # undef newlocale |
| 247 | # if HAVE_RAW_DECL_NEWLOCALE | 329 | # if HAVE_RAW_DECL_NEWLOCALE |
| @@ -249,53 +331,50 @@ _GL_WARN_ON_USE (newlocale, "newlocale is not portable"); | |||
| 249 | # endif | 331 | # endif |
| 250 | #endif | 332 | #endif |
| 251 | 333 | ||
| 252 | #if @GNULIB_DUPLOCALE@ || (@GNULIB_LOCALENAME_UNSAFE@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_DUPLOCALE@) | 334 | #if @GNULIB_DUPLOCALE@ || (@GNULIB_GETLOCALENAME_L_UNSAFE@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_DUPLOCALE@) |
| 253 | # if @HAVE_DUPLOCALE@ /* locale_t may be undefined if !@HAVE_DUPLOCALE@. */ | 335 | # if @REPLACE_DUPLOCALE@ |
| 254 | # if @REPLACE_DUPLOCALE@ | 336 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 255 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 337 | # undef duplocale |
| 256 | # undef duplocale | 338 | # define duplocale rpl_duplocale |
| 257 | # define duplocale rpl_duplocale | 339 | # define GNULIB_defined_duplocale 1 |
| 258 | # define GNULIB_defined_duplocale 1 | 340 | # endif |
| 259 | # endif | 341 | _GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale), _GL_ARG_NONNULL ((1))); |
| 260 | _GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale) _GL_ARG_NONNULL ((1))); | ||
| 261 | _GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale)); | 342 | _GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale)); |
| 262 | # else | 343 | # else |
| 263 | _GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale)); | 344 | # if !@HAVE_DUPLOCALE@ |
| 345 | _GL_FUNCDECL_SYS (duplocale, locale_t, (locale_t locale), _GL_ARG_NONNULL ((1))); | ||
| 264 | # endif | 346 | # endif |
| 347 | _GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale)); | ||
| 265 | # endif | 348 | # endif |
| 266 | # if __GLIBC__ >= 2 && @HAVE_DUPLOCALE@ | 349 | # if __GLIBC__ >= 2 |
| 267 | _GL_CXXALIASWARN (duplocale); | 350 | _GL_CXXALIASWARN (duplocale); |
| 268 | # endif | 351 | # endif |
| 269 | # if @HAVE_DUPLOCALE@ | ||
| 270 | # ifndef HAVE_WORKING_DUPLOCALE | ||
| 271 | # define HAVE_WORKING_DUPLOCALE 1 | ||
| 272 | # endif | ||
| 273 | # endif | ||
| 274 | #elif defined GNULIB_POSIXCHECK | 352 | #elif defined GNULIB_POSIXCHECK |
| 275 | # undef duplocale | 353 | # undef duplocale |
| 276 | # if HAVE_RAW_DECL_DUPLOCALE | 354 | # if HAVE_RAW_DECL_DUPLOCALE |
| 277 | _GL_WARN_ON_USE (duplocale, "duplocale is buggy on some glibc systems - " | 355 | _GL_WARN_ON_USE (duplocale, "duplocale is unportable and buggy on some glibc systems - " |
| 278 | "use gnulib module duplocale for portability"); | 356 | "use gnulib module duplocale for portability"); |
| 279 | # endif | 357 | # endif |
| 280 | #endif | 358 | #endif |
| 281 | 359 | ||
| 282 | #if /*@GNULIB_FREELOCALE@ ||*/ (@GNULIB_LOCALENAME_UNSAFE@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_FREELOCALE@) | 360 | #if @GNULIB_FREELOCALE@ || (@GNULIB_GETLOCALENAME_L_UNSAFE@ && @LOCALENAME_ENHANCE_LOCALE_FUNCS@ && @HAVE_FREELOCALE@) |
| 283 | # if @REPLACE_FREELOCALE@ | 361 | # if @REPLACE_FREELOCALE@ |
| 284 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 362 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 285 | # undef freelocale | 363 | # undef freelocale |
| 286 | # define freelocale rpl_freelocale | 364 | # define freelocale rpl_freelocale |
| 287 | # define GNULIB_defined_freelocale 1 | 365 | # define GNULIB_defined_freelocale 1 |
| 288 | # endif | 366 | # endif |
| 289 | _GL_FUNCDECL_RPL (freelocale, void, (locale_t locale) _GL_ARG_NONNULL ((1))); | 367 | _GL_FUNCDECL_RPL (freelocale, void, (locale_t locale), _GL_ARG_NONNULL ((1))); |
| 290 | _GL_CXXALIAS_RPL (freelocale, void, (locale_t locale)); | 368 | _GL_CXXALIAS_RPL (freelocale, void, (locale_t locale)); |
| 291 | # else | 369 | # else |
| 292 | # if @HAVE_FREELOCALE@ | 370 | # if !@HAVE_FREELOCALE@ |
| 371 | _GL_FUNCDECL_SYS (freelocale, void, (locale_t locale), _GL_ARG_NONNULL ((1))); | ||
| 372 | # endif | ||
| 293 | /* Need to cast, because on FreeBSD and Mac OS X 10.13, the return type is | 373 | /* Need to cast, because on FreeBSD and Mac OS X 10.13, the return type is |
| 294 | int. */ | 374 | int. */ |
| 295 | _GL_CXXALIAS_SYS_CAST (freelocale, void, (locale_t locale)); | 375 | _GL_CXXALIAS_SYS_CAST (freelocale, void, (locale_t locale)); |
| 296 | # endif | ||
| 297 | # endif | 376 | # endif |
| 298 | # if __GLIBC__ >= 2 && @HAVE_FREELOCALE@ | 377 | # if __GLIBC__ >= 2 |
| 299 | _GL_CXXALIASWARN (freelocale); | 378 | _GL_CXXALIASWARN (freelocale); |
| 300 | # endif | 379 | # endif |
| 301 | #elif defined GNULIB_POSIXCHECK | 380 | #elif defined GNULIB_POSIXCHECK |
| @@ -305,6 +384,36 @@ _GL_WARN_ON_USE (freelocale, "freelocale is not portable"); | |||
| 305 | # endif | 384 | # endif |
| 306 | #endif | 385 | #endif |
| 307 | 386 | ||
| 387 | #if @GNULIB_GETLOCALENAME_L@ | ||
| 388 | # if @REPLACE_GETLOCALENAME_L@ | ||
| 389 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 390 | # undef getlocalename_l | ||
| 391 | # define getlocalename_l rpl_getlocalename_l | ||
| 392 | # endif | ||
| 393 | _GL_FUNCDECL_RPL (getlocalename_l, const char *, | ||
| 394 | (int category, locale_t locale), | ||
| 395 | _GL_ARG_NONNULL ((2))); | ||
| 396 | _GL_CXXALIAS_RPL (getlocalename_l, const char *, | ||
| 397 | (int category, locale_t locale)); | ||
| 398 | # else | ||
| 399 | # if !@HAVE_GETLOCALENAME_L@ | ||
| 400 | _GL_FUNCDECL_SYS (getlocalename_l, const char *, | ||
| 401 | (int category, locale_t locale), | ||
| 402 | _GL_ARG_NONNULL ((2))); | ||
| 403 | # endif | ||
| 404 | _GL_CXXALIAS_SYS (getlocalename_l, const char *, | ||
| 405 | (int category, locale_t locale)); | ||
| 406 | # endif | ||
| 407 | # if __GLIBC__ >= 2 | ||
| 408 | _GL_CXXALIASWARN (getlocalename_l); | ||
| 409 | # endif | ||
| 410 | #elif defined GNULIB_POSIXCHECK | ||
| 411 | # undef getlocalename_l | ||
| 412 | # if HAVE_RAW_DECL_GETLOCALENAME_L | ||
| 413 | _GL_WARN_ON_USE (getlocalename_l, "getlocalename_l is not portable"); | ||
| 414 | # endif | ||
| 415 | #endif | ||
| 416 | |||
| 308 | #endif /* _@GUARD_PREFIX@_LOCALE_H */ | 417 | #endif /* _@GUARD_PREFIX@_LOCALE_H */ |
| 309 | #endif /* _@GUARD_PREFIX@_LOCALE_H */ | 418 | #endif /* _@GUARD_PREFIX@_LOCALE_H */ |
| 310 | #endif /* !(__need_locale_t || _GL_ALREADY_INCLUDING_LOCALE_H) */ | 419 | #endif /* !(__need_locale_t || _@GUARD_PREFIX@_ALREADY_INCLUDING_LOCALE_H) */ |
diff --git a/gl/localeconv.c b/gl/localeconv.c index 10fc7b74..a6bbdced 100644 --- a/gl/localeconv.c +++ b/gl/localeconv.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Query locale dependent information for formatting numbers. | 1 | /* Query locale dependent information for formatting numbers. |
| 2 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2012-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* An lseek() function that detects pipes. | 1 | /* An lseek() function that detects pipes. |
| 2 | Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/lstat.c b/gl/lstat.c new file mode 100644 index 00000000..bb4a59f1 --- /dev/null +++ b/gl/lstat.c | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | /* Work around a bug of lstat on some systems | ||
| 2 | |||
| 3 | Copyright (C) 1997-2006, 2008-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* written by Jim Meyering */ | ||
| 19 | |||
| 20 | /* If the user's config.h happens to include <sys/stat.h>, let it include only | ||
| 21 | the system's <sys/stat.h> here, so that orig_lstat doesn't recurse to | ||
| 22 | rpl_lstat. */ | ||
| 23 | #define __need_system_sys_stat_h | ||
| 24 | #include <config.h> | ||
| 25 | |||
| 26 | #if !HAVE_LSTAT | ||
| 27 | /* On systems that lack symlinks, our replacement <sys/stat.h> already | ||
| 28 | defined lstat as stat, so there is nothing further to do other than | ||
| 29 | avoid an empty file. */ | ||
| 30 | typedef int dummy; | ||
| 31 | #else /* HAVE_LSTAT */ | ||
| 32 | |||
| 33 | /* Get the original definition of lstat. It might be defined as a macro. */ | ||
| 34 | # include <sys/types.h> | ||
| 35 | # include <sys/stat.h> | ||
| 36 | # undef __need_system_sys_stat_h | ||
| 37 | |||
| 38 | static int | ||
| 39 | orig_lstat (const char *filename, struct stat *buf) | ||
| 40 | { | ||
| 41 | return lstat (filename, buf); | ||
| 42 | } | ||
| 43 | |||
| 44 | /* Specification. */ | ||
| 45 | # ifdef __osf__ | ||
| 46 | /* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc | ||
| 47 | eliminates this include because of the preliminary #include <sys/stat.h> | ||
| 48 | above. */ | ||
| 49 | # include "sys/stat.h" | ||
| 50 | # else | ||
| 51 | # include <sys/stat.h> | ||
| 52 | # endif | ||
| 53 | |||
| 54 | # include "stat-time.h" | ||
| 55 | |||
| 56 | # include <string.h> | ||
| 57 | # include <errno.h> | ||
| 58 | |||
| 59 | /* lstat works differently on Linux and Solaris systems. POSIX (see | ||
| 60 | "pathname resolution" in the glossary) requires that programs like | ||
| 61 | 'ls' take into consideration the fact that FILE has a trailing slash | ||
| 62 | when FILE is a symbolic link. On Linux and Solaris 10 systems, the | ||
| 63 | lstat function already has the desired semantics (in treating | ||
| 64 | 'lstat ("symlink/", sbuf)' just like 'lstat ("symlink/.", sbuf)', | ||
| 65 | but on Solaris 9 and earlier it does not. | ||
| 66 | |||
| 67 | If FILE has a trailing slash and specifies a symbolic link, | ||
| 68 | then use stat() to get more info on the referent of FILE. | ||
| 69 | If the referent is a non-directory, then set errno to ENOTDIR | ||
| 70 | and return -1. Otherwise, return stat's result. */ | ||
| 71 | |||
| 72 | int | ||
| 73 | rpl_lstat (const char *file, struct stat *sbuf) | ||
| 74 | { | ||
| 75 | int result = orig_lstat (file, sbuf); | ||
| 76 | |||
| 77 | /* This replacement file can blindly check against '/' rather than | ||
| 78 | using the ISSLASH macro, because all platforms with '\\' either | ||
| 79 | lack symlinks (mingw) or have working lstat (cygwin) and thus do | ||
| 80 | not compile this file. 0 len should have already been filtered | ||
| 81 | out above, with a failure return of ENOENT. */ | ||
| 82 | if (result == 0) | ||
| 83 | { | ||
| 84 | if (S_ISDIR (sbuf->st_mode) || file[strlen (file) - 1] != '/') | ||
| 85 | result = stat_time_normalize (result, sbuf); | ||
| 86 | else | ||
| 87 | { | ||
| 88 | /* At this point, a trailing slash is permitted only on | ||
| 89 | symlink-to-dir; but it should have found information on the | ||
| 90 | directory, not the symlink. Call 'stat' to get info about the | ||
| 91 | link's referent. Our replacement stat guarantees valid results, | ||
| 92 | even if the symlink is not pointing to a directory. */ | ||
| 93 | if (!S_ISLNK (sbuf->st_mode)) | ||
| 94 | { | ||
| 95 | errno = ENOTDIR; | ||
| 96 | return -1; | ||
| 97 | } | ||
| 98 | result = stat (file, sbuf); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | return result; | ||
| 102 | } | ||
| 103 | |||
| 104 | #endif /* HAVE_LSTAT */ | ||
diff --git a/gl/m4/00gnulib.m4 b/gl/m4/00gnulib.m4 index cd167718..2b205b35 100644 --- a/gl/m4/00gnulib.m4 +++ b/gl/m4/00gnulib.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # 00gnulib.m4 | 1 | # 00gnulib.m4 |
| 2 | # serial 9 | 2 | # serial 9 |
| 3 | dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl This file must be named something that sorts before all other | 9 | dnl This file must be named something that sorts before all other |
| 9 | dnl gnulib-provided .m4 files. It is needed until the clang fix has | 10 | dnl gnulib-provided .m4 files. It is needed until the clang fix has |
diff --git a/gl/m4/__inline.m4 b/gl/m4/__inline.m4 index 20baf164..d1b8257b 100644 --- a/gl/m4/__inline.m4 +++ b/gl/m4/__inline.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # __inline.m4 | 1 | # __inline.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright 2017-2024 Free Software Foundation, Inc. | 3 | dnl Copyright 2017-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Test for __inline keyword | 9 | # Test for __inline keyword |
| 9 | 10 | ||
diff --git a/gl/m4/absolute-header.m4 b/gl/m4/absolute-header.m4 index 0abd6d90..5501b07b 100644 --- a/gl/m4/absolute-header.m4 +++ b/gl/m4/absolute-header.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # absolute-header.m4 | 1 | # absolute-header.m4 |
| 2 | # serial 18 | 2 | # serial 18 |
| 3 | dnl Copyright (C) 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Derek Price. | 9 | dnl From Derek Price. |
| 9 | 10 | ||
diff --git a/gl/m4/af_alg.m4 b/gl/m4/af_alg.m4 index 33b74945..38575b6d 100644 --- a/gl/m4/af_alg.m4 +++ b/gl/m4/af_alg.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # af_alg.m4 | 1 | # af_alg.m4 |
| 2 | # serial 6 | 2 | # serial 6 |
| 3 | dnl Copyright 2018-2024 Free Software Foundation, Inc. | 3 | dnl Copyright 2018-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Matteo Croce. | 9 | dnl From Matteo Croce. |
| 9 | 10 | ||
diff --git a/gl/m4/alloca.m4 b/gl/m4/alloca.m4 index dc78dc19..68fc6211 100644 --- a/gl/m4/alloca.m4 +++ b/gl/m4/alloca.m4 | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | # alloca.m4 | 1 | # alloca.m4 |
| 2 | # serial 21 | 2 | # serial 21 |
| 3 | dnl Copyright (C) 2002-2004, 2006-2007, 2009-2024 Free Software Foundation, | 3 | dnl Copyright (C) 2002-2004, 2006-2007, 2009-2025 Free Software Foundation, |
| 4 | dnl Inc. | 4 | dnl Inc. |
| 5 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 6 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 7 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 8 | 9 | ||
| 9 | AC_DEFUN([gl_FUNC_ALLOCA], | 10 | AC_DEFUN([gl_FUNC_ALLOCA], |
| 10 | [ | 11 | [ |
diff --git a/gl/m4/arpa_inet_h.m4 b/gl/m4/arpa_inet_h.m4 index 9eac86d7..5dae6f72 100644 --- a/gl/m4/arpa_inet_h.m4 +++ b/gl/m4/arpa_inet_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # arpa_inet_h.m4 | 1 | # arpa_inet_h.m4 |
| 2 | # serial 17 | 2 | # serial 18 |
| 3 | dnl Copyright (C) 2006, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Written by Simon Josefsson and Bruno Haible | 9 | dnl Written by Simon Josefsson and Bruno Haible |
| 9 | 10 | ||
| @@ -68,8 +69,12 @@ AC_DEFUN([gl_ARPA_INET_H_REQUIRE_DEFAULTS], | |||
| 68 | AC_DEFUN([gl_ARPA_INET_H_DEFAULTS], | 69 | AC_DEFUN([gl_ARPA_INET_H_DEFAULTS], |
| 69 | [ | 70 | [ |
| 70 | dnl Assume proper GNU behavior unless another module says otherwise. | 71 | dnl Assume proper GNU behavior unless another module says otherwise. |
| 72 | HAVE_DECL_HTONL=1; AC_SUBST([HAVE_DECL_HTONL]) | ||
| 73 | HAVE_DECL_HTONS=1; AC_SUBST([HAVE_DECL_HTONS]) | ||
| 71 | HAVE_DECL_INET_NTOP=1; AC_SUBST([HAVE_DECL_INET_NTOP]) | 74 | HAVE_DECL_INET_NTOP=1; AC_SUBST([HAVE_DECL_INET_NTOP]) |
| 72 | HAVE_DECL_INET_PTON=1; AC_SUBST([HAVE_DECL_INET_PTON]) | 75 | HAVE_DECL_INET_PTON=1; AC_SUBST([HAVE_DECL_INET_PTON]) |
| 76 | HAVE_DECL_NTOHL=1; AC_SUBST([HAVE_DECL_NTOHL]) | ||
| 77 | HAVE_DECL_NTOHS=1; AC_SUBST([HAVE_DECL_NTOHS]) | ||
| 73 | REPLACE_INET_NTOP=0; AC_SUBST([REPLACE_INET_NTOP]) | 78 | REPLACE_INET_NTOP=0; AC_SUBST([REPLACE_INET_NTOP]) |
| 74 | REPLACE_INET_PTON=0; AC_SUBST([REPLACE_INET_PTON]) | 79 | REPLACE_INET_PTON=0; AC_SUBST([REPLACE_INET_PTON]) |
| 75 | ]) | 80 | ]) |
diff --git a/gl/m4/assert_h.m4 b/gl/m4/assert_h.m4 index b90d0f19..e77524ca 100644 --- a/gl/m4/assert_h.m4 +++ b/gl/m4/assert_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # assert_h.m4 | 1 | # assert_h.m4 |
| 2 | # serial 1 | 2 | # serial 5 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Paul Eggert. | 9 | dnl From Paul Eggert. |
| 9 | 10 | ||
| @@ -12,30 +13,31 @@ AC_DEFUN([gl_ASSERT_H], | |||
| 12 | AC_CACHE_CHECK([for static_assert], [gl_cv_static_assert], | 13 | AC_CACHE_CHECK([for static_assert], [gl_cv_static_assert], |
| 13 | [gl_saved_CFLAGS=$CFLAGS | 14 | [gl_saved_CFLAGS=$CFLAGS |
| 14 | for gl_working in "yes, a keyword" "yes, an <assert.h> macro"; do | 15 | for gl_working in "yes, a keyword" "yes, an <assert.h> macro"; do |
| 15 | AS_CASE([$gl_working], | 16 | AS_CASE([$gl_working], |
| 16 | [*assert.h*], [CFLAGS="$gl_saved_CFLAGS -DINCLUDE_ASSERT_H"]) | 17 | [*assert.h*], [CFLAGS="$gl_saved_CFLAGS -DINCLUDE_ASSERT_H"]) |
| 17 | 18 | AC_COMPILE_IFELSE( | |
| 18 | AC_COMPILE_IFELSE( | 19 | [AC_LANG_PROGRAM( |
| 19 | [AC_LANG_PROGRAM( | 20 | [[#if defined __clang__ && __STDC_VERSION__ < 202311 |
| 20 | [[#if defined __clang__ && __STDC_VERSION__ < 202311 | 21 | #pragma clang diagnostic error "-Wc2x-extensions" |
| 21 | #pragma clang diagnostic error "-Wc2x-extensions" | 22 | #pragma clang diagnostic error "-Wc++1z-extensions" |
| 22 | #pragma clang diagnostic error "-Wc++1z-extensions" | 23 | #endif |
| 23 | #endif | 24 | #ifdef INCLUDE_ASSERT_H |
| 24 | #ifdef INCLUDE_ASSERT_H | 25 | #include <assert.h> |
| 25 | #include <assert.h> | 26 | #endif |
| 26 | #endif | 27 | static_assert (2 + 2 == 4, "arithmetic does not work"); |
| 27 | static_assert (2 + 2 == 4, "arithmetic does not work"); | 28 | static_assert (2 + 2 == 4); |
| 28 | static_assert (2 + 2 == 4); | 29 | ]], |
| 29 | ]], | 30 | [[ |
| 30 | [[ | 31 | static_assert (sizeof (char) == 1, "sizeof does not work"); |
| 31 | static_assert (sizeof (char) == 1, "sizeof does not work"); | 32 | static_assert (sizeof (char) == 1); |
| 32 | static_assert (sizeof (char) == 1); | 33 | ]]) |
| 33 | ]])], | 34 | ], |
| 34 | [gl_cv_static_assert=$gl_working], | 35 | [gl_cv_static_assert=$gl_working], |
| 35 | [gl_cv_static_assert=no]) | 36 | [gl_cv_static_assert=no]) |
| 36 | CFLAGS=$gl_saved_CFLAGS | 37 | CFLAGS=$gl_saved_CFLAGS |
| 37 | test "$gl_cv_static_assert" != no && break | 38 | test "$gl_cv_static_assert" != no && break |
| 38 | done]) | 39 | done |
| 40 | ]) | ||
| 39 | 41 | ||
| 40 | GL_GENERATE_ASSERT_H=false | 42 | GL_GENERATE_ASSERT_H=false |
| 41 | AS_CASE([$gl_cv_static_assert], | 43 | AS_CASE([$gl_cv_static_assert], |
| @@ -48,6 +50,10 @@ AC_DEFUN([gl_ASSERT_H], | |||
| 48 | 50 | ||
| 49 | dnl The "zz" puts this toward config.h's end, to avoid potential | 51 | dnl The "zz" puts this toward config.h's end, to avoid potential |
| 50 | dnl collisions with other definitions. | 52 | dnl collisions with other definitions. |
| 53 | dnl Hardcode the known configuration results for GCC and clang, so that | ||
| 54 | dnl a configuration made with the C compiler works also with the C++ compiler | ||
| 55 | dnl and vice versa. | ||
| 56 | dnl The seemingly redundant parentheses are necessary for MSVC 14. | ||
| 51 | dnl #undef assert so that programs are not tempted to use it without | 57 | dnl #undef assert so that programs are not tempted to use it without |
| 52 | dnl specifically including assert.h. | 58 | dnl specifically including assert.h. |
| 53 | dnl #undef __ASSERT_H__ so that on IRIX, when programs later include | 59 | dnl #undef __ASSERT_H__ so that on IRIX, when programs later include |
| @@ -55,7 +61,18 @@ AC_DEFUN([gl_ASSERT_H], | |||
| 55 | dnl Break the #undef_s apart with a comment so that 'configure' does | 61 | dnl Break the #undef_s apart with a comment so that 'configure' does |
| 56 | dnl not comment them out. | 62 | dnl not comment them out. |
| 57 | AH_VERBATIM([zzstatic_assert], | 63 | AH_VERBATIM([zzstatic_assert], |
| 58 | [#if (!defined HAVE_C_STATIC_ASSERT && !defined assert \ | 64 | [#if (!(defined __clang__ \ |
| 65 | ? (defined __cplusplus \ | ||
| 66 | ? __cplusplus >= 201703L \ | ||
| 67 | : __STDC_VERSION__ >= 202000L && __clang_major__ >= 16 \ | ||
| 68 | && !defined __sun) \ | ||
| 69 | : (defined __GNUC__ \ | ||
| 70 | ? (defined __cplusplus \ | ||
| 71 | ? __cplusplus >= 201103L && __GNUG__ >= 6 \ | ||
| 72 | : __STDC_VERSION__ >= 202000L && __GNUC__ >= 13 \ | ||
| 73 | && !defined __sun) \ | ||
| 74 | : defined HAVE_C_STATIC_ASSERT)) \ | ||
| 75 | && !defined assert \ | ||
| 59 | && (!defined __cplusplus \ | 76 | && (!defined __cplusplus \ |
| 60 | || (__cpp_static_assert < 201411 \ | 77 | || (__cpp_static_assert < 201411 \ |
| 61 | && __GNUG__ < 6 && __clang_major__ < 6))) | 78 | && __GNUG__ < 6 && __clang_major__ < 6))) |
| @@ -65,8 +82,9 @@ AC_DEFUN([gl_ASSERT_H], | |||
| 65 | #undef/**/__ASSERT_H__ | 82 | #undef/**/__ASSERT_H__ |
| 66 | #endif | 83 | #endif |
| 67 | /* Solaris 11.4 <assert.h> defines static_assert as a macro with 2 arguments. | 84 | /* Solaris 11.4 <assert.h> defines static_assert as a macro with 2 arguments. |
| 68 | We need it also to be invocable with a single argument. */ | 85 | We need it also to be invocable with a single argument. |
| 69 | #if defined __sun && (__STDC_VERSION__ - 0 >= 201112L) && !defined __cplusplus | 86 | Haiku 2022 <assert.h> does not define static_assert at all. */ |
| 87 | #if (__STDC_VERSION__ - 0 >= 201112L) && !defined __cplusplus | ||
| 70 | #undef/**/static_assert | 88 | #undef/**/static_assert |
| 71 | #define static_assert _Static_assert | 89 | #define static_assert _Static_assert |
| 72 | #endif | 90 | #endif |
diff --git a/gl/m4/base64.m4 b/gl/m4/base64.m4 index 26f2af41..785d31c0 100644 --- a/gl/m4/base64.m4 +++ b/gl/m4/base64.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # base64.m4 | 1 | # base64.m4 |
| 2 | # serial 4 | 2 | # serial 4 |
| 3 | dnl Copyright (C) 2004, 2006, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2004, 2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_BASE64], | 9 | AC_DEFUN([gl_FUNC_BASE64], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/btowc.m4 b/gl/m4/btowc.m4 index d9dd7036..59d52be6 100644 --- a/gl/m4/btowc.m4 +++ b/gl/m4/btowc.m4 | |||
| @@ -1,13 +1,15 @@ | |||
| 1 | # btowc.m4 | 1 | # btowc.m4 |
| 2 | # serial 14 | 2 | # serial 15 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_BTOWC], | 9 | AC_DEFUN([gl_FUNC_BTOWC], |
| 9 | [ | 10 | [ |
| 10 | AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) | 11 | AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) |
| 12 | AC_REQUIRE([gt_TYPE_WINT_T]) | ||
| 11 | 13 | ||
| 12 | dnl Check whether <wchar.h> is usable at all, first. Otherwise the test | 14 | dnl Check whether <wchar.h> is usable at all, first. Otherwise the test |
| 13 | dnl program below may lead to an endless loop. See | 15 | dnl program below may lead to an endless loop. See |
| @@ -133,6 +135,13 @@ int main () | |||
| 133 | ]) | 135 | ]) |
| 134 | ]) | 136 | ]) |
| 135 | 137 | ||
| 138 | if test $GNULIBHEADERS_OVERRIDE_WINT_T = 1; then | ||
| 139 | dnl On mingw/ucrt, we override the return type of btowc(). | ||
| 140 | dnl While the original wint_t (= unsigned short) and the overridden wint_t | ||
| 141 | dnl (= unsigned int) are equivalent in function parameters, this is not | ||
| 142 | dnl the case for function return types. | ||
| 143 | REPLACE_BTOWC=1 | ||
| 144 | fi | ||
| 136 | case "$gl_cv_func_btowc_nul" in | 145 | case "$gl_cv_func_btowc_nul" in |
| 137 | *yes) ;; | 146 | *yes) ;; |
| 138 | *) REPLACE_BTOWC=1 ;; | 147 | *) REPLACE_BTOWC=1 ;; |
diff --git a/gl/m4/build-to-host.m4 b/gl/m4/build-to-host.m4 new file mode 100644 index 00000000..01bff8f3 --- /dev/null +++ b/gl/m4/build-to-host.m4 | |||
| @@ -0,0 +1,274 @@ | |||
| 1 | # build-to-host.m4 | ||
| 2 | # serial 5 | ||
| 3 | dnl Copyright (C) 2023-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl Written by Bruno Haible. | ||
| 10 | |||
| 11 | dnl When the build environment ($build_os) is different from the target runtime | ||
| 12 | dnl environment ($host_os), file names may need to be converted from the build | ||
| 13 | dnl environment syntax to the target runtime environment syntax. This is | ||
| 14 | dnl because the Makefiles are executed (mostly) by build environment tools and | ||
| 15 | dnl therefore expect file names in build environment syntax, whereas the runtime | ||
| 16 | dnl expects file names in target runtime environment syntax. | ||
| 17 | dnl | ||
| 18 | dnl For example, if $build_os = cygwin and $host_os = mingw32, filenames need | ||
| 19 | dnl be converted from Cygwin syntax to native Windows syntax: | ||
| 20 | dnl /cygdrive/c/foo/bar -> C:\foo\bar | ||
| 21 | dnl /usr/local/share -> C:\cygwin64\usr\local\share | ||
| 22 | dnl | ||
| 23 | dnl gl_BUILD_TO_HOST([somedir]) | ||
| 24 | dnl This macro takes as input an AC_SUBSTed variable 'somedir', which must | ||
| 25 | dnl already have its final value assigned, and produces two additional | ||
| 26 | dnl AC_SUBSTed variables 'somedir_c' and 'somedir_c_make', that designate the | ||
| 27 | dnl same file name value, just in different syntax: | ||
| 28 | dnl - somedir_c is the file name in target runtime environment syntax, | ||
| 29 | dnl as a C string (starting and ending with a double-quote, | ||
| 30 | dnl and with escaped backslashes and double-quotes in | ||
| 31 | dnl between). | ||
| 32 | dnl - somedir_c_make is the same thing, escaped for use in a Makefile. | ||
| 33 | |||
| 34 | AC_DEFUN([gl_BUILD_TO_HOST], | ||
| 35 | [ | ||
| 36 | AC_REQUIRE([AC_CANONICAL_BUILD]) | ||
| 37 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 38 | AC_REQUIRE([gl_BUILD_TO_HOST_INIT]) | ||
| 39 | |||
| 40 | dnl Define somedir_c. | ||
| 41 | gl_final_[$1]="$[$1]" | ||
| 42 | dnl Translate it from build syntax to host syntax. | ||
| 43 | case "$build_os" in | ||
| 44 | cygwin*) | ||
| 45 | case "$host_os" in | ||
| 46 | mingw* | windows*) | ||
| 47 | gl_final_[$1]=`cygpath -w "$gl_final_[$1]"` ;; | ||
| 48 | esac | ||
| 49 | ;; | ||
| 50 | esac | ||
| 51 | dnl Convert it to C string syntax. | ||
| 52 | [$1]_c=`printf '%s\n' "$gl_final_[$1]" | sed -e "$gl_sed_double_backslashes" -e "$gl_sed_escape_doublequotes" | tr -d "$gl_tr_cr"` | ||
| 53 | [$1]_c='"'"$[$1]_c"'"' | ||
| 54 | AC_SUBST([$1_c]) | ||
| 55 | |||
| 56 | dnl Define somedir_c_make. | ||
| 57 | [$1]_c_make=`printf '%s\n' "$[$1]_c" | sed -e "$gl_sed_escape_for_make_1" -e "$gl_sed_escape_for_make_2" | tr -d "$gl_tr_cr"` | ||
| 58 | dnl Use the substituted somedir variable, when possible, so that the user | ||
| 59 | dnl may adjust somedir a posteriori when there are no special characters. | ||
| 60 | if test "$[$1]_c_make" = '\"'"${gl_final_[$1]}"'\"'; then | ||
| 61 | [$1]_c_make='\"$([$1])\"' | ||
| 62 | fi | ||
| 63 | AC_SUBST([$1_c_make]) | ||
| 64 | ]) | ||
| 65 | |||
| 66 | dnl Some initializations for gl_BUILD_TO_HOST. | ||
| 67 | AC_DEFUN([gl_BUILD_TO_HOST_INIT], | ||
| 68 | [ | ||
| 69 | gl_sed_double_backslashes='s/\\/\\\\/g' | ||
| 70 | gl_sed_escape_doublequotes='s/"/\\"/g' | ||
| 71 | changequote(,)dnl | ||
| 72 | gl_sed_escape_for_make_1="s,\\([ \"&'();<>\\\\\`|]\\),\\\\\\1,g" | ||
| 73 | changequote([,])dnl | ||
| 74 | gl_sed_escape_for_make_2='s,\$,\\$$,g' | ||
| 75 | dnl Find out how to remove carriage returns from output. Solaris /usr/ucb/tr | ||
| 76 | dnl does not understand '\r'. | ||
| 77 | case `echo r | tr -d '\r'` in | ||
| 78 | '') gl_tr_cr='\015' ;; | ||
| 79 | *) gl_tr_cr='\r' ;; | ||
| 80 | esac | ||
| 81 | ]) | ||
| 82 | |||
| 83 | |||
| 84 | dnl The following macros are convenience invocations of gl_BUILD_TO_HOST | ||
| 85 | dnl for some of the variables that are defined by Autoconf. | ||
| 86 | dnl To do so for _all_ the possible variables, use the module 'configmake'. | ||
| 87 | |||
| 88 | dnl Defines bindir_c and bindir_c_make. | ||
| 89 | AC_DEFUN_ONCE([gl_BUILD_TO_HOST_BINDIR], | ||
| 90 | [ | ||
| 91 | dnl Find the final value of bindir. | ||
| 92 | gl_saved_prefix="${prefix}" | ||
| 93 | gl_saved_exec_prefix="${exec_prefix}" | ||
| 94 | gl_saved_bindir="${bindir}" | ||
| 95 | dnl Unfortunately, prefix and exec_prefix get only finally determined | ||
| 96 | dnl at the end of configure. | ||
| 97 | if test "X$prefix" = "XNONE"; then | ||
| 98 | prefix="$ac_default_prefix" | ||
| 99 | fi | ||
| 100 | if test "X$exec_prefix" = "XNONE"; then | ||
| 101 | exec_prefix='${prefix}' | ||
| 102 | fi | ||
| 103 | eval exec_prefix="$exec_prefix" | ||
| 104 | eval bindir="$bindir" | ||
| 105 | gl_BUILD_TO_HOST([bindir]) | ||
| 106 | bindir="${gl_saved_bindir}" | ||
| 107 | exec_prefix="${gl_saved_exec_prefix}" | ||
| 108 | prefix="${gl_saved_prefix}" | ||
| 109 | ]) | ||
| 110 | |||
| 111 | dnl Defines datadir_c and datadir_c_make, | ||
| 112 | dnl where datadir = $(datarootdir) | ||
| 113 | AC_DEFUN_ONCE([gl_BUILD_TO_HOST_DATADIR], | ||
| 114 | [ | ||
| 115 | dnl Find the final value of datadir. | ||
| 116 | gl_saved_prefix="${prefix}" | ||
| 117 | gl_saved_datarootdir="${datarootdir}" | ||
| 118 | gl_saved_datadir="${datadir}" | ||
| 119 | dnl Unfortunately, prefix gets only finally determined at the end of | ||
| 120 | dnl configure. | ||
| 121 | if test "X$prefix" = "XNONE"; then | ||
| 122 | prefix="$ac_default_prefix" | ||
| 123 | fi | ||
| 124 | eval datarootdir="$datarootdir" | ||
| 125 | eval datadir="$datadir" | ||
| 126 | gl_BUILD_TO_HOST([datadir]) | ||
| 127 | datadir="${gl_saved_datadir}" | ||
| 128 | datarootdir="${gl_saved_datarootdir}" | ||
| 129 | prefix="${gl_saved_prefix}" | ||
| 130 | ]) | ||
| 131 | |||
| 132 | dnl Defines libdir_c and libdir_c_make. | ||
| 133 | AC_DEFUN_ONCE([gl_BUILD_TO_HOST_LIBDIR], | ||
| 134 | [ | ||
| 135 | dnl Find the final value of libdir. | ||
| 136 | gl_saved_prefix="${prefix}" | ||
| 137 | gl_saved_exec_prefix="${exec_prefix}" | ||
| 138 | gl_saved_libdir="${libdir}" | ||
| 139 | dnl Unfortunately, prefix and exec_prefix get only finally determined | ||
| 140 | dnl at the end of configure. | ||
| 141 | if test "X$prefix" = "XNONE"; then | ||
| 142 | prefix="$ac_default_prefix" | ||
| 143 | fi | ||
| 144 | if test "X$exec_prefix" = "XNONE"; then | ||
| 145 | exec_prefix='${prefix}' | ||
| 146 | fi | ||
| 147 | eval exec_prefix="$exec_prefix" | ||
| 148 | eval libdir="$libdir" | ||
| 149 | gl_BUILD_TO_HOST([libdir]) | ||
| 150 | libdir="${gl_saved_libdir}" | ||
| 151 | exec_prefix="${gl_saved_exec_prefix}" | ||
| 152 | prefix="${gl_saved_prefix}" | ||
| 153 | ]) | ||
| 154 | |||
| 155 | dnl Defines libexecdir_c and libexecdir_c_make. | ||
| 156 | AC_DEFUN_ONCE([gl_BUILD_TO_HOST_LIBEXECDIR], | ||
| 157 | [ | ||
| 158 | dnl Find the final value of libexecdir. | ||
| 159 | gl_saved_prefix="${prefix}" | ||
| 160 | gl_saved_exec_prefix="${exec_prefix}" | ||
| 161 | gl_saved_libexecdir="${libexecdir}" | ||
| 162 | dnl Unfortunately, prefix and exec_prefix get only finally determined | ||
| 163 | dnl at the end of configure. | ||
| 164 | if test "X$prefix" = "XNONE"; then | ||
| 165 | prefix="$ac_default_prefix" | ||
| 166 | fi | ||
| 167 | if test "X$exec_prefix" = "XNONE"; then | ||
| 168 | exec_prefix='${prefix}' | ||
| 169 | fi | ||
| 170 | eval exec_prefix="$exec_prefix" | ||
| 171 | eval libexecdir="$libexecdir" | ||
| 172 | gl_BUILD_TO_HOST([libexecdir]) | ||
| 173 | libexecdir="${gl_saved_libexecdir}" | ||
| 174 | exec_prefix="${gl_saved_exec_prefix}" | ||
| 175 | prefix="${gl_saved_prefix}" | ||
| 176 | ]) | ||
| 177 | |||
| 178 | dnl Defines localedir_c and localedir_c_make. | ||
| 179 | AC_DEFUN_ONCE([gl_BUILD_TO_HOST_LOCALEDIR], | ||
| 180 | [ | ||
| 181 | dnl Find the final value of localedir. | ||
| 182 | gl_saved_prefix="${prefix}" | ||
| 183 | gl_saved_datarootdir="${datarootdir}" | ||
| 184 | gl_saved_localedir="${localedir}" | ||
| 185 | dnl Unfortunately, prefix gets only finally determined at the end of | ||
| 186 | dnl configure. | ||
| 187 | if test "X$prefix" = "XNONE"; then | ||
| 188 | prefix="$ac_default_prefix" | ||
| 189 | fi | ||
| 190 | eval datarootdir="$datarootdir" | ||
| 191 | eval localedir="$localedir" | ||
| 192 | gl_BUILD_TO_HOST([localedir]) | ||
| 193 | localedir="${gl_saved_localedir}" | ||
| 194 | datarootdir="${gl_saved_datarootdir}" | ||
| 195 | prefix="${gl_saved_prefix}" | ||
| 196 | ]) | ||
| 197 | |||
| 198 | dnl Defines pkgdatadir_c and pkgdatadir_c_make, | ||
| 199 | dnl where pkgdatadir = $(datadir)/$(PACKAGE) | ||
| 200 | AC_DEFUN_ONCE([gl_BUILD_TO_HOST_PKGDATADIR], | ||
| 201 | [ | ||
| 202 | dnl Find the final value of pkgdatadir. | ||
| 203 | gl_saved_prefix="${prefix}" | ||
| 204 | gl_saved_datarootdir="${datarootdir}" | ||
| 205 | gl_saved_datadir="${datadir}" | ||
| 206 | gl_saved_pkgdatadir="${pkgdatadir}" | ||
| 207 | dnl Unfortunately, prefix gets only finally determined at the end of | ||
| 208 | dnl configure. | ||
| 209 | if test "X$prefix" = "XNONE"; then | ||
| 210 | prefix="$ac_default_prefix" | ||
| 211 | fi | ||
| 212 | eval datarootdir="$datarootdir" | ||
| 213 | eval datadir="$datadir" | ||
| 214 | eval pkgdatadir="$pkgdatadir" | ||
| 215 | gl_BUILD_TO_HOST([pkgdatadir]) | ||
| 216 | pkgdatadir="${gl_saved_pkgdatadir}" | ||
| 217 | datadir="${gl_saved_datadir}" | ||
| 218 | datarootdir="${gl_saved_datarootdir}" | ||
| 219 | prefix="${gl_saved_prefix}" | ||
| 220 | ]) | ||
| 221 | |||
| 222 | dnl Defines pkglibdir_c and pkglibdir_c_make, | ||
| 223 | dnl where pkglibdir = $(libdir)/$(PACKAGE) | ||
| 224 | AC_DEFUN_ONCE([gl_BUILD_TO_HOST_PKGLIBDIR], | ||
| 225 | [ | ||
| 226 | dnl Find the final value of pkglibdir. | ||
| 227 | gl_saved_prefix="${prefix}" | ||
| 228 | gl_saved_exec_prefix="${exec_prefix}" | ||
| 229 | gl_saved_libdir="${libdir}" | ||
| 230 | gl_saved_pkglibdir="${pkglibdir}" | ||
| 231 | dnl Unfortunately, prefix and exec_prefix get only finally determined | ||
| 232 | dnl at the end of configure. | ||
| 233 | if test "X$prefix" = "XNONE"; then | ||
| 234 | prefix="$ac_default_prefix" | ||
| 235 | fi | ||
| 236 | if test "X$exec_prefix" = "XNONE"; then | ||
| 237 | exec_prefix='${prefix}' | ||
| 238 | fi | ||
| 239 | eval exec_prefix="$exec_prefix" | ||
| 240 | eval libdir="$libdir" | ||
| 241 | eval pkglibdir="$pkglibdir" | ||
| 242 | gl_BUILD_TO_HOST([pkglibdir]) | ||
| 243 | pkglibdir="${gl_saved_pkglibdir}" | ||
| 244 | libdir="${gl_saved_libdir}" | ||
| 245 | exec_prefix="${gl_saved_exec_prefix}" | ||
| 246 | prefix="${gl_saved_prefix}" | ||
| 247 | ]) | ||
| 248 | |||
| 249 | dnl Defines pkglibexecdir_c and pkglibexecdir_c_make, | ||
| 250 | dnl where pkglibexecdir = $(libexecdir)/$(PACKAGE) | ||
| 251 | AC_DEFUN_ONCE([gl_BUILD_TO_HOST_PKGLIBEXECDIR], | ||
| 252 | [ | ||
| 253 | dnl Find the final value of pkglibexecdir. | ||
| 254 | gl_saved_prefix="${prefix}" | ||
| 255 | gl_saved_exec_prefix="${exec_prefix}" | ||
| 256 | gl_saved_libexecdir="${libexecdir}" | ||
| 257 | gl_saved_pkglibexecdir="${pkglibexecdir}" | ||
| 258 | dnl Unfortunately, prefix and exec_prefix get only finally determined | ||
| 259 | dnl at the end of configure. | ||
| 260 | if test "X$prefix" = "XNONE"; then | ||
| 261 | prefix="$ac_default_prefix" | ||
| 262 | fi | ||
| 263 | if test "X$exec_prefix" = "XNONE"; then | ||
| 264 | exec_prefix='${prefix}' | ||
| 265 | fi | ||
| 266 | eval exec_prefix="$exec_prefix" | ||
| 267 | eval libexecdir="$libexecdir" | ||
| 268 | eval pkglibexecdir="$pkglibexecdir" | ||
| 269 | gl_BUILD_TO_HOST([pkglibexecdir]) | ||
| 270 | pkglibexecdir="${gl_saved_pkglibexecdir}" | ||
| 271 | libexecdir="${gl_saved_libexecdir}" | ||
| 272 | exec_prefix="${gl_saved_exec_prefix}" | ||
| 273 | prefix="${gl_saved_prefix}" | ||
| 274 | ]) | ||
diff --git a/gl/m4/builtin-expect.m4 b/gl/m4/builtin-expect.m4 index c7af926b..76d32867 100644 --- a/gl/m4/builtin-expect.m4 +++ b/gl/m4/builtin-expect.m4 | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | # builtin-expect.m4 | 1 | # builtin-expect.m4 |
| 2 | # serial 1 | 2 | # serial 3 |
| 3 | dnl Copyright 2016-2024 Free Software Foundation, Inc. | 3 | dnl Copyright 2016-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Check for __builtin_expect. | 9 | dnl Provide a GCC-compatible __builtin_expect macro in <config.h>. |
| 9 | 10 | ||
| 10 | dnl Written by Paul Eggert. | 11 | dnl Written by Paul Eggert. |
| 11 | 12 | ||
| @@ -47,5 +48,4 @@ AC_DEFUN([gl___BUILTIN_EXPECT], | |||
| 47 | #elif HAVE___BUILTIN_EXPECT == 2 | 48 | #elif HAVE___BUILTIN_EXPECT == 2 |
| 48 | # include <builtins.h> | 49 | # include <builtins.h> |
| 49 | #endif | 50 | #endif |
| 50 | ]) | 51 | ])]) |
| 51 | ]) | ||
diff --git a/gl/m4/byteswap.m4 b/gl/m4/byteswap.m4 index 0c76fe93..b53cb4d0 100644 --- a/gl/m4/byteswap.m4 +++ b/gl/m4/byteswap.m4 | |||
| @@ -1,18 +1,42 @@ | |||
| 1 | # byteswap.m4 | 1 | # byteswap.m4 |
| 2 | # serial 5 | 2 | # serial 7 |
| 3 | dnl Copyright (C) 2005, 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005, 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Written by Oskar Liljeblad. | 9 | dnl Written by Oskar Liljeblad. |
| 9 | 10 | ||
| 10 | AC_DEFUN([gl_BYTESWAP], | 11 | AC_DEFUN([gl_BYTESWAP], |
| 11 | [ | 12 | [ |
| 12 | dnl Prerequisites of lib/byteswap.in.h. | 13 | dnl Prerequisites of lib/byteswap.in.h. |
| 13 | AC_CHECK_HEADERS([byteswap.h], [ | 14 | AC_CHECK_HEADERS_ONCE([byteswap.h]) |
| 15 | if test $ac_cv_header_byteswap_h = yes; then | ||
| 16 | AC_CACHE_CHECK([for working bswap_16, bswap_32, bswap_64], | ||
| 17 | [gl_cv_header_working_byteswap_h], | ||
| 18 | [gl_cv_header_working_byteswap_h=no | ||
| 19 | dnl Check that floating point arguments work. | ||
| 20 | dnl This also checks C libraries with implementations like | ||
| 21 | dnl '#define bswap_16(x) (((x) >> 8 & 0xff) | (((x) & 0xff) << 8))' | ||
| 22 | dnl that mistakenly evaluate their arguments multiple times. | ||
| 23 | AC_COMPILE_IFELSE( | ||
| 24 | [AC_LANG_PROGRAM( | ||
| 25 | [[#include <byteswap.h> | ||
| 26 | ]], | ||
| 27 | [[int value_16 = bswap_16 (0.0); | ||
| 28 | int value_32 = bswap_32 (0.0); | ||
| 29 | int value_64 = bswap_64 (0.0); | ||
| 30 | return !(value_16 + value_32 + value_64); | ||
| 31 | ]]) | ||
| 32 | ], | ||
| 33 | [gl_cv_header_working_byteswap_h=yes], | ||
| 34 | [gl_cv_header_working_byteswap_h=no]) | ||
| 35 | ]) | ||
| 36 | fi | ||
| 37 | if test "$gl_cv_header_working_byteswap_h" = yes; then | ||
| 14 | GL_GENERATE_BYTESWAP_H=false | 38 | GL_GENERATE_BYTESWAP_H=false |
| 15 | ], [ | 39 | else |
| 16 | GL_GENERATE_BYTESWAP_H=true | 40 | GL_GENERATE_BYTESWAP_H=true |
| 17 | ]) | 41 | fi |
| 18 | ]) | 42 | ]) |
diff --git a/gl/m4/c-bool.m4 b/gl/m4/c-bool.m4 index 0fb0de3b..8fa8bfc8 100644 --- a/gl/m4/c-bool.m4 +++ b/gl/m4/c-bool.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # c-bool.m4 | 1 | # c-bool.m4 |
| 2 | # serial 1 | 2 | # serial 3 |
| 3 | dnl Copyright 2022-2024 Free Software Foundation, Inc. | 3 | dnl Copyright 2022-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Check for bool that conforms to C2023. | 9 | # Check for bool that conforms to C2023. |
| 9 | 10 | ||
| @@ -29,12 +30,23 @@ AC_DEFUN([gl_C_BOOL], | |||
| 29 | dnl The "zz" puts this toward config.h's end, to avoid potential | 30 | dnl The "zz" puts this toward config.h's end, to avoid potential |
| 30 | dnl collisions with other definitions. | 31 | dnl collisions with other definitions. |
| 31 | dnl If 'bool', 'true' and 'false' do not work, arrange for them to work. | 32 | dnl If 'bool', 'true' and 'false' do not work, arrange for them to work. |
| 32 | dnl In C, this means including <stdbool.h> if it is not already included. | 33 | dnl Hardcode the known configuration results for GCC and clang, so that |
| 34 | dnl a configuration made with the C compiler works also with the C++ compiler | ||
| 35 | dnl and vice versa. | ||
| 36 | dnl The seemingly redundant parentheses are necessary for MSVC 14. | ||
| 37 | dnl "Arrange for them to work", in C, means including <stdbool.h> if it is | ||
| 38 | dnl not already included. | ||
| 33 | dnl However, if the preprocessor mistakenly treats 'true' as 0, | 39 | dnl However, if the preprocessor mistakenly treats 'true' as 0, |
| 34 | dnl define it to a bool expression equal to 1; this is needed in | 40 | dnl define it to a bool expression equal to 1; this is needed in |
| 35 | dnl Sun C++ 5.11 (Oracle Solaris Studio 12.2, 2010) and older. | 41 | dnl Sun C++ 5.11 (Oracle Solaris Studio 12.2, 2010) and older. |
| 36 | AH_VERBATIM([zzbool], | 42 | AH_VERBATIM([zzbool], |
| 37 | [#ifndef HAVE_C_BOOL | 43 | [#if !(defined __cplusplus \ |
| 44 | ? 1 \ | ||
| 45 | : (defined __clang__ \ | ||
| 46 | ? __STDC_VERSION__ >= 202000L && __clang_major__ >= 15 \ | ||
| 47 | : (defined __GNUC__ \ | ||
| 48 | ? __STDC_VERSION__ >= 202000L && __GNUC__ >= 13 \ | ||
| 49 | : defined HAVE_C_BOOL))) | ||
| 38 | # if !defined __cplusplus && !defined __bool_true_false_are_defined | 50 | # if !defined __cplusplus && !defined __bool_true_false_are_defined |
| 39 | # if HAVE_STDBOOL_H | 51 | # if HAVE_STDBOOL_H |
| 40 | # include <stdbool.h> | 52 | # include <stdbool.h> |
diff --git a/gl/m4/c32rtomb.m4 b/gl/m4/c32rtomb.m4 new file mode 100644 index 00000000..ce26a31e --- /dev/null +++ b/gl/m4/c32rtomb.m4 | |||
| @@ -0,0 +1,187 @@ | |||
| 1 | # c32rtomb.m4 | ||
| 2 | # serial 8 | ||
| 3 | dnl Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN([gl_FUNC_C32RTOMB], | ||
| 10 | [ | ||
| 11 | AC_REQUIRE([gl_UCHAR_H_DEFAULTS]) | ||
| 12 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 13 | |||
| 14 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 15 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 16 | |||
| 17 | AC_REQUIRE([gl_CHECK_FUNC_C32RTOMB]) | ||
| 18 | if test $gl_cv_func_c32rtomb = no; then | ||
| 19 | HAVE_C32RTOMB=0 | ||
| 20 | else | ||
| 21 | dnl When we override mbrtoc32, redefining the meaning of the char32_t | ||
| 22 | dnl values, we need to override c32rtomb as well, for consistency. | ||
| 23 | if test $HAVE_WORKING_MBRTOC32 = 0; then | ||
| 24 | REPLACE_C32RTOMB=1 | ||
| 25 | fi | ||
| 26 | AC_CACHE_CHECK([whether c32rtomb return value is correct], | ||
| 27 | [gl_cv_func_c32rtomb_retval], | ||
| 28 | [ | ||
| 29 | dnl Initial guess, used when cross-compiling. | ||
| 30 | changequote(,)dnl | ||
| 31 | case "$host_os" in | ||
| 32 | # Guess no on AIX. | ||
| 33 | aix*) gl_cv_func_c32rtomb_retval="guessing no" ;; | ||
| 34 | # Guess yes otherwise. | ||
| 35 | *) gl_cv_func_c32rtomb_retval="guessing yes" ;; | ||
| 36 | esac | ||
| 37 | changequote([,])dnl | ||
| 38 | AC_RUN_IFELSE( | ||
| 39 | [AC_LANG_SOURCE([[ | ||
| 40 | #include <stddef.h> | ||
| 41 | #ifdef __HAIKU__ | ||
| 42 | #include <stdint.h> | ||
| 43 | #endif | ||
| 44 | #include <uchar.h> | ||
| 45 | int main () | ||
| 46 | { | ||
| 47 | int result = 0; | ||
| 48 | if (c32rtomb (NULL, 0, NULL) != 1) | ||
| 49 | result |= 1; | ||
| 50 | return result; | ||
| 51 | }]])], | ||
| 52 | [gl_cv_func_c32rtomb_retval=yes], | ||
| 53 | [gl_cv_func_c32rtomb_retval=no], | ||
| 54 | [:]) | ||
| 55 | ]) | ||
| 56 | case "$gl_cv_func_c32rtomb_retval" in | ||
| 57 | *yes) ;; | ||
| 58 | *) AC_DEFINE([C32RTOMB_RETVAL_BUG], [1], | ||
| 59 | [Define if the c32rtomb function has an incorrect return value.]) | ||
| 60 | REPLACE_C32RTOMB=1 ;; | ||
| 61 | esac | ||
| 62 | if test $HAVE_WORKING_C32RTOMB = 0; then | ||
| 63 | REPLACE_C32RTOMB=1 | ||
| 64 | fi | ||
| 65 | fi | ||
| 66 | ]) | ||
| 67 | |||
| 68 | AC_DEFUN([gl_CHECK_FUNC_C32RTOMB], | ||
| 69 | [ | ||
| 70 | dnl Cf. gl_CHECK_FUNCS_ANDROID | ||
| 71 | AC_CHECK_DECL([c32rtomb], , , | ||
| 72 | [[#ifdef __HAIKU__ | ||
| 73 | #include <stdint.h> | ||
| 74 | #endif | ||
| 75 | #include <uchar.h> | ||
| 76 | ]]) | ||
| 77 | if test $ac_cv_have_decl_c32rtomb = yes; then | ||
| 78 | dnl We can't use AC_CHECK_FUNC here, because c32rtomb() is defined as a | ||
| 79 | dnl static inline function on Haiku 2020. | ||
| 80 | AC_CACHE_CHECK([for c32rtomb], [gl_cv_func_c32rtomb], | ||
| 81 | [AC_LINK_IFELSE( | ||
| 82 | [AC_LANG_PROGRAM( | ||
| 83 | [[#include <stdlib.h> | ||
| 84 | #ifdef __HAIKU__ | ||
| 85 | #include <stdint.h> | ||
| 86 | #endif | ||
| 87 | #include <uchar.h> | ||
| 88 | ]], | ||
| 89 | [[char buf[8]; | ||
| 90 | return c32rtomb (buf, 0, NULL) == 0; | ||
| 91 | ]]) | ||
| 92 | ], | ||
| 93 | [gl_cv_func_c32rtomb=yes], | ||
| 94 | [gl_cv_func_c32rtomb=no]) | ||
| 95 | ]) | ||
| 96 | else | ||
| 97 | gl_cv_func_c32rtomb=no | ||
| 98 | fi | ||
| 99 | ]) | ||
| 100 | |||
| 101 | dnl Test whether c32rtomb works not worse than wcrtomb. | ||
| 102 | dnl Result is HAVE_WORKING_C32RTOMB. | ||
| 103 | |||
| 104 | AC_DEFUN([gl_C32RTOMB_SANITYCHECK], | ||
| 105 | [ | ||
| 106 | AC_REQUIRE([AC_PROG_CC]) | ||
| 107 | AC_REQUIRE([gl_TYPE_CHAR32_T]) | ||
| 108 | AC_REQUIRE([gl_CHECK_FUNC_C32RTOMB]) | ||
| 109 | AC_REQUIRE([gt_LOCALE_ZH_CN]) | ||
| 110 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 111 | if test $GNULIBHEADERS_OVERRIDE_CHAR32_T = 1 || test $gl_cv_func_c32rtomb = no; then | ||
| 112 | HAVE_WORKING_C32RTOMB=0 | ||
| 113 | else | ||
| 114 | AC_CACHE_CHECK([whether c32rtomb works as well as wcrtomb], | ||
| 115 | [gl_cv_func_c32rtomb_sanitycheck], | ||
| 116 | [ | ||
| 117 | dnl Initial guess, used when cross-compiling or when no suitable locale | ||
| 118 | dnl is present. | ||
| 119 | changequote(,)dnl | ||
| 120 | case "$host_os" in | ||
| 121 | # Guess no on Solaris derivatives. | ||
| 122 | solaris*) | ||
| 123 | if test -f /etc/release && grep 'Oracle Solaris' /etc/release >/dev/null; then | ||
| 124 | gl_cv_func_c32rtomb_sanitycheck="guessing yes" | ||
| 125 | else | ||
| 126 | gl_cv_func_c32rtomb_sanitycheck="guessing no" | ||
| 127 | fi | ||
| 128 | ;; | ||
| 129 | # Guess yes otherwise. | ||
| 130 | *) | ||
| 131 | gl_cv_func_c32rtomb_sanitycheck="guessing yes" | ||
| 132 | ;; | ||
| 133 | esac | ||
| 134 | changequote([,])dnl | ||
| 135 | if test $LOCALE_ZH_CN != none; then | ||
| 136 | AC_RUN_IFELSE( | ||
| 137 | [AC_LANG_SOURCE([[ | ||
| 138 | #include <locale.h> | ||
| 139 | #include <stdlib.h> | ||
| 140 | #include <string.h> | ||
| 141 | #include <wchar.h> | ||
| 142 | #ifdef __HAIKU__ | ||
| 143 | #include <stdint.h> | ||
| 144 | #endif | ||
| 145 | #include <uchar.h> | ||
| 146 | int main () | ||
| 147 | { | ||
| 148 | int result = 0; | ||
| 149 | /* This fails on Solaris 11 OmniOS: | ||
| 150 | c32rtomb returns (size_t)-1. | ||
| 151 | wcrtomb returns 4 (correct). */ | ||
| 152 | if (strcmp ("$LOCALE_ZH_CN", "none") != 0 | ||
| 153 | && setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) | ||
| 154 | { | ||
| 155 | mbstate_t state; | ||
| 156 | wchar_t wc = (wchar_t) 0xBADFACE; | ||
| 157 | char buf[16]; | ||
| 158 | memset (&state, '\0', sizeof (mbstate_t)); | ||
| 159 | if (mbrtowc (&wc, "\201\060\211\070", 4, &state) == 4 | ||
| 160 | && wcrtomb (buf, wc, NULL) == 4 | ||
| 161 | && memcmp (buf, "\201\060\211\070", 4) == 0) | ||
| 162 | { | ||
| 163 | char32_t c32 = (wchar_t) 0xBADFACE; | ||
| 164 | memset (&state, '\0', sizeof (mbstate_t)); | ||
| 165 | if (mbrtoc32 (&c32, "\201\060\211\070", 4, &state) == 4 | ||
| 166 | && c32rtomb (buf, c32, NULL) != 4) | ||
| 167 | result |= 1; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | return result; | ||
| 171 | }]])], | ||
| 172 | [gl_cv_func_c32rtomb_sanitycheck=yes], | ||
| 173 | [gl_cv_func_c32rtomb_sanitycheck=no], | ||
| 174 | [:]) | ||
| 175 | fi | ||
| 176 | ]) | ||
| 177 | case "$gl_cv_func_c32rtomb_sanitycheck" in | ||
| 178 | *yes) | ||
| 179 | HAVE_WORKING_C32RTOMB=1 | ||
| 180 | AC_DEFINE([HAVE_WORKING_C32RTOMB], [1], | ||
| 181 | [Define if the c32rtomb function basically works.]) | ||
| 182 | ;; | ||
| 183 | *) HAVE_WORKING_C32RTOMB=0 ;; | ||
| 184 | esac | ||
| 185 | fi | ||
| 186 | AC_SUBST([HAVE_WORKING_C32RTOMB]) | ||
| 187 | ]) | ||
diff --git a/gl/m4/calloc.m4 b/gl/m4/calloc.m4 index 550cf5cc..ac7d08d4 100644 --- a/gl/m4/calloc.m4 +++ b/gl/m4/calloc.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # calloc.m4 | 1 | # calloc.m4 |
| 2 | # serial 31 | 2 | # serial 36 |
| 3 | dnl Copyright (C) 2004-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2004-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Written by Jim Meyering. | 9 | # Written by Jim Meyering. |
| 9 | 10 | ||
| @@ -12,42 +13,35 @@ dnl with or without modifications, as long as this notice is preserved. | |||
| 12 | # If so, define HAVE_CALLOC. Otherwise, define calloc to rpl_calloc | 13 | # If so, define HAVE_CALLOC. Otherwise, define calloc to rpl_calloc |
| 13 | # and arrange to use a calloc wrapper function that does work in that case. | 14 | # and arrange to use a calloc wrapper function that does work in that case. |
| 14 | 15 | ||
| 15 | # _AC_FUNC_CALLOC_IF([IF-WORKS], [IF-NOT]) | 16 | # gl_FUNC_CALLOC_IF([IF-WORKS], [IF-NOT]) |
| 16 | # ------------------------------------- | 17 | # --------------------------------------- |
| 17 | # If calloc is compatible with GNU calloc, run IF-WORKS, otherwise, IF-NOT. | 18 | # If calloc is compatible with GNU calloc, run IF-WORKS, otherwise, IF-NOT. |
| 18 | AC_DEFUN([_AC_FUNC_CALLOC_IF], | 19 | AC_DEFUN([gl_FUNC_CALLOC_IF], |
| 19 | [ | 20 | [ |
| 20 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | 21 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles |
| 21 | AC_CACHE_CHECK([whether calloc (0, n) and calloc (n, 0) return nonnull], | 22 | AC_CACHE_CHECK([whether calloc (0, n) and calloc (n, 0) return nonnull], |
| 22 | [ac_cv_func_calloc_0_nonnull], | 23 | [gl_cv_func_calloc_0_nonnull], |
| 23 | [if test $cross_compiling != yes; then | 24 | [AC_RUN_IFELSE( |
| 24 | ac_cv_func_calloc_0_nonnull=yes | 25 | [AC_LANG_PROGRAM( |
| 25 | AC_RUN_IFELSE( | 26 | [[#include <stdlib.h> |
| 26 | [AC_LANG_PROGRAM( | 27 | /* Use pcalloc to test; "volatile" prevents the compiler |
| 27 | [AC_INCLUDES_DEFAULT], | 28 | from optimizing the calloc call away. */ |
| 28 | [[int result = 0; | 29 | void *(*volatile pcalloc) (size_t, size_t) = calloc;]], |
| 29 | char * volatile p = calloc (0, 0); | 30 | [[void *p = pcalloc (0, 0); |
| 30 | if (!p) | 31 | int result = !p; |
| 31 | result |= 1; | 32 | free (p); |
| 32 | free (p); | 33 | return result;]])], |
| 33 | return result; | 34 | [gl_cv_func_calloc_0_nonnull=yes], |
| 34 | ]])], | 35 | [gl_cv_func_calloc_0_nonnull=no], |
| 35 | [], | 36 | [AS_CASE([$host_os], |
| 36 | [ac_cv_func_calloc_0_nonnull=no]) | 37 | [# Guess yes on platforms where we know the result. |
| 37 | else | 38 | *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \ |
| 38 | case "$host_os" in | 39 | | gnu* | *-musl* | midipix* | midnightbsd* \ |
| 39 | # Guess yes on glibc systems. | 40 | | hpux* | solaris* | cygwin* | mingw* | windows* | msys*], |
| 40 | *-gnu* | gnu*) ac_cv_func_calloc_0_nonnull="guessing yes" ;; | 41 | [gl_cv_func_calloc_0_nonnull="guessing yes"], |
| 41 | # Guess yes on musl systems. | 42 | [# If we don't know, obey --enable-cross-guesses. |
| 42 | *-musl* | midipix*) ac_cv_func_calloc_0_nonnull="guessing yes" ;; | 43 | gl_cv_func_calloc_0_nonnull="$gl_cross_guess_normal"])])]) |
| 43 | # Guess yes on native Windows. | 44 | AS_CASE([$gl_cv_func_calloc_0_nonnull], [*yes], [$1], [$2]) |
| 44 | mingw* | windows*) ac_cv_func_calloc_0_nonnull="guessing yes" ;; | ||
| 45 | # If we don't know, obey --enable-cross-guesses. | ||
| 46 | *) ac_cv_func_calloc_0_nonnull="$gl_cross_guess_normal" ;; | ||
| 47 | esac | ||
| 48 | fi | ||
| 49 | ]) | ||
| 50 | AS_CASE([$ac_cv_func_calloc_0_nonnull], [*yes], [$1], [$2]) | ||
| 51 | ]) | 45 | ]) |
| 52 | 46 | ||
| 53 | 47 | ||
| @@ -58,9 +52,14 @@ AC_DEFUN([gl_FUNC_CALLOC_GNU], | |||
| 58 | [ | 52 | [ |
| 59 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 53 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
| 60 | AC_REQUIRE([gl_FUNC_CALLOC_POSIX]) | 54 | AC_REQUIRE([gl_FUNC_CALLOC_POSIX]) |
| 55 | |||
| 56 | dnl Through the dependency on module extensions-aix, _LINUX_SOURCE_COMPAT | ||
| 57 | dnl gets defined already before this macro gets invoked. This helps | ||
| 58 | dnl if !(__VEC__ || __AIXVEC), and doesn't hurt otherwise. | ||
| 59 | |||
| 61 | REPLACE_CALLOC_FOR_CALLOC_GNU="$REPLACE_CALLOC_FOR_CALLOC_POSIX" | 60 | REPLACE_CALLOC_FOR_CALLOC_GNU="$REPLACE_CALLOC_FOR_CALLOC_POSIX" |
| 62 | if test $REPLACE_CALLOC_FOR_CALLOC_GNU = 0; then | 61 | if test $REPLACE_CALLOC_FOR_CALLOC_GNU = 0; then |
| 63 | _AC_FUNC_CALLOC_IF([], [REPLACE_CALLOC_FOR_CALLOC_GNU=1]) | 62 | gl_FUNC_CALLOC_IF([], [REPLACE_CALLOC_FOR_CALLOC_GNU=1]) |
| 64 | fi | 63 | fi |
| 65 | ])# gl_FUNC_CALLOC_GNU | 64 | ])# gl_FUNC_CALLOC_GNU |
| 66 | 65 | ||
| @@ -73,9 +72,7 @@ AC_DEFUN([gl_FUNC_CALLOC_POSIX], | |||
| 73 | [ | 72 | [ |
| 74 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 73 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
| 75 | AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) | 74 | AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) |
| 76 | if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then | 75 | REPLACE_CALLOC_FOR_CALLOC_POSIX=$REPLACE_MALLOC_FOR_MALLOC_POSIX |
| 77 | REPLACE_CALLOC_FOR_CALLOC_POSIX=1 | ||
| 78 | fi | ||
| 79 | dnl Although in theory we should also test for size_t overflow, | 76 | dnl Although in theory we should also test for size_t overflow, |
| 80 | dnl in practice testing for ptrdiff_t overflow suffices | 77 | dnl in practice testing for ptrdiff_t overflow suffices |
| 81 | dnl since PTRDIFF_MAX <= SIZE_MAX on all known Gnulib porting targets. | 78 | dnl since PTRDIFF_MAX <= SIZE_MAX on all known Gnulib porting targets. |
diff --git a/gl/m4/close.m4 b/gl/m4/close.m4 index 88c37fab..314e321e 100644 --- a/gl/m4/close.m4 +++ b/gl/m4/close.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # close.m4 | 1 | # close.m4 |
| 2 | # serial 10 | 2 | # serial 10 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_FUNC_CLOSE], | 9 | AC_DEFUN_ONCE([gl_FUNC_CLOSE], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/codeset.m4 b/gl/m4/codeset.m4 index e69b7402..6bed9dee 100644 --- a/gl/m4/codeset.m4 +++ b/gl/m4/codeset.m4 | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | # codeset.m4 | 1 | # codeset.m4 |
| 2 | # serial 5 (gettext-0.18.2) | 2 | # serial 5 (gettext-0.18.2) |
| 3 | dnl Copyright (C) 2000-2002, 2006, 2008-2014, 2016, 2019-2024 Free Software | 3 | dnl Copyright (C) 2000-2002, 2006, 2008-2014, 2016, 2019-2025 Free Software |
| 4 | dnl Foundation, Inc. | 4 | dnl Foundation, Inc. |
| 5 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 6 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 7 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 8 | 9 | ||
| 9 | dnl From Bruno Haible. | 10 | dnl From Bruno Haible. |
| 10 | 11 | ||
diff --git a/gl/m4/double-slash-root.m4 b/gl/m4/double-slash-root.m4 index 3437c699..5c40b73c 100644 --- a/gl/m4/double-slash-root.m4 +++ b/gl/m4/double-slash-root.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # double-slash-root.m4 | 1 | # double-slash-root.m4 |
| 2 | # serial 4 -*- Autoconf -*- | 2 | # serial 4 -*- Autoconf -*- |
| 3 | dnl Copyright (C) 2006, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_DOUBLE_SLASH_ROOT], | 9 | AC_DEFUN([gl_DOUBLE_SLASH_ROOT], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/dup2.m4 b/gl/m4/dup2.m4 index 786121fd..5da3a0b9 100644 --- a/gl/m4/dup2.m4 +++ b/gl/m4/dup2.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # dup2.m4 | 1 | # dup2.m4 |
| 2 | # serial 28 | 2 | # serial 28 |
| 3 | dnl Copyright (C) 2002, 2005, 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002, 2005, 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_DUP2], | 9 | AC_DEFUN([gl_FUNC_DUP2], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/eealloc.m4 b/gl/m4/eealloc.m4 deleted file mode 100644 index 8a15e705..00000000 --- a/gl/m4/eealloc.m4 +++ /dev/null | |||
| @@ -1,32 +0,0 @@ | |||
| 1 | # eealloc.m4 | ||
| 2 | # serial 3 | ||
| 3 | dnl Copyright (C) 2003, 2009-2024 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | |||
| 8 | AC_DEFUN([gl_EEALLOC], | ||
| 9 | [ | ||
| 10 | AC_REQUIRE([gl_EEMALLOC]) | ||
| 11 | AC_REQUIRE([gl_EEREALLOC]) | ||
| 12 | ]) | ||
| 13 | |||
| 14 | AC_DEFUN([gl_EEMALLOC], | ||
| 15 | [ | ||
| 16 | _AC_FUNC_MALLOC_IF( | ||
| 17 | [gl_cv_func_malloc_0_nonnull=1], | ||
| 18 | [gl_cv_func_malloc_0_nonnull=0]) | ||
| 19 | AC_DEFINE_UNQUOTED([MALLOC_0_IS_NONNULL], [$gl_cv_func_malloc_0_nonnull], | ||
| 20 | [If malloc(0) is != NULL, define this to 1. Otherwise define this | ||
| 21 | to 0.]) | ||
| 22 | ]) | ||
| 23 | |||
| 24 | AC_DEFUN([gl_EEREALLOC], | ||
| 25 | [ | ||
| 26 | _AC_FUNC_REALLOC_IF( | ||
| 27 | [gl_cv_func_realloc_0_nonnull=1], | ||
| 28 | [gl_cv_func_realloc_0_nonnull=0]) | ||
| 29 | AC_DEFINE_UNQUOTED([REALLOC_0_IS_NONNULL], [$gl_cv_func_realloc_0_nonnull], | ||
| 30 | [If realloc(NULL,0) is != NULL, define this to 1. Otherwise define this | ||
| 31 | to 0.]) | ||
| 32 | ]) | ||
diff --git a/gl/m4/environ.m4 b/gl/m4/environ.m4 index 107960b2..e0690e54 100644 --- a/gl/m4/environ.m4 +++ b/gl/m4/environ.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # environ.m4 | 1 | # environ.m4 |
| 2 | # serial 8 | 2 | # serial 8 |
| 3 | dnl Copyright (C) 2001-2004, 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2001-2004, 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_ENVIRON], | 9 | AC_DEFUN_ONCE([gl_ENVIRON], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/errno_h.m4 b/gl/m4/errno_h.m4 index b6050e5d..420d5bb3 100644 --- a/gl/m4/errno_h.m4 +++ b/gl/m4/errno_h.m4 | |||
| @@ -1,15 +1,21 @@ | |||
| 1 | # errno_h.m4 | 1 | # errno_h.m4 |
| 2 | # serial 14 | 2 | # serial 18 |
| 3 | dnl Copyright (C) 2004, 2006, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2004, 2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_PREREQ([2.61]) | 9 | AC_PREREQ([2.61]) |
| 9 | 10 | ||
| 10 | AC_DEFUN_ONCE([gl_HEADER_ERRNO_H], | 11 | AC_DEFUN_ONCE([gl_HEADER_ERRNO_H], |
| 11 | [ | 12 | [ |
| 12 | AC_REQUIRE([AC_PROG_CC]) | 13 | AC_REQUIRE([AC_PROG_CC]) |
| 14 | |||
| 15 | dnl Through the dependency on module extensions-aix, _LINUX_SOURCE_COMPAT | ||
| 16 | dnl gets defined already before this macro gets invoked. This persuades | ||
| 17 | dnl AIX 7.3 errno.h to assign ENOTEMPTY a value different than EEXIST. | ||
| 18 | |||
| 13 | AC_CACHE_CHECK([for complete errno.h], [gl_cv_header_errno_h_complete], [ | 19 | AC_CACHE_CHECK([for complete errno.h], [gl_cv_header_errno_h_complete], [ |
| 14 | AC_EGREP_CPP([booboo],[ | 20 | AC_EGREP_CPP([booboo],[ |
| 15 | #include <errno.h> | 21 | #include <errno.h> |
| @@ -64,6 +70,9 @@ booboo | |||
| 64 | #if !defined EILSEQ | 70 | #if !defined EILSEQ |
| 65 | booboo | 71 | booboo |
| 66 | #endif | 72 | #endif |
| 73 | #if !defined ESOCKTNOSUPPORT | ||
| 74 | booboo | ||
| 75 | #endif | ||
| 67 | ], | 76 | ], |
| 68 | [gl_cv_header_errno_h_complete=no], | 77 | [gl_cv_header_errno_h_complete=no], |
| 69 | [gl_cv_header_errno_h_complete=yes]) | 78 | [gl_cv_header_errno_h_complete=yes]) |
diff --git a/gl/m4/error.m4 b/gl/m4/error.m4 index 273b636b..1572250a 100644 --- a/gl/m4/error.m4 +++ b/gl/m4/error.m4 | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | # error.m4 | 1 | # error.m4 |
| 2 | # serial 16 | 2 | # serial 16 |
| 3 | dnl Copyright (C) 1996-1998, 2001-2004, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 1996-1998, 2001-2004, 2009-2025 Free Software Foundation, |
| 4 | dnl Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 9 | ||
| 8 | AC_DEFUN([gl_ERROR], | 10 | AC_DEFUN([gl_ERROR], |
| 9 | [ | 11 | [ |
diff --git a/gl/m4/error_h.m4 b/gl/m4/error_h.m4 index 050a410c..4ef5cbff 100644 --- a/gl/m4/error_h.m4 +++ b/gl/m4/error_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # error_h.m4 | 1 | # error_h.m4 |
| 2 | # serial 4 | 2 | # serial 5 |
| 3 | dnl Copyright (C) 1996-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 1996-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | dnl Provide a working <error.h>. | 10 | dnl Provide a working <error.h>. |
| @@ -111,12 +112,15 @@ AC_DEFUN_ONCE([gl_ERROR_H], | |||
| 111 | esac | 112 | esac |
| 112 | fi | 113 | fi |
| 113 | 114 | ||
| 114 | if test $HAVE_ERROR = 0 || test $REPLACE_ERROR = 1 \ | 115 | m4_ifdef([gl_HAVE_MODULE_VERROR], |
| 115 | || test $HAVE_ERROR_AT_LINE = 0 || test $REPLACE_ERROR_AT_LINE = 1; then | 116 | [COMPILE_ERROR_C=1], |
| 116 | COMPILE_ERROR_C=1 | 117 | [if test $HAVE_ERROR = 0 || test $REPLACE_ERROR = 1 \ |
| 117 | else | 118 | || test $HAVE_ERROR_AT_LINE = 0 \ |
| 118 | COMPILE_ERROR_C=0 | 119 | || test $REPLACE_ERROR_AT_LINE = 1; then |
| 119 | fi | 120 | COMPILE_ERROR_C=1 |
| 121 | else | ||
| 122 | COMPILE_ERROR_C=0 | ||
| 123 | fi]) | ||
| 120 | 124 | ||
| 121 | AC_SUBST([HAVE_ERROR]) | 125 | AC_SUBST([HAVE_ERROR]) |
| 122 | AC_SUBST([HAVE_ERROR_AT_LINE]) | 126 | AC_SUBST([HAVE_ERROR_AT_LINE]) |
diff --git a/gl/m4/exponentd.m4 b/gl/m4/exponentd.m4 index db597afc..08e93397 100644 --- a/gl/m4/exponentd.m4 +++ b/gl/m4/exponentd.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # exponentd.m4 | 1 | # exponentd.m4 |
| 2 | # serial 4 | 2 | # serial 5 |
| 3 | dnl Copyright (C) 2007-2008, 2010-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2008, 2010-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | AC_DEFUN_ONCE([gl_DOUBLE_EXPONENT_LOCATION], | 8 | AC_DEFUN_ONCE([gl_DOUBLE_EXPONENT_LOCATION], |
| 8 | [ | 9 | [ |
| 9 | AC_CACHE_CHECK([where to find the exponent in a 'double'], | 10 | AC_CACHE_CHECK([where to find the exponent in a 'double'], |
| @@ -84,7 +85,7 @@ int main () | |||
| 84 | dnl The newer VFP instructions assume little-endian order | 85 | dnl The newer VFP instructions assume little-endian order |
| 85 | dnl consistently. | 86 | dnl consistently. |
| 86 | AC_EGREP_CPP([mixed_endianness], [ | 87 | AC_EGREP_CPP([mixed_endianness], [ |
| 87 | #if defined arm || defined __arm || defined __arm__ | 88 | #if defined __arm__ |
| 88 | mixed_endianness | 89 | mixed_endianness |
| 89 | #endif | 90 | #endif |
| 90 | ], | 91 | ], |
diff --git a/gl/m4/extensions-aix.m4 b/gl/m4/extensions-aix.m4 new file mode 100644 index 00000000..08b703b4 --- /dev/null +++ b/gl/m4/extensions-aix.m4 | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | # extensions-aix.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright (C) 2024-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | # On AIX, most extensions are already enabled through the _ALL_SOURCE macro, | ||
| 10 | # defined by gl_USE_SYSTEM_EXTENSIONS. gl_USE_AIX_EXTENSIONS additionally | ||
| 11 | # activates more GNU and Linux-like behaviours, affecting | ||
| 12 | # - the time_t type, | ||
| 13 | # - errno values in <errno.h>: ENOTEMPTY | ||
| 14 | # - functions in <stdlib.h>: malloc calloc realloc valloc | ||
| 15 | # <https://www.ibm.com/docs/en/aix/7.3?topic=m-malloc-free-realloc-calloc-mallopt-mallinfo-mallinfo-heap-alloca-valloc-posix-memalign-subroutine> | ||
| 16 | # - functions in <string.h>: strerror_r (returns 'char *', like glibc) | ||
| 17 | # - functions in <dirent.h>: scandir, alphasort, readdir_r | ||
| 18 | # - functions in <netdb.h>: gethostbyname_r gethostbyaddr_r | ||
| 19 | # - declarations in <unistd.h>: sbrk | ||
| 20 | # and a couple of secondary <sys/*> header files. | ||
| 21 | |||
| 22 | AC_DEFUN_ONCE([gl_USE_AIX_EXTENSIONS], | ||
| 23 | [ | ||
| 24 | AC_DEFINE([_LINUX_SOURCE_COMPAT], [1], | ||
| 25 | [Define so that AIX headers are more compatible with GNU/Linux.]) | ||
| 26 | ]) | ||
diff --git a/gl/m4/extensions.m4 b/gl/m4/extensions.m4 index 1fb68956..76516bce 100644 --- a/gl/m4/extensions.m4 +++ b/gl/m4/extensions.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # extensions.m4 | 1 | # extensions.m4 |
| 2 | # serial 25 -*- Autoconf -*- | 2 | # serial 25 -*- Autoconf -*- |
| 3 | dnl Copyright (C) 2003, 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003, 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Enable extensions on systems that normally disable them. | 9 | # Enable extensions on systems that normally disable them. |
| 9 | 10 | ||
diff --git a/gl/m4/extern-inline.m4 b/gl/m4/extern-inline.m4 index 547da82a..d4fe6d82 100644 --- a/gl/m4/extern-inline.m4 +++ b/gl/m4/extern-inline.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # extern-inline.m4 | 1 | # extern-inline.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright 2012-2024 Free Software Foundation, Inc. | 3 | dnl Copyright 2012-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl 'extern inline' a la ISO C99. | 9 | dnl 'extern inline' a la ISO C99. |
| 9 | 10 | ||
diff --git a/gl/m4/fclose.m4 b/gl/m4/fclose.m4 index 0c1358ed..cfb92e28 100644 --- a/gl/m4/fclose.m4 +++ b/gl/m4/fclose.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # fclose.m4 | 1 | # fclose.m4 |
| 2 | # serial 12 | 2 | # serial 12 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_FUNC_FCLOSE], | 9 | AC_DEFUN_ONCE([gl_FUNC_FCLOSE], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/fcntl-o.m4 b/gl/m4/fcntl-o.m4 index 43aa1325..8020c481 100644 --- a/gl/m4/fcntl-o.m4 +++ b/gl/m4/fcntl-o.m4 | |||
| @@ -1,15 +1,17 @@ | |||
| 1 | # fcntl-o.m4 | 1 | # fcntl-o.m4 |
| 2 | # serial 8 | 2 | # serial 12 |
| 3 | dnl Copyright (C) 2006, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Written by Paul Eggert. | 9 | dnl Written by Paul Eggert. |
| 9 | 10 | ||
| 10 | AC_PREREQ([2.60]) | 11 | AC_PREREQ([2.60]) |
| 11 | 12 | ||
| 12 | # Test whether the flags O_NOATIME and O_NOFOLLOW actually work. | 13 | # Test whether the flags O_DIRECTORY, O_NOATIME and O_NOFOLLOW actually work. |
| 14 | # Define HAVE_WORKING_O_DIRECTORY to 1 if O_DIRECTORY works, or to 0 otherwise. | ||
| 13 | # Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise. | 15 | # Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise. |
| 14 | # Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise. | 16 | # Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise. |
| 15 | AC_DEFUN([gl_FCNTL_O_FLAGS], | 17 | AC_DEFUN([gl_FCNTL_O_FLAGS], |
| @@ -30,16 +32,23 @@ AC_DEFUN([gl_FCNTL_O_FLAGS], | |||
| 30 | #else /* on Windows with MSVC */ | 32 | #else /* on Windows with MSVC */ |
| 31 | # include <io.h> | 33 | # include <io.h> |
| 32 | # include <stdlib.h> | 34 | # include <stdlib.h> |
| 33 | # defined sleep(n) _sleep ((n) * 1000) | 35 | # define sleep(n) _sleep ((n) * 1000) |
| 34 | #endif | 36 | #endif |
| 37 | #include <errno.h> | ||
| 35 | #include <fcntl.h> | 38 | #include <fcntl.h> |
| 36 | ]GL_MDA_DEFINES[ | 39 | ]GL_MDA_DEFINES[ |
| 40 | #ifndef O_DIRECTORY | ||
| 41 | #define O_DIRECTORY 0 | ||
| 42 | #endif | ||
| 37 | #ifndef O_NOATIME | 43 | #ifndef O_NOATIME |
| 38 | #define O_NOATIME 0 | 44 | #define O_NOATIME 0 |
| 39 | #endif | 45 | #endif |
| 40 | #ifndef O_NOFOLLOW | 46 | #ifndef O_NOFOLLOW |
| 41 | #define O_NOFOLLOW 0 | 47 | #define O_NOFOLLOW 0 |
| 42 | #endif | 48 | #endif |
| 49 | #ifndef O_SEARCH | ||
| 50 | #define O_SEARCH O_RDONLY | ||
| 51 | #endif | ||
| 43 | static int const constants[] = | 52 | static int const constants[] = |
| 44 | { | 53 | { |
| 45 | O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, | 54 | O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, |
| @@ -52,31 +61,38 @@ AC_DEFUN([gl_FCNTL_O_FLAGS], | |||
| 52 | { | 61 | { |
| 53 | static char const sym[] = "conftest.sym"; | 62 | static char const sym[] = "conftest.sym"; |
| 54 | if (symlink ("/dev/null", sym) != 0) | 63 | if (symlink ("/dev/null", sym) != 0) |
| 55 | result |= 2; | 64 | result |= 1; |
| 56 | else | 65 | else |
| 57 | { | 66 | { |
| 58 | int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0); | 67 | int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0); |
| 59 | if (fd >= 0) | 68 | if (fd >= 0) |
| 60 | { | 69 | { |
| 61 | close (fd); | 70 | close (fd); |
| 62 | result |= 4; | 71 | result |= 3; |
| 63 | } | 72 | } |
| 64 | } | 73 | } |
| 65 | if (unlink (sym) != 0 || symlink (".", sym) != 0) | 74 | if (unlink (sym) != 0 || symlink (".", sym) != 0) |
| 66 | result |= 2; | 75 | result |= 1; |
| 67 | else | 76 | else |
| 68 | { | 77 | { |
| 69 | int fd = open (sym, O_RDONLY | O_NOFOLLOW); | 78 | int fd = open (sym, O_RDONLY | O_NOFOLLOW); |
| 70 | if (fd >= 0) | 79 | if (fd >= 0) |
| 71 | { | 80 | { |
| 72 | close (fd); | 81 | close (fd); |
| 73 | result |= 4; | 82 | result |= 3; |
| 74 | } | 83 | } |
| 75 | } | 84 | } |
| 76 | unlink (sym); | 85 | unlink (sym); |
| 77 | } | 86 | } |
| 78 | #endif | 87 | #endif |
| 79 | { | 88 | { |
| 89 | int fd = open ("confdefs.h", O_SEARCH | O_DIRECTORY); | ||
| 90 | if (!(fd < 0 && errno == ENOTDIR)) | ||
| 91 | result |= 4; | ||
| 92 | if (0 <= fd) | ||
| 93 | close (fd); | ||
| 94 | } | ||
| 95 | { | ||
| 80 | static char const file[] = "confdefs.h"; | 96 | static char const file[] = "confdefs.h"; |
| 81 | int fd = open (file, O_RDONLY | O_NOATIME); | 97 | int fd = open (file, O_RDONLY | O_NOATIME); |
| 82 | if (fd < 0) | 98 | if (fd < 0) |
| @@ -111,31 +127,46 @@ AC_DEFUN([gl_FCNTL_O_FLAGS], | |||
| 111 | } | 127 | } |
| 112 | return result;]])], | 128 | return result;]])], |
| 113 | [gl_cv_header_working_fcntl_h=yes], | 129 | [gl_cv_header_working_fcntl_h=yes], |
| 114 | [case $? in #( | 130 | [AS_CASE([$?], |
| 115 | 4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( | 131 | dnl We cannot catch exit code 1 or 2 here, because |
| 116 | 64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #( | 132 | dnl - exit code 1 can occur through a compilation error on mingw (e.g. |
| 117 | 68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( | 133 | dnl when O_NOCTTY, O_NONBLOCK, O_SYNC are not defined) or when |
| 118 | *) gl_cv_header_working_fcntl_h='no';; | 134 | dnl result = 1, whereas |
| 119 | esac], | 135 | dnl - exit code 2 can occur through a compilation error on MSVC (e.g. |
| 120 | [case "$host_os" in | 136 | dnl again when O_NOCTTY, O_NONBLOCK, O_SYNC are not defined) or when |
| 121 | # Guess 'no' on native Windows. | 137 | dnl result = 2. |
| 122 | mingw* | windows*) gl_cv_header_working_fcntl_h='no' ;; | 138 | [ 3], [gl_cv_header_working_fcntl_h="no (bad O_NOFOLLOW)"], |
| 123 | *) gl_cv_header_working_fcntl_h=cross-compiling ;; | 139 | [ 4], [gl_cv_header_working_fcntl_h="no (bad O_DIRECTORY)"], |
| 124 | esac | 140 | [ 7], [gl_cv_header_working_fcntl_h="no (bad O_NOFOLLOW, O_DIRECTORY)"], |
| 125 | ]) | 141 | [64], [gl_cv_header_working_fcntl_h="no (bad O_NOATIME)"], |
| 126 | ]) | 142 | [67], [gl_cv_header_working_fcntl_h="no (bad O_NOFOLLOW, O_NOATIME)"], |
| 143 | [68], [gl_cv_header_working_fcntl_h="no (bad O_DIRECTORY, O_NOATIME)"], | ||
| 144 | [71], [gl_cv_header_working_fcntl_h="no (bad O_NOFOLLOW, O_DIRECTORY, O_NOATIME)"], | ||
| 145 | [gl_cv_header_working_fcntl_h="no"])], | ||
| 146 | [AS_CASE([$host_os,$gl_cross_guess_normal], | ||
| 147 | # The O_DIRECTORY test is known to fail on Mac OS X 10.4.11 (2007) | ||
| 148 | # (see <https://bugs.gnu.org/78509#95>) | ||
| 149 | # and to succeed on Mac OS X 10.5.8 [darwin9.8.0] (2009). | ||
| 150 | # Guess it fails on Mac OS X 10.4.x and earlier. | ||
| 151 | [darwin[[0-8]].*yes], | ||
| 152 | [gl_cv_header_working_fcntl_h="guessing no (bad O_DIRECTORY)"], | ||
| 153 | # Known to be "no" on native MS-Windows. | ||
| 154 | [mingw* | windows*], | ||
| 155 | [gl_cv_header_working_fcntl_h=no], | ||
| 156 | [gl_cv_header_working_fcntl_h=$gl_cross_guess_normal])])]) | ||
| 157 | |||
| 158 | AS_CASE([$gl_cv_header_working_fcntl_h], | ||
| 159 | [*O_DIRECTORY* | *no], [gl_val=0], [gl_val=1]) | ||
| 160 | AC_DEFINE_UNQUOTED([HAVE_WORKING_O_DIRECTORY], [$gl_val], | ||
| 161 | [Define to 1 if O_DIRECTORY works, 0 otherwise.]) | ||
| 127 | 162 | ||
| 128 | case $gl_cv_header_working_fcntl_h in #( | 163 | AS_CASE([$gl_cv_header_working_fcntl_h], |
| 129 | *O_NOATIME* | no | cross-compiling) ac_val=0;; #( | 164 | [*O_NOATIME* | *no], [gl_val=0], [gl_val=1]) |
| 130 | *) ac_val=1;; | 165 | AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$gl_val], |
| 131 | esac | 166 | [Define to 1 if O_NOATIME works, 0 otherwise.]) |
| 132 | AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val], | ||
| 133 | [Define to 1 if O_NOATIME works.]) | ||
| 134 | 167 | ||
| 135 | case $gl_cv_header_working_fcntl_h in #( | 168 | AS_CASE([$gl_cv_header_working_fcntl_h], |
| 136 | *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #( | 169 | [*O_NOFOLLOW* | *no], [gl_val=0], [gl_val=1]) |
| 137 | *) ac_val=1;; | 170 | AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$gl_val], |
| 138 | esac | 171 | [Define to 1 if O_NOFOLLOW works, 0 otherwise.]) |
| 139 | AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val], | ||
| 140 | [Define to 1 if O_NOFOLLOW works.]) | ||
| 141 | ]) | 172 | ]) |
diff --git a/gl/m4/fcntl.m4 b/gl/m4/fcntl.m4 index f6d0f377..08ab936f 100644 --- a/gl/m4/fcntl.m4 +++ b/gl/m4/fcntl.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # fcntl.m4 | 1 | # fcntl.m4 |
| 2 | # serial 12 | 2 | # serial 12 |
| 3 | dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # For now, this module ensures that fcntl() | 9 | # For now, this module ensures that fcntl() |
| 9 | # - supports F_DUPFD correctly | 10 | # - supports F_DUPFD correctly |
diff --git a/gl/m4/fcntl_h.m4 b/gl/m4/fcntl_h.m4 index b69f7a0c..1c9f9cce 100644 --- a/gl/m4/fcntl_h.m4 +++ b/gl/m4/fcntl_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # fcntl_h.m4 | 1 | # fcntl_h.m4 |
| 2 | # serial 20 | 2 | # serial 20 |
| 3 | dnl Copyright (C) 2006-2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006-2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Configure fcntl.h. | 9 | # Configure fcntl.h. |
| 9 | 10 | ||
diff --git a/gl/m4/fflush.m4 b/gl/m4/fflush.m4 index 43fc3bf3..399065b6 100644 --- a/gl/m4/fflush.m4 +++ b/gl/m4/fflush.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # fflush.m4 | 1 | # fflush.m4 |
| 2 | # serial 19 | 2 | # serial 20 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Eric Blake | 9 | dnl From Eric Blake |
| 9 | 10 | ||
| @@ -79,8 +80,9 @@ AC_DEFUN([gl_FUNC_FFLUSH_STDIN], | |||
| 79 | [gl_cv_func_fflush_stdin=yes], | 80 | [gl_cv_func_fflush_stdin=yes], |
| 80 | [gl_cv_func_fflush_stdin=no], | 81 | [gl_cv_func_fflush_stdin=no], |
| 81 | [case "$host_os" in | 82 | [case "$host_os" in |
| 82 | # Guess no on native Windows. | 83 | # Guess no on NetBSD, OpenBSD, native Windows. |
| 83 | mingw* | windows*) gl_cv_func_fflush_stdin="guessing no" ;; | 84 | netbsd* | openbsd* | mingw* | windows*) |
| 85 | gl_cv_func_fflush_stdin="guessing no" ;; | ||
| 84 | *) gl_cv_func_fflush_stdin=cross ;; | 86 | *) gl_cv_func_fflush_stdin=cross ;; |
| 85 | esac | 87 | esac |
| 86 | ]) | 88 | ]) |
| @@ -92,8 +94,8 @@ AC_DEFUN([gl_FUNC_FFLUSH_STDIN], | |||
| 92 | *) gl_func_fflush_stdin='(-1)' ;; | 94 | *) gl_func_fflush_stdin='(-1)' ;; |
| 93 | esac | 95 | esac |
| 94 | AC_DEFINE_UNQUOTED([FUNC_FFLUSH_STDIN], [$gl_func_fflush_stdin], | 96 | AC_DEFINE_UNQUOTED([FUNC_FFLUSH_STDIN], [$gl_func_fflush_stdin], |
| 95 | [Define to 1 if fflush is known to work on stdin as per POSIX.1-2008, | 97 | [Define to 1 if fflush is known to work on stdin as per POSIX.1-2008 |
| 96 | 0 if fflush is known to not work, -1 if unknown.]) | 98 | or later, 0 if fflush is known to not work, -1 if unknown.]) |
| 97 | ]) | 99 | ]) |
| 98 | 100 | ||
| 99 | # Prerequisites of lib/fflush.c. | 101 | # Prerequisites of lib/fflush.c. |
diff --git a/gl/m4/float_h.m4 b/gl/m4/float_h.m4 index c95d4171..8580c9c9 100644 --- a/gl/m4/float_h.m4 +++ b/gl/m4/float_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # float_h.m4 | 1 | # float_h.m4 |
| 2 | # serial 14 | 2 | # serial 15 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FLOAT_H], | 9 | AC_DEFUN([gl_FLOAT_H], |
| 9 | [ | 10 | [ |
| @@ -54,6 +55,31 @@ changequote([,])dnl | |||
| 54 | ;; | 55 | ;; |
| 55 | esac | 56 | esac |
| 56 | 57 | ||
| 58 | dnl Test for completeness w.r.t. ISO C 23. | ||
| 59 | REPLACE_FLOAT_SNAN=0 | ||
| 60 | AC_CACHE_CHECK([whether float.h conforms to ISO C23], | ||
| 61 | [gl_cv_header_float_h_isoc23], | ||
| 62 | [AC_COMPILE_IFELSE( | ||
| 63 | [AC_LANG_PROGRAM( | ||
| 64 | [[#include <float.h> | ||
| 65 | int x[] = { FLT_DECIMAL_DIG, DBL_DECIMAL_DIG, LDBL_DECIMAL_DIG }; | ||
| 66 | float maxf = FLT_NORM_MAX; | ||
| 67 | double maxd = DBL_NORM_MAX; | ||
| 68 | long double maxl = LDBL_NORM_MAX; | ||
| 69 | ]], | ||
| 70 | [[float sf = FLT_SNAN; | ||
| 71 | double sd = DBL_SNAN; | ||
| 72 | long double sl = LDBL_SNAN; | ||
| 73 | return (sf != 0) + (sd != 0) + (sl != 0); | ||
| 74 | ]])], | ||
| 75 | [gl_cv_header_float_h_isoc23=yes], | ||
| 76 | [gl_cv_header_float_h_isoc23=no]) | ||
| 77 | ]) | ||
| 78 | if test $gl_cv_header_float_h_isoc23 != yes; then | ||
| 79 | GL_GENERATE_FLOAT_H=true | ||
| 80 | REPLACE_FLOAT_SNAN=1 | ||
| 81 | fi | ||
| 82 | |||
| 57 | dnl Test against glibc-2.7 Linux/SPARC64 bug. | 83 | dnl Test against glibc-2.7 Linux/SPARC64 bug. |
| 58 | REPLACE_ITOLD=0 | 84 | REPLACE_ITOLD=0 |
| 59 | AC_CACHE_CHECK([whether conversion from 'int' to 'long double' works], | 85 | AC_CACHE_CHECK([whether conversion from 'int' to 'long double' works], |
diff --git a/gl/m4/floorf.m4 b/gl/m4/floorf.m4 index 2572c848..cb75fce9 100644 --- a/gl/m4/floorf.m4 +++ b/gl/m4/floorf.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # floorf.m4 | 1 | # floorf.m4 |
| 2 | # serial 21 | 2 | # serial 21 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_FLOORF], | 9 | AC_DEFUN([gl_FUNC_FLOORF], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/fopen.m4 b/gl/m4/fopen.m4 index f3b7aadd..e27b3270 100644 --- a/gl/m4/fopen.m4 +++ b/gl/m4/fopen.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # fopen.m4 | 1 | # fopen.m4 |
| 2 | # serial 16 | 2 | # serial 16 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_FOPEN_ITSELF], | 9 | AC_DEFUN([gl_FUNC_FOPEN_ITSELF], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/fpurge.m4 b/gl/m4/fpurge.m4 index a77f5b96..408a2579 100644 --- a/gl/m4/fpurge.m4 +++ b/gl/m4/fpurge.m4 | |||
| @@ -1,65 +1,65 @@ | |||
| 1 | # fpurge.m4 | 1 | # fpurge.m4 |
| 2 | # serial 14 | 2 | # serial 16 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_FPURGE], | 9 | AC_DEFUN([gl_FUNC_FPURGE], |
| 9 | [ | 10 | [ |
| 10 | AC_REQUIRE([gl_STDIO_H_DEFAULTS]) | 11 | AC_REQUIRE([gl_STDIO_H_DEFAULTS]) |
| 11 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 12 | AC_CHECK_HEADERS_ONCE([stdio_ext.h]) | 12 | AC_CHECK_HEADERS_ONCE([stdio_ext.h]) |
| 13 | AC_CHECK_FUNCS_ONCE([fpurge]) | 13 | AC_CHECK_FUNCS_ONCE([fpurge]) |
| 14 | gl_CHECK_FUNCS_ANDROID([__fpurge], [[#include <stdio_ext.h>]]) | 14 | gl_CHECK_FUNCS_ANDROID([__fpurge], [[#include <stdio_ext.h>]]) |
| 15 | AC_CHECK_DECLS([fpurge], , , [[#include <stdio.h>]]) | 15 | AC_CHECK_DECLS([fpurge], , , [[#include <stdio.h>]]) |
| 16 | if test "x$ac_cv_func_fpurge" = xyes; then | 16 | if test $ac_cv_func_fpurge = yes; then |
| 17 | HAVE_FPURGE=1 | 17 | HAVE_FPURGE=1 |
| 18 | # Detect BSD bug. Only cygwin 1.7 and musl are known to be immune. | 18 | # Detect BSD bug. Only cygwin 1.7 and musl are known to be immune. |
| 19 | AC_CACHE_CHECK([whether fpurge works], [gl_cv_func_fpurge_works], | 19 | AC_CACHE_CHECK([whether fpurge works], [gl_cv_func_fpurge_works], |
| 20 | [AC_RUN_IFELSE( | 20 | [if test $ac_cv_have_decl_fpurge = yes; then |
| 21 | [AC_LANG_PROGRAM( | 21 | AC_RUN_IFELSE( |
| 22 | [[#include <stdio.h> | 22 | [AC_LANG_PROGRAM( |
| 23 | ]], | 23 | [[#include <stdio.h> |
| 24 | [[FILE *f = fopen ("conftest.txt", "w+"); | 24 | ]], |
| 25 | if (!f) | 25 | [[FILE *f = fopen ("conftest.txt", "w+"); |
| 26 | return 1; | 26 | if (!f) |
| 27 | if (fputc ('a', f) != 'a') | 27 | return 1; |
| 28 | { fclose (f); return 2; } | 28 | if (fputc ('a', f) != 'a') |
| 29 | rewind (f); | 29 | { fclose (f); return 2; } |
| 30 | if (fgetc (f) != 'a') | 30 | rewind (f); |
| 31 | { fclose (f); return 3; } | 31 | if (fgetc (f) != 'a') |
| 32 | if (fgetc (f) != EOF) | 32 | { fclose (f); return 3; } |
| 33 | { fclose (f); return 4; } | 33 | if (fgetc (f) != EOF) |
| 34 | if (fpurge (f) != 0) | 34 | { fclose (f); return 4; } |
| 35 | { fclose (f); return 5; } | 35 | if (fpurge (f) != 0) |
| 36 | if (putc ('b', f) != 'b') | 36 | { fclose (f); return 5; } |
| 37 | { fclose (f); return 6; } | 37 | if (putc ('b', f) != 'b') |
| 38 | if (fclose (f) != 0) | 38 | { fclose (f); return 6; } |
| 39 | return 7; | 39 | if (fclose (f) != 0) |
| 40 | if ((f = fopen ("conftest.txt", "r")) == NULL) | 40 | return 7; |
| 41 | return 8; | 41 | if ((f = fopen ("conftest.txt", "r")) == NULL) |
| 42 | if (fgetc (f) != 'a') | 42 | return 8; |
| 43 | { fclose (f); return 9; } | 43 | if (fgetc (f) != 'a') |
| 44 | if (fgetc (f) != 'b') | 44 | { fclose (f); return 9; } |
| 45 | { fclose (f); return 10; } | 45 | if (fgetc (f) != 'b') |
| 46 | if (fgetc (f) != EOF) | 46 | { fclose (f); return 10; } |
| 47 | { fclose (f); return 11; } | 47 | if (fgetc (f) != EOF) |
| 48 | if (fclose (f) != 0) | 48 | { fclose (f); return 11; } |
| 49 | return 12; | 49 | if (fclose (f) != 0) |
| 50 | if (remove ("conftest.txt") != 0) | 50 | return 12; |
| 51 | return 13; | 51 | if (remove ("conftest.txt") != 0) |
| 52 | return 0; | 52 | return 13; |
| 53 | ]])], | 53 | return 0; |
| 54 | [gl_cv_func_fpurge_works=yes], | 54 | ]])], |
| 55 | [gl_cv_func_fpurge_works=no], | 55 | [gl_cv_func_fpurge_works=yes], |
| 56 | [case "$host_os" in | 56 | [gl_cv_func_fpurge_works=no], |
| 57 | # Guess yes on musl systems. | 57 | [# Obey --enable-cross-guesses. |
| 58 | *-musl* | midipix*) gl_cv_func_fpurge_works="guessing yes" ;; | 58 | gl_cv_func_fpurge_works="$gl_cross_guess_normal" |
| 59 | # Otherwise obey --enable-cross-guesses. | 59 | ]) |
| 60 | *) gl_cv_func_fpurge_works="$gl_cross_guess_normal" ;; | 60 | else |
| 61 | esac | 61 | gl_cv_func_fpurge_works=no |
| 62 | ]) | 62 | fi |
| 63 | ]) | 63 | ]) |
| 64 | case "$gl_cv_func_fpurge_works" in | 64 | case "$gl_cv_func_fpurge_works" in |
| 65 | *yes) ;; | 65 | *yes) ;; |
diff --git a/gl/m4/freading.m4 b/gl/m4/freading.m4 index be899456..373d2bff 100644 --- a/gl/m4/freading.m4 +++ b/gl/m4/freading.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # freading.m4 | 1 | # freading.m4 |
| 2 | # serial 3 | 2 | # serial 3 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_FREADING], | 9 | AC_DEFUN([gl_FUNC_FREADING], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/free.m4 b/gl/m4/free.m4 index a2b596d6..485d8243 100644 --- a/gl/m4/free.m4 +++ b/gl/m4/free.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # free.m4 | 1 | # free.m4 |
| 2 | # serial 6 | 2 | # serial 6 |
| 3 | dnl Copyright (C) 2003-2005, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003-2005, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Written by Paul Eggert and Bruno Haible. | 9 | # Written by Paul Eggert and Bruno Haible. |
| 9 | 10 | ||
diff --git a/gl/m4/fseek.m4 b/gl/m4/fseek.m4 index fb220a1f..ce728f60 100644 --- a/gl/m4/fseek.m4 +++ b/gl/m4/fseek.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # fseek.m4 | 1 | # fseek.m4 |
| 2 | # serial 4 | 2 | # serial 4 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_FSEEK], | 9 | AC_DEFUN([gl_FUNC_FSEEK], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/fseeko.m4 b/gl/m4/fseeko.m4 index 5682a1f2..c093d399 100644 --- a/gl/m4/fseeko.m4 +++ b/gl/m4/fseeko.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # fseeko.m4 | 1 | # fseeko.m4 |
| 2 | # serial 20 | 2 | # serial 21 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_FSEEKO], | 9 | AC_DEFUN([gl_FUNC_FSEEKO], |
| 9 | [ | 10 | [ |
| @@ -69,6 +70,10 @@ AC_DEFUN([gl_STDIN_LARGE_OFFSET], | |||
| 69 | # Prerequisites of lib/fseeko.c. | 70 | # Prerequisites of lib/fseeko.c. |
| 70 | AC_DEFUN([gl_PREREQ_FSEEKO], | 71 | AC_DEFUN([gl_PREREQ_FSEEKO], |
| 71 | [ | 72 | [ |
| 73 | if test $gl_cv_func_fseeko != no; then | ||
| 74 | AC_DEFINE([HAVE_FSEEKO], [1], | ||
| 75 | [Define to 1 if the system has the fseeko function.]) | ||
| 76 | fi | ||
| 72 | dnl Native Windows has the function _fseeki64. mingw hides it in some | 77 | dnl Native Windows has the function _fseeki64. mingw hides it in some |
| 73 | dnl circumstances, but mingw64 makes it usable again. | 78 | dnl circumstances, but mingw64 makes it usable again. |
| 74 | AC_CHECK_FUNCS([_fseeki64]) | 79 | AC_CHECK_FUNCS([_fseeki64]) |
diff --git a/gl/m4/fseterr.m4 b/gl/m4/fseterr.m4 new file mode 100644 index 00000000..3a94c288 --- /dev/null +++ b/gl/m4/fseterr.m4 | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # fseterr.m4 | ||
| 2 | # serial 2 | ||
| 3 | dnl Copyright (C) 2012-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN([gl_FUNC_FSETERR], | ||
| 10 | [ | ||
| 11 | gl_CHECK_FUNCS_ANDROID([__fseterr], | ||
| 12 | [[#include <stdio.h> | ||
| 13 | #include <stdio_ext.h> | ||
| 14 | ]]) | ||
| 15 | ]) | ||
diff --git a/gl/m4/fstat.m4 b/gl/m4/fstat.m4 index 47777b0c..e89bbc32 100644 --- a/gl/m4/fstat.m4 +++ b/gl/m4/fstat.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # fstat.m4 | 1 | # fstat.m4 |
| 2 | # serial 10 | 2 | # serial 10 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_FSTAT], | 9 | AC_DEFUN([gl_FUNC_FSTAT], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/fstypename.m4 b/gl/m4/fstypename.m4 index 05a68805..4407b765 100644 --- a/gl/m4/fstypename.m4 +++ b/gl/m4/fstypename.m4 | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | # fstypename.m4 | 1 | # fstypename.m4 |
| 2 | # serial 6 | 2 | # serial 6 |
| 3 | dnl Copyright (C) 1998-1999, 2001, 2004, 2006, 2009-2024 Free Software | 3 | dnl Copyright (C) 1998-1999, 2001, 2004, 2006, 2009-2025 Free Software |
| 4 | dnl Foundation, Inc. | 4 | dnl Foundation, Inc. |
| 5 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 6 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 7 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 8 | 9 | ||
| 9 | dnl From Jim Meyering. | 10 | dnl From Jim Meyering. |
| 10 | dnl | 11 | dnl |
diff --git a/gl/m4/fsusage.m4 b/gl/m4/fsusage.m4 index 1ce90660..bb7b6e43 100644 --- a/gl/m4/fsusage.m4 +++ b/gl/m4/fsusage.m4 | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | # fsusage.m4 | 1 | # fsusage.m4 |
| 2 | # serial 35 | 2 | # serial 35 |
| 3 | dnl Copyright (C) 1997-1998, 2000-2001, 2003-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 1997-1998, 2000-2001, 2003-2025 Free Software Foundation, |
| 4 | dnl Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 9 | ||
| 8 | # Obtaining file system usage information. | 10 | # Obtaining file system usage information. |
| 9 | 11 | ||
diff --git a/gl/m4/ftell.m4 b/gl/m4/ftell.m4 index ab10736b..d5610b70 100644 --- a/gl/m4/ftell.m4 +++ b/gl/m4/ftell.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # ftell.m4 | 1 | # ftell.m4 |
| 2 | # serial 3 | 2 | # serial 3 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_FTELL], | 9 | AC_DEFUN([gl_FUNC_FTELL], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/ftello.m4 b/gl/m4/ftello.m4 index 0eb8fa0d..35d30f98 100644 --- a/gl/m4/ftello.m4 +++ b/gl/m4/ftello.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # ftello.m4 | 1 | # ftello.m4 |
| 2 | # serial 16 | 2 | # serial 17 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_FTELLO], | 9 | AC_DEFUN([gl_FUNC_FTELLO], |
| 9 | [ | 10 | [ |
| @@ -157,6 +158,10 @@ main (void) | |||
| 157 | # Prerequisites of lib/ftello.c. | 158 | # Prerequisites of lib/ftello.c. |
| 158 | AC_DEFUN([gl_PREREQ_FTELLO], | 159 | AC_DEFUN([gl_PREREQ_FTELLO], |
| 159 | [ | 160 | [ |
| 161 | if test $gl_cv_func_ftello != no; then | ||
| 162 | AC_DEFINE([HAVE_FTELLO], [1], | ||
| 163 | [Define to 1 if the system has the ftello function.]) | ||
| 164 | fi | ||
| 160 | dnl Native Windows has the function _ftelli64. mingw hides it, but mingw64 | 165 | dnl Native Windows has the function _ftelli64. mingw hides it, but mingw64 |
| 161 | dnl makes it usable again. | 166 | dnl makes it usable again. |
| 162 | AC_CHECK_FUNCS([_ftelli64]) | 167 | AC_CHECK_FUNCS([_ftelli64]) |
diff --git a/gl/m4/getaddrinfo.m4 b/gl/m4/getaddrinfo.m4 index 8e209177..2931d526 100644 --- a/gl/m4/getaddrinfo.m4 +++ b/gl/m4/getaddrinfo.m4 | |||
| @@ -1,14 +1,16 @@ | |||
| 1 | # getaddrinfo.m4 | 1 | # getaddrinfo.m4 |
| 2 | # serial 35 | 2 | # serial 38 |
| 3 | dnl Copyright (C) 2004-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2004-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_GETADDRINFO], | 9 | AC_DEFUN([gl_GETADDRINFO], |
| 9 | [ | 10 | [ |
| 10 | AC_REQUIRE([gl_SYS_SOCKET_H])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H | 11 | AC_REQUIRE([gl_SYS_SOCKET_H])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H |
| 11 | AC_REQUIRE([gl_NETDB_H])dnl for HAVE_NETDB_H | 12 | AC_REQUIRE([gl_NETDB_H])dnl for HAVE_NETDB_H |
| 13 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 12 | GETADDRINFO_LIB= | 14 | GETADDRINFO_LIB= |
| 13 | gai_saved_LIBS="$LIBS" | 15 | gai_saved_LIBS="$LIBS" |
| 14 | 16 | ||
| @@ -87,6 +89,46 @@ int getaddrinfo (const char *, const char *, const struct addrinfo *, struct add | |||
| 87 | HAVE_GETADDRINFO=0 | 89 | HAVE_GETADDRINFO=0 |
| 88 | fi | 90 | fi |
| 89 | fi | 91 | fi |
| 92 | if test $HAVE_GETADDRINFO != 0; then | ||
| 93 | AC_CACHE_CHECK([whether getaddrinfo supports AI_NUMERICSERV], | ||
| 94 | [gl_cv_func_getaddrinfo_works], | ||
| 95 | [AC_RUN_IFELSE( | ||
| 96 | [AC_LANG_PROGRAM([[ | ||
| 97 | #include <sys/types.h> | ||
| 98 | #ifdef HAVE_SYS_SOCKET_H | ||
| 99 | #include <sys/socket.h> | ||
| 100 | #endif | ||
| 101 | #ifdef HAVE_NETDB_H | ||
| 102 | #include <netdb.h> | ||
| 103 | #endif | ||
| 104 | #ifdef HAVE_WS2TCPIP_H | ||
| 105 | #include <ws2tcpip.h> | ||
| 106 | #endif | ||
| 107 | #include <stddef.h> | ||
| 108 | #include <string.h> | ||
| 109 | ]], [[ | ||
| 110 | struct addrinfo hints; | ||
| 111 | struct addrinfo *ai; | ||
| 112 | memset (&hints, 0, sizeof (hints)); | ||
| 113 | hints.ai_flags = AI_NUMERICSERV; | ||
| 114 | return getaddrinfo ("www.gnu.org", "http", &hints, &ai) != EAI_NONAME; | ||
| 115 | ]]) | ||
| 116 | ], | ||
| 117 | [gl_cv_func_getaddrinfo_works=yes], | ||
| 118 | [gl_cv_func_getaddrinfo_works=no], | ||
| 119 | [case "$host_os" in | ||
| 120 | # Guess no on native Windows. | ||
| 121 | mingw* | windows*) gl_cv_func_getaddrinfo_works="guessing no" ;; | ||
| 122 | # Guess yes otherwise. | ||
| 123 | *) gl_cv_func_getaddrinfo_works="guessing yes" ;; | ||
| 124 | esac | ||
| 125 | ]) | ||
| 126 | ]) | ||
| 127 | case "$gl_cv_func_getaddrinfo_works" in | ||
| 128 | *yes) ;; | ||
| 129 | *) REPLACE_GETADDRINFO=1 ;; | ||
| 130 | esac | ||
| 131 | fi | ||
| 90 | AC_DEFINE_UNQUOTED([HAVE_GETADDRINFO], [$HAVE_GETADDRINFO], | 132 | AC_DEFINE_UNQUOTED([HAVE_GETADDRINFO], [$HAVE_GETADDRINFO], |
| 91 | [Define to 1 if getaddrinfo exists, or to 0 otherwise.]) | 133 | [Define to 1 if getaddrinfo exists, or to 0 otherwise.]) |
| 92 | 134 | ||
diff --git a/gl/m4/getdelim.m4 b/gl/m4/getdelim.m4 index 61139039..63d88306 100644 --- a/gl/m4/getdelim.m4 +++ b/gl/m4/getdelim.m4 | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | # getdelim.m4 | 1 | # getdelim.m4 |
| 2 | # serial 19 | 2 | # serial 19 |
| 3 | 3 | ||
| 4 | dnl Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc. | 4 | dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. |
| 5 | dnl | 5 | dnl |
| 6 | dnl This file is free software; the Free Software Foundation | 6 | dnl This file is free software; the Free Software Foundation |
| 7 | dnl gives unlimited permission to copy and/or distribute it, | 7 | dnl gives unlimited permission to copy and/or distribute it, |
| 8 | dnl with or without modifications, as long as this notice is preserved. | 8 | dnl with or without modifications, as long as this notice is preserved. |
| 9 | dnl This file is offered as-is, without any warranty. | ||
| 9 | 10 | ||
| 10 | AC_PREREQ([2.59]) | 11 | AC_PREREQ([2.59]) |
| 11 | 12 | ||
diff --git a/gl/m4/getdtablesize.m4 b/gl/m4/getdtablesize.m4 index aaefe9b2..112c1c4d 100644 --- a/gl/m4/getdtablesize.m4 +++ b/gl/m4/getdtablesize.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # getdtablesize.m4 | 1 | # getdtablesize.m4 |
| 2 | # serial 8 | 2 | # serial 8 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_GETDTABLESIZE], | 9 | AC_DEFUN([gl_FUNC_GETDTABLESIZE], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/gethostname.m4 b/gl/m4/gethostname.m4 index 2f743b7d..be71ff78 100644 --- a/gl/m4/gethostname.m4 +++ b/gl/m4/gethostname.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # gethostname.m4 | 1 | # gethostname.m4 |
| 2 | # serial 16 | 2 | # serial 16 |
| 3 | dnl Copyright (C) 2002, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Ensure | 9 | # Ensure |
| 9 | # - the gethostname() function, | 10 | # - the gethostname() function, |
diff --git a/gl/m4/getline.m4 b/gl/m4/getline.m4 index 36513cd4..b97b8011 100644 --- a/gl/m4/getline.m4 +++ b/gl/m4/getline.m4 | |||
| @@ -1,12 +1,13 @@ | |||
| 1 | # getline.m4 | 1 | # getline.m4 |
| 2 | # serial 33 | 2 | # serial 33 |
| 3 | 3 | ||
| 4 | dnl Copyright (C) 1998-2003, 2005-2007, 2009-2024 Free Software Foundation, | 4 | dnl Copyright (C) 1998-2003, 2005-2007, 2009-2025 Free Software Foundation, |
| 5 | dnl Inc. | 5 | dnl Inc. |
| 6 | dnl | 6 | dnl |
| 7 | dnl This file is free software; the Free Software Foundation | 7 | dnl This file is free software; the Free Software Foundation |
| 8 | dnl gives unlimited permission to copy and/or distribute it, | 8 | dnl gives unlimited permission to copy and/or distribute it, |
| 9 | dnl with or without modifications, as long as this notice is preserved. | 9 | dnl with or without modifications, as long as this notice is preserved. |
| 10 | dnl This file is offered as-is, without any warranty. | ||
| 10 | 11 | ||
| 11 | AC_PREREQ([2.59]) | 12 | AC_PREREQ([2.59]) |
| 12 | 13 | ||
diff --git a/gl/m4/getloadavg.m4 b/gl/m4/getloadavg.m4 index 0918bcd2..8ab613db 100644 --- a/gl/m4/getloadavg.m4 +++ b/gl/m4/getloadavg.m4 | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | # getloadavg.m4 | 1 | # getloadavg.m4 |
| 2 | # serial 13 | 2 | # serial 13 |
| 3 | dnl Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2024 Free Software | 3 | dnl Copyright (C) 1992-1996, 1999-2000, 2002-2003, 2006, 2008-2025 Free |
| 4 | dnl Foundation, Inc. | 4 | dnl Software Foundation, Inc. |
| 5 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 6 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 7 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 8 | 9 | ||
| 9 | # Check for getloadavg. | 10 | # Check for getloadavg. |
| 10 | 11 | ||
diff --git a/gl/m4/getopt.m4 b/gl/m4/getopt.m4 index 297722ea..cb344c15 100644 --- a/gl/m4/getopt.m4 +++ b/gl/m4/getopt.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # getopt.m4 | 1 | # getopt.m4 |
| 2 | # serial 49 | 2 | # serial 50 |
| 3 | dnl Copyright (C) 2002-2006, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Request a POSIX compliant getopt function. | 9 | # Request a POSIX compliant getopt function. |
| 9 | AC_DEFUN([gl_FUNC_GETOPT_POSIX], | 10 | AC_DEFUN([gl_FUNC_GETOPT_POSIX], |
| @@ -77,7 +78,7 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS], | |||
| 77 | fi | 78 | fi |
| 78 | 79 | ||
| 79 | dnl POSIX 2008 does not specify leading '+' behavior, but see | 80 | dnl POSIX 2008 does not specify leading '+' behavior, but see |
| 80 | dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on | 81 | dnl https://austingroupbugs.net/view.php?id=191 for a recommendation on |
| 81 | dnl the next version of POSIX. For now, we only guarantee leading '+' | 82 | dnl the next version of POSIX. For now, we only guarantee leading '+' |
| 82 | dnl behavior with getopt-gnu. | 83 | dnl behavior with getopt-gnu. |
| 83 | if test -z "$gl_replace_getopt"; then | 84 | if test -z "$gl_replace_getopt"; then |
| @@ -366,14 +367,7 @@ dnl is ambiguous with environment values that contain newlines. | |||
| 366 | 367 | ||
| 367 | AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], | 368 | AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], |
| 368 | [ | 369 | [ |
| 369 | AC_CHECK_HEADERS_ONCE([sys/cdefs.h]) | 370 | gl_CHECK_HEADER_SYS_CDEFS_H |
| 370 | if test $ac_cv_header_sys_cdefs_h = yes; then | ||
| 371 | HAVE_SYS_CDEFS_H=1 | ||
| 372 | else | ||
| 373 | HAVE_SYS_CDEFS_H=0 | ||
| 374 | fi | ||
| 375 | AC_SUBST([HAVE_SYS_CDEFS_H]) | ||
| 376 | |||
| 377 | AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], | 371 | AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], |
| 378 | [Define to rpl_ if the getopt replacement functions and variables | 372 | [Define to rpl_ if the getopt replacement functions and variables |
| 379 | should be used.]) | 373 | should be used.]) |
diff --git a/gl/m4/getprogname.m4 b/gl/m4/getprogname.m4 index b24f4480..90f34c74 100644 --- a/gl/m4/getprogname.m4 +++ b/gl/m4/getprogname.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # getprogname.m4 | 1 | # getprogname.m4 |
| 2 | # serial 8 | 2 | # serial 8 |
| 3 | dnl Copyright (C) 2016-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2016-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Check for getprogname or replacements for it | 9 | # Check for getprogname or replacements for it |
| 9 | 10 | ||
diff --git a/gl/m4/gl-openssl.m4 b/gl/m4/gl-openssl.m4 index c5e1f7ba..3cfea50f 100644 --- a/gl/m4/gl-openssl.m4 +++ b/gl/m4/gl-openssl.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # gl-openssl.m4 | 1 | # gl-openssl.m4 |
| 2 | # serial 7 | 2 | # serial 7 |
| 3 | dnl Copyright (C) 2013-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2013-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_SET_CRYPTO_CHECK_DEFAULT], | 9 | AC_DEFUN([gl_SET_CRYPTO_CHECK_DEFAULT], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4 index fcf84226..6a6e8593 100644 --- a/gl/m4/gnulib-cache.m4 +++ b/gl/m4/gnulib-cache.m4 | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # Copyright (C) 2002-2024 Free Software Foundation, Inc. | 1 | # Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 2 | # | 2 | # |
| 3 | # This file is free software; you can redistribute it and/or modify | 3 | # This file is free software; you can redistribute it and/or modify |
| 4 | # it under the terms of the GNU General Public License as published by | 4 | # it under the terms of the GNU General Public License as published by |
diff --git a/gl/m4/gnulib-common.m4 b/gl/m4/gnulib-common.m4 index cb730449..034dae69 100644 --- a/gl/m4/gnulib-common.m4 +++ b/gl/m4/gnulib-common.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # gnulib-common.m4 | 1 | # gnulib-common.m4 |
| 2 | # serial 93 | 2 | # serial 113 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_PREREQ([2.62]) | 9 | AC_PREREQ([2.62]) |
| 9 | 10 | ||
| @@ -20,43 +21,61 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 20 | [/* Witness that <config.h> has been included. */ | 21 | [/* Witness that <config.h> has been included. */ |
| 21 | #define _GL_CONFIG_H_INCLUDED 1 | 22 | #define _GL_CONFIG_H_INCLUDED 1 |
| 22 | ]) | 23 | ]) |
| 24 | dnl Avoid warnings from gcc -Wtrailing-whitespace. | ||
| 25 | dnl This is a temporary workaround until Autoconf fixes it. | ||
| 26 | dnl Test case: | ||
| 27 | dnl empty1=; empty2=; AC_DEFINE_UNQUOTED([FOO], [$empty1$empty2], [...]) | ||
| 28 | dnl should produce "#define FOO /**/", not "#define FOO ". | ||
| 29 | AH_TOP([#if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ | ||
| 30 | # pragma GCC diagnostic push | ||
| 31 | # pragma GCC diagnostic ignored "-Wtrailing-whitespace" | ||
| 32 | #endif | ||
| 33 | ]) | ||
| 34 | AH_BOTTOM([#if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ | ||
| 35 | # pragma GCC diagnostic pop | ||
| 36 | #endif | ||
| 37 | ]) | ||
| 23 | AH_VERBATIM([_GL_GNUC_PREREQ], | 38 | AH_VERBATIM([_GL_GNUC_PREREQ], |
| 24 | [/* True if the compiler says it groks GNU C version MAJOR.MINOR. */ | 39 | [/* True if the compiler says it groks GNU C version MAJOR.MINOR. |
| 25 | #if defined __GNUC__ && defined __GNUC_MINOR__ | 40 | Except that |
| 41 | - clang groks GNU C 4.2, even on Windows, where it does not define | ||
| 42 | __GNUC__. | ||
| 43 | - The OpenMandriva-modified clang compiler pretends that it groks | ||
| 44 | GNU C version 13.1, but it doesn't: It does not support | ||
| 45 | __attribute__ ((__malloc__ (f, i))), nor does it support | ||
| 46 | __attribute__ ((__warning__ (message))) on a function redeclaration. | ||
| 47 | - Users can make clang lie as well, through the -fgnuc-version option. */ | ||
| 48 | #if defined __GNUC__ && defined __GNUC_MINOR__ && !defined __clang__ | ||
| 26 | # define _GL_GNUC_PREREQ(major, minor) \ | 49 | # define _GL_GNUC_PREREQ(major, minor) \ |
| 27 | ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__)) | 50 | ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__)) |
| 51 | #elif defined __clang__ | ||
| 52 | /* clang really only groks GNU C 4.2. */ | ||
| 53 | # define _GL_GNUC_PREREQ(major, minor) \ | ||
| 54 | ((major) < 4 + ((minor) <= 2)) | ||
| 28 | #else | 55 | #else |
| 29 | # define _GL_GNUC_PREREQ(major, minor) 0 | 56 | # define _GL_GNUC_PREREQ(major, minor) 0 |
| 30 | #endif | 57 | #endif |
| 31 | ]) | 58 | ]) |
| 32 | AH_VERBATIM([_Noreturn], | 59 | AH_VERBATIM([_Noreturn], |
| 33 | [/* The _Noreturn keyword of C11. */ | 60 | [/* The _Noreturn keyword of C11. |
| 61 | Do not use [[noreturn]], because with it the syntax | ||
| 62 | extern _Noreturn void func (...); | ||
| 63 | would not be valid; such a declaration would be valid only with 'extern' | ||
| 64 | and '_Noreturn' swapped, or without the 'extern' keyword. However, some | ||
| 65 | AIX system header files and several gnulib header files use precisely | ||
| 66 | this syntax with 'extern'. So even though C23 deprecates _Noreturn, | ||
| 67 | it is currently more portable to prefer it to [[noreturn]]. | ||
| 68 | |||
| 69 | Also, do not try to work around LLVM bug 59792 (clang 15 or earlier). | ||
| 70 | This rare bug can be worked around by compiling with 'clang -D_Noreturn=', | ||
| 71 | though the workaround may generate many false-alarm warnings. */ | ||
| 34 | #ifndef _Noreturn | 72 | #ifndef _Noreturn |
| 35 | # if (defined __cplusplus \ | 73 | # if ((!defined __cplusplus || defined __clang__) \ |
| 36 | && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ | 74 | && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0))) |
| 37 | || (defined _MSC_VER && 1900 <= _MSC_VER)) \ | ||
| 38 | && 0) | ||
| 39 | /* [[noreturn]] is not practically usable, because with it the syntax | ||
| 40 | extern _Noreturn void func (...); | ||
| 41 | would not be valid; such a declaration would only be valid with 'extern' | ||
| 42 | and '_Noreturn' swapped, or without the 'extern' keyword. However, some | ||
| 43 | AIX system header files and several gnulib header files use precisely | ||
| 44 | this syntax with 'extern'. */ | ||
| 45 | # define _Noreturn [[noreturn]] | ||
| 46 | # elif (defined __clang__ && __clang_major__ < 16 \ | ||
| 47 | && defined _GL_WORK_AROUND_LLVM_BUG_59792) | ||
| 48 | /* Compile with -D_GL_WORK_AROUND_LLVM_BUG_59792 to work around | ||
| 49 | that rare LLVM bug, though you may get many false-alarm warnings. */ | ||
| 50 | # define _Noreturn | ||
| 51 | # elif ((!defined __cplusplus || defined __clang__) \ | ||
| 52 | && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ | ||
| 53 | || (!defined __STRICT_ANSI__ \ | ||
| 54 | && (_GL_GNUC_PREREQ (4, 7) \ | ||
| 55 | || (defined __apple_build_version__ \ | ||
| 56 | ? 6000000 <= __apple_build_version__ \ | ||
| 57 | : 3 < __clang_major__ + (5 <= __clang_minor__)))))) | ||
| 58 | /* _Noreturn works as-is. */ | 75 | /* _Noreturn works as-is. */ |
| 59 | # elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C | 76 | # elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C |
| 77 | /* Prefer __attribute__ ((__noreturn__)) to plain _Noreturn even if the | ||
| 78 | latter works, as 'gcc -std=gnu99 -Wpedantic' warns about _Noreturn. */ | ||
| 60 | # define _Noreturn __attribute__ ((__noreturn__)) | 79 | # define _Noreturn __attribute__ ((__noreturn__)) |
| 61 | # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) | 80 | # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) |
| 62 | # define _Noreturn __declspec (noreturn) | 81 | # define _Noreturn __declspec (noreturn) |
| @@ -90,6 +109,9 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 90 | # define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__) | 109 | # define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__) |
| 91 | # else | 110 | # else |
| 92 | # define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr | 111 | # define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr |
| 112 | /* The following lines list the first GCC version that supports the attribute. | ||
| 113 | Although the lines are not used in GCC 5 and later (as GCC 5 introduced | ||
| 114 | __has_attribute support), list GCC versions 5+ anyway for completeness. */ | ||
| 93 | # define _GL_ATTR_alloc_size _GL_GNUC_PREREQ (4, 3) | 115 | # define _GL_ATTR_alloc_size _GL_GNUC_PREREQ (4, 3) |
| 94 | # define _GL_ATTR_always_inline _GL_GNUC_PREREQ (3, 2) | 116 | # define _GL_ATTR_always_inline _GL_GNUC_PREREQ (3, 2) |
| 95 | # define _GL_ATTR_artificial _GL_GNUC_PREREQ (4, 3) | 117 | # define _GL_ATTR_artificial _GL_GNUC_PREREQ (4, 3) |
| @@ -110,12 +132,15 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 110 | # endif | 132 | # endif |
| 111 | # define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1) | 133 | # define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1) |
| 112 | # define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3) | 134 | # define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3) |
| 135 | # define _GL_ATTR_nonnull_if_nonzero _GL_GNUC_PREREQ (15, 1) | ||
| 113 | # define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0) | 136 | # define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0) |
| 114 | # define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3) | 137 | # define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3) |
| 115 | # define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7) | 138 | # define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7) |
| 116 | # define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96) | 139 | # define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96) |
| 140 | # define _GL_ATTR_reproducible _GL_GNUC_PREREQ (15, 1) | ||
| 117 | # define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9) | 141 | # define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9) |
| 118 | # define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0) | 142 | # define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0) |
| 143 | # define _GL_ATTR_unsequenced _GL_GNUC_PREREQ (15, 1) | ||
| 119 | # define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7) | 144 | # define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7) |
| 120 | # define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4) | 145 | # define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4) |
| 121 | # endif | 146 | # endif |
| @@ -131,6 +156,23 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 131 | # define _GL_HAVE___HAS_C_ATTRIBUTE 0 | 156 | # define _GL_HAVE___HAS_C_ATTRIBUTE 0 |
| 132 | #endif | 157 | #endif |
| 133 | 158 | ||
| 159 | /* Attributes in bracket syntax [[...]] vs. attributes in __attribute__((...)) | ||
| 160 | syntax, in function declarations. There are two problems here. | ||
| 161 | (Last tested with gcc/g++ 14 and clang/clang++ 18.) | ||
| 162 | |||
| 163 | 1) We want that the _GL_ATTRIBUTE_* can be cumulated on the same declaration | ||
| 164 | in any order. | ||
| 165 | =========================== foo.c = foo.cc =========================== | ||
| 166 | __attribute__ ((__deprecated__)) [[__nodiscard__]] int bar1 (int); | ||
| 167 | [[__nodiscard__]] __attribute__ ((__deprecated__)) int bar2 (int); | ||
| 168 | ====================================================================== | ||
| 169 | This gives a syntax error | ||
| 170 | - in C mode with gcc | ||
| 171 | <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796>, and | ||
| 172 | - in C++ mode with clang++ version < 16, and | ||
| 173 | - in C++ mode, inside extern "C" {}, still in newer clang++ versions | ||
| 174 | <https://github.com/llvm/llvm-project/issues/101990>. | ||
| 175 | */ | ||
| 134 | /* Define if, in a function declaration, the attributes in bracket syntax | 176 | /* Define if, in a function declaration, the attributes in bracket syntax |
| 135 | [[...]] must come before the attributes in __attribute__((...)) syntax. | 177 | [[...]] must come before the attributes in __attribute__((...)) syntax. |
| 136 | If this is defined, it is best to avoid the bracket syntax, so that the | 178 | If this is defined, it is best to avoid the bracket syntax, so that the |
| @@ -145,6 +187,176 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 145 | # define _GL_BRACKET_BEFORE_ATTRIBUTE 1 | 187 | # define _GL_BRACKET_BEFORE_ATTRIBUTE 1 |
| 146 | # endif | 188 | # endif |
| 147 | #endif | 189 | #endif |
| 190 | /* | ||
| 191 | 2) We want that the _GL_ATTRIBUTE_* can be placed in a declaration | ||
| 192 | - without 'extern', in C as well as in C++, | ||
| 193 | - with 'extern', in C, | ||
| 194 | - with 'extern "C"', in C++ | ||
| 195 | in the same position. That is, we don't want to be forced to use a | ||
| 196 | macro which arranges for the attribute to come before 'extern' in | ||
| 197 | one case and after 'extern' in the other case, because such a macro | ||
| 198 | would make the source code of .h files pretty ugly. | ||
| 199 | =========================== foo.c = foo.cc =========================== | ||
| 200 | #ifdef __cplusplus | ||
| 201 | # define CC "C" | ||
| 202 | #else | ||
| 203 | # define CC | ||
| 204 | #endif | ||
| 205 | |||
| 206 | #define ND [[__nodiscard__]] | ||
| 207 | #define WUR __attribute__((__warn_unused_result__)) | ||
| 208 | |||
| 209 | #ifdef __cplusplus | ||
| 210 | extern "C" { | ||
| 211 | #endif | ||
| 212 | // gcc clang g++ clang++ | ||
| 213 | |||
| 214 | ND int foo (int); | ||
| 215 | int ND foo (int); // warn error warn error | ||
| 216 | int foo ND (int); | ||
| 217 | int foo (int) ND; // warn error warn error | ||
| 218 | |||
| 219 | WUR int foo (int); | ||
| 220 | int WUR foo (int); | ||
| 221 | int fo1 WUR (int); // error error error error | ||
| 222 | int foo (int) WUR; | ||
| 223 | |||
| 224 | #ifdef __cplusplus | ||
| 225 | } | ||
| 226 | #endif | ||
| 227 | |||
| 228 | // gcc clang g++ clang++ | ||
| 229 | |||
| 230 | ND extern CC int foo (int); // error error | ||
| 231 | extern CC ND int foo (int); // error error | ||
| 232 | extern CC int ND foo (int); // warn error warn error | ||
| 233 | extern CC int foo ND (int); | ||
| 234 | extern CC int foo (int) ND; // warn error warn error | ||
| 235 | |||
| 236 | WUR extern CC int foo (int); // warn | ||
| 237 | extern CC WUR int foo (int); | ||
| 238 | extern CC int WUR foo (int); | ||
| 239 | extern CC int foo WUR (int); // error error error error | ||
| 240 | extern CC int foo (int) WUR; | ||
| 241 | |||
| 242 | ND EXTERN_C_FUNC int foo (int); // error error | ||
| 243 | EXTERN_C_FUNC ND int foo (int); | ||
| 244 | EXTERN_C_FUNC int ND foo (int); // warn error warn error | ||
| 245 | EXTERN_C_FUNC int foo ND (int); | ||
| 246 | EXTERN_C_FUNC int foo (int) ND; // warn error warn error | ||
| 247 | |||
| 248 | WUR EXTERN_C_FUNC int foo (int); // warn | ||
| 249 | EXTERN_C_FUNC WUR int foo (int); | ||
| 250 | EXTERN_C_FUNC int WUR foo (int); | ||
| 251 | EXTERN_C_FUNC int fo2 WUR (int); // error error error error | ||
| 252 | EXTERN_C_FUNC int foo (int) WUR; | ||
| 253 | ====================================================================== | ||
| 254 | So, if we insist on using the 'extern' keyword ('extern CC' idiom): | ||
| 255 | * If _GL_ATTRIBUTE_* expands to bracket syntax [[...]] | ||
| 256 | in both C and C++, there is one available position: | ||
| 257 | - between the function name and the parameter list. | ||
| 258 | * If _GL_ATTRIBUTE_* expands to __attribute__((...)) syntax | ||
| 259 | in both C and C++, there are several available positions: | ||
| 260 | - before the return type, | ||
| 261 | - between return type and function name, | ||
| 262 | - at the end of the declaration. | ||
| 263 | * If _GL_ATTRIBUTE_* expands to bracket syntax [[...]] in C and to | ||
| 264 | __attribute__((...)) syntax in C++, there is no available position: | ||
| 265 | it would need to come before 'extern' in C but after 'extern "C"' | ||
| 266 | in C++. | ||
| 267 | * If _GL_ATTRIBUTE_* expands to __attribute__((...)) syntax in C and | ||
| 268 | to bracket syntax [[...]] in C++, there is one available position: | ||
| 269 | - before the return type. | ||
| 270 | Whereas, if we use the 'EXTERN_C_FUNC' idiom, which conditionally | ||
| 271 | omits the 'extern' keyword: | ||
| 272 | * If _GL_ATTRIBUTE_* expands to bracket syntax [[...]] | ||
| 273 | in both C and C++, there are two available positions: | ||
| 274 | - before the return type, | ||
| 275 | - between the function name and the parameter list. | ||
| 276 | * If _GL_ATTRIBUTE_* expands to __attribute__((...)) syntax | ||
| 277 | in both C and C++, there are several available positions: | ||
| 278 | - before the return type, | ||
| 279 | - between return type and function name, | ||
| 280 | - at the end of the declaration. | ||
| 281 | * If _GL_ATTRIBUTE_* expands to bracket syntax [[...]] in C and to | ||
| 282 | __attribute__((...)) syntax in C++, there is one available position: | ||
| 283 | - before the return type. | ||
| 284 | * If _GL_ATTRIBUTE_* expands to __attribute__((...)) syntax in C and | ||
| 285 | to bracket syntax [[...]] in C++, there is one available position: | ||
| 286 | - before the return type. | ||
| 287 | The best choice is therefore to use the 'EXTERN_C_FUNC' idiom and | ||
| 288 | put the attributes before the return type. This works regardless | ||
| 289 | to what the _GL_ATTRIBUTE_* macros expand. | ||
| 290 | */ | ||
| 291 | |||
| 292 | /* Attributes in bracket syntax [[...]] vs. attributes in __attribute__((...)) | ||
| 293 | syntax, in static/inline function definitions. | ||
| 294 | |||
| 295 | There are similar constraints as for function declarations. However, here, | ||
| 296 | we cannot omit the storage-class specifier. Therefore, the following rule | ||
| 297 | applies: | ||
| 298 | * The macros | ||
| 299 | _GL_ATTRIBUTE_CONST | ||
| 300 | _GL_ATTRIBUTE_DEPRECATED | ||
| 301 | _GL_ATTRIBUTE_MAYBE_UNUSED | ||
| 302 | _GL_ATTRIBUTE_NODISCARD | ||
| 303 | _GL_ATTRIBUTE_PURE | ||
| 304 | _GL_ATTRIBUTE_REPRODUCIBLE | ||
| 305 | _GL_ATTRIBUTE_UNSEQUENCED | ||
| 306 | which may expand to bracket syntax [[...]], must come first, before the | ||
| 307 | storage-class specifier. | ||
| 308 | * Other _GL_ATTRIBUTE_* macros, that expand to __attribute__((...)) syntax, | ||
| 309 | are better placed between the storage-class specifier and the return | ||
| 310 | type. | ||
| 311 | */ | ||
| 312 | |||
| 313 | /* Attributes in bracket syntax [[...]] vs. attributes in __attribute__((...)) | ||
| 314 | syntax, in variable declarations. | ||
| 315 | |||
| 316 | At which position can they be placed? | ||
| 317 | (Last tested with gcc/g++ 14 and clang/clang++ 18.) | ||
| 318 | |||
| 319 | =========================== foo.c = foo.cc =========================== | ||
| 320 | #ifdef __cplusplus | ||
| 321 | # define CC "C" | ||
| 322 | #else | ||
| 323 | # define CC | ||
| 324 | #endif | ||
| 325 | |||
| 326 | #define BD [[__deprecated__]] | ||
| 327 | #define AD __attribute__ ((__deprecated__)) | ||
| 328 | |||
| 329 | // gcc clang g++ clang++ | ||
| 330 | |||
| 331 | BD extern CC int var; // error error | ||
| 332 | extern CC BD int var; // error error | ||
| 333 | extern CC int BD var; // warn error warn error | ||
| 334 | extern CC int var BD; | ||
| 335 | |||
| 336 | AD extern CC int var; // warn | ||
| 337 | extern CC AD int var; | ||
| 338 | extern CC int AD var; | ||
| 339 | extern CC int var AD; | ||
| 340 | |||
| 341 | BD extern CC int z[]; // error error | ||
| 342 | extern CC BD int z[]; // error error | ||
| 343 | extern CC int BD z[]; // warn error warn error | ||
| 344 | extern CC int z1 BD []; | ||
| 345 | extern CC int z[] BD; // warn error error | ||
| 346 | |||
| 347 | AD extern CC int z[]; // warn | ||
| 348 | extern CC AD int z[]; | ||
| 349 | extern CC int AD z[]; | ||
| 350 | extern CC int z2 AD []; // error error error error | ||
| 351 | extern CC int z[] AD; | ||
| 352 | ====================================================================== | ||
| 353 | |||
| 354 | * For non-array variables, the only good position is after the variable name, | ||
| 355 | that is, at the end of the declaration. | ||
| 356 | * For array variables, you will need to distinguish C and C++: | ||
| 357 | - In C, before the 'extern' keyword. | ||
| 358 | - In C++, between the 'extern "C"' and the variable's type. | ||
| 359 | */ | ||
| 148 | ]dnl There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's alignas instead. | 360 | ]dnl There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's alignas instead. |
| 149 | [ | 361 | [ |
| 150 | /* _GL_ATTRIBUTE_ALLOC_SIZE ((N)) declares that the Nth argument of the function | 362 | /* _GL_ATTRIBUTE_ALLOC_SIZE ((N)) declares that the Nth argument of the function |
| @@ -152,7 +364,7 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 152 | _GL_ATTRIBUTE_ALLOC_SIZE ((M, N)) declares that the Mth argument multiplied | 364 | _GL_ATTRIBUTE_ALLOC_SIZE ((M, N)) declares that the Mth argument multiplied |
| 153 | by the Nth argument of the function is the size of the returned memory block. | 365 | by the Nth argument of the function is the size of the returned memory block. |
| 154 | */ | 366 | */ |
| 155 | /* Applies to: function, pointer to function, function types. */ | 367 | /* Applies to: functions, pointer to functions, function types. */ |
| 156 | #ifndef _GL_ATTRIBUTE_ALLOC_SIZE | 368 | #ifndef _GL_ATTRIBUTE_ALLOC_SIZE |
| 157 | # if _GL_HAS_ATTRIBUTE (alloc_size) | 369 | # if _GL_HAS_ATTRIBUTE (alloc_size) |
| 158 | # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) | 370 | # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) |
| @@ -163,7 +375,7 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 163 | 375 | ||
| 164 | /* _GL_ATTRIBUTE_ALWAYS_INLINE tells that the compiler should always inline the | 376 | /* _GL_ATTRIBUTE_ALWAYS_INLINE tells that the compiler should always inline the |
| 165 | function and report an error if it cannot do so. */ | 377 | function and report an error if it cannot do so. */ |
| 166 | /* Applies to: function. */ | 378 | /* Applies to: functions. */ |
| 167 | #ifndef _GL_ATTRIBUTE_ALWAYS_INLINE | 379 | #ifndef _GL_ATTRIBUTE_ALWAYS_INLINE |
| 168 | # if _GL_HAS_ATTRIBUTE (always_inline) | 380 | # if _GL_HAS_ATTRIBUTE (always_inline) |
| 169 | # define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__)) | 381 | # define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__)) |
| @@ -175,7 +387,7 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 175 | /* _GL_ATTRIBUTE_ARTIFICIAL declares that the function is not important to show | 387 | /* _GL_ATTRIBUTE_ARTIFICIAL declares that the function is not important to show |
| 176 | in stack traces when debugging. The compiler should omit the function from | 388 | in stack traces when debugging. The compiler should omit the function from |
| 177 | stack traces. */ | 389 | stack traces. */ |
| 178 | /* Applies to: function. */ | 390 | /* Applies to: functions. */ |
| 179 | #ifndef _GL_ATTRIBUTE_ARTIFICIAL | 391 | #ifndef _GL_ATTRIBUTE_ARTIFICIAL |
| 180 | # if _GL_HAS_ATTRIBUTE (artificial) | 392 | # if _GL_HAS_ATTRIBUTE (artificial) |
| 181 | # define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__)) | 393 | # define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__)) |
| @@ -201,18 +413,23 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 201 | # endif | 413 | # endif |
| 202 | #endif | 414 | #endif |
| 203 | 415 | ||
| 204 | /* _GL_ATTRIBUTE_CONST declares that it is OK for a compiler to omit duplicate | 416 | /* _GL_ATTRIBUTE_CONST declares: |
| 205 | calls to the function with the same arguments. | 417 | It is OK for a compiler to move calls to the function and to omit |
| 206 | This attribute is safe for a function that neither depends on nor affects | 418 | calls to the function if another call has the same arguments or the |
| 207 | observable state, and always returns exactly once - e.g., does not loop | 419 | result is not used. |
| 208 | forever, and does not call longjmp. | 420 | This attribute is safe for a function that neither depends on |
| 209 | (This attribute is stricter than _GL_ATTRIBUTE_PURE.) */ | 421 | nor affects state, and always returns exactly once - |
| 422 | e.g., does not raise an exception, call longjmp, or loop forever. | ||
| 423 | (This attribute is stricter than _GL_ATTRIBUTE_PURE because the | ||
| 424 | function cannot observe state. It is stricter than | ||
| 425 | _GL_ATTRIBUTE_UNSEQUENCED because the function must return exactly | ||
| 426 | once and cannot depend on state addressed by its arguments.) */ | ||
| 210 | /* Applies to: functions. */ | 427 | /* Applies to: functions. */ |
| 211 | #ifndef _GL_ATTRIBUTE_CONST | 428 | #ifndef _GL_ATTRIBUTE_CONST |
| 212 | # if _GL_HAS_ATTRIBUTE (const) | 429 | # if _GL_HAS_ATTRIBUTE (const) |
| 213 | # define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) | 430 | # define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) |
| 214 | # else | 431 | # else |
| 215 | # define _GL_ATTRIBUTE_CONST | 432 | # define _GL_ATTRIBUTE_CONST _GL_ATTRIBUTE_UNSEQUENCED |
| 216 | # endif | 433 | # endif |
| 217 | #endif | 434 | #endif |
| 218 | 435 | ||
| @@ -460,6 +677,17 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 460 | # endif | 677 | # endif |
| 461 | #endif | 678 | #endif |
| 462 | 679 | ||
| 680 | /* _GL_ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) declares that the argument NP | ||
| 681 | (a pointer) must not be NULL if the argument NI (an integer) is != 0. */ | ||
| 682 | /* Applies to: functions. */ | ||
| 683 | #ifndef _GL_ATTRIBUTE_NONNULL_IF_NONZERO | ||
| 684 | # if _GL_HAS_ATTRIBUTE (nonnull_if_nonzero) | ||
| 685 | # define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) __attribute__ ((__nonnull_if_nonzero__ (np, ni))) | ||
| 686 | # else | ||
| 687 | # define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) | ||
| 688 | # endif | ||
| 689 | #endif | ||
| 690 | |||
| 463 | /* _GL_ATTRIBUTE_NONSTRING declares that the contents of a character array is | 691 | /* _GL_ATTRIBUTE_NONSTRING declares that the contents of a character array is |
| 464 | not meant to be NUL-terminated. */ | 692 | not meant to be NUL-terminated. */ |
| 465 | /* Applies to: struct/union members and variables that are arrays of element | 693 | /* Applies to: struct/union members and variables that are arrays of element |
| @@ -481,7 +709,7 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 481 | other attributes. */ | 709 | other attributes. */ |
| 482 | #ifndef _GL_ATTRIBUTE_NOTHROW | 710 | #ifndef _GL_ATTRIBUTE_NOTHROW |
| 483 | # if defined __cplusplus | 711 | # if defined __cplusplus |
| 484 | # if _GL_GNUC_PREREQ (2, 8) || __clang_major >= 4 | 712 | # if _GL_GNUC_PREREQ (2, 8) || __clang_major__ >= 4 |
| 485 | # if __cplusplus >= 201103L | 713 | # if __cplusplus >= 201103L |
| 486 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) | 714 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) |
| 487 | # else | 715 | # else |
| @@ -505,9 +733,9 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 505 | minimizing the memory required. */ | 733 | minimizing the memory required. */ |
| 506 | /* Applies to: struct members, struct, union, | 734 | /* Applies to: struct members, struct, union, |
| 507 | in C++ also: class. */ | 735 | in C++ also: class. */ |
| 736 | #ifndef _GL_ATTRIBUTE_PACKED | ||
| 508 | /* Oracle Studio 12.6 miscompiles code with __attribute__ ((__packed__)) despite | 737 | /* Oracle Studio 12.6 miscompiles code with __attribute__ ((__packed__)) despite |
| 509 | __has_attribute OK. */ | 738 | __has_attribute OK. */ |
| 510 | #ifndef _GL_ATTRIBUTE_PACKED | ||
| 511 | # if _GL_HAS_ATTRIBUTE (packed) && !defined __SUNPRO_C | 739 | # if _GL_HAS_ATTRIBUTE (packed) && !defined __SUNPRO_C |
| 512 | # define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__)) | 740 | # define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__)) |
| 513 | # else | 741 | # else |
| @@ -515,18 +743,51 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 515 | # endif | 743 | # endif |
| 516 | #endif | 744 | #endif |
| 517 | 745 | ||
| 518 | /* _GL_ATTRIBUTE_PURE declares that It is OK for a compiler to omit duplicate | 746 | /* _GL_ATTRIBUTE_PURE declares: |
| 519 | calls to the function with the same arguments if observable state is not | 747 | It is OK for a compiler to move calls to the function and to omit |
| 520 | changed between calls. | 748 | calls to the function if another call has the same arguments or the |
| 521 | This attribute is safe for a function that does not affect | 749 | result is not used, and if observable state is the same. |
| 522 | observable state, and always returns exactly once. | 750 | This attribute is safe for a function that does not affect observable state |
| 523 | (This attribute is looser than _GL_ATTRIBUTE_CONST.) */ | 751 | and always returns exactly once. |
| 752 | (This attribute is looser than _GL_ATTRIBUTE_CONST because the function | ||
| 753 | can depend on observable state. It is stricter than | ||
| 754 | _GL_ATTRIBUTE_REPRODUCIBLE because the function must return exactly | ||
| 755 | once and cannot affect state addressed by its arguments.) */ | ||
| 524 | /* Applies to: functions. */ | 756 | /* Applies to: functions. */ |
| 525 | #ifndef _GL_ATTRIBUTE_PURE | 757 | #ifndef _GL_ATTRIBUTE_PURE |
| 526 | # if _GL_HAS_ATTRIBUTE (pure) | 758 | # if _GL_HAS_ATTRIBUTE (pure) |
| 527 | # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) | 759 | # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) |
| 528 | # else | 760 | # else |
| 529 | # define _GL_ATTRIBUTE_PURE | 761 | # define _GL_ATTRIBUTE_PURE _GL_ATTRIBUTE_REPRODUCIBLE |
| 762 | # endif | ||
| 763 | #endif | ||
| 764 | |||
| 765 | /* _GL_ATTRIBUTE_REPRODUCIBLE declares: | ||
| 766 | It is OK for a compiler to move calls to the function and to omit duplicate | ||
| 767 | calls to the function with the same arguments, so long as the state | ||
| 768 | addressed by its arguments is the same and is updated in time for | ||
| 769 | the rest of the program. | ||
| 770 | This attribute is safe for a function that is effectless and idempotent; see | ||
| 771 | ISO C 23 § 6.7.12.7 for a definition of these terms. | ||
| 772 | (This attribute is looser than _GL_ATTRIBUTE_UNSEQUENCED because | ||
| 773 | the function need not be stateless and idempotent. It is looser | ||
| 774 | than _GL_ATTRIBUTE_PURE because the function need not return | ||
| 775 | exactly once and can affect state addressed by its arguments.) | ||
| 776 | See also <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2956.htm> and | ||
| 777 | <https://stackoverflow.com/questions/76847905/>. | ||
| 778 | ATTENTION! Efforts are underway to change the meaning of this attribute. | ||
| 779 | See <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3424.htm>. */ | ||
| 780 | /* Applies to: functions, pointer to functions, function types. */ | ||
| 781 | #ifndef _GL_ATTRIBUTE_REPRODUCIBLE | ||
| 782 | /* This may be revisited when gcc and clang support [[reproducible]] or possibly | ||
| 783 | __attribute__ ((__reproducible__)). */ | ||
| 784 | # ifndef _GL_BRACKET_BEFORE_ATTRIBUTE | ||
| 785 | # if _GL_HAS_ATTRIBUTE (reproducible) | ||
| 786 | # define _GL_ATTRIBUTE_REPRODUCIBLE [[reproducible]] | ||
| 787 | # endif | ||
| 788 | # endif | ||
| 789 | # ifndef _GL_ATTRIBUTE_REPRODUCIBLE | ||
| 790 | # define _GL_ATTRIBUTE_REPRODUCIBLE | ||
| 530 | # endif | 791 | # endif |
| 531 | #endif | 792 | #endif |
| 532 | 793 | ||
| @@ -554,6 +815,35 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 554 | # endif | 815 | # endif |
| 555 | #endif | 816 | #endif |
| 556 | 817 | ||
| 818 | /* _GL_ATTRIBUTE_UNSEQUENCED declares: | ||
| 819 | It is OK for a compiler to move calls to the function and to omit duplicate | ||
| 820 | calls to the function with the same arguments, so long as the state | ||
| 821 | addressed by its arguments is the same. | ||
| 822 | This attribute is safe for a function that is effectless, idempotent, | ||
| 823 | stateless, and independent; see ISO C 23 § 6.7.12.7 for a definition of | ||
| 824 | these terms. | ||
| 825 | (This attribute is stricter than _GL_ATTRIBUTE_REPRODUCIBLE because | ||
| 826 | the function must be stateless and independent. It is looser than | ||
| 827 | _GL_ATTRIBUTE_CONST because the function need not return exactly | ||
| 828 | once and can depend on state addressed by its arguments.) | ||
| 829 | See also <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2956.htm> and | ||
| 830 | <https://stackoverflow.com/questions/76847905/>. | ||
| 831 | ATTENTION! Efforts are underway to change the meaning of this attribute. | ||
| 832 | See <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3424.htm>. */ | ||
| 833 | /* Applies to: functions, pointer to functions, function types. */ | ||
| 834 | #ifndef _GL_ATTRIBUTE_UNSEQUENCED | ||
| 835 | /* This may be revisited when gcc and clang support [[unsequenced]] or possibly | ||
| 836 | __attribute__ ((__unsequenced__)). */ | ||
| 837 | # ifndef _GL_BRACKET_BEFORE_ATTRIBUTE | ||
| 838 | # if _GL_HAS_ATTRIBUTE (unsequenced) | ||
| 839 | # define _GL_ATTRIBUTE_UNSEQUENCED [[unsequenced]] | ||
| 840 | # endif | ||
| 841 | # endif | ||
| 842 | # ifndef _GL_ATTRIBUTE_UNSEQUENCED | ||
| 843 | # define _GL_ATTRIBUTE_UNSEQUENCED | ||
| 844 | # endif | ||
| 845 | #endif | ||
| 846 | |||
| 557 | /* A helper macro. Don't use it directly. */ | 847 | /* A helper macro. Don't use it directly. */ |
| 558 | #ifndef _GL_ATTRIBUTE_UNUSED | 848 | #ifndef _GL_ATTRIBUTE_UNUSED |
| 559 | # if _GL_HAS_ATTRIBUTE (unused) | 849 | # if _GL_HAS_ATTRIBUTE (unused) |
| @@ -578,6 +868,35 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 578 | # define _GL_UNUSED_LABEL | 868 | # define _GL_UNUSED_LABEL |
| 579 | # endif | 869 | # endif |
| 580 | #endif | 870 | #endif |
| 871 | |||
| 872 | /* The following attributes enable detection of multithread-safety problems | ||
| 873 | and resource leaks at compile-time, by clang ≥ 15, when the warning option | ||
| 874 | -Wthread-safety is enabled. For usage, see | ||
| 875 | <https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>. */ | ||
| 876 | #ifndef _GL_ATTRIBUTE_CAPABILITY_TYPE | ||
| 877 | # if __clang_major__ >= 15 | ||
| 878 | # define _GL_ATTRIBUTE_CAPABILITY_TYPE(concept) \ | ||
| 879 | __attribute__ ((__capability__ (concept))) | ||
| 880 | # else | ||
| 881 | # define _GL_ATTRIBUTE_CAPABILITY_TYPE(concept) | ||
| 882 | # endif | ||
| 883 | #endif | ||
| 884 | #ifndef _GL_ATTRIBUTE_ACQUIRE_CAPABILITY | ||
| 885 | # if __clang_major__ >= 15 | ||
| 886 | # define _GL_ATTRIBUTE_ACQUIRE_CAPABILITY(resource) \ | ||
| 887 | __attribute__ ((__acquire_capability__ (resource))) | ||
| 888 | # else | ||
| 889 | # define _GL_ATTRIBUTE_ACQUIRE_CAPABILITY(resource) | ||
| 890 | # endif | ||
| 891 | #endif | ||
| 892 | #ifndef _GL_ATTRIBUTE_RELEASE_CAPABILITY | ||
| 893 | # if __clang_major__ >= 15 | ||
| 894 | # define _GL_ATTRIBUTE_RELEASE_CAPABILITY(resource) \ | ||
| 895 | __attribute__ ((__release_capability__ (resource))) | ||
| 896 | # else | ||
| 897 | # define _GL_ATTRIBUTE_RELEASE_CAPABILITY(resource) | ||
| 898 | # endif | ||
| 899 | #endif | ||
| 581 | ]) | 900 | ]) |
| 582 | AH_VERBATIM([c_linkage], | 901 | AH_VERBATIM([c_linkage], |
| 583 | [/* In C++, there is the concept of "language linkage", that encompasses | 902 | [/* In C++, there is the concept of "language linkage", that encompasses |
| @@ -628,8 +947,8 @@ AC_DEFUN([gl_COMMON_BODY], [ | |||
| 628 | -1 if n1 < n2 | 947 | -1 if n1 < n2 |
| 629 | The naïve code (n1 > n2 ? 1 : n1 < n2 ? -1 : 0) produces a conditional | 948 | The naïve code (n1 > n2 ? 1 : n1 < n2 ? -1 : 0) produces a conditional |
| 630 | jump with nearly all GCC versions up to GCC 10. | 949 | jump with nearly all GCC versions up to GCC 10. |
| 631 | This variant (n1 < n2 ? -1 : n1 > n2) produces a conditional with many | 950 | This variant (n1 < n2 ? -1 : n1 > n2) produces a conditional jump with |
| 632 | GCC versions up to GCC 9. | 951 | many GCC versions up to GCC 9. |
| 633 | The better code (n1 > n2) - (n1 < n2) from Hacker's Delight § 2-9 | 952 | The better code (n1 > n2) - (n1 < n2) from Hacker's Delight § 2-9 |
| 634 | avoids conditional jumps in all GCC versions >= 3.4. */ | 953 | avoids conditional jumps in all GCC versions >= 3.4. */ |
| 635 | #define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2))) | 954 | #define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2))) |
| @@ -1006,7 +1325,7 @@ AC_DEFUN([gl_CC_ALLOW_WARNINGS], | |||
| 1006 | AC_REQUIRE([AC_PROG_CC]) | 1325 | AC_REQUIRE([AC_PROG_CC]) |
| 1007 | AC_CACHE_CHECK([for C compiler option to allow warnings], | 1326 | AC_CACHE_CHECK([for C compiler option to allow warnings], |
| 1008 | [gl_cv_cc_wallow], | 1327 | [gl_cv_cc_wallow], |
| 1009 | [rm -f conftest* | 1328 | [rm -fr conftest* |
| 1010 | echo 'int dummy;' > conftest.c | 1329 | echo 'int dummy;' > conftest.c |
| 1011 | AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c 2>conftest1.err]) >/dev/null | 1330 | AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c 2>conftest1.err]) >/dev/null |
| 1012 | AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -Wno-error -c conftest.c 2>conftest2.err]) >/dev/null | 1331 | AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -Wno-error -c conftest.c 2>conftest2.err]) >/dev/null |
| @@ -1019,7 +1338,7 @@ AC_DEFUN([gl_CC_ALLOW_WARNINGS], | |||
| 1019 | else | 1338 | else |
| 1020 | gl_cv_cc_wallow=none | 1339 | gl_cv_cc_wallow=none |
| 1021 | fi | 1340 | fi |
| 1022 | rm -f conftest* | 1341 | rm -fr conftest* |
| 1023 | ]) | 1342 | ]) |
| 1024 | case "$gl_cv_cc_wallow" in | 1343 | case "$gl_cv_cc_wallow" in |
| 1025 | none) GL_CFLAG_ALLOW_WARNINGS='' ;; | 1344 | none) GL_CFLAG_ALLOW_WARNINGS='' ;; |
| @@ -1037,7 +1356,7 @@ AC_DEFUN([gl_CXX_ALLOW_WARNINGS], | |||
| 1037 | if test -n "$CXX" && test "$CXX" != no; then | 1356 | if test -n "$CXX" && test "$CXX" != no; then |
| 1038 | AC_CACHE_CHECK([for C++ compiler option to allow warnings], | 1357 | AC_CACHE_CHECK([for C++ compiler option to allow warnings], |
| 1039 | [gl_cv_cxx_wallow], | 1358 | [gl_cv_cxx_wallow], |
| 1040 | [rm -f conftest* | 1359 | [rm -fr conftest* |
| 1041 | echo 'int dummy;' > conftest.cc | 1360 | echo 'int dummy;' > conftest.cc |
| 1042 | AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -c conftest.cc 2>conftest1.err]) >/dev/null | 1361 | AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -c conftest.cc 2>conftest1.err]) >/dev/null |
| 1043 | AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -Wno-error -c conftest.cc 2>conftest2.err]) >/dev/null | 1362 | AC_TRY_COMMAND([${CXX-c++} $CXXFLAGS $CPPFLAGS -Wno-error -c conftest.cc 2>conftest2.err]) >/dev/null |
| @@ -1050,7 +1369,7 @@ AC_DEFUN([gl_CXX_ALLOW_WARNINGS], | |||
| 1050 | else | 1369 | else |
| 1051 | gl_cv_cxx_wallow=none | 1370 | gl_cv_cxx_wallow=none |
| 1052 | fi | 1371 | fi |
| 1053 | rm -f conftest* | 1372 | rm -fr conftest* |
| 1054 | ]) | 1373 | ]) |
| 1055 | case "$gl_cv_cxx_wallow" in | 1374 | case "$gl_cv_cxx_wallow" in |
| 1056 | none) GL_CXXFLAG_ALLOW_WARNINGS='' ;; | 1375 | none) GL_CXXFLAG_ALLOW_WARNINGS='' ;; |
| @@ -1087,11 +1406,12 @@ AC_DEFUN([gl_CC_GNULIB_WARNINGS], | |||
| 1087 | dnl -Wno-type-limits >= 4.3 >= 3.9 | 1406 | dnl -Wno-type-limits >= 4.3 >= 3.9 |
| 1088 | dnl -Wno-undef >= 3 >= 3.9 | 1407 | dnl -Wno-undef >= 3 >= 3.9 |
| 1089 | dnl -Wno-unsuffixed-float-constants >= 4.5 | 1408 | dnl -Wno-unsuffixed-float-constants >= 4.5 |
| 1409 | dnl -Wno-unused-const-variable >= 4.4 >= 3.9 | ||
| 1090 | dnl -Wno-unused-function >= 3 >= 3.9 | 1410 | dnl -Wno-unused-function >= 3 >= 3.9 |
| 1091 | dnl -Wno-unused-parameter >= 3 >= 3.9 | 1411 | dnl -Wno-unused-parameter >= 3 >= 3.9 |
| 1092 | dnl | 1412 | dnl |
| 1093 | cat > conftest.c <<\EOF | 1413 | cat > conftest.c <<\EOF |
| 1094 | #if __GNUC__ >= 3 || (__clang_major__ + (__clang_minor__ >= 9) > 3) | 1414 | #if (__GNUC__ >= 3 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) |
| 1095 | -Wno-cast-qual | 1415 | -Wno-cast-qual |
| 1096 | -Wno-conversion | 1416 | -Wno-conversion |
| 1097 | -Wno-float-equal | 1417 | -Wno-float-equal |
| @@ -1100,23 +1420,26 @@ AC_DEFUN([gl_CC_GNULIB_WARNINGS], | |||
| 1100 | -Wno-unused-function | 1420 | -Wno-unused-function |
| 1101 | -Wno-unused-parameter | 1421 | -Wno-unused-parameter |
| 1102 | #endif | 1422 | #endif |
| 1103 | #if __GNUC__ + (__GNUC_MINOR__ >= 9) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) | 1423 | #if (__GNUC__ + (__GNUC_MINOR__ >= 9) > 4 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) |
| 1104 | -Wno-float-conversion | 1424 | -Wno-float-conversion |
| 1105 | #endif | 1425 | #endif |
| 1106 | #if __GNUC__ >= 7 || (__clang_major__ + (__clang_minor__ >= 9) > 3) | 1426 | #if (__GNUC__ >= 7 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) |
| 1107 | -Wimplicit-fallthrough | 1427 | -Wimplicit-fallthrough |
| 1108 | #endif | 1428 | #endif |
| 1109 | #if __GNUC__ + (__GNUC_MINOR__ >= 8) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) | 1429 | #if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 4 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) |
| 1110 | -Wno-pedantic | 1430 | -Wno-pedantic |
| 1111 | #endif | 1431 | #endif |
| 1112 | #if 3 < __clang_major__ + (9 <= __clang_minor__) | 1432 | #if 3 < __clang_major__ + (9 <= __clang_minor__) |
| 1113 | -Wno-tautological-constant-out-of-range-compare | 1433 | -Wno-tautological-constant-out-of-range-compare |
| 1114 | #endif | 1434 | #endif |
| 1115 | #if __GNUC__ + (__GNUC_MINOR__ >= 3) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) | 1435 | #if (__GNUC__ + (__GNUC_MINOR__ >= 3) > 4 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) |
| 1116 | -Wno-sign-conversion | 1436 | -Wno-sign-conversion |
| 1117 | -Wno-type-limits | 1437 | -Wno-type-limits |
| 1118 | #endif | 1438 | #endif |
| 1119 | #if __GNUC__ + (__GNUC_MINOR__ >= 5) > 4 | 1439 | #if (__GNUC__ + (__GNUC_MINOR__ >= 4) > 4 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) |
| 1440 | -Wno-unused-const-variable | ||
| 1441 | #endif | ||
| 1442 | #if (__GNUC__ + (__GNUC_MINOR__ >= 5) > 4 && !defined __clang__) | ||
| 1120 | -Wno-unsuffixed-float-constants | 1443 | -Wno-unsuffixed-float-constants |
| 1121 | #endif | 1444 | #endif |
| 1122 | EOF | 1445 | EOF |
| @@ -1240,13 +1563,25 @@ AC_DEFUN([gl_CHECK_FUNCS_CASE_FOR_MACOS], | |||
| 1240 | if test $[ac_cv_func_][$1] = yes; then | 1563 | if test $[ac_cv_func_][$1] = yes; then |
| 1241 | [gl_cv_onwards_func_][$1]=yes | 1564 | [gl_cv_onwards_func_][$1]=yes |
| 1242 | else | 1565 | else |
| 1566 | dnl This is a bit complicated, because here we need the behaviour | ||
| 1567 | dnl of AC_CHECK_DECL before the | ||
| 1568 | dnl commit e1bbc9b93cdff61d70719c224b37970e065008bb (2025-05-26). | ||
| 1569 | [ac_cv_have_decl_][$1][_saved]="$[ac_cv_have_decl_][$1]" | ||
| 1243 | unset [ac_cv_have_decl_][$1] | 1570 | unset [ac_cv_have_decl_][$1] |
| 1571 | ac_c_future_darwin_options_saved="$ac_c_future_darwin_options" | ||
| 1572 | ac_cxx_future_darwin_options_saved="$ac_cxx_future_darwin_options" | ||
| 1573 | ac_c_future_darwin_options= | ||
| 1574 | ac_cxx_future_darwin_options= | ||
| 1244 | AC_CHECK_DECL([$1], , , [$2]) | 1575 | AC_CHECK_DECL([$1], , , [$2]) |
| 1576 | ac_c_future_darwin_options="$ac_c_future_darwin_options_saved" | ||
| 1577 | ac_cxx_future_darwin_options="$ac_cxx_future_darwin_options_saved" | ||
| 1245 | if test $[ac_cv_have_decl_][$1] = yes; then | 1578 | if test $[ac_cv_have_decl_][$1] = yes; then |
| 1246 | [gl_cv_onwards_func_][$1]='future OS version' | 1579 | [gl_cv_onwards_func_][$1]='future OS version' |
| 1247 | else | 1580 | else |
| 1248 | [gl_cv_onwards_func_][$1]=no | 1581 | [gl_cv_onwards_func_][$1]=no |
| 1249 | fi | 1582 | fi |
| 1583 | [ac_cv_have_decl_][$1]="$[ac_cv_have_decl_][$1][_saved]" | ||
| 1584 | unset [ac_cv_have_decl_][$1][_saved] | ||
| 1250 | fi | 1585 | fi |
| 1251 | else | 1586 | else |
| 1252 | AC_CHECK_FUNC([$1]) | 1587 | AC_CHECK_FUNC([$1]) |
| @@ -1299,7 +1634,7 @@ dnl | |||
| 1299 | dnl This macro sets two variables: | 1634 | dnl This macro sets two variables: |
| 1300 | dnl - gl_cv_onwards_func_<func> to yes / no / "future OS version" | 1635 | dnl - gl_cv_onwards_func_<func> to yes / no / "future OS version" |
| 1301 | dnl - ac_cv_func_<func> to yes / no / no | 1636 | dnl - ac_cv_func_<func> to yes / no / no |
| 1302 | dnl The first variable allows to distinguish all three cases. | 1637 | dnl The first variable allows distinguishing all three cases. |
| 1303 | dnl The second variable is set, so that an invocation | 1638 | dnl The second variable is set, so that an invocation |
| 1304 | dnl gl_CHECK_FUNCS_ANDROID([func], [[#include <foo.h>]]) | 1639 | dnl gl_CHECK_FUNCS_ANDROID([func], [[#include <foo.h>]]) |
| 1305 | dnl can be used as a drop-in replacement for | 1640 | dnl can be used as a drop-in replacement for |
| @@ -1352,7 +1687,7 @@ dnl | |||
| 1352 | dnl This macro sets two variables: | 1687 | dnl This macro sets two variables: |
| 1353 | dnl - gl_cv_onwards_func_<func> to yes / no / "future OS version" | 1688 | dnl - gl_cv_onwards_func_<func> to yes / no / "future OS version" |
| 1354 | dnl - ac_cv_func_<func> to yes / no / no | 1689 | dnl - ac_cv_func_<func> to yes / no / no |
| 1355 | dnl The first variable allows to distinguish all three cases. | 1690 | dnl The first variable allows distinguishing all three cases. |
| 1356 | dnl The second variable is set, so that an invocation | 1691 | dnl The second variable is set, so that an invocation |
| 1357 | dnl gl_CHECK_FUNCS_MACOS([func], [[#include <foo.h>]]) | 1692 | dnl gl_CHECK_FUNCS_MACOS([func], [[#include <foo.h>]]) |
| 1358 | dnl can be used as a drop-in replacement for | 1693 | dnl can be used as a drop-in replacement for |
diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4 index 83a0f727..50e98454 100644 --- a/gl/m4/gnulib-comp.m4 +++ b/gl/m4/gnulib-comp.m4 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | # DO NOT EDIT! GENERATED AUTOMATICALLY! | 1 | # DO NOT EDIT! GENERATED AUTOMATICALLY! |
| 2 | # Copyright (C) 2002-2024 Free Software Foundation, Inc. | 2 | # Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 3 | # | 3 | # |
| 4 | # This file is free software; you can redistribute it and/or modify | 4 | # This file is free software; you can redistribute it and/or modify |
| 5 | # it under the terms of the GNU General Public License as published by | 5 | # it under the terms of the GNU General Public License as published by |
| @@ -45,14 +45,30 @@ AC_DEFUN([gl_EARLY], | |||
| 45 | # Code from module absolute-header: | 45 | # Code from module absolute-header: |
| 46 | # Code from module alignasof: | 46 | # Code from module alignasof: |
| 47 | # Code from module alloca-opt: | 47 | # Code from module alloca-opt: |
| 48 | # Code from module arpa_inet: | 48 | # Code from module arpa_inet-h: |
| 49 | # Code from module assert-h: | 49 | # Code from module assert-h: |
| 50 | # Code from module attribute: | 50 | # Code from module attribute: |
| 51 | # Code from module base64: | 51 | # Code from module base64: |
| 52 | # Code from module basename-lgpl: | 52 | # Code from module basename-lgpl: |
| 53 | # Code from module bool: | ||
| 53 | # Code from module btowc: | 54 | # Code from module btowc: |
| 54 | # Code from module builtin-expect: | 55 | # Code from module builtin-expect: |
| 55 | # Code from module byteswap: | 56 | # Code from module byteswap: |
| 57 | # Code from module c-ctype: | ||
| 58 | # Code from module c32isalnum: | ||
| 59 | # Code from module c32isalpha: | ||
| 60 | # Code from module c32isblank: | ||
| 61 | # Code from module c32iscntrl: | ||
| 62 | # Code from module c32isdigit: | ||
| 63 | # Code from module c32isgraph: | ||
| 64 | # Code from module c32islower: | ||
| 65 | # Code from module c32isprint: | ||
| 66 | # Code from module c32ispunct: | ||
| 67 | # Code from module c32isspace: | ||
| 68 | # Code from module c32isupper: | ||
| 69 | # Code from module c32isxdigit: | ||
| 70 | # Code from module c32tolower: | ||
| 71 | # Code from module c32width: | ||
| 56 | # Code from module c99: | 72 | # Code from module c99: |
| 57 | # Code from module calloc-gnu: | 73 | # Code from module calloc-gnu: |
| 58 | # Code from module calloc-posix: | 74 | # Code from module calloc-posix: |
| @@ -66,11 +82,15 @@ AC_DEFUN([gl_EARLY], | |||
| 66 | # Code from module double-slash-root: | 82 | # Code from module double-slash-root: |
| 67 | # Code from module dup2: | 83 | # Code from module dup2: |
| 68 | # Code from module environ: | 84 | # Code from module environ: |
| 69 | # Code from module errno: | 85 | # Code from module errno-h: |
| 70 | # Code from module error: | 86 | # Code from module error: |
| 71 | # Code from module error-h: | 87 | # Code from module error-h: |
| 72 | # Code from module exitfail: | 88 | # Code from module exitfail: |
| 73 | # Code from module extensions: | 89 | # Code from module extensions: |
| 90 | # This is actually already done in the pre-early phase. | ||
| 91 | # AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | ||
| 92 | # Code from module extensions-aix: | ||
| 93 | AC_REQUIRE([gl_USE_AIX_EXTENSIONS]) | ||
| 74 | # Code from module extern-inline: | 94 | # Code from module extern-inline: |
| 75 | # Code from module fcntl: | 95 | # Code from module fcntl: |
| 76 | # Code from module fcntl-h: | 96 | # Code from module fcntl-h: |
| @@ -78,7 +98,7 @@ AC_DEFUN([gl_EARLY], | |||
| 78 | # Code from module fflush: | 98 | # Code from module fflush: |
| 79 | AC_REQUIRE([gl_SET_LARGEFILE_SOURCE]) | 99 | AC_REQUIRE([gl_SET_LARGEFILE_SOURCE]) |
| 80 | # Code from module filename: | 100 | # Code from module filename: |
| 81 | # Code from module float: | 101 | # Code from module float-h: |
| 82 | # Code from module floorf: | 102 | # Code from module floorf: |
| 83 | # Code from module fopen: | 103 | # Code from module fopen: |
| 84 | # Code from module fopen-gnu: | 104 | # Code from module fopen-gnu: |
| @@ -88,6 +108,7 @@ AC_DEFUN([gl_EARLY], | |||
| 88 | # Code from module fseek: | 108 | # Code from module fseek: |
| 89 | # Code from module fseeko: | 109 | # Code from module fseeko: |
| 90 | AC_REQUIRE([gl_SET_LARGEFILE_SOURCE]) | 110 | AC_REQUIRE([gl_SET_LARGEFILE_SOURCE]) |
| 111 | # Code from module fseterr: | ||
| 91 | # Code from module fstat: | 112 | # Code from module fstat: |
| 92 | # Code from module fsusage: | 113 | # Code from module fsusage: |
| 93 | # Code from module ftell: | 114 | # Code from module ftell: |
| @@ -105,6 +126,7 @@ AC_DEFUN([gl_EARLY], | |||
| 105 | # Code from module getprogname: | 126 | # Code from module getprogname: |
| 106 | # Code from module gettext-h: | 127 | # Code from module gettext-h: |
| 107 | # Code from module glibc-internal/dynarray: | 128 | # Code from module glibc-internal/dynarray: |
| 129 | # Code from module gnulib-i18n: | ||
| 108 | # Code from module hard-locale: | 130 | # Code from module hard-locale: |
| 109 | # Code from module hostent: | 131 | # Code from module hostent: |
| 110 | # Code from module ialloc: | 132 | # Code from module ialloc: |
| @@ -112,29 +134,35 @@ AC_DEFUN([gl_EARLY], | |||
| 112 | # Code from module idx: | 134 | # Code from module idx: |
| 113 | # Code from module include_next: | 135 | # Code from module include_next: |
| 114 | # Code from module inet_ntop: | 136 | # Code from module inet_ntop: |
| 137 | # Code from module inet_pton: | ||
| 115 | # Code from module intprops: | 138 | # Code from module intprops: |
| 116 | # Code from module inttypes-incomplete: | 139 | # Code from module inttypes-h-incomplete: |
| 117 | # Code from module iswblank: | 140 | # Code from module iswblank: |
| 118 | # Code from module iswctype: | 141 | # Code from module iswctype: |
| 119 | # Code from module iswdigit: | 142 | # Code from module iswdigit: |
| 120 | # Code from module iswpunct: | 143 | # Code from module iswpunct: |
| 121 | # Code from module iswxdigit: | 144 | # Code from module iswxdigit: |
| 122 | # Code from module langinfo: | 145 | # Code from module langinfo-h: |
| 123 | # Code from module largefile: | 146 | # Code from module largefile: |
| 124 | AC_REQUIRE([AC_SYS_LARGEFILE]) | 147 | AC_REQUIRE([AC_SYS_LARGEFILE]) |
| 125 | # Code from module libc-config: | 148 | # Code from module libc-config: |
| 126 | # Code from module limits-h: | 149 | # Code from module limits-h: |
| 127 | # Code from module localcharset: | 150 | # Code from module localcharset: |
| 128 | # Code from module locale: | 151 | # Code from module locale-h: |
| 129 | # Code from module localeconv: | 152 | # Code from module localeconv: |
| 130 | # Code from module lock: | 153 | # Code from module lock: |
| 131 | # Code from module lseek: | 154 | # Code from module lseek: |
| 155 | # Code from module lstat: | ||
| 132 | # Code from module malloc-gnu: | 156 | # Code from module malloc-gnu: |
| 133 | # Code from module malloc-posix: | 157 | # Code from module malloc-posix: |
| 134 | # Code from module malloca: | 158 | # Code from module malloca: |
| 135 | # Code from module math: | 159 | # Code from module math-h: |
| 160 | # Code from module mbchar: | ||
| 161 | # Code from module mbiterf: | ||
| 162 | # Code from module mbrtoc32: | ||
| 136 | # Code from module mbrtowc: | 163 | # Code from module mbrtowc: |
| 137 | # Code from module mbsinit: | 164 | # Code from module mbsinit: |
| 165 | # Code from module mbsnlen: | ||
| 138 | # Code from module mbszero: | 166 | # Code from module mbszero: |
| 139 | # Code from module mbtowc: | 167 | # Code from module mbtowc: |
| 140 | # Code from module memchr: | 168 | # Code from module memchr: |
| @@ -145,16 +173,20 @@ AC_DEFUN([gl_EARLY], | |||
| 145 | # Code from module msvc-inval: | 173 | # Code from module msvc-inval: |
| 146 | # Code from module msvc-nothrow: | 174 | # Code from module msvc-nothrow: |
| 147 | # Code from module multiarch: | 175 | # Code from module multiarch: |
| 148 | # Code from module netdb: | 176 | # Code from module netdb-h: |
| 149 | # Code from module netinet_in: | 177 | # Code from module netinet_in-h: |
| 150 | # Code from module nl_langinfo: | 178 | # Code from module nl_langinfo: |
| 151 | # Code from module nocrash: | 179 | # Code from module nocrash: |
| 180 | # Code from module once: | ||
| 152 | # Code from module open: | 181 | # Code from module open: |
| 153 | # Code from module pathmax: | 182 | # Code from module pathmax: |
| 154 | # Code from module realloc-gnu: | 183 | # Code from module pthread-h: |
| 184 | gl_ANYTHREADLIB_EARLY | ||
| 185 | # Code from module pthread-once: | ||
| 155 | # Code from module realloc-posix: | 186 | # Code from module realloc-posix: |
| 156 | # Code from module reallocarray: | 187 | # Code from module reallocarray: |
| 157 | # Code from module regex: | 188 | # Code from module regex: |
| 189 | # Code from module sched-h: | ||
| 158 | # Code from module servent: | 190 | # Code from module servent: |
| 159 | # Code from module setenv: | 191 | # Code from module setenv: |
| 160 | # Code from module setlocale-null: | 192 | # Code from module setlocale-null: |
| @@ -172,33 +204,56 @@ AC_DEFUN([gl_EARLY], | |||
| 172 | # Code from module stat: | 204 | # Code from module stat: |
| 173 | # Code from module stat-time: | 205 | # Code from module stat-time: |
| 174 | # Code from module std-gnu11: | 206 | # Code from module std-gnu11: |
| 175 | # Code from module stdbool: | 207 | # Code from module stdckdint-h: |
| 176 | # Code from module stdckdint: | 208 | # Code from module stddef-h: |
| 177 | # Code from module stddef: | 209 | # Code from module stdint-h: |
| 178 | # Code from module stdint: | 210 | # Code from module stdio-h: |
| 179 | # Code from module stdio: | ||
| 180 | gl_STDIO_H_EARLY | 211 | gl_STDIO_H_EARLY |
| 181 | # Code from module stdlib: | 212 | # Code from module stdlib-h: |
| 182 | # Code from module strcase: | 213 | # Code from module strcase: |
| 214 | # Code from module strcasecmp: | ||
| 183 | # Code from module strcasestr: | 215 | # Code from module strcasestr: |
| 184 | # Code from module strcasestr-simple: | 216 | # Code from module strcasestr-simple: |
| 185 | # Code from module streq: | 217 | # Code from module streq: |
| 186 | # Code from module strerror: | 218 | # Code from module strerror: |
| 187 | # Code from module strerror-override: | 219 | # Code from module strerror-override: |
| 188 | # Code from module string: | 220 | # Code from module string-h: |
| 189 | # Code from module strings: | 221 | # Code from module strings-h: |
| 222 | # Code from module strncasecmp: | ||
| 223 | # Code from module strncpy: | ||
| 190 | # Code from module strsep: | 224 | # Code from module strsep: |
| 191 | # Code from module strstr-simple: | 225 | # Code from module strstr-simple: |
| 192 | # Code from module sys_socket: | 226 | # Code from module sys_socket-h: |
| 193 | # Code from module sys_stat: | 227 | # Code from module sys_stat-h: |
| 194 | # Code from module sys_types: | 228 | # Code from module sys_types-h: |
| 195 | # Code from module sys_uio: | 229 | AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) |
| 230 | # Code from module sys_uio-h: | ||
| 196 | # Code from module threadlib: | 231 | # Code from module threadlib: |
| 197 | gl_THREADLIB_EARLY | 232 | gl_THREADLIB_EARLY |
| 198 | # Code from module time-h: | 233 | # Code from module time-h: |
| 199 | # Code from module time_r: | 234 | # Code from module time_r: |
| 200 | # Code from module timegm: | 235 | # Code from module timegm: |
| 201 | # Code from module unistd: | 236 | # Code from module uchar-h: |
| 237 | # Code from module unicase/base: | ||
| 238 | # Code from module unicase/tolower: | ||
| 239 | # Code from module unictype/base: | ||
| 240 | # Code from module unictype/ctype-alnum: | ||
| 241 | # Code from module unictype/ctype-alpha: | ||
| 242 | # Code from module unictype/ctype-blank: | ||
| 243 | # Code from module unictype/ctype-cntrl: | ||
| 244 | # Code from module unictype/ctype-digit: | ||
| 245 | # Code from module unictype/ctype-graph: | ||
| 246 | # Code from module unictype/ctype-lower: | ||
| 247 | # Code from module unictype/ctype-print: | ||
| 248 | # Code from module unictype/ctype-punct: | ||
| 249 | # Code from module unictype/ctype-space: | ||
| 250 | # Code from module unictype/ctype-upper: | ||
| 251 | # Code from module unictype/ctype-xdigit: | ||
| 252 | # Code from module uninorm/base: | ||
| 253 | # Code from module unistd-h: | ||
| 254 | # Code from module unitypes-h: | ||
| 255 | # Code from module uniwidth/base: | ||
| 256 | # Code from module uniwidth/width: | ||
| 202 | # Code from module unlocked-io-internal: | 257 | # Code from module unlocked-io-internal: |
| 203 | # Code from module unsetenv: | 258 | # Code from module unsetenv: |
| 204 | # Code from module vararrays: | 259 | # Code from module vararrays: |
| @@ -206,10 +261,12 @@ AC_DEFUN([gl_EARLY], | |||
| 206 | # Code from module vasprintf: | 261 | # Code from module vasprintf: |
| 207 | # Code from module verify: | 262 | # Code from module verify: |
| 208 | # Code from module vsnprintf: | 263 | # Code from module vsnprintf: |
| 209 | # Code from module wchar: | 264 | # Code from module vsnzprintf: |
| 265 | # Code from module wchar-h: | ||
| 210 | # Code from module wcrtomb: | 266 | # Code from module wcrtomb: |
| 211 | # Code from module wctype: | 267 | # Code from module wctype: |
| 212 | # Code from module wctype-h: | 268 | # Code from module wctype-h: |
| 269 | # Code from module wcwidth: | ||
| 213 | # Code from module windows-mutex: | 270 | # Code from module windows-mutex: |
| 214 | # Code from module windows-once: | 271 | # Code from module windows-once: |
| 215 | # Code from module windows-recmutex: | 272 | # Code from module windows-recmutex: |
| @@ -250,6 +307,7 @@ AC_DEFUN([gl_INIT], | |||
| 250 | gl_CONDITIONAL_HEADER([assert.h]) | 307 | gl_CONDITIONAL_HEADER([assert.h]) |
| 251 | AC_PROG_MKDIR_P | 308 | AC_PROG_MKDIR_P |
| 252 | gl_FUNC_BASE64 | 309 | gl_FUNC_BASE64 |
| 310 | gl_C_BOOL | ||
| 253 | gl_FUNC_BTOWC | 311 | gl_FUNC_BTOWC |
| 254 | gl_CONDITIONAL([GL_COND_OBJ_BTOWC], | 312 | gl_CONDITIONAL([GL_COND_OBJ_BTOWC], |
| 255 | [test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1]) | 313 | [test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1]) |
| @@ -261,6 +319,104 @@ AC_DEFUN([gl_INIT], | |||
| 261 | gl_BYTESWAP | 319 | gl_BYTESWAP |
| 262 | gl_CONDITIONAL_HEADER([byteswap.h]) | 320 | gl_CONDITIONAL_HEADER([byteswap.h]) |
| 263 | AC_PROG_MKDIR_P | 321 | AC_PROG_MKDIR_P |
| 322 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 323 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 324 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 325 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 326 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 327 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 328 | gl_UCHAR_MODULE_INDICATOR([c32isalnum]) | ||
| 329 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 330 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 331 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 332 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 333 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 334 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 335 | gl_UCHAR_MODULE_INDICATOR([c32isalpha]) | ||
| 336 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 337 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 338 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 339 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 340 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 341 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 342 | gl_UCHAR_MODULE_INDICATOR([c32isblank]) | ||
| 343 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 344 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 345 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 346 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 347 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 348 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 349 | gl_UCHAR_MODULE_INDICATOR([c32iscntrl]) | ||
| 350 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 351 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 352 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 353 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 354 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 355 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 356 | gl_UCHAR_MODULE_INDICATOR([c32isdigit]) | ||
| 357 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 358 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 359 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 360 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 361 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 362 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 363 | gl_UCHAR_MODULE_INDICATOR([c32isgraph]) | ||
| 364 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 365 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 366 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 367 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 368 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 369 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 370 | gl_UCHAR_MODULE_INDICATOR([c32islower]) | ||
| 371 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 372 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 373 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 374 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 375 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 376 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 377 | gl_UCHAR_MODULE_INDICATOR([c32isprint]) | ||
| 378 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 379 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 380 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 381 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 382 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 383 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 384 | gl_UCHAR_MODULE_INDICATOR([c32ispunct]) | ||
| 385 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 386 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 387 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 388 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 389 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 390 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 391 | gl_UCHAR_MODULE_INDICATOR([c32isspace]) | ||
| 392 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 393 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 394 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 395 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 396 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 397 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 398 | gl_UCHAR_MODULE_INDICATOR([c32isupper]) | ||
| 399 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 400 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 401 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 402 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 403 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 404 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 405 | gl_UCHAR_MODULE_INDICATOR([c32isxdigit]) | ||
| 406 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 407 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 408 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 409 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 410 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 411 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 412 | gl_UCHAR_MODULE_INDICATOR([c32tolower]) | ||
| 413 | AC_REQUIRE([gl_UCHAR_H]) | ||
| 414 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 415 | dnl determined. It describes how mbrtoc32 is implemented. | ||
| 416 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 417 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 418 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 419 | gl_UCHAR_MODULE_INDICATOR([c32width]) | ||
| 264 | gl_FUNC_CALLOC_GNU | 420 | gl_FUNC_CALLOC_GNU |
| 265 | if test $REPLACE_CALLOC_FOR_CALLOC_GNU = 1; then | 421 | if test $REPLACE_CALLOC_FOR_CALLOC_GNU = 1; then |
| 266 | AC_LIBOBJ([calloc]) | 422 | AC_LIBOBJ([calloc]) |
| @@ -275,6 +431,7 @@ AC_DEFUN([gl_INIT], | |||
| 275 | gl_FUNC_CLOSE | 431 | gl_FUNC_CLOSE |
| 276 | gl_CONDITIONAL([GL_COND_OBJ_CLOSE], [test $REPLACE_CLOSE = 1]) | 432 | gl_CONDITIONAL([GL_COND_OBJ_CLOSE], [test $REPLACE_CLOSE = 1]) |
| 277 | gl_UNISTD_MODULE_INDICATOR([close]) | 433 | gl_UNISTD_MODULE_INDICATOR([close]) |
| 434 | gl_MODULE_INDICATOR([close]) | ||
| 278 | gl_AF_ALG | 435 | gl_AF_ALG |
| 279 | AC_REQUIRE([AC_C_RESTRICT]) | 436 | AC_REQUIRE([AC_C_RESTRICT]) |
| 280 | gl_SHA256 | 437 | gl_SHA256 |
| @@ -320,8 +477,11 @@ AC_DEFUN([gl_INIT], | |||
| 320 | gl_FLOAT_H | 477 | gl_FLOAT_H |
| 321 | gl_CONDITIONAL_HEADER([float.h]) | 478 | gl_CONDITIONAL_HEADER([float.h]) |
| 322 | AC_PROG_MKDIR_P | 479 | AC_PROG_MKDIR_P |
| 323 | gl_CONDITIONAL([GL_COND_OBJ_FLOAT], [test $REPLACE_FLOAT_LDBL = 1]) | 480 | gl_CONDITIONAL([GL_COND_OBJ_FLOAT], |
| 481 | [test $REPLACE_FLOAT_LDBL = 1 || test $REPLACE_FLOAT_SNAN = 1]) | ||
| 324 | gl_CONDITIONAL([GL_COND_OBJ_ITOLD], [test $REPLACE_ITOLD = 1]) | 482 | gl_CONDITIONAL([GL_COND_OBJ_ITOLD], [test $REPLACE_ITOLD = 1]) |
| 483 | dnl Prerequisites of lib/float.c. | ||
| 484 | AC_REQUIRE([gl_BIGENDIAN]) | ||
| 325 | gl_FUNC_FLOORF | 485 | gl_FUNC_FLOORF |
| 326 | gl_CONDITIONAL([GL_COND_OBJ_FLOORF], | 486 | gl_CONDITIONAL([GL_COND_OBJ_FLOORF], |
| 327 | [test $HAVE_DECL_FLOORF = 0 || test $REPLACE_FLOORF = 1]) | 487 | [test $HAVE_DECL_FLOORF = 0 || test $REPLACE_FLOORF = 1]) |
| @@ -360,6 +520,8 @@ AC_DEFUN([gl_INIT], | |||
| 360 | gl_PREREQ_FSEEKO | 520 | gl_PREREQ_FSEEKO |
| 361 | ]) | 521 | ]) |
| 362 | gl_STDIO_MODULE_INDICATOR([fseeko]) | 522 | gl_STDIO_MODULE_INDICATOR([fseeko]) |
| 523 | gl_FUNC_FSETERR | ||
| 524 | gl_CONDITIONAL([GL_COND_OBJ_FSETERR], [test $ac_cv_func___fseterr = no]) | ||
| 363 | gl_FUNC_FSTAT | 525 | gl_FUNC_FSTAT |
| 364 | gl_CONDITIONAL([GL_COND_OBJ_FSTAT], [test $REPLACE_FSTAT = 1]) | 526 | gl_CONDITIONAL([GL_COND_OBJ_FSTAT], [test $REPLACE_FSTAT = 1]) |
| 365 | AM_COND_IF([GL_COND_OBJ_FSTAT], [ | 527 | AM_COND_IF([GL_COND_OBJ_FSTAT], [ |
| @@ -371,6 +533,7 @@ AC_DEFUN([gl_INIT], | |||
| 371 | gl_PREREQ_FSTAT | 533 | gl_PREREQ_FSTAT |
| 372 | ]) | 534 | ]) |
| 373 | gl_SYS_STAT_MODULE_INDICATOR([fstat]) | 535 | gl_SYS_STAT_MODULE_INDICATOR([fstat]) |
| 536 | gl_MODULE_INDICATOR([fstat]) | ||
| 374 | gl_FSUSAGE | 537 | gl_FSUSAGE |
| 375 | gl_CONDITIONAL([GL_COND_OBJ_FSUSAGE], [test $gl_cv_fs_space = yes]) | 538 | gl_CONDITIONAL([GL_COND_OBJ_FSUSAGE], [test $gl_cv_fs_space = yes]) |
| 376 | AM_COND_IF([GL_COND_OBJ_FSUSAGE], [ | 539 | AM_COND_IF([GL_COND_OBJ_FSUSAGE], [ |
| @@ -412,6 +575,7 @@ AC_DEFUN([gl_INIT], | |||
| 412 | gl_PREREQ_GETHOSTNAME | 575 | gl_PREREQ_GETHOSTNAME |
| 413 | ]) | 576 | ]) |
| 414 | gl_UNISTD_MODULE_INDICATOR([gethostname]) | 577 | gl_UNISTD_MODULE_INDICATOR([gethostname]) |
| 578 | gl_MODULE_INDICATOR([gethostname]) | ||
| 415 | gl_FUNC_GETLINE | 579 | gl_FUNC_GETLINE |
| 416 | gl_CONDITIONAL([GL_COND_OBJ_GETLINE], [test $REPLACE_GETLINE = 1]) | 580 | gl_CONDITIONAL([GL_COND_OBJ_GETLINE], [test $REPLACE_GETLINE = 1]) |
| 417 | AM_COND_IF([GL_COND_OBJ_GETLINE], [ | 581 | AM_COND_IF([GL_COND_OBJ_GETLINE], [ |
| @@ -441,6 +605,8 @@ AC_DEFUN([gl_INIT], | |||
| 441 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_GETOPT], [1]) | 605 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNISTD_H_GETOPT], [1]) |
| 442 | ]) | 606 | ]) |
| 443 | gl_UNISTD_MODULE_INDICATOR([getopt-posix]) | 607 | gl_UNISTD_MODULE_INDICATOR([getopt-posix]) |
| 608 | gl_MUSL_LIBC | ||
| 609 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 444 | gl_FUNC_GETPROGNAME | 610 | gl_FUNC_GETPROGNAME |
| 445 | gl_CONDITIONAL([GL_COND_OBJ_GETPROGNAME], | 611 | gl_CONDITIONAL([GL_COND_OBJ_GETPROGNAME], |
| 446 | [test $HAVE_GETPROGNAME = 0 || test $REPLACE_GETPROGNAME = 1]) | 612 | [test $HAVE_GETPROGNAME = 0 || test $REPLACE_GETPROGNAME = 1]) |
| @@ -451,6 +617,7 @@ AC_DEFUN([gl_INIT], | |||
| 451 | AC_SUBST([LIBINTL]) | 617 | AC_SUBST([LIBINTL]) |
| 452 | AC_SUBST([LTLIBINTL]) | 618 | AC_SUBST([LTLIBINTL]) |
| 453 | AC_PROG_MKDIR_P | 619 | AC_PROG_MKDIR_P |
| 620 | GNULIB_I18N | ||
| 454 | AC_REQUIRE([gl_FUNC_SETLOCALE_NULL]) | 621 | AC_REQUIRE([gl_FUNC_SETLOCALE_NULL]) |
| 455 | HARD_LOCALE_LIB="$SETLOCALE_NULL_LIB" | 622 | HARD_LOCALE_LIB="$SETLOCALE_NULL_LIB" |
| 456 | AC_SUBST([HARD_LOCALE_LIB]) | 623 | AC_SUBST([HARD_LOCALE_LIB]) |
| @@ -466,6 +633,13 @@ AC_DEFUN([gl_INIT], | |||
| 466 | gl_PREREQ_INET_NTOP | 633 | gl_PREREQ_INET_NTOP |
| 467 | ]) | 634 | ]) |
| 468 | gl_ARPA_INET_MODULE_INDICATOR([inet_ntop]) | 635 | gl_ARPA_INET_MODULE_INDICATOR([inet_ntop]) |
| 636 | gl_FUNC_INET_PTON | ||
| 637 | gl_CONDITIONAL([GL_COND_OBJ_INET_PTON], | ||
| 638 | [test $HAVE_INET_PTON = 0 || test $REPLACE_INET_PTON = 1]) | ||
| 639 | AM_COND_IF([GL_COND_OBJ_INET_PTON], [ | ||
| 640 | gl_PREREQ_INET_PTON | ||
| 641 | ]) | ||
| 642 | gl_ARPA_INET_MODULE_INDICATOR([inet_pton]) | ||
| 469 | gl_INTTYPES_INCOMPLETE | 643 | gl_INTTYPES_INCOMPLETE |
| 470 | gl_INTTYPES_H_REQUIRE_DEFAULTS | 644 | gl_INTTYPES_H_REQUIRE_DEFAULTS |
| 471 | AC_PROG_MKDIR_P | 645 | AC_PROG_MKDIR_P |
| @@ -510,11 +684,19 @@ AC_DEFUN([gl_INIT], | |||
| 510 | gl_PREREQ_LOCALECONV | 684 | gl_PREREQ_LOCALECONV |
| 511 | ]) | 685 | ]) |
| 512 | gl_LOCALE_MODULE_INDICATOR([localeconv]) | 686 | gl_LOCALE_MODULE_INDICATOR([localeconv]) |
| 687 | gl_MODULE_INDICATOR([localeconv]) | ||
| 513 | gl_LOCK | 688 | gl_LOCK |
| 514 | gl_MODULE_INDICATOR([lock]) | 689 | gl_MODULE_INDICATOR([lock]) |
| 515 | gl_FUNC_LSEEK | 690 | gl_FUNC_LSEEK |
| 516 | gl_CONDITIONAL([GL_COND_OBJ_LSEEK], [test $REPLACE_LSEEK = 1]) | 691 | gl_CONDITIONAL([GL_COND_OBJ_LSEEK], [test $REPLACE_LSEEK = 1]) |
| 517 | gl_UNISTD_MODULE_INDICATOR([lseek]) | 692 | gl_UNISTD_MODULE_INDICATOR([lseek]) |
| 693 | gl_FUNC_LSTAT | ||
| 694 | gl_CONDITIONAL([GL_COND_OBJ_LSTAT], [test $REPLACE_LSTAT = 1]) | ||
| 695 | AM_COND_IF([GL_COND_OBJ_LSTAT], [ | ||
| 696 | gl_PREREQ_LSTAT | ||
| 697 | ]) | ||
| 698 | gl_SYS_STAT_MODULE_INDICATOR([lstat]) | ||
| 699 | gl_MODULE_INDICATOR([lstat]) | ||
| 518 | gl_FUNC_MALLOC_GNU | 700 | gl_FUNC_MALLOC_GNU |
| 519 | if test $REPLACE_MALLOC_FOR_MALLOC_GNU = 1; then | 701 | if test $REPLACE_MALLOC_FOR_MALLOC_GNU = 1; then |
| 520 | AC_LIBOBJ([malloc]) | 702 | AC_LIBOBJ([malloc]) |
| @@ -529,6 +711,20 @@ AC_DEFUN([gl_INIT], | |||
| 529 | gl_MATH_H | 711 | gl_MATH_H |
| 530 | gl_MATH_H_REQUIRE_DEFAULTS | 712 | gl_MATH_H_REQUIRE_DEFAULTS |
| 531 | AC_PROG_MKDIR_P | 713 | AC_PROG_MKDIR_P |
| 714 | gl_MBCHAR | ||
| 715 | gl_MBITER | ||
| 716 | gl_FUNC_MBRTOC32 | ||
| 717 | gl_CONDITIONAL([GL_COND_OBJ_MBRTOC32], | ||
| 718 | [test $HAVE_MBRTOC32 = 0 || test $REPLACE_MBRTOC32 = 1]) | ||
| 719 | AM_COND_IF([GL_COND_OBJ_MBRTOC32], [ | ||
| 720 | if test $REPLACE_MBSTATE_T = 1; then | ||
| 721 | AC_LIBOBJ([lc-charset-dispatch]) | ||
| 722 | AC_LIBOBJ([mbtowc-lock]) | ||
| 723 | gl_PREREQ_MBTOWC_LOCK | ||
| 724 | fi | ||
| 725 | gl_PREREQ_MBRTOC32 | ||
| 726 | ]) | ||
| 727 | gl_UCHAR_MODULE_INDICATOR([mbrtoc32]) | ||
| 532 | gl_FUNC_MBRTOWC | 728 | gl_FUNC_MBRTOWC |
| 533 | gl_CONDITIONAL([GL_COND_OBJ_MBRTOWC], | 729 | gl_CONDITIONAL([GL_COND_OBJ_MBRTOWC], |
| 534 | [test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1]) | 730 | [test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1]) |
| @@ -548,6 +744,7 @@ AC_DEFUN([gl_INIT], | |||
| 548 | gl_PREREQ_MBSINIT | 744 | gl_PREREQ_MBSINIT |
| 549 | ]) | 745 | ]) |
| 550 | gl_WCHAR_MODULE_INDICATOR([mbsinit]) | 746 | gl_WCHAR_MODULE_INDICATOR([mbsinit]) |
| 747 | gl_STRING_MODULE_INDICATOR([mbsnlen]) | ||
| 551 | AC_REQUIRE([AC_TYPE_MBSTATE_T]) | 748 | AC_REQUIRE([AC_TYPE_MBSTATE_T]) |
| 552 | gl_MBSTATE_T_BROKEN | 749 | gl_MBSTATE_T_BROKEN |
| 553 | gl_MUSL_LIBC | 750 | gl_MUSL_LIBC |
| @@ -578,10 +775,7 @@ AC_DEFUN([gl_INIT], | |||
| 578 | gl_PREREQ_MKTIME | 775 | gl_PREREQ_MKTIME |
| 579 | fi | 776 | fi |
| 580 | gl_MOUNTLIST | 777 | gl_MOUNTLIST |
| 581 | gl_CONDITIONAL([GL_COND_OBJ_MOUNTLIST], [test $gl_cv_list_mounted_fs = yes]) | 778 | gl_PREREQ_MOUNTLIST_EXTRA |
| 582 | AM_COND_IF([GL_COND_OBJ_MOUNTLIST], [ | ||
| 583 | gl_PREREQ_MOUNTLIST_EXTRA | ||
| 584 | ]) | ||
| 585 | AC_REQUIRE([gl_MSVC_INVAL]) | 779 | AC_REQUIRE([gl_MSVC_INVAL]) |
| 586 | gl_CONDITIONAL([GL_COND_OBJ_MSVC_INVAL], | 780 | gl_CONDITIONAL([GL_COND_OBJ_MSVC_INVAL], |
| 587 | [test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1]) | 781 | [test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1]) |
| @@ -605,6 +799,7 @@ AC_DEFUN([gl_INIT], | |||
| 605 | gl_PREREQ_NL_LANGINFO_LOCK | 799 | gl_PREREQ_NL_LANGINFO_LOCK |
| 606 | fi | 800 | fi |
| 607 | gl_LANGINFO_MODULE_INDICATOR([nl_langinfo]) | 801 | gl_LANGINFO_MODULE_INDICATOR([nl_langinfo]) |
| 802 | gl_ONCE | ||
| 608 | gl_FUNC_OPEN | 803 | gl_FUNC_OPEN |
| 609 | gl_CONDITIONAL([GL_COND_OBJ_OPEN], [test $REPLACE_OPEN = 1]) | 804 | gl_CONDITIONAL([GL_COND_OBJ_OPEN], [test $REPLACE_OPEN = 1]) |
| 610 | AM_COND_IF([GL_COND_OBJ_OPEN], [ | 805 | AM_COND_IF([GL_COND_OBJ_OPEN], [ |
| @@ -612,15 +807,17 @@ AC_DEFUN([gl_INIT], | |||
| 612 | ]) | 807 | ]) |
| 613 | gl_FCNTL_MODULE_INDICATOR([open]) | 808 | gl_FCNTL_MODULE_INDICATOR([open]) |
| 614 | gl_PATHMAX | 809 | gl_PATHMAX |
| 615 | gl_FUNC_REALLOC_GNU | 810 | gl_PTHREAD_H |
| 616 | if test $REPLACE_REALLOC_FOR_REALLOC_GNU = 1; then | 811 | gl_PTHREAD_H_REQUIRE_DEFAULTS |
| 617 | AC_LIBOBJ([realloc]) | 812 | AC_PROG_MKDIR_P |
| 618 | fi | 813 | gl_PTHREAD_ONCE |
| 619 | gl_STDLIB_MODULE_INDICATOR([realloc-gnu]) | 814 | gl_CONDITIONAL([GL_COND_OBJ_PTHREAD_ONCE], |
| 815 | [test $HAVE_PTHREAD_ONCE = 0 || test $REPLACE_PTHREAD_ONCE = 1]) | ||
| 816 | gl_PTHREAD_MODULE_INDICATOR([pthread-once]) | ||
| 620 | gl_FUNC_REALLOC_POSIX | 817 | gl_FUNC_REALLOC_POSIX |
| 621 | if test $REPLACE_REALLOC_FOR_REALLOC_POSIX = 1; then | 818 | gl_FUNC_REALLOC_0_NONNULL |
| 622 | AC_LIBOBJ([realloc]) | 819 | gl_CONDITIONAL([GL_COND_OBJ_REALLOC_POSIX], |
| 623 | fi | 820 | [test $REPLACE_REALLOC_FOR_REALLOC_POSIX != 0]) |
| 624 | gl_STDLIB_MODULE_INDICATOR([realloc-posix]) | 821 | gl_STDLIB_MODULE_INDICATOR([realloc-posix]) |
| 625 | gl_FUNC_REALLOCARRAY | 822 | gl_FUNC_REALLOCARRAY |
| 626 | gl_CONDITIONAL([GL_COND_OBJ_REALLOCARRAY], | 823 | gl_CONDITIONAL([GL_COND_OBJ_REALLOCARRAY], |
| @@ -635,6 +832,9 @@ AC_DEFUN([gl_INIT], | |||
| 635 | AM_COND_IF([GL_COND_OBJ_REGEX], [ | 832 | AM_COND_IF([GL_COND_OBJ_REGEX], [ |
| 636 | gl_PREREQ_REGEX | 833 | gl_PREREQ_REGEX |
| 637 | ]) | 834 | ]) |
| 835 | gl_SCHED_H | ||
| 836 | gl_SCHED_H_REQUIRE_DEFAULTS | ||
| 837 | AC_PROG_MKDIR_P | ||
| 638 | gl_SERVENT | 838 | gl_SERVENT |
| 639 | gl_FUNC_SETENV | 839 | gl_FUNC_SETENV |
| 640 | gl_CONDITIONAL([GL_COND_OBJ_SETENV], | 840 | gl_CONDITIONAL([GL_COND_OBJ_SETENV], |
| @@ -666,15 +866,10 @@ AC_DEFUN([gl_INIT], | |||
| 666 | gl_PREREQ_STAT | 866 | gl_PREREQ_STAT |
| 667 | ]) | 867 | ]) |
| 668 | gl_SYS_STAT_MODULE_INDICATOR([stat]) | 868 | gl_SYS_STAT_MODULE_INDICATOR([stat]) |
| 869 | gl_MODULE_INDICATOR([stat]) | ||
| 669 | gl_STAT_TIME | 870 | gl_STAT_TIME |
| 670 | gl_STAT_BIRTHTIME | 871 | gl_STAT_BIRTHTIME |
| 671 | gl_C_BOOL | 872 | gl_STDCKDINT_H |
| 672 | AC_CHECK_HEADERS_ONCE([stdckdint.h]) | ||
| 673 | if test $ac_cv_header_stdckdint_h = yes; then | ||
| 674 | GL_GENERATE_STDCKDINT_H=false | ||
| 675 | else | ||
| 676 | GL_GENERATE_STDCKDINT_H=true | ||
| 677 | fi | ||
| 678 | gl_CONDITIONAL_HEADER([stdckdint.h]) | 873 | gl_CONDITIONAL_HEADER([stdckdint.h]) |
| 679 | AC_PROG_MKDIR_P | 874 | AC_PROG_MKDIR_P |
| 680 | gl_STDDEF_H | 875 | gl_STDDEF_H |
| @@ -689,6 +884,19 @@ AC_DEFUN([gl_INIT], | |||
| 689 | gl_STDIO_H | 884 | gl_STDIO_H |
| 690 | gl_STDIO_H_REQUIRE_DEFAULTS | 885 | gl_STDIO_H_REQUIRE_DEFAULTS |
| 691 | AC_PROG_MKDIR_P | 886 | AC_PROG_MKDIR_P |
| 887 | USES_MSVCRT=0 | ||
| 888 | case "$host_os" in | ||
| 889 | mingw* | windows*) | ||
| 890 | AC_EGREP_CPP([Special], [ | ||
| 891 | #ifndef _UCRT | ||
| 892 | Special | ||
| 893 | #endif | ||
| 894 | ], | ||
| 895 | [USES_MSVCRT=1]) | ||
| 896 | ;; | ||
| 897 | esac | ||
| 898 | gl_CONDITIONAL([GL_COND_OBJ_STDIO_CONSOLESAFE], [test $USES_MSVCRT = 1]) | ||
| 899 | AC_CHECK_FUNCS([vasprintf]) | ||
| 692 | gl_CONDITIONAL([GL_COND_OBJ_STDIO_READ], [test $REPLACE_STDIO_READ_FUNCS = 1]) | 900 | gl_CONDITIONAL([GL_COND_OBJ_STDIO_READ], [test $REPLACE_STDIO_READ_FUNCS = 1]) |
| 693 | gl_CONDITIONAL([GL_COND_OBJ_STDIO_WRITE], [test $REPLACE_STDIO_WRITE_FUNCS = 1]) | 901 | gl_CONDITIONAL([GL_COND_OBJ_STDIO_WRITE], [test $REPLACE_STDIO_WRITE_FUNCS = 1]) |
| 694 | dnl No need to create extra modules for these functions. Everyone who uses | 902 | dnl No need to create extra modules for these functions. Everyone who uses |
| @@ -717,15 +925,13 @@ AC_DEFUN([gl_INIT], | |||
| 717 | gl_STDLIB_H | 925 | gl_STDLIB_H |
| 718 | gl_STDLIB_H_REQUIRE_DEFAULTS | 926 | gl_STDLIB_H_REQUIRE_DEFAULTS |
| 719 | AC_PROG_MKDIR_P | 927 | AC_PROG_MKDIR_P |
| 720 | gl_STRCASE | 928 | gl_FUNC_STRCASECMP |
| 721 | gl_CONDITIONAL([GL_COND_OBJ_STRCASECMP], [test $HAVE_STRCASECMP = 0]) | 929 | gl_CONDITIONAL([GL_COND_OBJ_STRCASECMP], |
| 930 | [test $HAVE_STRCASECMP = 0 || test $REPLACE_STRCASECMP = 1]) | ||
| 722 | AM_COND_IF([GL_COND_OBJ_STRCASECMP], [ | 931 | AM_COND_IF([GL_COND_OBJ_STRCASECMP], [ |
| 723 | gl_PREREQ_STRCASECMP | 932 | gl_PREREQ_STRCASECMP |
| 724 | ]) | 933 | ]) |
| 725 | gl_CONDITIONAL([GL_COND_OBJ_STRNCASECMP], [test $HAVE_STRNCASECMP = 0]) | 934 | gl_STRINGS_MODULE_INDICATOR([strcasecmp]) |
| 726 | AM_COND_IF([GL_COND_OBJ_STRNCASECMP], [ | ||
| 727 | gl_PREREQ_STRNCASECMP | ||
| 728 | ]) | ||
| 729 | gl_FUNC_STRCASESTR | 935 | gl_FUNC_STRCASESTR |
| 730 | if test $HAVE_STRCASESTR = 0 || test $REPLACE_STRCASESTR = 1; then | 936 | if test $HAVE_STRCASESTR = 0 || test $REPLACE_STRCASESTR = 1; then |
| 731 | AC_LIBOBJ([strcasestr]) | 937 | AC_LIBOBJ([strcasestr]) |
| @@ -754,6 +960,19 @@ AC_DEFUN([gl_INIT], | |||
| 754 | gl_STRINGS_H | 960 | gl_STRINGS_H |
| 755 | gl_STRINGS_H_REQUIRE_DEFAULTS | 961 | gl_STRINGS_H_REQUIRE_DEFAULTS |
| 756 | AC_PROG_MKDIR_P | 962 | AC_PROG_MKDIR_P |
| 963 | gl_FUNC_STRNCASECMP | ||
| 964 | gl_CONDITIONAL([GL_COND_OBJ_STRNCASECMP], | ||
| 965 | [test $HAVE_STRNCASECMP = 0 || test $REPLACE_STRNCASECMP = 1]) | ||
| 966 | AM_COND_IF([GL_COND_OBJ_STRNCASECMP], [ | ||
| 967 | gl_PREREQ_STRNCASECMP | ||
| 968 | ]) | ||
| 969 | gl_STRINGS_MODULE_INDICATOR([strncasecmp]) | ||
| 970 | gl_FUNC_STRNCPY | ||
| 971 | gl_CONDITIONAL([GL_COND_OBJ_STRNCPY], [test $REPLACE_STRNCPY = 1]) | ||
| 972 | AM_COND_IF([GL_COND_OBJ_STRNCPY], [ | ||
| 973 | gl_PREREQ_STRNCPY | ||
| 974 | ]) | ||
| 975 | gl_STRING_MODULE_INDICATOR([strncpy]) | ||
| 757 | gl_FUNC_STRSEP | 976 | gl_FUNC_STRSEP |
| 758 | gl_CONDITIONAL([GL_COND_OBJ_STRSEP], [test $HAVE_STRSEP = 0]) | 977 | gl_CONDITIONAL([GL_COND_OBJ_STRSEP], [test $HAVE_STRSEP = 0]) |
| 759 | AM_COND_IF([GL_COND_OBJ_STRSEP], [ | 978 | AM_COND_IF([GL_COND_OBJ_STRSEP], [ |
| @@ -795,9 +1014,55 @@ AC_DEFUN([gl_INIT], | |||
| 795 | gl_PREREQ_TIMEGM | 1014 | gl_PREREQ_TIMEGM |
| 796 | ]) | 1015 | ]) |
| 797 | gl_TIME_MODULE_INDICATOR([timegm]) | 1016 | gl_TIME_MODULE_INDICATOR([timegm]) |
| 1017 | gl_UCHAR_H | ||
| 1018 | gl_UCHAR_H_REQUIRE_DEFAULTS | ||
| 1019 | AC_PROG_MKDIR_P | ||
| 1020 | gl_LIBUNISTRING_LIBHEADER([1.2], [unicase.h]) | ||
| 1021 | gl_UNICASE_H | ||
| 1022 | gl_UNICASE_H_REQUIRE_DEFAULTS | ||
| 1023 | AC_PROG_MKDIR_P | ||
| 1024 | gl_LIBUNISTRING_MODULE([1.3], [unicase/tolower]) | ||
| 1025 | gl_LIBUNISTRING_LIBHEADER([1.3], [unictype.h]) | ||
| 1026 | gl_UNICTYPE_H | ||
| 1027 | gl_UNICTYPE_H_REQUIRE_DEFAULTS | ||
| 1028 | AC_PROG_MKDIR_P | ||
| 1029 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1030 | gl_LIBUNISTRING_MODULE([1.3], [unictype/ctype-alnum]) | ||
| 1031 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1032 | gl_LIBUNISTRING_MODULE([1.3], [unictype/ctype-alpha]) | ||
| 1033 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1034 | gl_LIBUNISTRING_MODULE([0.9.8], [unictype/ctype-blank]) | ||
| 1035 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1036 | gl_LIBUNISTRING_MODULE([0.9.8], [unictype/ctype-cntrl]) | ||
| 1037 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1038 | gl_LIBUNISTRING_MODULE([0.9.8], [unictype/ctype-digit]) | ||
| 1039 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1040 | gl_LIBUNISTRING_MODULE([1.3], [unictype/ctype-graph]) | ||
| 1041 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1042 | gl_LIBUNISTRING_MODULE([1.3], [unictype/ctype-lower]) | ||
| 1043 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1044 | gl_LIBUNISTRING_MODULE([1.3], [unictype/ctype-print]) | ||
| 1045 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1046 | gl_LIBUNISTRING_MODULE([1.3], [unictype/ctype-punct]) | ||
| 1047 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1048 | gl_LIBUNISTRING_MODULE([0.9.8], [unictype/ctype-space]) | ||
| 1049 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1050 | gl_LIBUNISTRING_MODULE([1.3], [unictype/ctype-upper]) | ||
| 1051 | AC_REQUIRE([AC_C_INLINE]) | ||
| 1052 | gl_LIBUNISTRING_MODULE([0.9.8], [unictype/ctype-xdigit]) | ||
| 1053 | gl_LIBUNISTRING_LIBHEADER([1.2], [uninorm.h]) | ||
| 1054 | gl_UNINORM_H | ||
| 1055 | gl_UNINORM_H_REQUIRE_DEFAULTS | ||
| 1056 | AC_PROG_MKDIR_P | ||
| 798 | gl_UNISTD_H | 1057 | gl_UNISTD_H |
| 799 | gl_UNISTD_H_REQUIRE_DEFAULTS | 1058 | gl_UNISTD_H_REQUIRE_DEFAULTS |
| 800 | AC_PROG_MKDIR_P | 1059 | AC_PROG_MKDIR_P |
| 1060 | gl_LIBUNISTRING_LIBHEADER([0.9.11], [unitypes.h]) | ||
| 1061 | AC_PROG_MKDIR_P | ||
| 1062 | gl_UNITYPES_H | ||
| 1063 | gl_LIBUNISTRING_LIBHEADER([0.9.11], [uniwidth.h]) | ||
| 1064 | AC_PROG_MKDIR_P | ||
| 1065 | gl_LIBUNISTRING_MODULE([1.3], [uniwidth/width]) | ||
| 801 | gl_FUNC_GLIBC_UNLOCKED_IO | 1066 | gl_FUNC_GLIBC_UNLOCKED_IO |
| 802 | gl_FUNC_UNSETENV | 1067 | gl_FUNC_UNSETENV |
| 803 | gl_CONDITIONAL([GL_COND_OBJ_UNSETENV], | 1068 | gl_CONDITIONAL([GL_COND_OBJ_UNSETENV], |
| @@ -816,6 +1081,7 @@ AC_DEFUN([gl_INIT], | |||
| 816 | AM_][XGETTEXT_OPTION([--flag=vasprintf:2:c-format])]) | 1081 | AM_][XGETTEXT_OPTION([--flag=vasprintf:2:c-format])]) |
| 817 | gl_FUNC_VSNPRINTF | 1082 | gl_FUNC_VSNPRINTF |
| 818 | gl_STDIO_MODULE_INDICATOR([vsnprintf]) | 1083 | gl_STDIO_MODULE_INDICATOR([vsnprintf]) |
| 1084 | gl_STDIO_MODULE_INDICATOR([vsnzprintf]) | ||
| 819 | gl_WCHAR_H | 1085 | gl_WCHAR_H |
| 820 | gl_WCHAR_H_REQUIRE_DEFAULTS | 1086 | gl_WCHAR_H_REQUIRE_DEFAULTS |
| 821 | AC_PROG_MKDIR_P | 1087 | AC_PROG_MKDIR_P |
| @@ -832,6 +1098,13 @@ AC_DEFUN([gl_INIT], | |||
| 832 | gl_WCTYPE_H | 1098 | gl_WCTYPE_H |
| 833 | gl_WCTYPE_H_REQUIRE_DEFAULTS | 1099 | gl_WCTYPE_H_REQUIRE_DEFAULTS |
| 834 | AC_PROG_MKDIR_P | 1100 | AC_PROG_MKDIR_P |
| 1101 | gl_FUNC_WCWIDTH | ||
| 1102 | gl_CONDITIONAL([GL_COND_OBJ_WCWIDTH], | ||
| 1103 | [test $HAVE_WCWIDTH = 0 || test $REPLACE_WCWIDTH = 1]) | ||
| 1104 | AM_COND_IF([GL_COND_OBJ_WCWIDTH], [ | ||
| 1105 | gl_PREREQ_WCWIDTH | ||
| 1106 | ]) | ||
| 1107 | gl_WCHAR_MODULE_INDICATOR([wcwidth]) | ||
| 835 | AC_REQUIRE([AC_CANONICAL_HOST]) | 1108 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 836 | gl_CONDITIONAL([GL_COND_OBJ_WINDOWS_MUTEX], | 1109 | gl_CONDITIONAL([GL_COND_OBJ_WINDOWS_MUTEX], |
| 837 | [case "$host_os" in mingw* | windows*) true;; *) false;; esac]) | 1110 | [case "$host_os" in mingw* | windows*) true;; *) false;; esac]) |
| @@ -871,27 +1144,35 @@ AC_DEFUN([gl_INIT], | |||
| 871 | gl_libobjs= | 1144 | gl_libobjs= |
| 872 | gl_ltlibobjs= | 1145 | gl_ltlibobjs= |
| 873 | gl_libobjdeps= | 1146 | gl_libobjdeps= |
| 1147 | gl_libgnu_libobjs= | ||
| 1148 | gl_libgnu_ltlibobjs= | ||
| 1149 | gl_libgnu_libobjdeps= | ||
| 874 | if test -n "$gl_LIBOBJS"; then | 1150 | if test -n "$gl_LIBOBJS"; then |
| 875 | # Remove the extension. | 1151 | # Remove the extension. |
| 876 | changequote(,)dnl | 1152 | changequote(,)dnl |
| 877 | sed_drop_objext='s/\.o$//;s/\.obj$//' | 1153 | sed_drop_objext='s/\.o$//;s/\.obj$//' |
| 878 | sed_dirname1='s,//*,/,g' | 1154 | sed_dirname1='s,//*,/,g' |
| 879 | sed_dirname2='s,\(.\)/$,\1,' | 1155 | sed_dirname2='s,\(.\)/$,\1,' |
| 880 | sed_dirname3='s,^[^/]*$,.,' | 1156 | sed_dirname3='s,[^/]*$,,' |
| 881 | sed_dirname4='s,\(.\)/[^/]*$,\1,' | ||
| 882 | sed_basename1='s,.*/,,' | 1157 | sed_basename1='s,.*/,,' |
| 883 | changequote([, ])dnl | 1158 | changequote([, ])dnl |
| 884 | for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do | 1159 | for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do |
| 885 | gl_libobjs="$gl_libobjs $i.$ac_objext" | 1160 | gl_libobjs="$gl_libobjs $i.$ac_objext" |
| 886 | gl_ltlibobjs="$gl_ltlibobjs $i.lo" | 1161 | gl_ltlibobjs="$gl_ltlibobjs $i.lo" |
| 887 | i_dir=`echo "$i" | sed -e "$sed_dirname1" -e "$sed_dirname2" -e "$sed_dirname3" -e "$sed_dirname4"` | 1162 | i_dir=`echo "$i" | sed -e "$sed_dirname1" -e "$sed_dirname2" -e "$sed_dirname3"` |
| 888 | i_base=`echo "$i" | sed -e "$sed_basename1"` | 1163 | i_base=`echo "$i" | sed -e "$sed_basename1"` |
| 889 | gl_libobjdeps="$gl_libobjdeps $i_dir/\$(DEPDIR)/$i_base.Po" | 1164 | gl_libgnu_libobjs="$gl_libgnu_libobjs $i_dir""libgnu_a-$i_base.$ac_objext" |
| 1165 | gl_libgnu_ltlibobjs="$gl_libgnu_ltlibobjs $i_dir""libgnu_la-$i_base.lo" | ||
| 1166 | gl_libobjdeps="$gl_libobjdeps $i_dir\$(DEPDIR)/$i_base.Po" | ||
| 1167 | gl_libgnu_libobjdeps="$gl_libgnu_libobjdeps $i_dir\$(DEPDIR)/libgnu_a-$i_base.Po" | ||
| 890 | done | 1168 | done |
| 891 | fi | 1169 | fi |
| 892 | AC_SUBST([gl_LIBOBJS], [$gl_libobjs]) | 1170 | AC_SUBST([gl_LIBOBJS], [$gl_libobjs]) |
| 893 | AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs]) | 1171 | AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs]) |
| 894 | AC_SUBST([gl_LIBOBJDEPS], [$gl_libobjdeps]) | 1172 | AC_SUBST([gl_LIBOBJDEPS], [$gl_libobjdeps]) |
| 1173 | AC_SUBST([gl_libgnu_LIBOBJS], [$gl_libgnu_libobjs]) | ||
| 1174 | AC_SUBST([gl_libgnu_LTLIBOBJS], [$gl_libgnu_ltlibobjs]) | ||
| 1175 | AC_SUBST([gl_libgnu_LIBOBJDEPS], [$gl_libgnu_libobjdeps]) | ||
| 895 | ]) | 1176 | ]) |
| 896 | gltests_libdeps= | 1177 | gltests_libdeps= |
| 897 | gltests_ltlibdeps= | 1178 | gltests_ltlibdeps= |
| @@ -934,27 +1215,35 @@ changequote([, ])dnl | |||
| 934 | gltests_libobjs= | 1215 | gltests_libobjs= |
| 935 | gltests_ltlibobjs= | 1216 | gltests_ltlibobjs= |
| 936 | gltests_libobjdeps= | 1217 | gltests_libobjdeps= |
| 1218 | gltests_libgnu_libobjs= | ||
| 1219 | gltests_libgnu_ltlibobjs= | ||
| 1220 | gltests_libgnu_libobjdeps= | ||
| 937 | if test -n "$gltests_LIBOBJS"; then | 1221 | if test -n "$gltests_LIBOBJS"; then |
| 938 | # Remove the extension. | 1222 | # Remove the extension. |
| 939 | changequote(,)dnl | 1223 | changequote(,)dnl |
| 940 | sed_drop_objext='s/\.o$//;s/\.obj$//' | 1224 | sed_drop_objext='s/\.o$//;s/\.obj$//' |
| 941 | sed_dirname1='s,//*,/,g' | 1225 | sed_dirname1='s,//*,/,g' |
| 942 | sed_dirname2='s,\(.\)/$,\1,' | 1226 | sed_dirname2='s,\(.\)/$,\1,' |
| 943 | sed_dirname3='s,^[^/]*$,.,' | 1227 | sed_dirname3='s,[^/]*$,,' |
| 944 | sed_dirname4='s,\(.\)/[^/]*$,\1,' | ||
| 945 | sed_basename1='s,.*/,,' | 1228 | sed_basename1='s,.*/,,' |
| 946 | changequote([, ])dnl | 1229 | changequote([, ])dnl |
| 947 | for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do | 1230 | for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do |
| 948 | gltests_libobjs="$gltests_libobjs $i.$ac_objext" | 1231 | gltests_libobjs="$gltests_libobjs $i.$ac_objext" |
| 949 | gltests_ltlibobjs="$gltests_ltlibobjs $i.lo" | 1232 | gltests_ltlibobjs="$gltests_ltlibobjs $i.lo" |
| 950 | i_dir=`echo "$i" | sed -e "$sed_dirname1" -e "$sed_dirname2" -e "$sed_dirname3" -e "$sed_dirname4"` | 1233 | i_dir=`echo "$i" | sed -e "$sed_dirname1" -e "$sed_dirname2" -e "$sed_dirname3"` |
| 951 | i_base=`echo "$i" | sed -e "$sed_basename1"` | 1234 | i_base=`echo "$i" | sed -e "$sed_basename1"` |
| 952 | gltests_libobjdeps="$gltests_libobjdeps $i_dir/\$(DEPDIR)/$i_base.Po" | 1235 | gltests_libgnu_libobjs="$gltests_libgnu_libobjs $i_dir""libgnu_a-$i_base.$ac_objext" |
| 1236 | gltests_libgnu_ltlibobjs="$gltests_libgnu_ltlibobjs $i_dir""libgnu_la-$i_base.lo" | ||
| 1237 | gltests_libobjdeps="$gltests_libobjdeps $i_dir\$(DEPDIR)/$i_base.Po" | ||
| 1238 | gltests_libgnu_libobjdeps="$gltests_libgnu_libobjdeps $i_dir\$(DEPDIR)/libgnu_a-$i_base.Po" | ||
| 953 | done | 1239 | done |
| 954 | fi | 1240 | fi |
| 955 | AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs]) | 1241 | AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs]) |
| 956 | AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs]) | 1242 | AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs]) |
| 957 | AC_SUBST([gltests_LIBOBJDEPS], [$gltests_libobjdeps]) | 1243 | AC_SUBST([gltests_LIBOBJDEPS], [$gltests_libobjdeps]) |
| 1244 | AC_SUBST([gltests_libgnu_LIBOBJS], [$gltests_libgnu_libobjs]) | ||
| 1245 | AC_SUBST([gltests_libgnu_LTLIBOBJS], [$gltests_libgnu_ltlibobjs]) | ||
| 1246 | AC_SUBST([gltests_libgnu_LIBOBJDEPS], [$gltests_libgnu_libobjdeps]) | ||
| 958 | ]) | 1247 | ]) |
| 959 | AC_REQUIRE([gl_CC_GNULIB_WARNINGS]) | 1248 | AC_REQUIRE([gl_CC_GNULIB_WARNINGS]) |
| 960 | LIBGNU_LIBDEPS="$gl_libdeps" | 1249 | LIBGNU_LIBDEPS="$gl_libdeps" |
| @@ -1025,6 +1314,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1025 | lib/af_alg.h | 1314 | lib/af_alg.h |
| 1026 | lib/alloca.in.h | 1315 | lib/alloca.in.h |
| 1027 | lib/arg-nonnull.h | 1316 | lib/arg-nonnull.h |
| 1317 | lib/arpa_inet.c | ||
| 1028 | lib/arpa_inet.in.h | 1318 | lib/arpa_inet.in.h |
| 1029 | lib/asnprintf.c | 1319 | lib/asnprintf.c |
| 1030 | lib/asprintf.c | 1320 | lib/asprintf.c |
| @@ -1036,8 +1326,27 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1036 | lib/basename-lgpl.h | 1326 | lib/basename-lgpl.h |
| 1037 | lib/basename.c | 1327 | lib/basename.c |
| 1038 | lib/btowc.c | 1328 | lib/btowc.c |
| 1329 | lib/byteswap.c | ||
| 1039 | lib/byteswap.in.h | 1330 | lib/byteswap.in.h |
| 1040 | lib/c++defs.h | 1331 | lib/c++defs.h |
| 1332 | lib/c-ctype.c | ||
| 1333 | lib/c-ctype.h | ||
| 1334 | lib/c32is-impl.h | ||
| 1335 | lib/c32isalnum.c | ||
| 1336 | lib/c32isalpha.c | ||
| 1337 | lib/c32isblank.c | ||
| 1338 | lib/c32iscntrl.c | ||
| 1339 | lib/c32isdigit.c | ||
| 1340 | lib/c32isgraph.c | ||
| 1341 | lib/c32islower.c | ||
| 1342 | lib/c32isprint.c | ||
| 1343 | lib/c32ispunct.c | ||
| 1344 | lib/c32isspace.c | ||
| 1345 | lib/c32isupper.c | ||
| 1346 | lib/c32isxdigit.c | ||
| 1347 | lib/c32to-impl.h | ||
| 1348 | lib/c32tolower.c | ||
| 1349 | lib/c32width.c | ||
| 1041 | lib/calloc.c | 1350 | lib/calloc.c |
| 1042 | lib/cdefs.h | 1351 | lib/cdefs.h |
| 1043 | lib/cloexec.c | 1352 | lib/cloexec.c |
| @@ -1071,6 +1380,8 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1071 | lib/free.c | 1380 | lib/free.c |
| 1072 | lib/fseek.c | 1381 | lib/fseek.c |
| 1073 | lib/fseeko.c | 1382 | lib/fseeko.c |
| 1383 | lib/fseterr.c | ||
| 1384 | lib/fseterr.h | ||
| 1074 | lib/fstat.c | 1385 | lib/fstat.c |
| 1075 | lib/fsusage.c | 1386 | lib/fsusage.c |
| 1076 | lib/fsusage.h | 1387 | lib/fsusage.h |
| @@ -1098,6 +1409,8 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1098 | lib/gl_openssl.h | 1409 | lib/gl_openssl.h |
| 1099 | lib/glthread/lock.c | 1410 | lib/glthread/lock.c |
| 1100 | lib/glthread/lock.h | 1411 | lib/glthread/lock.h |
| 1412 | lib/glthread/once.c | ||
| 1413 | lib/glthread/once.h | ||
| 1101 | lib/glthread/threadlib.c | 1414 | lib/glthread/threadlib.c |
| 1102 | lib/hard-locale.c | 1415 | lib/hard-locale.c |
| 1103 | lib/hard-locale.h | 1416 | lib/hard-locale.h |
| @@ -1107,6 +1420,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1107 | lib/idpriv.h | 1420 | lib/idpriv.h |
| 1108 | lib/idx.h | 1421 | lib/idx.h |
| 1109 | lib/inet_ntop.c | 1422 | lib/inet_ntop.c |
| 1423 | lib/inet_pton.c | ||
| 1110 | lib/intprops-internal.h | 1424 | lib/intprops-internal.h |
| 1111 | lib/intprops.h | 1425 | lib/intprops.h |
| 1112 | lib/inttypes.in.h | 1426 | lib/inttypes.in.h |
| @@ -1127,6 +1441,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1127 | lib/locale.in.h | 1441 | lib/locale.in.h |
| 1128 | lib/localeconv.c | 1442 | lib/localeconv.c |
| 1129 | lib/lseek.c | 1443 | lib/lseek.c |
| 1444 | lib/lstat.c | ||
| 1130 | lib/malloc.c | 1445 | lib/malloc.c |
| 1131 | lib/malloc/dynarray-skeleton.c | 1446 | lib/malloc/dynarray-skeleton.c |
| 1132 | lib/malloc/dynarray.h | 1447 | lib/malloc/dynarray.h |
| @@ -1139,10 +1454,16 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1139 | lib/malloca.h | 1454 | lib/malloca.h |
| 1140 | lib/math.c | 1455 | lib/math.c |
| 1141 | lib/math.in.h | 1456 | lib/math.in.h |
| 1457 | lib/mbchar.c | ||
| 1458 | lib/mbchar.h | ||
| 1459 | lib/mbiterf.c | ||
| 1460 | lib/mbiterf.h | ||
| 1461 | lib/mbrtoc32.c | ||
| 1142 | lib/mbrtowc-impl-utf8.h | 1462 | lib/mbrtowc-impl-utf8.h |
| 1143 | lib/mbrtowc-impl.h | 1463 | lib/mbrtowc-impl.h |
| 1144 | lib/mbrtowc.c | 1464 | lib/mbrtowc.c |
| 1145 | lib/mbsinit.c | 1465 | lib/mbsinit.c |
| 1466 | lib/mbsnlen.c | ||
| 1146 | lib/mbszero.c | 1467 | lib/mbszero.c |
| 1147 | lib/mbtowc-impl.h | 1468 | lib/mbtowc-impl.h |
| 1148 | lib/mbtowc-lock.c | 1469 | lib/mbtowc-lock.c |
| @@ -1169,6 +1490,8 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1169 | lib/printf-args.h | 1490 | lib/printf-args.h |
| 1170 | lib/printf-parse.c | 1491 | lib/printf-parse.c |
| 1171 | lib/printf-parse.h | 1492 | lib/printf-parse.h |
| 1493 | lib/pthread-once.c | ||
| 1494 | lib/pthread.in.h | ||
| 1172 | lib/realloc.c | 1495 | lib/realloc.c |
| 1173 | lib/reallocarray.c | 1496 | lib/reallocarray.c |
| 1174 | lib/regcomp.c | 1497 | lib/regcomp.c |
| @@ -1177,6 +1500,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1177 | lib/regex_internal.c | 1500 | lib/regex_internal.c |
| 1178 | lib/regex_internal.h | 1501 | lib/regex_internal.h |
| 1179 | lib/regexec.c | 1502 | lib/regexec.c |
| 1503 | lib/sched.in.h | ||
| 1180 | lib/setenv.c | 1504 | lib/setenv.c |
| 1181 | lib/setlocale-lock.c | 1505 | lib/setlocale-lock.c |
| 1182 | lib/setlocale_null-unlocked.c | 1506 | lib/setlocale_null-unlocked.c |
| @@ -1197,10 +1521,12 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1197 | lib/stdckdint.in.h | 1521 | lib/stdckdint.in.h |
| 1198 | lib/stddef.in.h | 1522 | lib/stddef.in.h |
| 1199 | lib/stdint.in.h | 1523 | lib/stdint.in.h |
| 1524 | lib/stdio-consolesafe.c | ||
| 1200 | lib/stdio-impl.h | 1525 | lib/stdio-impl.h |
| 1201 | lib/stdio-read.c | 1526 | lib/stdio-read.c |
| 1202 | lib/stdio-write.c | 1527 | lib/stdio-write.c |
| 1203 | lib/stdio.in.h | 1528 | lib/stdio.in.h |
| 1529 | lib/stdlib.c | ||
| 1204 | lib/stdlib.in.h | 1530 | lib/stdlib.in.h |
| 1205 | lib/str-two-way.h | 1531 | lib/str-two-way.h |
| 1206 | lib/strcasecmp.c | 1532 | lib/strcasecmp.c |
| @@ -1213,6 +1539,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1213 | lib/strings.in.h | 1539 | lib/strings.in.h |
| 1214 | lib/stripslash.c | 1540 | lib/stripslash.c |
| 1215 | lib/strncasecmp.c | 1541 | lib/strncasecmp.c |
| 1542 | lib/strncpy.c | ||
| 1216 | lib/strsep.c | 1543 | lib/strsep.c |
| 1217 | lib/strstr.c | 1544 | lib/strstr.c |
| 1218 | lib/sys-limits.h | 1545 | lib/sys-limits.h |
| @@ -1224,8 +1551,46 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1224 | lib/time.in.h | 1551 | lib/time.in.h |
| 1225 | lib/time_r.c | 1552 | lib/time_r.c |
| 1226 | lib/timegm.c | 1553 | lib/timegm.c |
| 1554 | lib/uchar.in.h | ||
| 1555 | lib/unicase.in.h | ||
| 1556 | lib/unicase/simple-mapping.h | ||
| 1557 | lib/unicase/tolower.c | ||
| 1558 | lib/unicase/tolower.h | ||
| 1559 | lib/unictype.in.h | ||
| 1560 | lib/unictype/bitmap.h | ||
| 1561 | lib/unictype/ctype_alnum.c | ||
| 1562 | lib/unictype/ctype_alnum.h | ||
| 1563 | lib/unictype/ctype_alpha.c | ||
| 1564 | lib/unictype/ctype_alpha.h | ||
| 1565 | lib/unictype/ctype_blank.c | ||
| 1566 | lib/unictype/ctype_blank.h | ||
| 1567 | lib/unictype/ctype_cntrl.c | ||
| 1568 | lib/unictype/ctype_cntrl.h | ||
| 1569 | lib/unictype/ctype_digit.c | ||
| 1570 | lib/unictype/ctype_digit.h | ||
| 1571 | lib/unictype/ctype_graph.c | ||
| 1572 | lib/unictype/ctype_graph.h | ||
| 1573 | lib/unictype/ctype_lower.c | ||
| 1574 | lib/unictype/ctype_lower.h | ||
| 1575 | lib/unictype/ctype_print.c | ||
| 1576 | lib/unictype/ctype_print.h | ||
| 1577 | lib/unictype/ctype_punct.c | ||
| 1578 | lib/unictype/ctype_punct.h | ||
| 1579 | lib/unictype/ctype_space.c | ||
| 1580 | lib/unictype/ctype_space.h | ||
| 1581 | lib/unictype/ctype_upper.c | ||
| 1582 | lib/unictype/ctype_upper.h | ||
| 1583 | lib/unictype/ctype_xdigit.c | ||
| 1584 | lib/unictype/ctype_xdigit.h | ||
| 1585 | lib/uninorm.in.h | ||
| 1227 | lib/unistd.c | 1586 | lib/unistd.c |
| 1228 | lib/unistd.in.h | 1587 | lib/unistd.in.h |
| 1588 | lib/unitypes.in.h | ||
| 1589 | lib/uniwidth.in.h | ||
| 1590 | lib/uniwidth/cjk.h | ||
| 1591 | lib/uniwidth/width.c | ||
| 1592 | lib/uniwidth/width0.h | ||
| 1593 | lib/uniwidth/width2.h | ||
| 1229 | lib/unlocked-io.h | 1594 | lib/unlocked-io.h |
| 1230 | lib/unsetenv.c | 1595 | lib/unsetenv.c |
| 1231 | lib/vasnprintf.c | 1596 | lib/vasnprintf.c |
| @@ -1233,6 +1598,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1233 | lib/vasprintf.c | 1598 | lib/vasprintf.c |
| 1234 | lib/verify.h | 1599 | lib/verify.h |
| 1235 | lib/vsnprintf.c | 1600 | lib/vsnprintf.c |
| 1601 | lib/vsnzprintf.c | ||
| 1236 | lib/w32sock.h | 1602 | lib/w32sock.h |
| 1237 | lib/warn-on-use.h | 1603 | lib/warn-on-use.h |
| 1238 | lib/wchar.in.h | 1604 | lib/wchar.in.h |
| @@ -1241,6 +1607,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1241 | lib/wctype-impl.h | 1607 | lib/wctype-impl.h |
| 1242 | lib/wctype.c | 1608 | lib/wctype.c |
| 1243 | lib/wctype.in.h | 1609 | lib/wctype.in.h |
| 1610 | lib/wcwidth.c | ||
| 1244 | lib/windows-initguard.h | 1611 | lib/windows-initguard.h |
| 1245 | lib/windows-mutex.c | 1612 | lib/windows-mutex.c |
| 1246 | lib/windows-mutex.h | 1613 | lib/windows-mutex.h |
| @@ -1265,20 +1632,22 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1265 | m4/assert_h.m4 | 1632 | m4/assert_h.m4 |
| 1266 | m4/base64.m4 | 1633 | m4/base64.m4 |
| 1267 | m4/btowc.m4 | 1634 | m4/btowc.m4 |
| 1635 | m4/build-to-host.m4 | ||
| 1268 | m4/builtin-expect.m4 | 1636 | m4/builtin-expect.m4 |
| 1269 | m4/byteswap.m4 | 1637 | m4/byteswap.m4 |
| 1270 | m4/c-bool.m4 | 1638 | m4/c-bool.m4 |
| 1639 | m4/c32rtomb.m4 | ||
| 1271 | m4/calloc.m4 | 1640 | m4/calloc.m4 |
| 1272 | m4/close.m4 | 1641 | m4/close.m4 |
| 1273 | m4/codeset.m4 | 1642 | m4/codeset.m4 |
| 1274 | m4/double-slash-root.m4 | 1643 | m4/double-slash-root.m4 |
| 1275 | m4/dup2.m4 | 1644 | m4/dup2.m4 |
| 1276 | m4/eealloc.m4 | ||
| 1277 | m4/environ.m4 | 1645 | m4/environ.m4 |
| 1278 | m4/errno_h.m4 | 1646 | m4/errno_h.m4 |
| 1279 | m4/error.m4 | 1647 | m4/error.m4 |
| 1280 | m4/error_h.m4 | 1648 | m4/error_h.m4 |
| 1281 | m4/exponentd.m4 | 1649 | m4/exponentd.m4 |
| 1650 | m4/extensions-aix.m4 | ||
| 1282 | m4/extensions.m4 | 1651 | m4/extensions.m4 |
| 1283 | m4/extern-inline.m4 | 1652 | m4/extern-inline.m4 |
| 1284 | m4/fclose.m4 | 1653 | m4/fclose.m4 |
| @@ -1294,6 +1663,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1294 | m4/free.m4 | 1663 | m4/free.m4 |
| 1295 | m4/fseek.m4 | 1664 | m4/fseek.m4 |
| 1296 | m4/fseeko.m4 | 1665 | m4/fseeko.m4 |
| 1666 | m4/fseterr.m4 | ||
| 1297 | m4/fstat.m4 | 1667 | m4/fstat.m4 |
| 1298 | m4/fstypename.m4 | 1668 | m4/fstypename.m4 |
| 1299 | m4/fsusage.m4 | 1669 | m4/fsusage.m4 |
| @@ -1309,10 +1679,12 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1309 | m4/getprogname.m4 | 1679 | m4/getprogname.m4 |
| 1310 | m4/gl-openssl.m4 | 1680 | m4/gl-openssl.m4 |
| 1311 | m4/gnulib-common.m4 | 1681 | m4/gnulib-common.m4 |
| 1682 | m4/gnulib-i18n.m4 | ||
| 1312 | m4/hostent.m4 | 1683 | m4/hostent.m4 |
| 1313 | m4/idpriv.m4 | 1684 | m4/idpriv.m4 |
| 1314 | m4/include_next.m4 | 1685 | m4/include_next.m4 |
| 1315 | m4/inet_ntop.m4 | 1686 | m4/inet_ntop.m4 |
| 1687 | m4/inet_pton.m4 | ||
| 1316 | m4/intmax_t.m4 | 1688 | m4/intmax_t.m4 |
| 1317 | m4/inttypes.m4 | 1689 | m4/inttypes.m4 |
| 1318 | m4/inttypes_h.m4 | 1690 | m4/inttypes_h.m4 |
| @@ -1323,8 +1695,10 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1323 | m4/iswxdigit.m4 | 1695 | m4/iswxdigit.m4 |
| 1324 | m4/langinfo_h.m4 | 1696 | m4/langinfo_h.m4 |
| 1325 | m4/largefile.m4 | 1697 | m4/largefile.m4 |
| 1698 | m4/libunistring-base.m4 | ||
| 1326 | m4/limits-h.m4 | 1699 | m4/limits-h.m4 |
| 1327 | m4/localcharset.m4 | 1700 | m4/localcharset.m4 |
| 1701 | m4/locale-en.m4 | ||
| 1328 | m4/locale-fr.m4 | 1702 | m4/locale-fr.m4 |
| 1329 | m4/locale-ja.m4 | 1703 | m4/locale-ja.m4 |
| 1330 | m4/locale-zh.m4 | 1704 | m4/locale-zh.m4 |
| @@ -1332,9 +1706,13 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1332 | m4/localeconv.m4 | 1706 | m4/localeconv.m4 |
| 1333 | m4/lock.m4 | 1707 | m4/lock.m4 |
| 1334 | m4/lseek.m4 | 1708 | m4/lseek.m4 |
| 1709 | m4/lstat.m4 | ||
| 1335 | m4/malloc.m4 | 1710 | m4/malloc.m4 |
| 1336 | m4/malloca.m4 | 1711 | m4/malloca.m4 |
| 1337 | m4/math_h.m4 | 1712 | m4/math_h.m4 |
| 1713 | m4/mbchar.m4 | ||
| 1714 | m4/mbiter.m4 | ||
| 1715 | m4/mbrtoc32.m4 | ||
| 1338 | m4/mbrtowc.m4 | 1716 | m4/mbrtowc.m4 |
| 1339 | m4/mbsinit.m4 | 1717 | m4/mbsinit.m4 |
| 1340 | m4/mbstate_t.m4 | 1718 | m4/mbstate_t.m4 |
| @@ -1353,17 +1731,23 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1353 | m4/netinet_in_h.m4 | 1731 | m4/netinet_in_h.m4 |
| 1354 | m4/nl_langinfo.m4 | 1732 | m4/nl_langinfo.m4 |
| 1355 | m4/nocrash.m4 | 1733 | m4/nocrash.m4 |
| 1734 | m4/off64_t.m4 | ||
| 1356 | m4/off_t.m4 | 1735 | m4/off_t.m4 |
| 1736 | m4/once.m4 | ||
| 1357 | m4/open-cloexec.m4 | 1737 | m4/open-cloexec.m4 |
| 1358 | m4/open-slash.m4 | 1738 | m4/open-slash.m4 |
| 1359 | m4/open.m4 | 1739 | m4/open.m4 |
| 1360 | m4/pathmax.m4 | 1740 | m4/pathmax.m4 |
| 1361 | m4/pid_t.m4 | 1741 | m4/pid_t.m4 |
| 1362 | m4/printf.m4 | 1742 | m4/printf.m4 |
| 1743 | m4/pthread-once.m4 | ||
| 1744 | m4/pthread-spin.m4 | ||
| 1745 | m4/pthread_h.m4 | ||
| 1363 | m4/pthread_rwlock_rdlock.m4 | 1746 | m4/pthread_rwlock_rdlock.m4 |
| 1364 | m4/realloc.m4 | 1747 | m4/realloc.m4 |
| 1365 | m4/reallocarray.m4 | 1748 | m4/reallocarray.m4 |
| 1366 | m4/regex.m4 | 1749 | m4/regex.m4 |
| 1750 | m4/sched_h.m4 | ||
| 1367 | m4/servent.m4 | 1751 | m4/servent.m4 |
| 1368 | m4/setenv.m4 | 1752 | m4/setenv.m4 |
| 1369 | m4/setlocale_null.m4 | 1753 | m4/setlocale_null.m4 |
| @@ -1379,18 +1763,22 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1379 | m4/stat.m4 | 1763 | m4/stat.m4 |
| 1380 | m4/std-gnu11.m4 | 1764 | m4/std-gnu11.m4 |
| 1381 | m4/stdalign.m4 | 1765 | m4/stdalign.m4 |
| 1766 | m4/stdckdint_h.m4 | ||
| 1382 | m4/stddef_h.m4 | 1767 | m4/stddef_h.m4 |
| 1383 | m4/stdint.m4 | 1768 | m4/stdint.m4 |
| 1384 | m4/stdint_h.m4 | 1769 | m4/stdint_h.m4 |
| 1385 | m4/stdio_h.m4 | 1770 | m4/stdio_h.m4 |
| 1386 | m4/stdlib_h.m4 | 1771 | m4/stdlib_h.m4 |
| 1387 | m4/strcase.m4 | 1772 | m4/strcasecmp.m4 |
| 1388 | m4/strcasestr.m4 | 1773 | m4/strcasestr.m4 |
| 1389 | m4/strerror.m4 | 1774 | m4/strerror.m4 |
| 1390 | m4/string_h.m4 | 1775 | m4/string_h.m4 |
| 1391 | m4/strings_h.m4 | 1776 | m4/strings_h.m4 |
| 1777 | m4/strncasecmp.m4 | ||
| 1778 | m4/strncpy.m4 | ||
| 1392 | m4/strsep.m4 | 1779 | m4/strsep.m4 |
| 1393 | m4/strstr.m4 | 1780 | m4/strstr.m4 |
| 1781 | m4/sys_cdefs_h.m4 | ||
| 1394 | m4/sys_socket_h.m4 | 1782 | m4/sys_socket_h.m4 |
| 1395 | m4/sys_stat_h.m4 | 1783 | m4/sys_stat_h.m4 |
| 1396 | m4/sys_types_h.m4 | 1784 | m4/sys_types_h.m4 |
| @@ -1399,8 +1787,13 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1399 | m4/time_h.m4 | 1787 | m4/time_h.m4 |
| 1400 | m4/time_r.m4 | 1788 | m4/time_r.m4 |
| 1401 | m4/timegm.m4 | 1789 | m4/timegm.m4 |
| 1790 | m4/uchar_h.m4 | ||
| 1402 | m4/ungetc.m4 | 1791 | m4/ungetc.m4 |
| 1792 | m4/unicase_h.m4 | ||
| 1793 | m4/unictype_h.m4 | ||
| 1794 | m4/uninorm_h.m4 | ||
| 1403 | m4/unistd_h.m4 | 1795 | m4/unistd_h.m4 |
| 1796 | m4/unitypes_h.m4 | ||
| 1404 | m4/unlocked-io.m4 | 1797 | m4/unlocked-io.m4 |
| 1405 | m4/vararrays.m4 | 1798 | m4/vararrays.m4 |
| 1406 | m4/vasnprintf.m4 | 1799 | m4/vasnprintf.m4 |
| @@ -1409,10 +1802,10 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1409 | m4/vsnprintf.m4 | 1802 | m4/vsnprintf.m4 |
| 1410 | m4/warn-on-use.m4 | 1803 | m4/warn-on-use.m4 |
| 1411 | m4/wchar_h.m4 | 1804 | m4/wchar_h.m4 |
| 1412 | m4/wchar_t.m4 | ||
| 1413 | m4/wcrtomb.m4 | 1805 | m4/wcrtomb.m4 |
| 1414 | m4/wctype.m4 | 1806 | m4/wctype.m4 |
| 1415 | m4/wctype_h.m4 | 1807 | m4/wctype_h.m4 |
| 1808 | m4/wcwidth.m4 | ||
| 1416 | m4/wint_t.m4 | 1809 | m4/wint_t.m4 |
| 1417 | m4/xalloc.m4 | 1810 | m4/xalloc.m4 |
| 1418 | m4/xsize.m4 | 1811 | m4/xsize.m4 |
diff --git a/gl/m4/gnulib-i18n.m4 b/gl/m4/gnulib-i18n.m4 new file mode 100644 index 00000000..868043e7 --- /dev/null +++ b/gl/m4/gnulib-i18n.m4 | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | # gnulib-i18n.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright (C) 2005-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl From Bruno Haible. | ||
| 10 | |||
| 11 | dnl Support for internationalization of Gnulib code. | ||
| 12 | |||
| 13 | dnl GNULIB_I18N | ||
| 14 | dnl Sets GNULIB_LOCALEDIR to indicate where to find the gnulib.mo files. | ||
| 15 | dnl Also it defines GNULIB_LOCALEDIR as macro in config.h, that expands to | ||
| 16 | dnl the corresponding C string. | ||
| 17 | AC_DEFUN([GNULIB_I18N], | ||
| 18 | [ | ||
| 19 | dnl It is best to not test "$USE_NLS" here, because: It would be empty | ||
| 20 | dnl in case the package is internationalized but this macro is used before | ||
| 21 | dnl AM_GNU_GETTEXT. We would need to warn about this situation. But since | ||
| 22 | dnl this module is used as a dependency of many packages, such a warning is | ||
| 23 | dnl not welcome. | ||
| 24 | |||
| 25 | dnl Determine gnulib's localedir. | ||
| 26 | dnl Generally, accept an option --with-gnulib-prefix=PREFIX to indicate | ||
| 27 | dnl where to find gnulib's runtime data. | ||
| 28 | dnl Usually ${prefix}/share/locale, but can be influenced by the configure | ||
| 29 | dnl options --datarootdir and --localedir. | ||
| 30 | GNULIB_LOCALEDIR="${localedir}" | ||
| 31 | AC_ARG_WITH([gnulib-prefix], | ||
| 32 | [[ --with-gnulib-prefix=DIR search for gnulib's runtime data in DIR/share]], | ||
| 33 | [if test "X$withval" != "X" && test "X$withval" != "Xno"; then | ||
| 34 | GNULIB_LOCALEDIR="$withval/share/locale" | ||
| 35 | fi | ||
| 36 | ]) | ||
| 37 | AC_SUBST([GNULIB_LOCALEDIR]) | ||
| 38 | |||
| 39 | dnl Define GNULIB_LOCALEDIR_c and GNULIB_LOCALEDIR_c_make. | ||
| 40 | dnl Find the final value of GNULIB_LOCALEDIR. | ||
| 41 | gl_saved_prefix="${prefix}" | ||
| 42 | gl_saved_datarootdir="${datarootdir}" | ||
| 43 | gl_saved_localedir="${localedir}" | ||
| 44 | gl_saved_gnuliblocaledir="${GNULIB_LOCALEDIR}" | ||
| 45 | dnl Unfortunately, prefix gets only finally determined at the end of | ||
| 46 | dnl configure. | ||
| 47 | if test "X$prefix" = "XNONE"; then | ||
| 48 | prefix="$ac_default_prefix" | ||
| 49 | fi | ||
| 50 | eval datarootdir="$datarootdir" | ||
| 51 | eval localedir="$localedir" | ||
| 52 | eval GNULIB_LOCALEDIR="$GNULIB_LOCALEDIR" | ||
| 53 | gl_BUILD_TO_HOST([GNULIB_LOCALEDIR]) | ||
| 54 | GNULIB_LOCALEDIR="${gl_saved_gnuliblocaledir}" | ||
| 55 | localedir="${gl_saved_localedir}" | ||
| 56 | datarootdir="${gl_saved_datarootdir}" | ||
| 57 | prefix="${gl_saved_prefix}" | ||
| 58 | |||
| 59 | AC_DEFINE_UNQUOTED([GNULIB_LOCALEDIR], [${GNULIB_LOCALEDIR_c}], | ||
| 60 | [Define to the directory where to find the localizations of the translation domain 'gnulib', as a C string.]) | ||
| 61 | ]) | ||
diff --git a/gl/m4/gnulib-tool.m4 b/gl/m4/gnulib-tool.m4 index ef45f51f..8634a6e9 100644 --- a/gl/m4/gnulib-tool.m4 +++ b/gl/m4/gnulib-tool.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # gnulib-tool.m4 | 1 | # gnulib-tool.m4 |
| 2 | # serial 4 | 2 | # serial 5 |
| 3 | dnl Copyright (C) 2004-2005, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2004-2005, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl The following macros need not be invoked explicitly. | 9 | dnl The following macros need not be invoked explicitly. |
| 9 | dnl Invoking them does nothing except to declare default arguments | 10 | dnl Invoking them does nothing except to declare default arguments |
| @@ -42,6 +43,9 @@ AC_DEFUN([gl_LIB], []) | |||
| 42 | dnl Usage: gl_LGPL or gl_LGPL([VERSION]) | 43 | dnl Usage: gl_LGPL or gl_LGPL([VERSION]) |
| 43 | AC_DEFUN([gl_LGPL], []) | 44 | AC_DEFUN([gl_LGPL], []) |
| 44 | 45 | ||
| 46 | dnl Usage: gl_GPL([VERSION]) | ||
| 47 | AC_DEFUN([gl_GPL], []) | ||
| 48 | |||
| 45 | dnl Usage: gl_MAKEFILE_NAME([FILENAME]) | 49 | dnl Usage: gl_MAKEFILE_NAME([FILENAME]) |
| 46 | AC_DEFUN([gl_MAKEFILE_NAME], []) | 50 | AC_DEFUN([gl_MAKEFILE_NAME], []) |
| 47 | 51 | ||
diff --git a/gl/m4/hostent.m4 b/gl/m4/hostent.m4 index 36dc636e..9278285c 100644 --- a/gl/m4/hostent.m4 +++ b/gl/m4/hostent.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # hostent.m4 | 1 | # hostent.m4 |
| 2 | # serial 5 | 2 | # serial 5 |
| 3 | dnl Copyright (C) 2008, 2010-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008, 2010-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_HOSTENT], | 9 | AC_DEFUN([gl_HOSTENT], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/idpriv.m4 b/gl/m4/idpriv.m4 index 53693527..6e855e9a 100644 --- a/gl/m4/idpriv.m4 +++ b/gl/m4/idpriv.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # idpriv.m4 | 1 | # idpriv.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_IDPRIV], | 9 | AC_DEFUN([gl_IDPRIV], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/include_next.m4 b/gl/m4/include_next.m4 index 03e85251..80de991e 100644 --- a/gl/m4/include_next.m4 +++ b/gl/m4/include_next.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # include_next.m4 | 1 | # include_next.m4 |
| 2 | # serial 27 | 2 | # serial 27 |
| 3 | dnl Copyright (C) 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Paul Eggert and Derek Price. | 9 | dnl From Paul Eggert and Derek Price. |
| 9 | 10 | ||
diff --git a/gl/m4/inet_ntop.m4 b/gl/m4/inet_ntop.m4 index 168e17e0..693bd51b 100644 --- a/gl/m4/inet_ntop.m4 +++ b/gl/m4/inet_ntop.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # inet_ntop.m4 | 1 | # inet_ntop.m4 |
| 2 | # serial 22 | 2 | # serial 22 |
| 3 | dnl Copyright (C) 2005-2006, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005-2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_INET_NTOP], | 9 | AC_DEFUN([gl_FUNC_INET_NTOP], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/inet_pton.m4 b/gl/m4/inet_pton.m4 new file mode 100644 index 00000000..b6e59a25 --- /dev/null +++ b/gl/m4/inet_pton.m4 | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | # inet_pton.m4 | ||
| 2 | # serial 20 | ||
| 3 | dnl Copyright (C) 2006, 2008-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN([gl_FUNC_INET_PTON], | ||
| 10 | [ | ||
| 11 | AC_REQUIRE([gl_ARPA_INET_H_DEFAULTS]) | ||
| 12 | |||
| 13 | dnl Persuade Solaris <arpa/inet.h> to declare inet_pton. | ||
| 14 | AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | ||
| 15 | |||
| 16 | AC_REQUIRE([AC_C_RESTRICT]) | ||
| 17 | |||
| 18 | dnl Most platforms that provide inet_pton define it in libc. | ||
| 19 | dnl Solaris 8..10 provide inet_pton in libnsl instead. | ||
| 20 | dnl Solaris 2.6..7 provide inet_pton in libresolv instead. | ||
| 21 | dnl Haiku provides it in -lnetwork. | ||
| 22 | dnl Native Windows provides it in -lws2_32 instead, with a declaration in | ||
| 23 | dnl <ws2tcpip.h>, and it uses stdcall calling convention, not cdecl | ||
| 24 | dnl (hence we cannot use AC_CHECK_FUNCS, AC_SEARCH_LIBS to find it). | ||
| 25 | HAVE_INET_PTON=1 | ||
| 26 | INET_PTON_LIB= | ||
| 27 | gl_PREREQ_SYS_H_WINSOCK2 | ||
| 28 | if test $HAVE_WINSOCK2_H = 1; then | ||
| 29 | dnl It needs to be overridden, because the stdcall calling convention | ||
| 30 | dnl is not compliant with POSIX. Set REPLACE_INET_PTON in order to avoid | ||
| 31 | dnl a name conflict at the linker level, even though the header file | ||
| 32 | dnl <ws2tcpip.h> declares inet_pton only if _WIN32_WINNT >= 0x0600. | ||
| 33 | REPLACE_INET_PTON=1 | ||
| 34 | AC_CHECK_DECLS([inet_pton],,, [[#include <ws2tcpip.h>]]) | ||
| 35 | if test $ac_cv_have_decl_inet_pton = yes; then | ||
| 36 | INET_PTON_LIB="-lws2_32" | ||
| 37 | else | ||
| 38 | HAVE_DECL_INET_PTON=0 | ||
| 39 | fi | ||
| 40 | else | ||
| 41 | gl_saved_LIBS=$LIBS | ||
| 42 | AC_SEARCH_LIBS([inet_pton], [nsl resolv network], [], | ||
| 43 | [AC_CHECK_FUNCS([inet_pton]) | ||
| 44 | if test $ac_cv_func_inet_pton = no; then | ||
| 45 | HAVE_INET_PTON=0 | ||
| 46 | fi | ||
| 47 | ]) | ||
| 48 | LIBS=$gl_saved_LIBS | ||
| 49 | |||
| 50 | if test "$ac_cv_search_inet_pton" != "no" \ | ||
| 51 | && test "$ac_cv_search_inet_pton" != "none required"; then | ||
| 52 | INET_PTON_LIB="$ac_cv_search_inet_pton" | ||
| 53 | fi | ||
| 54 | |||
| 55 | AC_CHECK_HEADERS_ONCE([netdb.h]) | ||
| 56 | AC_CHECK_DECLS([inet_pton],,, | ||
| 57 | [[#include <arpa/inet.h> | ||
| 58 | #if HAVE_NETDB_H | ||
| 59 | # include <netdb.h> | ||
| 60 | #endif | ||
| 61 | ]]) | ||
| 62 | if test $ac_cv_have_decl_inet_pton = no; then | ||
| 63 | HAVE_DECL_INET_PTON=0 | ||
| 64 | fi | ||
| 65 | fi | ||
| 66 | AC_SUBST([INET_PTON_LIB]) | ||
| 67 | ]) | ||
| 68 | |||
| 69 | # Prerequisites of lib/inet_pton.c. | ||
| 70 | AC_DEFUN([gl_PREREQ_INET_PTON], [ | ||
| 71 | AC_REQUIRE([gl_SOCKET_FAMILIES]) | ||
| 72 | ]) | ||
diff --git a/gl/m4/intmax_t.m4 b/gl/m4/intmax_t.m4 index 72858ea8..c1df7b27 100644 --- a/gl/m4/intmax_t.m4 +++ b/gl/m4/intmax_t.m4 | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | # intmax_t.m4 | 1 | # intmax_t.m4 |
| 2 | # serial 9 | 2 | # serial 9 |
| 3 | dnl Copyright (C) 1997-2004, 2006-2007, 2009-2024 Free Software Foundation, | 3 | dnl Copyright (C) 1997-2004, 2006-2007, 2009-2025 Free Software Foundation, |
| 4 | dnl Inc. | 4 | dnl Inc. |
| 5 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 6 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 7 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 8 | 9 | ||
| 9 | dnl From Paul Eggert. | 10 | dnl From Paul Eggert. |
| 10 | 11 | ||
diff --git a/gl/m4/inttypes.m4 b/gl/m4/inttypes.m4 index c43cd162..63c82c61 100644 --- a/gl/m4/inttypes.m4 +++ b/gl/m4/inttypes.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # inttypes.m4 | 1 | # inttypes.m4 |
| 2 | # serial 37 | 2 | # serial 37 |
| 3 | dnl Copyright (C) 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Derek Price, Bruno Haible. | 9 | dnl From Derek Price, Bruno Haible. |
| 9 | dnl Test whether <inttypes.h> is supported or must be substituted. | 10 | dnl Test whether <inttypes.h> is supported or must be substituted. |
diff --git a/gl/m4/inttypes_h.m4 b/gl/m4/inttypes_h.m4 index 3b9da5b0..ad939a53 100644 --- a/gl/m4/inttypes_h.m4 +++ b/gl/m4/inttypes_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # inttypes_h.m4 | 1 | # inttypes_h.m4 |
| 2 | # serial 10 | 2 | # serial 10 |
| 3 | dnl Copyright (C) 1997-2004, 2006, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 1997-2004, 2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Paul Eggert. | 9 | dnl From Paul Eggert. |
| 9 | 10 | ||
diff --git a/gl/m4/iswblank.m4 b/gl/m4/iswblank.m4 index 4dc12d9a..d06b16a2 100644 --- a/gl/m4/iswblank.m4 +++ b/gl/m4/iswblank.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # iswblank.m4 | 1 | # iswblank.m4 |
| 2 | # serial 7 | 2 | # serial 7 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_ISWBLANK], | 9 | AC_DEFUN([gl_FUNC_ISWBLANK], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/iswctype.m4 b/gl/m4/iswctype.m4 index 16031be4..f5a3b760 100644 --- a/gl/m4/iswctype.m4 +++ b/gl/m4/iswctype.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # iswctype.m4 | 1 | # iswctype.m4 |
| 2 | # serial 3 | 2 | # serial 3 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_ISWCTYPE], | 9 | AC_DEFUN([gl_FUNC_ISWCTYPE], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/iswdigit.m4 b/gl/m4/iswdigit.m4 index 999acd28..4582f598 100644 --- a/gl/m4/iswdigit.m4 +++ b/gl/m4/iswdigit.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # iswdigit.m4 | 1 | # iswdigit.m4 |
| 2 | # serial 7 | 2 | # serial 9 |
| 3 | dnl Copyright (C) 2020-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2020-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_ISWDIGIT], | 9 | AC_DEFUN([gl_FUNC_ISWDIGIT], |
| 9 | [ | 10 | [ |
| @@ -11,7 +12,7 @@ AC_DEFUN([gl_FUNC_ISWDIGIT], | |||
| 11 | AC_REQUIRE([gl_WCTYPE_H]) | 12 | AC_REQUIRE([gl_WCTYPE_H]) |
| 12 | AC_REQUIRE([gt_LOCALE_FR]) | 13 | AC_REQUIRE([gt_LOCALE_FR]) |
| 13 | AC_REQUIRE([gt_LOCALE_JA]) | 14 | AC_REQUIRE([gt_LOCALE_JA]) |
| 14 | AC_REQUIRE([gt_LOCALE_FR_UTF8]) | 15 | AC_REQUIRE([gt_LOCALE_EN_UTF8]) |
| 15 | AC_REQUIRE([gt_LOCALE_ZH_CN]) | 16 | AC_REQUIRE([gt_LOCALE_ZH_CN]) |
| 16 | AC_REQUIRE([AC_CANONICAL_HOST]) | 17 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 17 | 18 | ||
| @@ -26,14 +27,14 @@ AC_DEFUN([gl_FUNC_ISWDIGIT], | |||
| 26 | dnl is present. | 27 | dnl is present. |
| 27 | changequote(,)dnl | 28 | changequote(,)dnl |
| 28 | case "$host_os" in | 29 | case "$host_os" in |
| 29 | # Guess no on FreeBSD, NetBSD, Solaris, native Windows. | 30 | # Guess no on FreeBSD, NetBSD, OpenBSD, Solaris, native Windows, Haiku, Android. |
| 30 | freebsd* | dragonfly* | netbsd* | solaris* | mingw* | windows*) | 31 | freebsd* | dragonfly* | netbsd* | openbsd* | solaris* | mingw* | windows* | haiku* | *-android*) |
| 31 | gl_cv_func_iswdigit_works="guessing no" ;; | 32 | gl_cv_func_iswdigit_works="guessing no" ;; |
| 32 | # Guess yes otherwise. | 33 | # Guess yes otherwise. |
| 33 | *) gl_cv_func_iswdigit_works="guessing yes" ;; | 34 | *) gl_cv_func_iswdigit_works="guessing yes" ;; |
| 34 | esac | 35 | esac |
| 35 | changequote([,])dnl | 36 | changequote([,])dnl |
| 36 | if test $LOCALE_FR != none || test $LOCALE_JA != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_ZH_CN != none; then | 37 | if test $LOCALE_FR != none || test $LOCALE_JA != none || test "$LOCALE_EN_UTF8" != none || test $LOCALE_ZH_CN != none; then |
| 37 | AC_RUN_IFELSE( | 38 | AC_RUN_IFELSE( |
| 38 | [AC_LANG_SOURCE([[ | 39 | [AC_LANG_SOURCE([[ |
| 39 | #include <locale.h> | 40 | #include <locale.h> |
| @@ -83,15 +84,15 @@ main (int argc, char *argv[]) | |||
| 83 | if (!(is == 0)) | 84 | if (!(is == 0)) |
| 84 | result |= 2; | 85 | result |= 2; |
| 85 | } | 86 | } |
| 86 | if (strcmp ("$LOCALE_FR_UTF8", "none") != 0 | 87 | if (strcmp ("$LOCALE_EN_UTF8", "none") != 0 |
| 87 | && setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) | 88 | && setlocale (LC_ALL, "$LOCALE_EN_UTF8") != NULL) |
| 88 | { | 89 | { |
| 89 | /* This fails on FreeBSD 13.0, NetBSD 10.0, MSVC 14. */ | 90 | /* This fails on FreeBSD 13.0, NetBSD 10.0, OpenBSD 7.5, MSVC 14, Haiku, Android. */ |
| 90 | /* U+0663 ARABIC-INDIC DIGIT THREE */ | 91 | /* U+0663 ARABIC-INDIC DIGIT THREE */ |
| 91 | is = for_character ("\331\243", 2); | 92 | is = for_character ("\331\243", 2); |
| 92 | if (!(is == 0)) | 93 | if (!(is == 0)) |
| 93 | result |= 4; | 94 | result |= 4; |
| 94 | /* This fails on FreeBSD 13.0, NetBSD 10.0, MSVC 14. */ | 95 | /* This fails on FreeBSD 13.0, NetBSD 10.0, OpenBSD 7.5, MSVC 14, Haiku, Android. */ |
| 95 | /* U+FF11 FULLWIDTH DIGIT ONE */ | 96 | /* U+FF11 FULLWIDTH DIGIT ONE */ |
| 96 | is = for_character ("\357\274\221", 3); | 97 | is = for_character ("\357\274\221", 3); |
| 97 | if (!(is == 0)) | 98 | if (!(is == 0)) |
diff --git a/gl/m4/iswpunct.m4 b/gl/m4/iswpunct.m4 index 1edf58aa..d8e8d712 100644 --- a/gl/m4/iswpunct.m4 +++ b/gl/m4/iswpunct.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # iswpunct.m4 | 1 | # iswpunct.m4 |
| 2 | # serial 2 | 2 | # serial 2 |
| 3 | dnl Copyright (C) 2023-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2023-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_ISWPUNCT], | 9 | AC_DEFUN([gl_FUNC_ISWPUNCT], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/iswxdigit.m4 b/gl/m4/iswxdigit.m4 index 6085bf6b..95226fc4 100644 --- a/gl/m4/iswxdigit.m4 +++ b/gl/m4/iswxdigit.m4 | |||
| @@ -1,16 +1,17 @@ | |||
| 1 | # iswxdigit.m4 | 1 | # iswxdigit.m4 |
| 2 | # serial 7 | 2 | # serial 9 |
| 3 | dnl Copyright (C) 2020-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2020-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_ISWXDIGIT], | 9 | AC_DEFUN([gl_FUNC_ISWXDIGIT], |
| 9 | [ | 10 | [ |
| 10 | AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) | 11 | AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) |
| 11 | AC_REQUIRE([gl_WCTYPE_H]) | 12 | AC_REQUIRE([gl_WCTYPE_H]) |
| 12 | AC_REQUIRE([gt_LOCALE_JA]) | 13 | AC_REQUIRE([gt_LOCALE_JA]) |
| 13 | AC_REQUIRE([gt_LOCALE_FR_UTF8]) | 14 | AC_REQUIRE([gt_LOCALE_EN_UTF8]) |
| 14 | AC_REQUIRE([gt_LOCALE_ZH_CN]) | 15 | AC_REQUIRE([gt_LOCALE_ZH_CN]) |
| 15 | AC_REQUIRE([AC_CANONICAL_HOST]) | 16 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 16 | 17 | ||
| @@ -25,14 +26,14 @@ AC_DEFUN([gl_FUNC_ISWXDIGIT], | |||
| 25 | dnl is present. | 26 | dnl is present. |
| 26 | changequote(,)dnl | 27 | changequote(,)dnl |
| 27 | case "$host_os" in | 28 | case "$host_os" in |
| 28 | # Guess no on FreeBSD, NetBSD, Solaris, native Windows. | 29 | # Guess no on FreeBSD, NetBSD, OpenBSD, Solaris, native Windows, Haiku, Android. |
| 29 | freebsd* | dragonfly* | netbsd* | solaris* | mingw* | windows*) | 30 | freebsd* | dragonfly* | netbsd* | openbsd* | solaris* | mingw* | windows* | haiku* | *-android*) |
| 30 | gl_cv_func_iswxdigit_works="guessing no" ;; | 31 | gl_cv_func_iswxdigit_works="guessing no" ;; |
| 31 | # Guess yes otherwise. | 32 | # Guess yes otherwise. |
| 32 | *) gl_cv_func_iswxdigit_works="guessing yes" ;; | 33 | *) gl_cv_func_iswxdigit_works="guessing yes" ;; |
| 33 | esac | 34 | esac |
| 34 | changequote([,])dnl | 35 | changequote([,])dnl |
| 35 | if test $LOCALE_JA != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_ZH_CN != none; then | 36 | if test $LOCALE_JA != none || test "$LOCALE_EN_UTF8" != none || test $LOCALE_ZH_CN != none; then |
| 36 | AC_RUN_IFELSE( | 37 | AC_RUN_IFELSE( |
| 37 | [AC_LANG_SOURCE([[ | 38 | [AC_LANG_SOURCE([[ |
| 38 | #include <locale.h> | 39 | #include <locale.h> |
| @@ -73,15 +74,15 @@ main (int argc, char *argv[]) | |||
| 73 | if (!(is == 0)) | 74 | if (!(is == 0)) |
| 74 | result |= 1; | 75 | result |= 1; |
| 75 | } | 76 | } |
| 76 | if (strcmp ("$LOCALE_FR_UTF8", "none") != 0 | 77 | if (strcmp ("$LOCALE_EN_UTF8", "none") != 0 |
| 77 | && setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) | 78 | && setlocale (LC_ALL, "$LOCALE_EN_UTF8") != NULL) |
| 78 | { | 79 | { |
| 79 | /* This fails on FreeBSD 13.0. */ | 80 | /* This fails on FreeBSD 13.0, Haiku, Android. */ |
| 80 | /* U+0663 ARABIC-INDIC DIGIT THREE */ | 81 | /* U+0663 ARABIC-INDIC DIGIT THREE */ |
| 81 | is = for_character ("\331\243", 2); | 82 | is = for_character ("\331\243", 2); |
| 82 | if (!(is == 0)) | 83 | if (!(is == 0)) |
| 83 | result |= 2; | 84 | result |= 2; |
| 84 | /* This fails on NetBSD 10.0, MSVC 14. */ | 85 | /* This fails on NetBSD 10.0, OpenBSD 7.5, MSVC 14, Haiku, Android. */ |
| 85 | /* U+FF21 FULLWIDTH LATIN CAPITAL LETTER A */ | 86 | /* U+FF21 FULLWIDTH LATIN CAPITAL LETTER A */ |
| 86 | is = for_character ("\357\274\241", 3); | 87 | is = for_character ("\357\274\241", 3); |
| 87 | if (!(is == 0)) | 88 | if (!(is == 0)) |
diff --git a/gl/m4/langinfo_h.m4 b/gl/m4/langinfo_h.m4 index 5eee8a71..69f936f0 100644 --- a/gl/m4/langinfo_h.m4 +++ b/gl/m4/langinfo_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # langinfo_h.m4 | 1 | # langinfo_h.m4 |
| 2 | # serial 12 | 2 | # serial 13 |
| 3 | dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_LANGINFO_H], | 9 | AC_DEFUN_ONCE([gl_LANGINFO_H], |
| 9 | [ | 10 | [ |
| @@ -19,6 +20,7 @@ AC_DEFUN_ONCE([gl_LANGINFO_H], | |||
| 19 | HAVE_LANGINFO_CODESET=0 | 20 | HAVE_LANGINFO_CODESET=0 |
| 20 | HAVE_LANGINFO_T_FMT_AMPM=0 | 21 | HAVE_LANGINFO_T_FMT_AMPM=0 |
| 21 | HAVE_LANGINFO_ALTMON=0 | 22 | HAVE_LANGINFO_ALTMON=0 |
| 23 | HAVE_LANGINFO_ABALTMON=0 | ||
| 22 | HAVE_LANGINFO_ERA=0 | 24 | HAVE_LANGINFO_ERA=0 |
| 23 | HAVE_LANGINFO_YESEXPR=0 | 25 | HAVE_LANGINFO_YESEXPR=0 |
| 24 | AC_CHECK_HEADERS_ONCE([langinfo.h]) | 26 | AC_CHECK_HEADERS_ONCE([langinfo.h]) |
| @@ -29,6 +31,7 @@ AC_DEFUN_ONCE([gl_LANGINFO_H], | |||
| 29 | dnl ERA etc. are missing on OpenBSD 6.7. | 31 | dnl ERA etc. are missing on OpenBSD 6.7. |
| 30 | dnl T_FMT_AMPM and YESEXPR, NOEXPR are missing on IRIX 5.3. | 32 | dnl T_FMT_AMPM and YESEXPR, NOEXPR are missing on IRIX 5.3. |
| 31 | dnl ALTMON_* are missing on glibc 2.26 and many other systems. | 33 | dnl ALTMON_* are missing on glibc 2.26 and many other systems. |
| 34 | dnl ABALTMON_* are missing on glibc 2.41 and many other systems. | ||
| 32 | AC_CACHE_CHECK([whether langinfo.h defines CODESET], | 35 | AC_CACHE_CHECK([whether langinfo.h defines CODESET], |
| 33 | [gl_cv_header_langinfo_codeset], | 36 | [gl_cv_header_langinfo_codeset], |
| 34 | [AC_COMPILE_IFELSE( | 37 | [AC_COMPILE_IFELSE( |
| @@ -65,6 +68,18 @@ int a = ALTMON_1; | |||
| 65 | if test $gl_cv_header_langinfo_altmon = yes; then | 68 | if test $gl_cv_header_langinfo_altmon = yes; then |
| 66 | HAVE_LANGINFO_ALTMON=1 | 69 | HAVE_LANGINFO_ALTMON=1 |
| 67 | fi | 70 | fi |
| 71 | AC_CACHE_CHECK([whether langinfo.h defines ABALTMON_1], | ||
| 72 | [gl_cv_header_langinfo_abaltmon], | ||
| 73 | [AC_COMPILE_IFELSE( | ||
| 74 | [AC_LANG_PROGRAM([[#include <langinfo.h> | ||
| 75 | int a = ABALTMON_1; | ||
| 76 | ]])], | ||
| 77 | [gl_cv_header_langinfo_abaltmon=yes], | ||
| 78 | [gl_cv_header_langinfo_abaltmon=no]) | ||
| 79 | ]) | ||
| 80 | if test $gl_cv_header_langinfo_abaltmon = yes; then | ||
| 81 | HAVE_LANGINFO_ABALTMON=1 | ||
| 82 | fi | ||
| 68 | AC_CACHE_CHECK([whether langinfo.h defines ERA], | 83 | AC_CACHE_CHECK([whether langinfo.h defines ERA], |
| 69 | [gl_cv_header_langinfo_era], | 84 | [gl_cv_header_langinfo_era], |
| 70 | [AC_COMPILE_IFELSE( | 85 | [AC_COMPILE_IFELSE( |
| @@ -96,6 +111,7 @@ int a = YESEXPR; | |||
| 96 | AC_SUBST([HAVE_LANGINFO_CODESET]) | 111 | AC_SUBST([HAVE_LANGINFO_CODESET]) |
| 97 | AC_SUBST([HAVE_LANGINFO_T_FMT_AMPM]) | 112 | AC_SUBST([HAVE_LANGINFO_T_FMT_AMPM]) |
| 98 | AC_SUBST([HAVE_LANGINFO_ALTMON]) | 113 | AC_SUBST([HAVE_LANGINFO_ALTMON]) |
| 114 | AC_SUBST([HAVE_LANGINFO_ABALTMON]) | ||
| 99 | AC_SUBST([HAVE_LANGINFO_ERA]) | 115 | AC_SUBST([HAVE_LANGINFO_ERA]) |
| 100 | AC_SUBST([HAVE_LANGINFO_YESEXPR]) | 116 | AC_SUBST([HAVE_LANGINFO_YESEXPR]) |
| 101 | 117 | ||
diff --git a/gl/m4/largefile.m4 b/gl/m4/largefile.m4 index 2f824089..b24f657d 100644 --- a/gl/m4/largefile.m4 +++ b/gl/m4/largefile.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # largefile.m4 | 1 | # largefile.m4 |
| 2 | # serial 1 | 2 | # serial 2 |
| 3 | dnl Copyright 1992-1996, 1998-2024 Free Software Foundation, Inc. | 3 | dnl Copyright 1992-1996, 1998-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Enable large files on systems where this is not the default. | 9 | # Enable large files on systems where this is not the default. |
| 9 | # Enable support for files on Linux file systems with 64-bit inode numbers. | 10 | # Enable support for files on Linux file systems with 64-bit inode numbers. |
| @@ -88,7 +89,7 @@ m4_define([_AC_SYS_YEAR2038_OPTIONS], m4_normalize( | |||
| 88 | # If you change this macro you may also need to change | 89 | # If you change this macro you may also need to change |
| 89 | # _AC_SYS_YEAR2038_OPTIONS. | 90 | # _AC_SYS_YEAR2038_OPTIONS. |
| 90 | AC_DEFUN([_AC_SYS_YEAR2038_PROBE], | 91 | AC_DEFUN([_AC_SYS_YEAR2038_PROBE], |
| 91 | [AC_CACHE_CHECK([for $CPPFLAGS option for timestamps after 2038], | 92 | [AC_CACHE_CHECK([for $CC option to support timestamps after 2038], |
| 92 | [ac_cv_sys_year2038_opts], | 93 | [ac_cv_sys_year2038_opts], |
| 93 | [ac_save_CPPFLAGS="$CPPFLAGS" | 94 | [ac_save_CPPFLAGS="$CPPFLAGS" |
| 94 | ac_opt_found=no | 95 | ac_opt_found=no |
| @@ -234,7 +235,7 @@ m4_define([_AC_SYS_LARGEFILE_OPTIONS], m4_normalize( | |||
| 234 | # If you change this macro you may also need to change | 235 | # If you change this macro you may also need to change |
| 235 | # _AC_SYS_LARGEFILE_OPTIONS. | 236 | # _AC_SYS_LARGEFILE_OPTIONS. |
| 236 | AC_DEFUN([_AC_SYS_LARGEFILE_PROBE], | 237 | AC_DEFUN([_AC_SYS_LARGEFILE_PROBE], |
| 237 | [AC_CACHE_CHECK([for $CPPFLAGS option for large files], | 238 | [AC_CACHE_CHECK([for $CC option to support large files], |
| 238 | [ac_cv_sys_largefile_opts], | 239 | [ac_cv_sys_largefile_opts], |
| 239 | [ac_save_CPPFLAGS=$CPPFLAGS | 240 | [ac_save_CPPFLAGS=$CPPFLAGS |
| 240 | ac_opt_found=no | 241 | ac_opt_found=no |
| @@ -294,7 +295,7 @@ AC_CONFIG_COMMANDS_PRE([_AC_SYS_YEAR2038_ENABLE])]) | |||
| 294 | # By default, many hosts won't let programs access large files; | 295 | # By default, many hosts won't let programs access large files; |
| 295 | # one must use special compiler options to get large-file access to work. | 296 | # one must use special compiler options to get large-file access to work. |
| 296 | # For more details about this brain damage please see: | 297 | # For more details about this brain damage please see: |
| 297 | # http://www.unix.org/version2/whatsnew/lfs20mar.html | 298 | # https://www.unix.org/version2/whatsnew/lfs20mar.html |
| 298 | # Additionally, on Linux file systems with 64-bit inodes a file that happens | 299 | # Additionally, on Linux file systems with 64-bit inodes a file that happens |
| 299 | # to have a 64-bit inode number cannot be accessed by 32-bit applications on | 300 | # to have a 64-bit inode number cannot be accessed by 32-bit applications on |
| 300 | # Linux x86/x86_64. This can occur with file systems such as XFS and NFS. | 301 | # Linux x86/x86_64. This can occur with file systems such as XFS and NFS. |
diff --git a/gl/m4/libunistring-base.m4 b/gl/m4/libunistring-base.m4 new file mode 100644 index 00000000..9b5795ed --- /dev/null +++ b/gl/m4/libunistring-base.m4 | |||
| @@ -0,0 +1,204 @@ | |||
| 1 | # libunistring-base.m4 | ||
| 2 | # serial 10 | ||
| 3 | dnl Copyright (C) 2010-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl From Paolo Bonzini and Bruno Haible. | ||
| 10 | |||
| 11 | dnl gl_LIBUNISTRING_MODULE([VERSION], [Module]) | ||
| 12 | dnl Declares that the source files of Module should be compiled, unless we | ||
| 13 | dnl are linking with libunistring and its version is >= the given VERSION. | ||
| 14 | dnl Defines an automake conditional LIBUNISTRING_COMPILE_$MODULE that is | ||
| 15 | dnl true if the source files of Module should be compiled. | ||
| 16 | dnl This macro is to be used for public libunistring API, not for | ||
| 17 | dnl undocumented API. | ||
| 18 | dnl | ||
| 19 | dnl You have to bump the VERSION argument to the next projected version | ||
| 20 | dnl number each time you make a change that affects the behaviour of the | ||
| 21 | dnl functions defined in Module (even if the sources of Module itself do not | ||
| 22 | dnl change). | ||
| 23 | dnl | ||
| 24 | dnl This macro invocation must not occur in macros that are AC_REQUIREd. | ||
| 25 | |||
| 26 | AC_DEFUN([gl_LIBUNISTRING_MODULE], | ||
| 27 | [ | ||
| 28 | AC_REQUIRE([gl_LIBUNISTRING_LIB_PREPARE]) | ||
| 29 | dnl Use the variables HAVE_LIBUNISTRING, LIBUNISTRING_VERSION from | ||
| 30 | dnl gl_LIBUNISTRING_CORE if that macro has been run. | ||
| 31 | gl_CONDITIONAL(AS_TR_CPP([LIBUNISTRING_COMPILE_$2]), | ||
| 32 | [gl_LIBUNISTRING_VERSION_CMP([$1])]) | ||
| 33 | ]) | ||
| 34 | |||
| 35 | dnl gl_LIBUNISTRING_MODULE_WITH_VARIABLE([VERSION], [Module]) | ||
| 36 | dnl is like gl_LIBUNISTRING_MODULE([VERSION], [Module]), except that it also | ||
| 37 | dnl defines an AC_SUBSTed autoconf variable GNULIB_$MODULE_DLL_VARIABLE. | ||
| 38 | dnl What's the expansion of this autoconf variable? | ||
| 39 | dnl - When building libunistring, it expands to LIBUNISTRING_DLL_VARIABLE. | ||
| 40 | dnl (This is necessary because this token must be present in the .h files | ||
| 41 | dnl when the .h files get installed.) | ||
| 42 | dnl - When building gnulib or application code it expands to | ||
| 43 | dnl - LIBUNISTRING_DLL_VARIABLE by default, | ||
| 44 | dnl - if the automake conditional LIBUNISTRING_COMPILE_$MODULE evaluates | ||
| 45 | dnl to true: the value of | ||
| 46 | dnl ${module_indicator_prefix}_GNULIB_LIBUNISTRING_DLL_VARIABLE_NAME | ||
| 47 | dnl (which usually is empty, unless explicitly set in configure.ac). | ||
| 48 | dnl (This is necessary because when the conditional evaluates to false, | ||
| 49 | dnl the application code expects to use the declared variable from the | ||
| 50 | dnl installed libunistring; it's in this case that the | ||
| 51 | dnl LIBUNISTRING_DLL_VARIABLE macro from the installed | ||
| 52 | dnl <unistring/woe32dll.h> must be used.) | ||
| 53 | dnl | ||
| 54 | dnl This macro invocation must not occur in macros that are AC_REQUIREd. | ||
| 55 | |||
| 56 | AC_DEFUN([gl_LIBUNISTRING_MODULE_WITH_VARIABLE], | ||
| 57 | [ | ||
| 58 | gl_LIBUNISTRING_MODULE([$1], [$2]) | ||
| 59 | m4_ifndef([gl_IN_LIBUNISTRING], | ||
| 60 | [if test -z "${AS_TR_CPP([LIBUNISTRING_COMPILE_$2])_TRUE}"; then | ||
| 61 | GL_MODULE_INDICATOR_PREFIX[]_GNULIB_[]AS_TR_CPP([$2_DLL_VARIABLE])=$GL_MODULE_INDICATOR_PREFIX[]_GNULIB_LIBUNISTRING_DLL_VARIABLE_NAME | ||
| 62 | fi | ||
| 63 | ]) | ||
| 64 | ]) | ||
| 65 | |||
| 66 | dnl gl_LIBUNISTRING_LIBHEADER([VERSION], [HeaderFile]) | ||
| 67 | dnl Declares that HeaderFile should be created, unless we are linking | ||
| 68 | dnl with libunistring and its version is >= the given VERSION. | ||
| 69 | dnl HeaderFile should be relative to the lib directory and end in '.h'. | ||
| 70 | dnl Prepares for substituting LIBUNISTRING_HEADERFILE (to HeaderFile or empty). | ||
| 71 | dnl | ||
| 72 | dnl When we are linking with the already installed libunistring and its version | ||
| 73 | dnl is < VERSION, we create HeaderFile here, because we may compile functions | ||
| 74 | dnl (via gl_LIBUNISTRING_MODULE above) that are not contained in the installed | ||
| 75 | dnl version. | ||
| 76 | dnl When we are linking with the already installed libunistring and its version | ||
| 77 | dnl is > VERSION, we don't create HeaderFile here: it could cause compilation | ||
| 78 | dnl errors in other libunistring header files if some types are missing. | ||
| 79 | dnl | ||
| 80 | dnl You have to bump the VERSION argument to the next projected version | ||
| 81 | dnl number each time you make a non-comment change to the HeaderFile. | ||
| 82 | |||
| 83 | AC_DEFUN([gl_LIBUNISTRING_LIBHEADER], | ||
| 84 | [ | ||
| 85 | AC_REQUIRE([gl_LIBUNISTRING_LIB_PREPARE]) | ||
| 86 | dnl Use the variables HAVE_LIBUNISTRING, LIBUNISTRING_VERSION from | ||
| 87 | dnl gl_LIBUNISTRING_CORE if that macro has been run. | ||
| 88 | if gl_LIBUNISTRING_VERSION_CMP([$1]); then | ||
| 89 | dnl It is OK to use a .h file in lib/ from within tests/, but not vice | ||
| 90 | dnl versa. | ||
| 91 | if test -z "$LIBUNISTRING_[]AS_TR_CPP([$2])"; then | ||
| 92 | LIBUNISTRING_[]AS_TR_CPP([$2])="${gl_source_base_prefix}$2" | ||
| 93 | fi | ||
| 94 | else | ||
| 95 | LIBUNISTRING_[]AS_TR_CPP([$2])= | ||
| 96 | fi | ||
| 97 | AC_SUBST([LIBUNISTRING_]AS_TR_CPP([$2])) | ||
| 98 | ]) | ||
| 99 | |||
| 100 | dnl Miscellaneous preparations/initializations. | ||
| 101 | |||
| 102 | AC_DEFUN([gl_LIBUNISTRING_LIB_PREPARE], | ||
| 103 | [ | ||
| 104 | dnl Ensure that HAVE_LIBUNISTRING is fully determined at this point. | ||
| 105 | m4_ifdef([gl_LIBUNISTRING], [AC_REQUIRE([gl_LIBUNISTRING])]) | ||
| 106 | |||
| 107 | AC_REQUIRE([AC_PROG_AWK]) | ||
| 108 | |||
| 109 | dnl Sed expressions to extract the parts of a version number. | ||
| 110 | changequote(,) | ||
| 111 | gl_libunistring_sed_extract_major='/^[0-9]/{s/^\([0-9]*\).*/\1/p;q;} | ||
| 112 | i\ | ||
| 113 | 0 | ||
| 114 | q | ||
| 115 | ' | ||
| 116 | gl_libunistring_sed_extract_minor='/^[0-9][0-9]*[.][0-9]/{s/^[0-9]*[.]\([0-9]*\).*/\1/p;q;} | ||
| 117 | i\ | ||
| 118 | 0 | ||
| 119 | q | ||
| 120 | ' | ||
| 121 | gl_libunistring_sed_extract_subminor='/^[0-9][0-9]*[.][0-9][0-9]*[.][0-9]/{s/^[0-9]*[.][0-9]*[.]\([0-9]*\).*/\1/p;q;} | ||
| 122 | i\ | ||
| 123 | 0 | ||
| 124 | q | ||
| 125 | ' | ||
| 126 | changequote([,]) | ||
| 127 | |||
| 128 | if test "$HAVE_LIBUNISTRING" = yes; then | ||
| 129 | LIBUNISTRING_VERSION_MAJOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_major"` | ||
| 130 | LIBUNISTRING_VERSION_MINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_minor"` | ||
| 131 | LIBUNISTRING_VERSION_SUBMINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_subminor"` | ||
| 132 | fi | ||
| 133 | |||
| 134 | dnl Determine whether <unistring/woe32dll.h> from an installed libunistring | ||
| 135 | dnl is available. | ||
| 136 | m4_ifdef([gl_IN_LIBUNISTRING], | ||
| 137 | [dnl In libunistring, all .h files that declare variables need to | ||
| 138 | dnl #include <unistring/woe32dll.h>. This references the file | ||
| 139 | dnl unistring/woe32dll.h in libunistring. | ||
| 140 | HAVE_UNISTRING_WOE32DLL_H=1 | ||
| 141 | ], | ||
| 142 | [dnl In gnulib or in applications, we need a #include <unistring/woe32dll.h> | ||
| 143 | dnl if and only if an installed libunistring is available. | ||
| 144 | if test "$HAVE_LIBUNISTRING" = yes; then | ||
| 145 | AC_CHECK_HEADERS([unistring/woe32dll.h], | ||
| 146 | [HAVE_UNISTRING_WOE32DLL_H=1], | ||
| 147 | [HAVE_UNISTRING_WOE32DLL_H=0]) | ||
| 148 | else | ||
| 149 | HAVE_UNISTRING_WOE32DLL_H=0 | ||
| 150 | fi | ||
| 151 | ]) | ||
| 152 | AC_SUBST([HAVE_UNISTRING_WOE32DLL_H]) | ||
| 153 | ]) | ||
| 154 | |||
| 155 | dnl gl_LIBUNISTRING_VERSION_CMP([VERSION]) | ||
| 156 | dnl Expands to a shell statement that evaluates to true if LIBUNISTRING_VERSION | ||
| 157 | dnl is less than the VERSION argument. | ||
| 158 | AC_DEFUN([gl_LIBUNISTRING_VERSION_CMP], | ||
| 159 | [dnl VERSION = 999.9 means to evaluates to true always, i.e. to ignore | ||
| 160 | dnl the installed libunistring regardless of its version. | ||
| 161 | m4_if([$1], [999.9], | ||
| 162 | [true], | ||
| 163 | [ { test "$HAVE_LIBUNISTRING" != yes \ | ||
| 164 | || { | ||
| 165 | dnl AS_LITERAL_IF exists and works fine since autoconf-2.59 at least. | ||
| 166 | AS_LITERAL_IF([$1], | ||
| 167 | [dnl This is the optimized variant, that assumes the argument is a literal: | ||
| 168 | m4_pushdef([requested_version_major], | ||
| 169 | [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^\([0-9]*\).*], [\1]), [])]) | ||
| 170 | m4_pushdef([requested_version_minor], | ||
| 171 | [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^[0-9]*[.]\([0-9]*\).*], [\1]), [$1])]) | ||
| 172 | m4_pushdef([requested_version_subminor], | ||
| 173 | [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^[0-9]*[.][0-9]*[.]\([0-9]*\).*], [\1]), [$1])]) | ||
| 174 | test $LIBUNISTRING_VERSION_MAJOR -lt requested_version_major \ | ||
| 175 | || { test $LIBUNISTRING_VERSION_MAJOR -eq requested_version_major \ | ||
| 176 | && { test $LIBUNISTRING_VERSION_MINOR -lt requested_version_minor \ | ||
| 177 | || { test $LIBUNISTRING_VERSION_MINOR -eq requested_version_minor \ | ||
| 178 | && test $LIBUNISTRING_VERSION_SUBMINOR -lt requested_version_subminor | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | ||
| 182 | m4_popdef([requested_version_subminor]) | ||
| 183 | m4_popdef([requested_version_minor]) | ||
| 184 | m4_popdef([requested_version_major]) | ||
| 185 | ], | ||
| 186 | [dnl This is the unoptimized variant: | ||
| 187 | requested_version_major=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_major"` | ||
| 188 | requested_version_minor=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_minor"` | ||
| 189 | requested_version_subminor=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_subminor"` | ||
| 190 | test $LIBUNISTRING_VERSION_MAJOR -lt $requested_version_major \ | ||
| 191 | || { test $LIBUNISTRING_VERSION_MAJOR -eq $requested_version_major \ | ||
| 192 | && { test $LIBUNISTRING_VERSION_MINOR -lt $requested_version_minor \ | ||
| 193 | || { test $LIBUNISTRING_VERSION_MINOR -eq $requested_version_minor \ | ||
| 194 | && test $LIBUNISTRING_VERSION_SUBMINOR -lt $requested_version_subminor | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | ]) | ||
| 199 | } | ||
| 200 | }])]) | ||
| 201 | |||
| 202 | dnl gl_LIBUNISTRING_ARG_OR_ZERO([ARG], [ORIG]) expands to ARG if it is not the | ||
| 203 | dnl same as ORIG, otherwise to 0. | ||
| 204 | m4_define([gl_LIBUNISTRING_ARG_OR_ZERO], [m4_if([$1], [$2], [0], [$1])]) | ||
diff --git a/gl/m4/limits-h.m4 b/gl/m4/limits-h.m4 index 1b619e1e..202df492 100644 --- a/gl/m4/limits-h.m4 +++ b/gl/m4/limits-h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # limits-h.m4 | 1 | # limits-h.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright 2016-2024 Free Software Foundation, Inc. | 3 | dnl Copyright 2016-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Check whether limits.h has needed features. | 9 | dnl Check whether limits.h has needed features. |
| 9 | 10 | ||
diff --git a/gl/m4/localcharset.m4 b/gl/m4/localcharset.m4 index 807a5eed..374a48f1 100644 --- a/gl/m4/localcharset.m4 +++ b/gl/m4/localcharset.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # localcharset.m4 | 1 | # localcharset.m4 |
| 2 | # serial 8 | 2 | # serial 8 |
| 3 | dnl Copyright (C) 2002, 2004, 2006, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002, 2004, 2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_LOCALCHARSET], | 9 | AC_DEFUN([gl_LOCALCHARSET], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/locale-en.m4 b/gl/m4/locale-en.m4 new file mode 100644 index 00000000..4151428a --- /dev/null +++ b/gl/m4/locale-en.m4 | |||
| @@ -0,0 +1,138 @@ | |||
| 1 | # locale-en.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright (C) 2003-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl From Bruno Haible. | ||
| 10 | |||
| 11 | dnl Determine the name of an English (or American English) locale with | ||
| 12 | dnl UTF-8 encoding. | ||
| 13 | AC_DEFUN_ONCE([gt_LOCALE_EN_UTF8], | ||
| 14 | [ | ||
| 15 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 16 | AC_REQUIRE([AM_LANGINFO_CODESET]) | ||
| 17 | AC_CACHE_CHECK([for an english Unicode locale], [gt_cv_locale_en_utf8], [ | ||
| 18 | case "$host_os" in | ||
| 19 | *-musl* | midipix*) | ||
| 20 | dnl On musl libc, all kinds of ll_CC.UTF-8 locales exist, even without | ||
| 21 | dnl any locale file on disk. But they are effectively equivalent to the | ||
| 22 | dnl C.UTF-8 locale, except for locale categories (such as LC_MESSSAGES) | ||
| 23 | dnl for which localizations (.mo files) have been installed. | ||
| 24 | gt_cv_locale_en_utf8=en_US.UTF-8 | ||
| 25 | ;; | ||
| 26 | *) | ||
| 27 | AC_LANG_CONFTEST([AC_LANG_SOURCE([[ | ||
| 28 | #include <locale.h> | ||
| 29 | #include <time.h> | ||
| 30 | #if HAVE_LANGINFO_CODESET | ||
| 31 | # include <langinfo.h> | ||
| 32 | #endif | ||
| 33 | #include <stdlib.h> | ||
| 34 | #include <string.h> | ||
| 35 | struct tm t; | ||
| 36 | char buf[16]; | ||
| 37 | int main () { | ||
| 38 | /* On BeOS and Haiku, locales are not implemented in libc. Rather, libintl | ||
| 39 | imitates locale dependent behaviour by looking at the environment | ||
| 40 | variables, and all locales use the UTF-8 encoding. */ | ||
| 41 | #if !(defined __BEOS__ || defined __HAIKU__) | ||
| 42 | /* Check whether the given locale name is recognized by the system. */ | ||
| 43 | # if defined _WIN32 && !defined __CYGWIN__ | ||
| 44 | /* On native Windows, setlocale(category, "") looks at the system settings, | ||
| 45 | not at the environment variables. Also, when an encoding suffix such | ||
| 46 | as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE | ||
| 47 | category of the locale to "C". */ | ||
| 48 | if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL | ||
| 49 | || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) | ||
| 50 | return 1; | ||
| 51 | # else | ||
| 52 | if (setlocale (LC_ALL, "") == NULL) return 1; | ||
| 53 | # endif | ||
| 54 | /* Check whether nl_langinfo(CODESET) is "UTF-8" or equivalent. */ | ||
| 55 | # if HAVE_LANGINFO_CODESET | ||
| 56 | { | ||
| 57 | const char *cs = nl_langinfo (CODESET); | ||
| 58 | if (!(strcmp (cs, "UTF-8") == 0 || strcmp (cs, "UTF8") == 0 | ||
| 59 | || strcmp (cs, "utf-8") == 0 || strcmp (cs, "utf8") == 0)) | ||
| 60 | return 1; | ||
| 61 | } | ||
| 62 | # endif | ||
| 63 | # ifdef __CYGWIN__ | ||
| 64 | /* On Cygwin, avoid locale names without encoding suffix, because the | ||
| 65 | locale_charset() function relies on the encoding suffix. Note that | ||
| 66 | LC_ALL is set on the command line. */ | ||
| 67 | if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; | ||
| 68 | # endif | ||
| 69 | /* Check the third month name. */ | ||
| 70 | t.tm_year = 1975 - 1900; t.tm_mon = 3 - 1; t.tm_mday = 24; | ||
| 71 | if (strftime (buf, sizeof (buf), "%B", &t) < 5 || strcmp (buf, "March") != 0) | ||
| 72 | return 1; | ||
| 73 | #endif | ||
| 74 | #if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ | ||
| 75 | /* Check whether the decimal separator is a dot. */ | ||
| 76 | if (localeconv () ->decimal_point[0] != '.') return 1; | ||
| 77 | #endif | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | ]])]) | ||
| 81 | if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then | ||
| 82 | case "$host_os" in | ||
| 83 | # Handle native Windows specially, because there setlocale() interprets | ||
| 84 | # "ar" or "ara" as "Arabic" or "Arabic_Saudi Arabia.1256", | ||
| 85 | # "en" or "eng" as "English" or "English_United States.1252", | ||
| 86 | # "fr" or "fra" as "French" or "French_France.1252", | ||
| 87 | # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", | ||
| 88 | # "ja" or "jpn" as "Japanese" or "Japanese_Japan.932", | ||
| 89 | # and similar. | ||
| 90 | mingw* | windows*) | ||
| 91 | # Test for the hypothetical native Windows locale name. | ||
| 92 | if (LC_ALL='English_United States.65001' LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then | ||
| 93 | gt_cv_locale_en_utf8='English_United States.65001' | ||
| 94 | else | ||
| 95 | # None found. | ||
| 96 | gt_cv_locale_en_utf8=none | ||
| 97 | fi | ||
| 98 | ;; | ||
| 99 | *) | ||
| 100 | # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because | ||
| 101 | # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the | ||
| 102 | # configure script would override the LC_ALL setting. Likewise for | ||
| 103 | # LC_CTYPE, which is also set at the beginning of the configure script. | ||
| 104 | # Test for the locale name with explicit encoding suffix first | ||
| 105 | # (this is necessary on Haiku). | ||
| 106 | if (LC_ALL=en_US.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then | ||
| 107 | gt_cv_locale_en_utf8=en_US.UTF-8 | ||
| 108 | else | ||
| 109 | # Test for the locale name without encoding suffix. | ||
| 110 | if (LC_ALL=en_US LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then | ||
| 111 | gt_cv_locale_en_utf8=en_US | ||
| 112 | else | ||
| 113 | # Test for the Solaris 10 locale name. | ||
| 114 | if (LC_ALL=en.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then | ||
| 115 | gt_cv_locale_en_utf8=en.UTF-8 | ||
| 116 | else | ||
| 117 | # None found. | ||
| 118 | gt_cv_locale_en_utf8=none | ||
| 119 | fi | ||
| 120 | fi | ||
| 121 | fi | ||
| 122 | ;; | ||
| 123 | esac | ||
| 124 | fi | ||
| 125 | rm -fr conftest* | ||
| 126 | ;; | ||
| 127 | esac | ||
| 128 | ]) | ||
| 129 | LOCALE_EN_UTF8="$gt_cv_locale_en_utf8" | ||
| 130 | case "$LOCALE_EN_UTF8" in #( | ||
| 131 | '' | *[[\"\$\'*@<:@]]*) | ||
| 132 | dnl The empty value occurs when the conftest.c program above could not | ||
| 133 | dnl be compiled. The other values might cause trouble with sh or make. | ||
| 134 | AC_MSG_WARN([invalid locale "$LOCALE_EN_UTF8"; assuming "none"]) | ||
| 135 | LOCALE_EN_UTF8=none;; | ||
| 136 | esac | ||
| 137 | AC_SUBST([LOCALE_EN_UTF8]) | ||
| 138 | ]) | ||
diff --git a/gl/m4/locale-fr.m4 b/gl/m4/locale-fr.m4 index f8d7c543..f504d5b5 100644 --- a/gl/m4/locale-fr.m4 +++ b/gl/m4/locale-fr.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # locale-fr.m4 | 1 | # locale-fr.m4 |
| 2 | # serial 23 | 2 | # serial 24 |
| 3 | dnl Copyright (C) 2003, 2005-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003, 2005-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | 10 | ||
| @@ -71,8 +72,9 @@ int main () { | |||
| 71 | if (strftime (buf, sizeof (buf), "%b", &t) < 3 || buf[2] != 'v') return 1; | 72 | if (strftime (buf, sizeof (buf), "%b", &t) < 3 || buf[2] != 'v') return 1; |
| 72 | # if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ | 73 | # if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ |
| 73 | /* Check whether the decimal separator is a comma. | 74 | /* Check whether the decimal separator is a comma. |
| 74 | On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point | 75 | On NetBSD 3.0 in the fr_FR.ISO8859-1 locale |
| 75 | are nl_langinfo(RADIXCHAR) are both ".". */ | 76 | and on Haiku in the fr_FR.UTF-8 locale, |
| 77 | localeconv()->decimal_point are nl_langinfo(RADIXCHAR) are both ".". */ | ||
| 76 | if (localeconv () ->decimal_point[0] != ',') return 1; | 78 | if (localeconv () ->decimal_point[0] != ',') return 1; |
| 77 | # endif | 79 | # endif |
| 78 | return 0; | 80 | return 0; |
| @@ -82,10 +84,11 @@ int main () { | |||
| 82 | if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then | 84 | if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then |
| 83 | case "$host_os" in | 85 | case "$host_os" in |
| 84 | # Handle native Windows specially, because there setlocale() interprets | 86 | # Handle native Windows specially, because there setlocale() interprets |
| 85 | # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", | 87 | # "ar" or "ara" as "Arabic" or "Arabic_Saudi Arabia.1256", |
| 88 | # "en" or "eng" as "English" or "English_United States.1252", | ||
| 86 | # "fr" or "fra" as "French" or "French_France.1252", | 89 | # "fr" or "fra" as "French" or "French_France.1252", |
| 87 | # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", | 90 | # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", |
| 88 | # "ja" as "Japanese" or "Japanese_Japan.932", | 91 | # "ja" or "jpn" as "Japanese" or "Japanese_Japan.932", |
| 89 | # and similar. | 92 | # and similar. |
| 90 | mingw* | windows*) | 93 | mingw* | windows*) |
| 91 | # Test for the native Windows locale name. | 94 | # Test for the native Windows locale name. |
| @@ -214,8 +217,9 @@ int main () { | |||
| 214 | #endif | 217 | #endif |
| 215 | #if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ | 218 | #if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ |
| 216 | /* Check whether the decimal separator is a comma. | 219 | /* Check whether the decimal separator is a comma. |
| 217 | On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point | 220 | On NetBSD 3.0 in the fr_FR.ISO8859-1 locale |
| 218 | are nl_langinfo(RADIXCHAR) are both ".". */ | 221 | and on Haiku in the fr_FR.UTF-8 locale, |
| 222 | localeconv()->decimal_point are nl_langinfo(RADIXCHAR) are both ".". */ | ||
| 219 | if (localeconv () ->decimal_point[0] != ',') return 1; | 223 | if (localeconv () ->decimal_point[0] != ',') return 1; |
| 220 | #endif | 224 | #endif |
| 221 | return 0; | 225 | return 0; |
| @@ -224,10 +228,11 @@ int main () { | |||
| 224 | if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then | 228 | if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then |
| 225 | case "$host_os" in | 229 | case "$host_os" in |
| 226 | # Handle native Windows specially, because there setlocale() interprets | 230 | # Handle native Windows specially, because there setlocale() interprets |
| 227 | # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", | 231 | # "ar" or "ara" as "Arabic" or "Arabic_Saudi Arabia.1256", |
| 232 | # "en" or "eng" as "English" or "English_United States.1252", | ||
| 228 | # "fr" or "fra" as "French" or "French_France.1252", | 233 | # "fr" or "fra" as "French" or "French_France.1252", |
| 229 | # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", | 234 | # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", |
| 230 | # "ja" as "Japanese" or "Japanese_Japan.932", | 235 | # "ja" or "jpn" as "Japanese" or "Japanese_Japan.932", |
| 231 | # and similar. | 236 | # and similar. |
| 232 | mingw* | windows*) | 237 | mingw* | windows*) |
| 233 | # Test for the hypothetical native Windows locale name. | 238 | # Test for the hypothetical native Windows locale name. |
diff --git a/gl/m4/locale-ja.m4 b/gl/m4/locale-ja.m4 index 8423bcb9..1c813b89 100644 --- a/gl/m4/locale-ja.m4 +++ b/gl/m4/locale-ja.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # locale-ja.m4 | 1 | # locale-ja.m4 |
| 2 | # serial 18 | 2 | # serial 19 |
| 3 | dnl Copyright (C) 2003, 2005-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003, 2005-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | 10 | ||
| @@ -86,10 +87,11 @@ int main () | |||
| 86 | if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then | 87 | if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then |
| 87 | case "$host_os" in | 88 | case "$host_os" in |
| 88 | # Handle native Windows specially, because there setlocale() interprets | 89 | # Handle native Windows specially, because there setlocale() interprets |
| 89 | # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", | 90 | # "ar" or "ara" as "Arabic" or "Arabic_Saudi Arabia.1256", |
| 91 | # "en" or "eng" as "English" or "English_United States.1252", | ||
| 90 | # "fr" or "fra" as "French" or "French_France.1252", | 92 | # "fr" or "fra" as "French" or "French_France.1252", |
| 91 | # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", | 93 | # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", |
| 92 | # "ja" as "Japanese" or "Japanese_Japan.932", | 94 | # "ja" or "jpn" as "Japanese" or "Japanese_Japan.932", |
| 93 | # and similar. | 95 | # and similar. |
| 94 | mingw* | windows*) | 96 | mingw* | windows*) |
| 95 | # Note that on native Windows, the Japanese locale is | 97 | # Note that on native Windows, the Japanese locale is |
diff --git a/gl/m4/locale-zh.m4 b/gl/m4/locale-zh.m4 index 7f1a10be..6f9374d2 100644 --- a/gl/m4/locale-zh.m4 +++ b/gl/m4/locale-zh.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # locale-zh.m4 | 1 | # locale-zh.m4 |
| 2 | # serial 18 | 2 | # serial 20 |
| 3 | dnl Copyright (C) 2003, 2005-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003, 2005-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | 10 | ||
| @@ -22,6 +23,7 @@ AC_DEFUN_ONCE([gt_LOCALE_ZH_CN], | |||
| 22 | #endif | 23 | #endif |
| 23 | #include <stdlib.h> | 24 | #include <stdlib.h> |
| 24 | #include <string.h> | 25 | #include <string.h> |
| 26 | #include <wchar.h> | ||
| 25 | struct tm t; | 27 | struct tm t; |
| 26 | char buf[16]; | 28 | char buf[16]; |
| 27 | int main () | 29 | int main () |
| @@ -80,6 +82,19 @@ int main () | |||
| 80 | single wide character. This excludes the GB2312 and GBK encodings. */ | 82 | single wide character. This excludes the GB2312 and GBK encodings. */ |
| 81 | if (mblen ("\203\062\332\066", 5) != 4) | 83 | if (mblen ("\203\062\332\066", 5) != 4) |
| 82 | return 1; | 84 | return 1; |
| 85 | /* Check whether mbrtowc accept this character one byte at a time. | ||
| 86 | This excludes NetBSD 10.0. */ | ||
| 87 | if (sizeof (wchar_t) > 2) | ||
| 88 | { | ||
| 89 | wchar_t wc; | ||
| 90 | mbstate_t state; | ||
| 91 | memset (&state, 0, sizeof (state)); | ||
| 92 | if (!(mbrtowc (&wc, "\203", 1, &state) == (size_t)(-2) | ||
| 93 | && mbrtowc (&wc, "\062", 1, &state) == (size_t)(-2) | ||
| 94 | && mbrtowc (&wc, "\332", 1, &state) == (size_t)(-2) | ||
| 95 | && mbrtowc (&wc, "\066", 1, &state) == 1)) | ||
| 96 | return 1; | ||
| 97 | } | ||
| 83 | return 0; | 98 | return 0; |
| 84 | #endif | 99 | #endif |
| 85 | } | 100 | } |
| @@ -87,10 +102,11 @@ int main () | |||
| 87 | if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then | 102 | if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then |
| 88 | case "$host_os" in | 103 | case "$host_os" in |
| 89 | # Handle native Windows specially, because there setlocale() interprets | 104 | # Handle native Windows specially, because there setlocale() interprets |
| 90 | # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", | 105 | # "ar" or "ara" as "Arabic" or "Arabic_Saudi Arabia.1256", |
| 106 | # "en" or "eng" as "English" or "English_United States.1252", | ||
| 91 | # "fr" or "fra" as "French" or "French_France.1252", | 107 | # "fr" or "fra" as "French" or "French_France.1252", |
| 92 | # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", | 108 | # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", |
| 93 | # "ja" as "Japanese" or "Japanese_Japan.932", | 109 | # "ja" or "jpn" as "Japanese" or "Japanese_Japan.932", |
| 94 | # and similar. | 110 | # and similar. |
| 95 | mingw* | windows*) | 111 | mingw* | windows*) |
| 96 | # Test for the hypothetical native Windows locale name. | 112 | # Test for the hypothetical native Windows locale name. |
diff --git a/gl/m4/locale_h.m4 b/gl/m4/locale_h.m4 index cd1c81ec..e1afbc16 100644 --- a/gl/m4/locale_h.m4 +++ b/gl/m4/locale_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # locale_h.m4 | 1 | # locale_h.m4 |
| 2 | # serial 31 | 2 | # serial 37 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_LOCALE_H], | 9 | AC_DEFUN_ONCE([gl_LOCALE_H], |
| 9 | [ | 10 | [ |
| @@ -19,6 +20,26 @@ AC_DEFUN_ONCE([gl_LOCALE_H], | |||
| 19 | AC_REQUIRE([gl_STDDEF_H]) | 20 | AC_REQUIRE([gl_STDDEF_H]) |
| 20 | 21 | ||
| 21 | AC_REQUIRE([gl_LOCALE_T]) | 22 | AC_REQUIRE([gl_LOCALE_T]) |
| 23 | dnl On native Windows, there is a type '_locale_t' that can be used to | ||
| 24 | dnl define locale_t. | ||
| 25 | AC_CACHE_CHECK([whether locale.h defines _locale_t], | ||
| 26 | [gl_cv_header_locale_has_windows_locale_t], | ||
| 27 | [AC_COMPILE_IFELSE( | ||
| 28 | [AC_LANG_PROGRAM( | ||
| 29 | [[#include <locale.h> | ||
| 30 | _locale_t x;]], | ||
| 31 | [[]])], | ||
| 32 | [gl_cv_header_locale_has_windows_locale_t=yes], | ||
| 33 | [gl_cv_header_locale_has_windows_locale_t=no]) | ||
| 34 | ]) | ||
| 35 | if test $gl_cv_header_locale_has_windows_locale_t = yes; then | ||
| 36 | HAVE_WINDOWS_LOCALE_T=1 | ||
| 37 | AC_DEFINE([HAVE_WINDOWS_LOCALE_T], [1], | ||
| 38 | [Define to 1 if <locale.h> defines the _locale_t type.]) | ||
| 39 | else | ||
| 40 | HAVE_WINDOWS_LOCALE_T=0 | ||
| 41 | fi | ||
| 42 | AC_SUBST([HAVE_WINDOWS_LOCALE_T]) | ||
| 22 | 43 | ||
| 23 | dnl Solaris 11.0 defines the int_p_*, int_n_* members of 'struct lconv' | 44 | dnl Solaris 11.0 defines the int_p_*, int_n_* members of 'struct lconv' |
| 24 | dnl only if _LCONV_C99 is defined. | 45 | dnl only if _LCONV_C99 is defined. |
| @@ -86,7 +107,7 @@ AC_DEFUN_ONCE([gl_LOCALE_H], | |||
| 86 | # include <xlocale.h> | 107 | # include <xlocale.h> |
| 87 | #endif | 108 | #endif |
| 88 | ]], | 109 | ]], |
| 89 | [setlocale newlocale duplocale freelocale]) | 110 | [setlocale newlocale duplocale freelocale getlocalename_l]) |
| 90 | ]) | 111 | ]) |
| 91 | 112 | ||
| 92 | dnl Checks to determine whether the system has the locale_t type, | 113 | dnl Checks to determine whether the system has the locale_t type, |
| @@ -130,6 +151,7 @@ AC_DEFUN([gl_LOCALE_T], | |||
| 130 | fi | 151 | fi |
| 131 | fi | 152 | fi |
| 132 | AC_SUBST([HAVE_XLOCALE_H]) | 153 | AC_SUBST([HAVE_XLOCALE_H]) |
| 154 | AC_SUBST([HAVE_LOCALE_T]) | ||
| 133 | ]) | 155 | ]) |
| 134 | 156 | ||
| 135 | # gl_LOCALE_MODULE_INDICATOR([modulename]) | 157 | # gl_LOCALE_MODULE_INDICATOR([modulename]) |
| @@ -154,7 +176,11 @@ AC_DEFUN([gl_LOCALE_H_REQUIRE_DEFAULTS], | |||
| 154 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALECONV]) | 176 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALECONV]) |
| 155 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE]) | 177 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE]) |
| 156 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE_NULL]) | 178 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETLOCALE_NULL]) |
| 179 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NEWLOCALE]) | ||
| 157 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUPLOCALE]) | 180 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DUPLOCALE]) |
| 181 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FREELOCALE]) | ||
| 182 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOCALENAME_L]) | ||
| 183 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLOCALENAME_L_UNSAFE]) | ||
| 158 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALENAME_UNSAFE]) | 184 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOCALENAME_UNSAFE]) |
| 159 | ]) | 185 | ]) |
| 160 | m4_require(GL_MODULE_INDICATOR_PREFIX[_LOCALE_H_MODULE_INDICATOR_DEFAULTS]) | 186 | m4_require(GL_MODULE_INDICATOR_PREFIX[_LOCALE_H_MODULE_INDICATOR_DEFAULTS]) |
| @@ -164,14 +190,16 @@ AC_DEFUN([gl_LOCALE_H_REQUIRE_DEFAULTS], | |||
| 164 | AC_DEFUN([gl_LOCALE_H_DEFAULTS], | 190 | AC_DEFUN([gl_LOCALE_H_DEFAULTS], |
| 165 | [ | 191 | [ |
| 166 | dnl Assume proper GNU behavior unless another module says otherwise. | 192 | dnl Assume proper GNU behavior unless another module says otherwise. |
| 167 | HAVE_NEWLOCALE=1; AC_SUBST([HAVE_NEWLOCALE]) | 193 | HAVE_NEWLOCALE=1; AC_SUBST([HAVE_NEWLOCALE]) |
| 168 | HAVE_DUPLOCALE=1; AC_SUBST([HAVE_DUPLOCALE]) | 194 | HAVE_DUPLOCALE=1; AC_SUBST([HAVE_DUPLOCALE]) |
| 169 | HAVE_FREELOCALE=1; AC_SUBST([HAVE_FREELOCALE]) | 195 | HAVE_FREELOCALE=1; AC_SUBST([HAVE_FREELOCALE]) |
| 170 | REPLACE_LOCALECONV=0; AC_SUBST([REPLACE_LOCALECONV]) | 196 | HAVE_GETLOCALENAME_L=1; AC_SUBST([HAVE_GETLOCALENAME_L]) |
| 171 | REPLACE_SETLOCALE=0; AC_SUBST([REPLACE_SETLOCALE]) | 197 | REPLACE_LOCALECONV=0; AC_SUBST([REPLACE_LOCALECONV]) |
| 172 | REPLACE_NEWLOCALE=0; AC_SUBST([REPLACE_NEWLOCALE]) | 198 | REPLACE_SETLOCALE=0; AC_SUBST([REPLACE_SETLOCALE]) |
| 173 | REPLACE_DUPLOCALE=0; AC_SUBST([REPLACE_DUPLOCALE]) | 199 | REPLACE_NEWLOCALE=0; AC_SUBST([REPLACE_NEWLOCALE]) |
| 174 | REPLACE_FREELOCALE=0; AC_SUBST([REPLACE_FREELOCALE]) | 200 | REPLACE_DUPLOCALE=0; AC_SUBST([REPLACE_DUPLOCALE]) |
| 175 | REPLACE_STRUCT_LCONV=0; AC_SUBST([REPLACE_STRUCT_LCONV]) | 201 | REPLACE_FREELOCALE=0; AC_SUBST([REPLACE_FREELOCALE]) |
| 202 | REPLACE_GETLOCALENAME_L=0; AC_SUBST([REPLACE_GETLOCALENAME_L]) | ||
| 203 | REPLACE_STRUCT_LCONV=0; AC_SUBST([REPLACE_STRUCT_LCONV]) | ||
| 176 | LOCALENAME_ENHANCE_LOCALE_FUNCS=0; AC_SUBST([LOCALENAME_ENHANCE_LOCALE_FUNCS]) | 204 | LOCALENAME_ENHANCE_LOCALE_FUNCS=0; AC_SUBST([LOCALENAME_ENHANCE_LOCALE_FUNCS]) |
| 177 | ]) | 205 | ]) |
diff --git a/gl/m4/localeconv.m4 b/gl/m4/localeconv.m4 index 77d5684f..55a669d0 100644 --- a/gl/m4/localeconv.m4 +++ b/gl/m4/localeconv.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # localeconv.m4 | 1 | # localeconv.m4 |
| 2 | # serial 3 | 2 | # serial 3 |
| 3 | dnl Copyright (C) 2012-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2012-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_LOCALECONV], | 9 | AC_DEFUN([gl_FUNC_LOCALECONV], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/lock.m4 b/gl/m4/lock.m4 index eb0fc6a1..b1d3f435 100644 --- a/gl/m4/lock.m4 +++ b/gl/m4/lock.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # lock.m4 | 1 | # lock.m4 |
| 2 | # serial 14 | 2 | # serial 14 |
| 3 | dnl Copyright (C) 2005-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | 10 | ||
diff --git a/gl/m4/lseek.m4 b/gl/m4/lseek.m4 index 0bc3d65e..ddfadd38 100644 --- a/gl/m4/lseek.m4 +++ b/gl/m4/lseek.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # lseek.m4 | 1 | # lseek.m4 |
| 2 | # serial 15 | 2 | # serial 15 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_LSEEK], | 9 | AC_DEFUN([gl_FUNC_LSEEK], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/lstat.m4 b/gl/m4/lstat.m4 new file mode 100644 index 00000000..efae2485 --- /dev/null +++ b/gl/m4/lstat.m4 | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | # lstat.m4 | ||
| 2 | # serial 36 | ||
| 3 | dnl Copyright (C) 1997-2001, 2003-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl From Jim Meyering. | ||
| 10 | |||
| 11 | AC_DEFUN([gl_FUNC_LSTAT], | ||
| 12 | [ | ||
| 13 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 14 | AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) | ||
| 15 | dnl If lstat does not exist, the replacement <sys/stat.h> does | ||
| 16 | dnl "#define lstat stat", and lstat.c is a no-op. | ||
| 17 | AC_CHECK_FUNCS_ONCE([lstat]) | ||
| 18 | if test $ac_cv_func_lstat = yes; then | ||
| 19 | AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK]) | ||
| 20 | case $host_os,$gl_cv_func_lstat_dereferences_slashed_symlink in | ||
| 21 | darwin* | solaris* | *no) | ||
| 22 | REPLACE_LSTAT=1 | ||
| 23 | ;; | ||
| 24 | esac | ||
| 25 | else | ||
| 26 | HAVE_LSTAT=0 | ||
| 27 | fi | ||
| 28 | ]) | ||
| 29 | |||
| 30 | # Prerequisites of lib/lstat.c. | ||
| 31 | AC_DEFUN([gl_PREREQ_LSTAT], [:]) | ||
| 32 | |||
| 33 | AC_DEFUN([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK], | ||
| 34 | [ | ||
| 35 | dnl We don't use AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK any more, because it | ||
| 36 | dnl is no longer maintained in Autoconf and because it invokes AC_LIBOBJ. | ||
| 37 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 38 | AC_CACHE_CHECK([whether lstat correctly handles trailing slash], | ||
| 39 | [gl_cv_func_lstat_dereferences_slashed_symlink], | ||
| 40 | [rm -f conftest.sym conftest.file | ||
| 41 | echo >conftest.file | ||
| 42 | AC_RUN_IFELSE( | ||
| 43 | [AC_LANG_PROGRAM( | ||
| 44 | [AC_INCLUDES_DEFAULT], | ||
| 45 | [[struct stat sbuf; | ||
| 46 | if (symlink ("conftest.file", "conftest.sym") != 0) | ||
| 47 | return 1; | ||
| 48 | /* Linux will dereference the symlink and fail, as required by | ||
| 49 | POSIX. That is better in the sense that it means we will not | ||
| 50 | have to compile and use the lstat wrapper. */ | ||
| 51 | return lstat ("conftest.sym/", &sbuf) == 0; | ||
| 52 | ]])], | ||
| 53 | [gl_cv_func_lstat_dereferences_slashed_symlink=yes], | ||
| 54 | [gl_cv_func_lstat_dereferences_slashed_symlink=no], | ||
| 55 | [case "$host_os" in | ||
| 56 | linux-* | linux) | ||
| 57 | # Guess yes on Linux systems. | ||
| 58 | gl_cv_func_lstat_dereferences_slashed_symlink="guessing yes" ;; | ||
| 59 | midipix*) | ||
| 60 | # Guess yes on systems that emulate the Linux system calls. | ||
| 61 | gl_cv_func_lstat_dereferences_slashed_symlink="guessing yes" ;; | ||
| 62 | *-gnu* | gnu*) | ||
| 63 | # Guess yes on glibc systems. | ||
| 64 | gl_cv_func_lstat_dereferences_slashed_symlink="guessing yes" ;; | ||
| 65 | mingw* | windows*) | ||
| 66 | # Guess no on native Windows. | ||
| 67 | gl_cv_func_lstat_dereferences_slashed_symlink="guessing no" ;; | ||
| 68 | *) | ||
| 69 | # If we don't know, obey --enable-cross-guesses. | ||
| 70 | gl_cv_func_lstat_dereferences_slashed_symlink="$gl_cross_guess_normal" ;; | ||
| 71 | esac | ||
| 72 | ]) | ||
| 73 | rm -f conftest.sym conftest.file | ||
| 74 | ]) | ||
| 75 | case "$gl_cv_func_lstat_dereferences_slashed_symlink" in | ||
| 76 | *yes) | ||
| 77 | AC_DEFINE_UNQUOTED([LSTAT_FOLLOWS_SLASHED_SYMLINK], [1], | ||
| 78 | [Define to 1 if 'lstat' dereferences a symlink specified | ||
| 79 | with a trailing slash.]) | ||
| 80 | ;; | ||
| 81 | esac | ||
| 82 | ]) | ||
diff --git a/gl/m4/malloc.m4 b/gl/m4/malloc.m4 index 41a46937..547b4e4d 100644 --- a/gl/m4/malloc.m4 +++ b/gl/m4/malloc.m4 | |||
| @@ -1,12 +1,24 @@ | |||
| 1 | # malloc.m4 | 1 | # malloc.m4 |
| 2 | # serial 31 | 2 | # serial 43.1 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # This is adapted with modifications from upstream Autoconf here: | 9 | m4_version_prereq([2.73], [], [ |
| 9 | # https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n949 | 10 | # Modules that use this macro directly or indirectly should depend |
| 11 | # on extensions-aix, so that _LINUX_SOURCE_COMPAT gets defined | ||
| 12 | # before this macro gets invoked. This helps on AIX 7.2 and earlier | ||
| 13 | # if !(__VEC__ || __AIXVEC), and doesn't hurt otherwise. | ||
| 14 | # | ||
| 15 | # This is copied from upstream Autoconf here: | ||
| 16 | # https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=1f38316f6af7bf63e5e7dd187ff6456e07ad743e#n971 | ||
| 17 | # _AC_FUNC_MALLOC_IF(IF-WORKS, IF-NOT[, UNKNOWN-ASSUME]) | ||
| 18 | # ------------------------------------------------------ | ||
| 19 | # If 'malloc (0)' returns nonnull, run IF-WORKS, otherwise, IF-NOT. | ||
| 20 | # If it is not known whether it works, assume the shell word UNKNOWN-ASSUME, | ||
| 21 | # which should end in "yes" or in something else (the latter is the default). | ||
| 10 | AC_DEFUN([_AC_FUNC_MALLOC_IF], | 22 | AC_DEFUN([_AC_FUNC_MALLOC_IF], |
| 11 | [ | 23 | [ |
| 12 | AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles | 24 | AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles |
| @@ -15,56 +27,81 @@ AC_DEFUN([_AC_FUNC_MALLOC_IF], | |||
| 15 | [AC_RUN_IFELSE( | 27 | [AC_RUN_IFELSE( |
| 16 | [AC_LANG_PROGRAM( | 28 | [AC_LANG_PROGRAM( |
| 17 | [[#include <stdlib.h> | 29 | [[#include <stdlib.h> |
| 18 | ]], | 30 | /* Use pmalloc to test; 'volatile' prevents the compiler |
| 19 | [[void *p = malloc (0); | 31 | from optimizing the malloc call away. */ |
| 20 | void * volatile vp = p; | 32 | void *(*volatile pmalloc) (size_t) = malloc;]], |
| 21 | int result = !vp; | 33 | [[void *p = pmalloc (0); |
| 34 | int result = !p; | ||
| 22 | free (p); | 35 | free (p); |
| 23 | return result;]]) | 36 | return result;]])], |
| 24 | ], | ||
| 25 | [ac_cv_func_malloc_0_nonnull=yes], | 37 | [ac_cv_func_malloc_0_nonnull=yes], |
| 26 | [ac_cv_func_malloc_0_nonnull=no], | 38 | [ac_cv_func_malloc_0_nonnull=no], |
| 27 | [case "$host_os" in | 39 | [AS_CASE([$host_os], |
| 28 | # Guess yes on platforms where we know the result. | 40 | [# Guess yes on platforms where we know the result. |
| 29 | *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \ | 41 | *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \ |
| 30 | | gnu* | *-musl* | midipix* | midnightbsd* \ | 42 | | gnu* | *-musl* | midipix* | midnightbsd* \ |
| 31 | | hpux* | solaris* | cygwin* | mingw* | windows* | msys* ) | 43 | | hpux* | solaris* | cygwin* | mingw* | windows* | msys*], |
| 32 | ac_cv_func_malloc_0_nonnull="guessing yes" ;; | 44 | [ac_cv_func_malloc_0_nonnull="guessing yes"], |
| 33 | # If we don't know, obey --enable-cross-guesses. | 45 | [# Guess as follows if we don't know. |
| 34 | *) ac_cv_func_malloc_0_nonnull="$gl_cross_guess_normal" ;; | 46 | ac_cv_func_malloc_0_nonnull=m4_default([$3], ["guessing no"])])])]) |
| 35 | esac | ||
| 36 | ]) | ||
| 37 | ]) | ||
| 38 | AS_CASE([$ac_cv_func_malloc_0_nonnull], [*yes], [$1], [$2]) | 47 | AS_CASE([$ac_cv_func_malloc_0_nonnull], [*yes], [$1], [$2]) |
| 39 | ])# _AC_FUNC_MALLOC_IF | 48 | ])# _AC_FUNC_MALLOC_IF |
| 49 | ]) | ||
| 50 | |||
| 51 | # gl_FUNC_MALLOC_0_NONNULL | ||
| 52 | # ------------------------ | ||
| 53 | # If 'malloc (0)' returns nonnull define HAVE_MALLOC_0_NONNULL. | ||
| 54 | # Also, set ac_cv_func_malloc_0_nonnull to a string that ends in | ||
| 55 | # "yes", otherwise set it to something else. If unknown whether | ||
| 56 | # malloc (0) works, guess as normal for cross-builds. | ||
| 57 | AC_DEFUN([gl_FUNC_MALLOC_0_NONNULL], | ||
| 58 | [ | ||
| 59 | _AC_FUNC_MALLOC_IF( | ||
| 60 | [AC_DEFINE([HAVE_MALLOC_0_NONNULL], [1], | ||
| 61 | [Define to 1 if malloc (0) returns nonnull.])], | ||
| 62 | [], | ||
| 63 | ["$gl_cross_guess_normal"]) | ||
| 64 | ]) | ||
| 40 | 65 | ||
| 41 | # gl_FUNC_MALLOC_GNU | 66 | # gl_FUNC_MALLOC_GNU |
| 42 | # ------------------ | 67 | # ------------------ |
| 43 | # Replace malloc if it is not compatible with GNU libc. | 68 | # Test whether malloc (0) is compatible with GNU libc. |
| 69 | # Replace malloc if not. | ||
| 70 | # Define HAVE_MALLOC_0_NONNULL if malloc (0) returns nonnull (except upon | ||
| 71 | # out-of-memory). | ||
| 72 | # Define HAVE_MALLOC_PTRDIFF if malloc (N) reliably fails when N exceeds | ||
| 73 | # PTRDIFF_MAX. | ||
| 44 | AC_DEFUN([gl_FUNC_MALLOC_GNU], | 74 | AC_DEFUN([gl_FUNC_MALLOC_GNU], |
| 45 | [ | 75 | [ |
| 46 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 76 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
| 47 | AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) | 77 | AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) |
| 48 | REPLACE_MALLOC_FOR_MALLOC_GNU="$REPLACE_MALLOC_FOR_MALLOC_POSIX" | 78 | AC_REQUIRE([gl_FUNC_MALLOC_0_NONNULL]) |
| 49 | if test $REPLACE_MALLOC_FOR_MALLOC_GNU = 0; then | 79 | |
| 50 | _AC_FUNC_MALLOC_IF([], [REPLACE_MALLOC_FOR_MALLOC_GNU=1]) | 80 | AS_CASE([$ac_cv_func_malloc_0_nonnull], |
| 51 | fi | 81 | [*yes], |
| 82 | [REPLACE_MALLOC_FOR_MALLOC_GNU=$REPLACE_MALLOC_FOR_MALLOC_POSIX], | ||
| 83 | [REPLACE_MALLOC_FOR_MALLOC_GNU=1]) | ||
| 52 | ]) | 84 | ]) |
| 53 | 85 | ||
| 54 | # gl_FUNC_MALLOC_PTRDIFF | 86 | # gl_FUNC_MALLOC_PTRDIFF |
| 55 | # ---------------------- | 87 | # ---------------------- |
| 56 | # Test whether malloc (N) reliably fails when N exceeds PTRDIFF_MAX, | 88 | # Test whether malloc (N) reliably fails when N exceeds PTRDIFF_MAX. |
| 57 | # and replace malloc otherwise. | 89 | # Define HAVE_MALLOC_PTRDIFF if yes. |
| 90 | # Replace malloc if not. | ||
| 58 | AC_DEFUN([gl_FUNC_MALLOC_PTRDIFF], | 91 | AC_DEFUN([gl_FUNC_MALLOC_PTRDIFF], |
| 59 | [ | 92 | [ |
| 60 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 93 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
| 61 | AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF]) | 94 | AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF]) |
| 62 | test "$gl_cv_malloc_ptrdiff" = yes || REPLACE_MALLOC_FOR_MALLOC_POSIX=1 | 95 | AS_IF([test "$gl_cv_malloc_ptrdiff" = yes], |
| 96 | [AC_DEFINE([HAVE_MALLOC_PTRDIFF], 1, | ||
| 97 | [Define to 1 if malloc-like functions do not allocate objects | ||
| 98 | larger than PTRDIFF_MAX bytes.])], | ||
| 99 | [REPLACE_MALLOC_FOR_MALLOC_POSIX=1]) | ||
| 63 | ]) | 100 | ]) |
| 64 | 101 | ||
| 65 | # Test whether malloc, realloc, calloc refuse to create objects | 102 | # Test whether malloc, calloc refuse to create objects |
| 66 | # larger than what can be expressed in ptrdiff_t. | 103 | # larger than what can be expressed in ptrdiff_t. |
| 67 | # Set gl_cv_func_malloc_gnu to yes or no accordingly. | 104 | # Set gl_cv_func_malloc_gnu. |
| 68 | AC_DEFUN([gl_CHECK_MALLOC_PTRDIFF], | 105 | AC_DEFUN([gl_CHECK_MALLOC_PTRDIFF], |
| 69 | [ | 106 | [ |
| 70 | AC_CACHE_CHECK([whether malloc is ptrdiff_t safe], | 107 | AC_CACHE_CHECK([whether malloc is ptrdiff_t safe], |
| @@ -108,30 +145,48 @@ AC_DEFUN([gl_FUNC_MALLOC_POSIX], | |||
| 108 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 145 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
| 109 | AC_REQUIRE([gl_FUNC_MALLOC_PTRDIFF]) | 146 | AC_REQUIRE([gl_FUNC_MALLOC_PTRDIFF]) |
| 110 | AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) | 147 | AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) |
| 111 | if test "$gl_cv_func_malloc_posix" = yes; then | 148 | case "$gl_cv_func_malloc_posix" in |
| 112 | AC_DEFINE([HAVE_MALLOC_POSIX], [1], | 149 | *yes) |
| 113 | [Define if malloc, realloc, and calloc set errno on allocation failure.]) | 150 | AC_DEFINE([HAVE_MALLOC_POSIX], [1], |
| 114 | else | 151 | [Define if malloc and calloc set errno on allocation failure.]) |
| 115 | REPLACE_MALLOC_FOR_MALLOC_POSIX=1 | 152 | ;; |
| 116 | fi | 153 | *) |
| 154 | REPLACE_MALLOC_FOR_MALLOC_POSIX=1 | ||
| 155 | ;; | ||
| 156 | esac | ||
| 117 | ]) | 157 | ]) |
| 118 | 158 | ||
| 119 | # Test whether malloc, realloc, calloc set errno to ENOMEM on failure. | 159 | # Test whether malloc, calloc set errno to ENOMEM on failure. |
| 120 | # Set gl_cv_func_malloc_posix to yes or no accordingly. | 160 | # Set gl_cv_func_malloc_posix to *yes or *no accordingly. |
| 121 | AC_DEFUN([gl_CHECK_MALLOC_POSIX], | 161 | AC_DEFUN([gl_CHECK_MALLOC_POSIX], |
| 122 | [ | 162 | [ |
| 123 | AC_REQUIRE([AC_CANONICAL_HOST]) | 163 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 124 | AC_CACHE_CHECK([whether malloc, realloc, calloc set errno on failure], | 164 | AC_CACHE_CHECK([whether malloc, calloc set errno on failure], |
| 125 | [gl_cv_func_malloc_posix], | 165 | [gl_cv_func_malloc_posix], |
| 126 | [ | 166 | [ |
| 127 | dnl It is too dangerous to try to allocate a large amount of memory: | 167 | dnl It is too dangerous to try to allocate a large amount of memory: |
| 128 | dnl some systems go to their knees when you do that. So assume that | 168 | dnl some systems go to their knees when you do that. So assume that |
| 129 | dnl all Unix implementations of the function set errno on failure, | 169 | dnl all Unix implementations of the function set errno on failure, |
| 130 | dnl except on those platforms where we have seen 'test-malloc-gnu', | 170 | dnl except on those platforms where we have seen 'test-malloc-gnu', |
| 131 | dnl 'test-realloc-gnu', 'test-calloc-gnu' fail. | 171 | dnl 'test-realloc-posix', 'test-calloc-gnu' fail. For platforms |
| 172 | dnl where only 'test-realloc-posix', see realloc.m4. | ||
| 132 | case "$host_os" in | 173 | case "$host_os" in |
| 133 | mingw* | windows*) | 174 | mingw* | windows*) |
| 134 | gl_cv_func_malloc_posix=no ;; | 175 | dnl Old MSVCRT from 2001 did not set errno=ENOMEM when malloc failed. |
| 176 | dnl More recent MSVCRT from 2019 does so. | ||
| 177 | dnl UCRT is the successor of MSVCRT. Assume that UCRT does so as well. | ||
| 178 | AC_COMPILE_IFELSE( | ||
| 179 | [AC_LANG_PROGRAM( | ||
| 180 | [[#include <stdio.h> | ||
| 181 | #ifndef _UCRT | ||
| 182 | msvcrt yuck | ||
| 183 | #endif | ||
| 184 | ]], | ||
| 185 | [[]]) | ||
| 186 | ], | ||
| 187 | [gl_cv_func_malloc_posix="guessing yes"], | ||
| 188 | [gl_cv_func_malloc_posix="guessing no"]) | ||
| 189 | ;; | ||
| 135 | irix* | solaris*) | 190 | irix* | solaris*) |
| 136 | dnl On IRIX 6.5, the three functions return NULL with errno unset | 191 | dnl On IRIX 6.5, the three functions return NULL with errno unset |
| 137 | dnl when the argument is larger than PTRDIFF_MAX. | 192 | dnl when the argument is larger than PTRDIFF_MAX. |
diff --git a/gl/m4/malloca.m4 b/gl/m4/malloca.m4 index 9e09d22c..cabe5fe7 100644 --- a/gl/m4/malloca.m4 +++ b/gl/m4/malloca.m4 | |||
| @@ -1,15 +1,16 @@ | |||
| 1 | # malloca.m4 | 1 | # malloca.m4 |
| 2 | # serial 2 | 2 | # serial 3 |
| 3 | dnl Copyright (C) 2003-2004, 2006-2007, 2009-2024 Free Software Foundation, | 3 | dnl Copyright (C) 2003-2004, 2006-2007, 2009-2025 Free Software Foundation, |
| 4 | dnl Inc. | 4 | dnl Inc. |
| 5 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 6 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 7 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 8 | 9 | ||
| 9 | AC_DEFUN([gl_MALLOCA], | 10 | AC_DEFUN([gl_MALLOCA], |
| 10 | [ | 11 | [ |
| 11 | dnl Use the autoconf tests for alloca(), but not the AC_SUBSTed variables | 12 | dnl Use the autoconf tests for alloca(), but not the AC_SUBSTed variables |
| 12 | dnl @ALLOCA@ and @LTALLOCA@. | 13 | dnl @ALLOCA@ and @LTALLOCA@. |
| 13 | dnl gl_FUNC_ALLOCA dnl Already brought in by the module dependencies. | 14 | dnl gl_FUNC_ALLOCA dnl Already brought in by the module dependencies. |
| 14 | AC_REQUIRE([gl_EEMALLOC]) | 15 | AC_REQUIRE([gl_FUNC_MALLOC_GNU]) |
| 15 | ]) | 16 | ]) |
diff --git a/gl/m4/math_h.m4 b/gl/m4/math_h.m4 index 4b26c9e9..8c27503b 100644 --- a/gl/m4/math_h.m4 +++ b/gl/m4/math_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # math_h.m4 | 1 | # math_h.m4 |
| 2 | # serial 138 | 2 | # serial 140.1 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_MATH_H], | 9 | AC_DEFUN_ONCE([gl_MATH_H], |
| 9 | [ | 10 | [ |
| @@ -49,7 +50,7 @@ AC_DEFUN_ONCE([gl_MATH_H], | |||
| 49 | ilogb ilogbf ilogbl | 50 | ilogb ilogbf ilogbl |
| 50 | ldexpf ldexpl | 51 | ldexpf ldexpl |
| 51 | log logf logl log10 log10f log10l log1p log1pf log1pl log2 log2f log2l | 52 | log logf logl log10 log10f log10l log1p log1pf log1pl log2 log2f log2l |
| 52 | logb logbf logbl | 53 | logb logbf logbl logp1 log1pf logp1l |
| 53 | modf modff modfl powf | 54 | modf modff modfl powf |
| 54 | remainder remainderf remainderl | 55 | remainder remainderf remainderl |
| 55 | rint rintf rintl round roundf roundl | 56 | rint rintf rintl round roundf roundl |
| @@ -153,6 +154,9 @@ AC_DEFUN([gl_MATH_H_REQUIRE_DEFAULTS], | |||
| 153 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGB]) | 154 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGB]) |
| 154 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGBF]) | 155 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGBF]) |
| 155 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGBL]) | 156 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGBL]) |
| 157 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGP1]) | ||
| 158 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGP1F]) | ||
| 159 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LOGP1L]) | ||
| 156 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MODF]) | 160 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MODF]) |
| 157 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MODFF]) | 161 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MODFF]) |
| 158 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MODFL]) | 162 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MODFL]) |
| @@ -253,6 +257,9 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], | |||
| 253 | HAVE_LOG1PL=1; AC_SUBST([HAVE_LOG1PL]) | 257 | HAVE_LOG1PL=1; AC_SUBST([HAVE_LOG1PL]) |
| 254 | HAVE_LOGBF=1; AC_SUBST([HAVE_LOGBF]) | 258 | HAVE_LOGBF=1; AC_SUBST([HAVE_LOGBF]) |
| 255 | HAVE_LOGBL=1; AC_SUBST([HAVE_LOGBL]) | 259 | HAVE_LOGBL=1; AC_SUBST([HAVE_LOGBL]) |
| 260 | HAVE_LOGP1=1; AC_SUBST([HAVE_LOGP1]) | ||
| 261 | HAVE_LOGP1F=1; AC_SUBST([HAVE_LOGP1F]) | ||
| 262 | HAVE_LOGP1L=1; AC_SUBST([HAVE_LOGP1L]) | ||
| 256 | HAVE_MODFF=1; AC_SUBST([HAVE_MODFF]) | 263 | HAVE_MODFF=1; AC_SUBST([HAVE_MODFF]) |
| 257 | HAVE_MODFL=1; AC_SUBST([HAVE_MODFL]) | 264 | HAVE_MODFL=1; AC_SUBST([HAVE_MODFL]) |
| 258 | HAVE_POWF=1; AC_SUBST([HAVE_POWF]) | 265 | HAVE_POWF=1; AC_SUBST([HAVE_POWF]) |
| @@ -392,6 +399,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], | |||
| 392 | REPLACE_SIGNBIT_USING_BUILTINS=0; AC_SUBST([REPLACE_SIGNBIT_USING_BUILTINS]) | 399 | REPLACE_SIGNBIT_USING_BUILTINS=0; AC_SUBST([REPLACE_SIGNBIT_USING_BUILTINS]) |
| 393 | REPLACE_SINF=0; AC_SUBST([REPLACE_SINF]) | 400 | REPLACE_SINF=0; AC_SUBST([REPLACE_SINF]) |
| 394 | REPLACE_SINHF=0; AC_SUBST([REPLACE_SINHF]) | 401 | REPLACE_SINHF=0; AC_SUBST([REPLACE_SINHF]) |
| 402 | REPLACE_SINL=0; AC_SUBST([REPLACE_SINL]) | ||
| 395 | REPLACE_SQRTF=0; AC_SUBST([REPLACE_SQRTF]) | 403 | REPLACE_SQRTF=0; AC_SUBST([REPLACE_SQRTF]) |
| 396 | REPLACE_SQRTL=0; AC_SUBST([REPLACE_SQRTL]) | 404 | REPLACE_SQRTL=0; AC_SUBST([REPLACE_SQRTL]) |
| 397 | REPLACE_TANF=0; AC_SUBST([REPLACE_TANF]) | 405 | REPLACE_TANF=0; AC_SUBST([REPLACE_TANF]) |
diff --git a/gl/m4/mbchar.m4 b/gl/m4/mbchar.m4 new file mode 100644 index 00000000..b76f1d7b --- /dev/null +++ b/gl/m4/mbchar.m4 | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | # mbchar.m4 | ||
| 2 | # serial 9 | ||
| 3 | dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl autoconf tests required for use of mbchar.m4 | ||
| 10 | dnl From Bruno Haible. | ||
| 11 | |||
| 12 | AC_DEFUN([gl_MBCHAR], | ||
| 13 | [ | ||
| 14 | AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) | ||
| 15 | ]) | ||
diff --git a/gl/m4/mbiter.m4 b/gl/m4/mbiter.m4 new file mode 100644 index 00000000..b51242e6 --- /dev/null +++ b/gl/m4/mbiter.m4 | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | # mbiter.m4 | ||
| 2 | # serial 7 | ||
| 3 | dnl Copyright (C) 2005, 2008-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl autoconf tests required for use of mbiter.h | ||
| 10 | dnl From Bruno Haible. | ||
| 11 | |||
| 12 | AC_DEFUN([gl_MBITER], | ||
| 13 | [ | ||
| 14 | AC_REQUIRE([AC_TYPE_MBSTATE_T]) | ||
| 15 | : | ||
| 16 | ]) | ||
diff --git a/gl/m4/mbrtoc32.m4 b/gl/m4/mbrtoc32.m4 new file mode 100644 index 00000000..1991529c --- /dev/null +++ b/gl/m4/mbrtoc32.m4 | |||
| @@ -0,0 +1,326 @@ | |||
| 1 | # mbrtoc32.m4 | ||
| 2 | # serial 21 | ||
| 3 | dnl Copyright (C) 2014-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN([gl_FUNC_MBRTOC32], | ||
| 10 | [ | ||
| 11 | AC_REQUIRE([gl_UCHAR_H_DEFAULTS]) | ||
| 12 | |||
| 13 | AC_REQUIRE([AC_TYPE_MBSTATE_T]) | ||
| 14 | dnl Determine REPLACE_MBSTATE_T, from which GNULIB_defined_mbstate_t is | ||
| 15 | dnl determined. It describes how our overridden mbrtowc is implemented. | ||
| 16 | dnl We then implement mbrtoc32 accordingly. | ||
| 17 | AC_REQUIRE([gl_MBSTATE_T_BROKEN]) | ||
| 18 | |||
| 19 | AC_REQUIRE([gl_TYPE_CHAR32_T]) | ||
| 20 | AC_REQUIRE([gl_MBRTOC32_SANITYCHECK]) | ||
| 21 | |||
| 22 | AC_REQUIRE([gl_CHECK_FUNC_MBRTOC32]) | ||
| 23 | if test $gl_cv_func_mbrtoc32 = no; then | ||
| 24 | HAVE_MBRTOC32=0 | ||
| 25 | else | ||
| 26 | if test $GNULIBHEADERS_OVERRIDE_CHAR32_T = 1 || test $REPLACE_MBSTATE_T = 1; then | ||
| 27 | REPLACE_MBRTOC32=1 | ||
| 28 | else | ||
| 29 | gl_MBRTOC32_EMPTY_INPUT | ||
| 30 | gl_MBRTOC32_C_LOCALE | ||
| 31 | gl_MBRTOC32_UTF8_LOCALE | ||
| 32 | case "$gl_cv_func_mbrtoc32_empty_input" in | ||
| 33 | *yes) ;; | ||
| 34 | *) AC_DEFINE([MBRTOC32_EMPTY_INPUT_BUG], [1], | ||
| 35 | [Define if the mbrtoc32 function does not return (size_t) -2 for empty input.]) | ||
| 36 | REPLACE_MBRTOC32=1 | ||
| 37 | ;; | ||
| 38 | esac | ||
| 39 | case "$gl_cv_func_mbrtoc32_C_locale_sans_EILSEQ" in | ||
| 40 | *yes) ;; | ||
| 41 | *) AC_DEFINE([MBRTOC32_IN_C_LOCALE_MAYBE_EILSEQ], [1], | ||
| 42 | [Define if the mbrtoc32 function may signal encoding errors in the C locale.]) | ||
| 43 | REPLACE_MBRTOC32=1 | ||
| 44 | ;; | ||
| 45 | esac | ||
| 46 | case "$gl_cv_func_mbrtoc32_utf8_locale_works" in | ||
| 47 | *yes) ;; | ||
| 48 | *) AC_DEFINE([MBRTOC32_MULTIBYTE_LOCALE_BUG], [1], | ||
| 49 | [Define if the mbrtoc32 function does not accept the input bytes one-by-one.]) | ||
| 50 | REPLACE_MBRTOC32=1 | ||
| 51 | dnl Our replacement mbrtoc32 can handle UTF-8, but not GB18030. | ||
| 52 | LOCALE_ZH_CN=none | ||
| 53 | ;; | ||
| 54 | esac | ||
| 55 | fi | ||
| 56 | if test $HAVE_WORKING_MBRTOC32 = 0; then | ||
| 57 | REPLACE_MBRTOC32=1 | ||
| 58 | fi | ||
| 59 | fi | ||
| 60 | ]) | ||
| 61 | |||
| 62 | AC_DEFUN([gl_CHECK_FUNC_MBRTOC32], | ||
| 63 | [ | ||
| 64 | dnl Cf. gl_CHECK_FUNCS_ANDROID | ||
| 65 | AC_CHECK_DECL([mbrtoc32], , , | ||
| 66 | [[#ifdef __HAIKU__ | ||
| 67 | #include <stdint.h> | ||
| 68 | #endif | ||
| 69 | #include <uchar.h> | ||
| 70 | ]]) | ||
| 71 | if test $ac_cv_have_decl_mbrtoc32 = yes; then | ||
| 72 | dnl We can't use AC_CHECK_FUNC here, because mbrtoc32() is defined as a | ||
| 73 | dnl static inline function on Haiku 2020. | ||
| 74 | AC_CACHE_CHECK([for mbrtoc32], [gl_cv_func_mbrtoc32], | ||
| 75 | [AC_LINK_IFELSE( | ||
| 76 | [AC_LANG_PROGRAM( | ||
| 77 | [[#include <stdlib.h> | ||
| 78 | #ifdef __HAIKU__ | ||
| 79 | #include <stdint.h> | ||
| 80 | #endif | ||
| 81 | #include <uchar.h> | ||
| 82 | ]], | ||
| 83 | [[char32_t c; | ||
| 84 | return mbrtoc32 (&c, "", 1, NULL) == 0; | ||
| 85 | ]]) | ||
| 86 | ], | ||
| 87 | [gl_cv_func_mbrtoc32=yes], | ||
| 88 | [gl_cv_func_mbrtoc32=no]) | ||
| 89 | ]) | ||
| 90 | else | ||
| 91 | gl_cv_func_mbrtoc32=no | ||
| 92 | fi | ||
| 93 | ]) | ||
| 94 | |||
| 95 | dnl Test whether mbrtoc32 returns the correct value on empty input. | ||
| 96 | |||
| 97 | AC_DEFUN([gl_MBRTOC32_EMPTY_INPUT], | ||
| 98 | [ | ||
| 99 | AC_REQUIRE([AC_PROG_CC]) | ||
| 100 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 101 | AC_CACHE_CHECK([whether mbrtoc32 works on empty input], | ||
| 102 | [gl_cv_func_mbrtoc32_empty_input], | ||
| 103 | [ | ||
| 104 | AC_RUN_IFELSE( | ||
| 105 | [AC_LANG_SOURCE([[ | ||
| 106 | #ifdef __HAIKU__ | ||
| 107 | #include <stdint.h> | ||
| 108 | #endif | ||
| 109 | #include <uchar.h> | ||
| 110 | static char32_t wc; | ||
| 111 | static mbstate_t mbs; | ||
| 112 | int | ||
| 113 | main (void) | ||
| 114 | { | ||
| 115 | return mbrtoc32 (&wc, "", 0, &mbs) != (size_t) -2; | ||
| 116 | }]])], | ||
| 117 | [gl_cv_func_mbrtoc32_empty_input=yes], | ||
| 118 | [gl_cv_func_mbrtoc32_empty_input=no], | ||
| 119 | [case "$host_os" in | ||
| 120 | # Guess no on glibc systems. | ||
| 121 | *-gnu* | gnu*) gl_cv_func_mbrtoc32_empty_input="guessing no" ;; | ||
| 122 | # Guess no on Android. | ||
| 123 | linux*-android*) gl_cv_func_mbrtoc32_empty_input="guessing no" ;; | ||
| 124 | # Guess no on native Windows. | ||
| 125 | mingw* | windows*) gl_cv_func_mbrtoc32_empty_input="guessing no" ;; | ||
| 126 | *) gl_cv_func_mbrtoc32_empty_input="guessing yes" ;; | ||
| 127 | esac | ||
| 128 | ]) | ||
| 129 | ]) | ||
| 130 | ]) | ||
| 131 | |||
| 132 | dnl <https://pubs.opengroup.org/onlinepubs/9699919799/functions/mbrtowc.html> | ||
| 133 | dnl POSIX:2018 says regarding mbrtowc: "In the POSIX locale an [EILSEQ] error | ||
| 134 | dnl cannot occur since all byte values are valid characters." It is reasonable | ||
| 135 | dnl to expect mbrtoc32 to behave in the same way. | ||
| 136 | |||
| 137 | AC_DEFUN([gl_MBRTOC32_C_LOCALE], | ||
| 138 | [ | ||
| 139 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 140 | AC_CACHE_CHECK([whether the C locale is free of encoding errors], | ||
| 141 | [gl_cv_func_mbrtoc32_C_locale_sans_EILSEQ], | ||
| 142 | [AC_RUN_IFELSE( | ||
| 143 | [AC_LANG_PROGRAM( | ||
| 144 | [[#include <limits.h> | ||
| 145 | #include <locale.h> | ||
| 146 | #ifdef __HAIKU__ | ||
| 147 | #include <stdint.h> | ||
| 148 | #endif | ||
| 149 | #include <uchar.h> | ||
| 150 | ]], [[ | ||
| 151 | int i; | ||
| 152 | char *locale = setlocale (LC_ALL, "C"); | ||
| 153 | if (! locale) | ||
| 154 | return 2; | ||
| 155 | for (i = CHAR_MIN; i <= CHAR_MAX; i++) | ||
| 156 | { | ||
| 157 | char c = i; | ||
| 158 | char32_t wc; | ||
| 159 | mbstate_t mbs = { 0, }; | ||
| 160 | size_t ss = mbrtoc32 (&wc, &c, 1, &mbs); | ||
| 161 | if (1 < ss) | ||
| 162 | return 3; | ||
| 163 | } | ||
| 164 | return 0; | ||
| 165 | ]])], | ||
| 166 | [gl_cv_func_mbrtoc32_C_locale_sans_EILSEQ=yes], | ||
| 167 | [gl_cv_func_mbrtoc32_C_locale_sans_EILSEQ=no], | ||
| 168 | [case "$host_os" in | ||
| 169 | # Guess yes on native Windows. | ||
| 170 | mingw* | windows*) gl_cv_func_mbrtoc32_C_locale_sans_EILSEQ="guessing yes" ;; | ||
| 171 | *) gl_cv_func_mbrtoc32_C_locale_sans_EILSEQ="$gl_cross_guess_normal" ;; | ||
| 172 | esac | ||
| 173 | ]) | ||
| 174 | ]) | ||
| 175 | ]) | ||
| 176 | |||
| 177 | dnl Test whether mbrtoc32 works when it's fed the bytes one-by-one in an UTF-8 | ||
| 178 | dnl locale. | ||
| 179 | |||
| 180 | AC_DEFUN([gl_MBRTOC32_UTF8_LOCALE], | ||
| 181 | [ | ||
| 182 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 183 | AC_CACHE_CHECK([whether mbrtoc32 works in an UTF-8 locale], | ||
| 184 | [gl_cv_func_mbrtoc32_utf8_locale_works], | ||
| 185 | [AC_RUN_IFELSE( | ||
| 186 | [AC_LANG_PROGRAM( | ||
| 187 | [[#include <locale.h> | ||
| 188 | #ifdef __HAIKU__ | ||
| 189 | #include <stdint.h> | ||
| 190 | #endif | ||
| 191 | #include <uchar.h> | ||
| 192 | ]], [[ | ||
| 193 | char *locale = setlocale (LC_ALL, "en_US.UTF-8"); | ||
| 194 | if (locale) | ||
| 195 | { | ||
| 196 | /* This test fails on Cygwin 3.5.3. */ | ||
| 197 | mbstate_t state = { 0, }; | ||
| 198 | char32_t uc = 0xDEADBEEF; | ||
| 199 | /* \360\237\220\203 = U+0001F403 */ | ||
| 200 | if (mbrtoc32 (&uc, "\360", 1, &state) != (size_t)-2) | ||
| 201 | return 1; | ||
| 202 | if (mbrtoc32 (&uc, "\237", 1, &state) != (size_t)-2) | ||
| 203 | return 2; | ||
| 204 | if (mbrtoc32 (&uc, "\220", 1, &state) != (size_t)-2) | ||
| 205 | return 3; | ||
| 206 | if (mbrtoc32 (&uc, "\203", 1, &state) != 1) | ||
| 207 | return 4; | ||
| 208 | if (uc != 0x0001F403) | ||
| 209 | return 5; | ||
| 210 | } | ||
| 211 | return 0; | ||
| 212 | ]])], | ||
| 213 | [gl_cv_func_mbrtoc32_utf8_locale_works=yes], | ||
| 214 | [gl_cv_func_mbrtoc32_utf8_locale_works=no], | ||
| 215 | [case "$host_os" in | ||
| 216 | # Guess no on Cygwin. | ||
| 217 | cygwin*) gl_cv_func_mbrtoc32_utf8_locale_works="guessing no" ;; | ||
| 218 | *) gl_cv_func_mbrtoc32_utf8_locale_works="$gl_cross_guess_normal" ;; | ||
| 219 | esac | ||
| 220 | ]) | ||
| 221 | ]) | ||
| 222 | ]) | ||
| 223 | |||
| 224 | dnl Test whether mbrtoc32 works not worse than mbrtowc. | ||
| 225 | dnl Result is HAVE_WORKING_MBRTOC32. | ||
| 226 | |||
| 227 | AC_DEFUN([gl_MBRTOC32_SANITYCHECK], | ||
| 228 | [ | ||
| 229 | AC_REQUIRE([AC_PROG_CC]) | ||
| 230 | AC_REQUIRE([gl_TYPE_CHAR32_T]) | ||
| 231 | AC_REQUIRE([gl_CHECK_FUNC_MBRTOC32]) | ||
| 232 | AC_REQUIRE([gt_LOCALE_FR]) | ||
| 233 | AC_REQUIRE([gt_LOCALE_ZH_CN]) | ||
| 234 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 235 | if test $GNULIBHEADERS_OVERRIDE_CHAR32_T = 1 || test $gl_cv_func_mbrtoc32 = no; then | ||
| 236 | HAVE_WORKING_MBRTOC32=0 | ||
| 237 | else | ||
| 238 | AC_CACHE_CHECK([whether mbrtoc32 works as well as mbrtowc], | ||
| 239 | [gl_cv_func_mbrtoc32_sanitycheck], | ||
| 240 | [ | ||
| 241 | dnl Initial guess, used when cross-compiling or when no suitable locale | ||
| 242 | dnl is present. | ||
| 243 | changequote(,)dnl | ||
| 244 | case "$host_os" in | ||
| 245 | # Guess no on FreeBSD, Solaris, native Windows. | ||
| 246 | freebsd* | midnightbsd* | solaris* | mingw* | windows*) | ||
| 247 | gl_cv_func_mbrtoc32_sanitycheck="guessing no" | ||
| 248 | ;; | ||
| 249 | # Guess yes otherwise. | ||
| 250 | *) | ||
| 251 | gl_cv_func_mbrtoc32_sanitycheck="guessing yes" | ||
| 252 | ;; | ||
| 253 | esac | ||
| 254 | changequote([,])dnl | ||
| 255 | if test $LOCALE_FR != none || test $LOCALE_ZH_CN != none; then | ||
| 256 | AC_RUN_IFELSE( | ||
| 257 | [AC_LANG_SOURCE([[ | ||
| 258 | #include <locale.h> | ||
| 259 | #include <stdlib.h> | ||
| 260 | #include <string.h> | ||
| 261 | #include <wchar.h> | ||
| 262 | #ifdef __HAIKU__ | ||
| 263 | #include <stdint.h> | ||
| 264 | #endif | ||
| 265 | #include <uchar.h> | ||
| 266 | int main () | ||
| 267 | { | ||
| 268 | int result = 0; | ||
| 269 | /* This fails on native Windows: | ||
| 270 | mbrtoc32 returns (size_t)-1. | ||
| 271 | mbrtowc returns 1 (correct). */ | ||
| 272 | if (strcmp ("$LOCALE_FR", "none") != 0 | ||
| 273 | && setlocale (LC_ALL, "$LOCALE_FR") != NULL) | ||
| 274 | { | ||
| 275 | mbstate_t state; | ||
| 276 | wchar_t wc = (wchar_t) 0xBADFACE; | ||
| 277 | memset (&state, '\0', sizeof (mbstate_t)); | ||
| 278 | if (mbrtowc (&wc, "\374", 1, &state) == 1) | ||
| 279 | { | ||
| 280 | char32_t c32 = (wchar_t) 0xBADFACE; | ||
| 281 | memset (&state, '\0', sizeof (mbstate_t)); | ||
| 282 | if (mbrtoc32 (&c32, "\374", 1, &state) != 1) | ||
| 283 | result |= 1; | ||
| 284 | } | ||
| 285 | } | ||
| 286 | /* This fails on FreeBSD 13.0 and Solaris 11.4: | ||
| 287 | mbrtoc32 returns (size_t)-2 or (size_t)-1. | ||
| 288 | mbrtowc returns 4 (correct). */ | ||
| 289 | if (strcmp ("$LOCALE_ZH_CN", "none") != 0 | ||
| 290 | && setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) | ||
| 291 | { | ||
| 292 | mbstate_t state; | ||
| 293 | wchar_t wc = (wchar_t) 0xBADFACE; | ||
| 294 | memset (&state, '\0', sizeof (mbstate_t)); | ||
| 295 | if (mbrtowc (&wc, "\224\071\375\067", 4, &state) == 4) | ||
| 296 | { | ||
| 297 | char32_t c32 = (wchar_t) 0xBADFACE; | ||
| 298 | memset (&state, '\0', sizeof (mbstate_t)); | ||
| 299 | if (mbrtoc32 (&c32, "\224\071\375\067", 4, &state) != 4) | ||
| 300 | result |= 2; | ||
| 301 | } | ||
| 302 | } | ||
| 303 | return result; | ||
| 304 | }]])], | ||
| 305 | [gl_cv_func_mbrtoc32_sanitycheck=yes], | ||
| 306 | [gl_cv_func_mbrtoc32_sanitycheck=no], | ||
| 307 | [:]) | ||
| 308 | fi | ||
| 309 | ]) | ||
| 310 | case "$gl_cv_func_mbrtoc32_sanitycheck" in | ||
| 311 | *yes) | ||
| 312 | HAVE_WORKING_MBRTOC32=1 | ||
| 313 | AC_DEFINE([HAVE_WORKING_MBRTOC32], [1], | ||
| 314 | [Define if the mbrtoc32 function basically works.]) | ||
| 315 | ;; | ||
| 316 | *) HAVE_WORKING_MBRTOC32=0 ;; | ||
| 317 | esac | ||
| 318 | fi | ||
| 319 | AC_SUBST([HAVE_WORKING_MBRTOC32]) | ||
| 320 | ]) | ||
| 321 | |||
| 322 | # Prerequisites of lib/mbrtoc32.c and lib/lc-charset-dispatch.c. | ||
| 323 | AC_DEFUN([gl_PREREQ_MBRTOC32], [ | ||
| 324 | AC_REQUIRE([gl_C32RTOMB_SANITYCHECK]) | ||
| 325 | : | ||
| 326 | ]) | ||
diff --git a/gl/m4/mbrtowc.m4 b/gl/m4/mbrtowc.m4 index 62c4fdb3..cc09a5fb 100644 --- a/gl/m4/mbrtowc.m4 +++ b/gl/m4/mbrtowc.m4 | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | # mbrtowc.m4 | 1 | # mbrtowc.m4 |
| 2 | # serial 44 -*- coding: utf-8 -*- | 2 | # serial 46 |
| 3 | dnl Copyright (C) 2001-2002, 2004-2005, 2008-2024 Free Software Foundation, | 3 | dnl Copyright (C) 2001-2002, 2004-2005, 2008-2025 Free Software Foundation, |
| 4 | dnl Inc. | 4 | dnl Inc. |
| 5 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 6 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 7 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 8 | 9 | ||
| 9 | AC_DEFUN([gl_FUNC_MBRTOWC], | 10 | AC_DEFUN([gl_FUNC_MBRTOWC], |
| 10 | [ | 11 | [ |
| @@ -160,7 +161,7 @@ AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE], | |||
| 160 | [ | 161 | [ |
| 161 | AC_REQUIRE([AC_PROG_CC]) | 162 | AC_REQUIRE([AC_PROG_CC]) |
| 162 | AC_REQUIRE([gt_LOCALE_JA]) | 163 | AC_REQUIRE([gt_LOCALE_JA]) |
| 163 | AC_REQUIRE([gt_LOCALE_FR_UTF8]) | 164 | AC_REQUIRE([gt_LOCALE_EN_UTF8]) |
| 164 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | 165 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles |
| 165 | AC_CACHE_CHECK([whether mbrtowc handles incomplete characters], | 166 | AC_CACHE_CHECK([whether mbrtowc handles incomplete characters], |
| 166 | [gl_cv_func_mbrtowc_incomplete_state], | 167 | [gl_cv_func_mbrtowc_incomplete_state], |
| @@ -200,7 +201,7 @@ int main () | |||
| 200 | [gl_cv_func_mbrtowc_incomplete_state=no], | 201 | [gl_cv_func_mbrtowc_incomplete_state=no], |
| 201 | [:]) | 202 | [:]) |
| 202 | else | 203 | else |
| 203 | if test $LOCALE_FR_UTF8 != none; then | 204 | if test "$LOCALE_EN_UTF8" != none; then |
| 204 | AC_RUN_IFELSE( | 205 | AC_RUN_IFELSE( |
| 205 | [AC_LANG_SOURCE([[ | 206 | [AC_LANG_SOURCE([[ |
| 206 | #include <locale.h> | 207 | #include <locale.h> |
| @@ -208,7 +209,7 @@ int main () | |||
| 208 | #include <wchar.h> | 209 | #include <wchar.h> |
| 209 | int main () | 210 | int main () |
| 210 | { | 211 | { |
| 211 | if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) | 212 | if (setlocale (LC_ALL, "$LOCALE_EN_UTF8") != NULL) |
| 212 | { | 213 | { |
| 213 | const char input[] = "B\303\274\303\237er"; /* "Büßer" */ | 214 | const char input[] = "B\303\274\303\237er"; /* "Büßer" */ |
| 214 | mbstate_t state; | 215 | mbstate_t state; |
| @@ -288,7 +289,7 @@ dnl Result is gl_cv_func_mbrtowc_null_arg1. | |||
| 288 | AC_DEFUN([gl_MBRTOWC_NULL_ARG1], | 289 | AC_DEFUN([gl_MBRTOWC_NULL_ARG1], |
| 289 | [ | 290 | [ |
| 290 | AC_REQUIRE([AC_PROG_CC]) | 291 | AC_REQUIRE([AC_PROG_CC]) |
| 291 | AC_REQUIRE([gt_LOCALE_FR_UTF8]) | 292 | AC_REQUIRE([gt_LOCALE_EN_UTF8]) |
| 292 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | 293 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles |
| 293 | AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument], | 294 | AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument], |
| 294 | [gl_cv_func_mbrtowc_null_arg1], | 295 | [gl_cv_func_mbrtowc_null_arg1], |
| @@ -303,7 +304,7 @@ changequote(,)dnl | |||
| 303 | *) gl_cv_func_mbrtowc_null_arg1="guessing yes" ;; | 304 | *) gl_cv_func_mbrtowc_null_arg1="guessing yes" ;; |
| 304 | esac | 305 | esac |
| 305 | changequote([,])dnl | 306 | changequote([,])dnl |
| 306 | if test $LOCALE_FR_UTF8 != none; then | 307 | if test "$LOCALE_EN_UTF8" != none; then |
| 307 | AC_RUN_IFELSE( | 308 | AC_RUN_IFELSE( |
| 308 | [AC_LANG_SOURCE([[ | 309 | [AC_LANG_SOURCE([[ |
| 309 | #include <locale.h> | 310 | #include <locale.h> |
| @@ -314,7 +315,7 @@ int main () | |||
| 314 | { | 315 | { |
| 315 | int result = 0; | 316 | int result = 0; |
| 316 | 317 | ||
| 317 | if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) | 318 | if (setlocale (LC_ALL, "$LOCALE_EN_UTF8") != NULL) |
| 318 | { | 319 | { |
| 319 | char input[] = "\303\237er"; | 320 | char input[] = "\303\237er"; |
| 320 | mbstate_t state; | 321 | mbstate_t state; |
| @@ -351,7 +352,7 @@ dnl Result is gl_cv_func_mbrtowc_null_arg2. | |||
| 351 | AC_DEFUN([gl_MBRTOWC_NULL_ARG2], | 352 | AC_DEFUN([gl_MBRTOWC_NULL_ARG2], |
| 352 | [ | 353 | [ |
| 353 | AC_REQUIRE([AC_PROG_CC]) | 354 | AC_REQUIRE([AC_PROG_CC]) |
| 354 | AC_REQUIRE([gt_LOCALE_FR_UTF8]) | 355 | AC_REQUIRE([gt_LOCALE_EN_UTF8]) |
| 355 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | 356 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles |
| 356 | AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument], | 357 | AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument], |
| 357 | [gl_cv_func_mbrtowc_null_arg2], | 358 | [gl_cv_func_mbrtowc_null_arg2], |
| @@ -366,7 +367,7 @@ changequote(,)dnl | |||
| 366 | *) gl_cv_func_mbrtowc_null_arg2="guessing yes" ;; | 367 | *) gl_cv_func_mbrtowc_null_arg2="guessing yes" ;; |
| 367 | esac | 368 | esac |
| 368 | changequote([,])dnl | 369 | changequote([,])dnl |
| 369 | if test $LOCALE_FR_UTF8 != none; then | 370 | if test "$LOCALE_EN_UTF8" != none; then |
| 370 | AC_RUN_IFELSE( | 371 | AC_RUN_IFELSE( |
| 371 | [AC_LANG_SOURCE([[ | 372 | [AC_LANG_SOURCE([[ |
| 372 | #include <locale.h> | 373 | #include <locale.h> |
| @@ -374,7 +375,7 @@ changequote([,])dnl | |||
| 374 | #include <wchar.h> | 375 | #include <wchar.h> |
| 375 | int main () | 376 | int main () |
| 376 | { | 377 | { |
| 377 | if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) | 378 | if (setlocale (LC_ALL, "$LOCALE_EN_UTF8") != NULL) |
| 378 | { | 379 | { |
| 379 | mbstate_t state; | 380 | mbstate_t state; |
| 380 | wchar_t wc; | 381 | wchar_t wc; |
| @@ -404,7 +405,7 @@ dnl Result is gl_cv_func_mbrtowc_retval. | |||
| 404 | AC_DEFUN([gl_MBRTOWC_RETVAL], | 405 | AC_DEFUN([gl_MBRTOWC_RETVAL], |
| 405 | [ | 406 | [ |
| 406 | AC_REQUIRE([AC_PROG_CC]) | 407 | AC_REQUIRE([AC_PROG_CC]) |
| 407 | AC_REQUIRE([gt_LOCALE_FR_UTF8]) | 408 | AC_REQUIRE([gt_LOCALE_EN_UTF8]) |
| 408 | AC_REQUIRE([gt_LOCALE_JA]) | 409 | AC_REQUIRE([gt_LOCALE_JA]) |
| 409 | AC_REQUIRE([AC_CANONICAL_HOST]) | 410 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 410 | AC_CACHE_CHECK([whether mbrtowc has a correct return value], | 411 | AC_CACHE_CHECK([whether mbrtowc has a correct return value], |
| @@ -422,7 +423,7 @@ changequote(,)dnl | |||
| 422 | gl_cv_func_mbrtowc_retval="guessing yes" ;; | 423 | gl_cv_func_mbrtowc_retval="guessing yes" ;; |
| 423 | esac | 424 | esac |
| 424 | changequote([,])dnl | 425 | changequote([,])dnl |
| 425 | if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none \ | 426 | if test "$LOCALE_EN_UTF8" != none || test $LOCALE_JA != none \ |
| 426 | || { case "$host_os" in mingw* | windows*) true;; *) false;; esac; }; then | 427 | || { case "$host_os" in mingw* | windows*) true;; *) false;; esac; }; then |
| 427 | AC_RUN_IFELSE( | 428 | AC_RUN_IFELSE( |
| 428 | [AC_LANG_SOURCE([[ | 429 | [AC_LANG_SOURCE([[ |
| @@ -434,8 +435,8 @@ int main () | |||
| 434 | int result = 0; | 435 | int result = 0; |
| 435 | int found_some_locale = 0; | 436 | int found_some_locale = 0; |
| 436 | /* This fails on Solaris. */ | 437 | /* This fails on Solaris. */ |
| 437 | if (strcmp ("$LOCALE_FR_UTF8", "none") != 0 | 438 | if (strcmp ("$LOCALE_EN_UTF8", "none") != 0 |
| 438 | && setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) | 439 | && setlocale (LC_ALL, "$LOCALE_EN_UTF8") != NULL) |
| 439 | { | 440 | { |
| 440 | char input[] = "B\303\274\303\237er"; /* "Büßer" */ | 441 | char input[] = "B\303\274\303\237er"; /* "Büßer" */ |
| 441 | mbstate_t state; | 442 | mbstate_t state; |
| @@ -649,8 +650,8 @@ int main () | |||
| 649 | [:]) | 650 | [:]) |
| 650 | ;; | 651 | ;; |
| 651 | *) | 652 | *) |
| 652 | AC_REQUIRE([gt_LOCALE_FR_UTF8]) | 653 | AC_REQUIRE([gt_LOCALE_EN_UTF8]) |
| 653 | if test $LOCALE_FR_UTF8 != none; then | 654 | if test "$LOCALE_EN_UTF8" != none; then |
| 654 | AC_RUN_IFELSE( | 655 | AC_RUN_IFELSE( |
| 655 | [AC_LANG_SOURCE([[ | 656 | [AC_LANG_SOURCE([[ |
| 656 | #include <locale.h> | 657 | #include <locale.h> |
| @@ -658,7 +659,7 @@ int main () | |||
| 658 | #include <wchar.h> | 659 | #include <wchar.h> |
| 659 | int main () | 660 | int main () |
| 660 | { | 661 | { |
| 661 | if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) | 662 | if (setlocale (LC_ALL, "$LOCALE_EN_UTF8") != NULL) |
| 662 | { | 663 | { |
| 663 | wchar_t wc = (wchar_t) 0xBADFACE; | 664 | wchar_t wc = (wchar_t) 0xBADFACE; |
| 664 | mbstate_t state; | 665 | mbstate_t state; |
diff --git a/gl/m4/mbsinit.m4 b/gl/m4/mbsinit.m4 index 10c86ba9..69cfa574 100644 --- a/gl/m4/mbsinit.m4 +++ b/gl/m4/mbsinit.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # mbsinit.m4 | 1 | # mbsinit.m4 |
| 2 | # serial 10 | 2 | # serial 10 |
| 3 | dnl Copyright (C) 2008, 2010-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008, 2010-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_MBSINIT], | 9 | AC_DEFUN([gl_FUNC_MBSINIT], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/mbstate_t.m4 b/gl/m4/mbstate_t.m4 index 66d65cd7..59df1e2e 100644 --- a/gl/m4/mbstate_t.m4 +++ b/gl/m4/mbstate_t.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # mbstate_t.m4 | 1 | # mbstate_t.m4 |
| 2 | # serial 14 | 2 | # serial 14 |
| 3 | dnl Copyright (C) 2000-2002, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2000-2002, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # From Paul Eggert. | 9 | # From Paul Eggert. |
| 9 | 10 | ||
diff --git a/gl/m4/mbtowc.m4 b/gl/m4/mbtowc.m4 index 603b0c1a..3e3f6ce0 100644 --- a/gl/m4/mbtowc.m4 +++ b/gl/m4/mbtowc.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # mbtowc.m4 | 1 | # mbtowc.m4 |
| 2 | # serial 5 | 2 | # serial 5 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_MBTOWC], | 9 | AC_DEFUN([gl_FUNC_MBTOWC], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/memchr.m4 b/gl/m4/memchr.m4 index 346a2882..1c2ecf1d 100644 --- a/gl/m4/memchr.m4 +++ b/gl/m4/memchr.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # memchr.m4 | 1 | # memchr.m4 |
| 2 | # serial 19 | 2 | # serial 20 |
| 3 | dnl Copyright (C) 2002-2004, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2004, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_FUNC_MEMCHR], | 9 | AC_DEFUN_ONCE([gl_FUNC_MEMCHR], |
| 9 | [ | 10 | [ |
| @@ -49,7 +50,7 @@ AC_DEFUN_ONCE([gl_FUNC_MEMCHR], | |||
| 49 | if (fd >= 0) | 50 | if (fd >= 0) |
| 50 | # endif | 51 | # endif |
| 51 | { | 52 | { |
| 52 | int pagesize = getpagesize (); | 53 | long int pagesize = sysconf (_SC_PAGESIZE); |
| 53 | char *two_pages = | 54 | char *two_pages = |
| 54 | (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE, | 55 | (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE, |
| 55 | flags, fd, 0); | 56 | flags, fd, 0); |
diff --git a/gl/m4/minmax.m4 b/gl/m4/minmax.m4 index bc7d0c34..69c8a89f 100644 --- a/gl/m4/minmax.m4 +++ b/gl/m4/minmax.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # minmax.m4 | 1 | # minmax.m4 |
| 2 | # serial 4 | 2 | # serial 4 |
| 3 | dnl Copyright (C) 2005, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_PREREQ([2.53]) | 9 | AC_PREREQ([2.53]) |
| 9 | 10 | ||
diff --git a/gl/m4/mktime.m4 b/gl/m4/mktime.m4 index 85c52454..eca6c4d8 100644 --- a/gl/m4/mktime.m4 +++ b/gl/m4/mktime.m4 | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | # mktime.m4 | 1 | # mktime.m4 |
| 2 | # serial 39 | 2 | # serial 42 |
| 3 | dnl Copyright (C) 2002-2003, 2005-2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2003, 2005-2007, 2009-2025 Free Software Foundation, |
| 4 | dnl Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 9 | ||
| 8 | dnl From Jim Meyering. | 10 | dnl From Jim Meyering. |
| 9 | 11 | ||
diff --git a/gl/m4/mmap-anon.m4 b/gl/m4/mmap-anon.m4 index 61ca0120..3f7a6656 100644 --- a/gl/m4/mmap-anon.m4 +++ b/gl/m4/mmap-anon.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # mmap-anon.m4 | 1 | # mmap-anon.m4 |
| 2 | # serial 12 | 2 | # serial 12 |
| 3 | dnl Copyright (C) 2005, 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005, 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Detect how mmap can be used to create anonymous (not file-backed) memory | 9 | # Detect how mmap can be used to create anonymous (not file-backed) memory |
| 9 | # mappings. | 10 | # mappings. |
diff --git a/gl/m4/mode_t.m4 b/gl/m4/mode_t.m4 index 0d5c2808..7dae201b 100644 --- a/gl/m4/mode_t.m4 +++ b/gl/m4/mode_t.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # mode_t.m4 | 1 | # mode_t.m4 |
| 2 | # serial 2 | 2 | # serial 2 |
| 3 | dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # For using mode_t, it's sufficient to use AC_TYPE_MODE_T and | 9 | # For using mode_t, it's sufficient to use AC_TYPE_MODE_T and |
| 9 | # include <sys/types.h>. | 10 | # include <sys/types.h>. |
diff --git a/gl/m4/mountlist.m4 b/gl/m4/mountlist.m4 index ff414e66..e7eac2e9 100644 --- a/gl/m4/mountlist.m4 +++ b/gl/m4/mountlist.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # mountlist.m4 | 1 | # mountlist.m4 |
| 2 | # serial 17 | 2 | # serial 18 |
| 3 | dnl Copyright (C) 2002-2006, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Jim Meyering. | 9 | dnl From Jim Meyering. |
| 9 | 10 | ||
| @@ -318,12 +319,17 @@ int getmntinfo (struct statfs **, int); | |||
| 318 | fi | 319 | fi |
| 319 | 320 | ||
| 320 | if test -z "$ac_list_mounted_fs"; then | 321 | if test -z "$ac_list_mounted_fs"; then |
| 321 | AC_MSG_ERROR([could not determine how to read list of mounted file systems]) | 322 | case "$host_os" in |
| 322 | # FIXME -- no need to abort building the whole package | 323 | mingw* | windows*) ac_list_mounted_fs=found ;; |
| 323 | # Can't build mountlist.c or anything that needs its functions | 324 | esac |
| 325 | fi | ||
| 326 | |||
| 327 | if test -z "$ac_list_mounted_fs"; then | ||
| 328 | AC_DEFINE([MOUNTED_NOT_PORTED], [1], | ||
| 329 | [Define if we don't know how to determine the list of mounted file systems.]) | ||
| 324 | fi | 330 | fi |
| 325 | 331 | ||
| 326 | if test $ac_list_mounted_fs = found; then | 332 | if test "$ac_list_mounted_fs" = found; then |
| 327 | gl_cv_list_mounted_fs=yes | 333 | gl_cv_list_mounted_fs=yes |
| 328 | else | 334 | else |
| 329 | gl_cv_list_mounted_fs=no | 335 | gl_cv_list_mounted_fs=no |
diff --git a/gl/m4/msvc-inval.m4 b/gl/m4/msvc-inval.m4 index 7919ff12..bfbb983b 100644 --- a/gl/m4/msvc-inval.m4 +++ b/gl/m4/msvc-inval.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # msvc-inval.m4 | 1 | # msvc-inval.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_MSVC_INVAL], | 9 | AC_DEFUN([gl_MSVC_INVAL], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/msvc-nothrow.m4 b/gl/m4/msvc-nothrow.m4 index 007c7620..6a470971 100644 --- a/gl/m4/msvc-nothrow.m4 +++ b/gl/m4/msvc-nothrow.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # msvc-nothrow.m4 | 1 | # msvc-nothrow.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_MSVC_NOTHROW], | 9 | AC_DEFUN([gl_MSVC_NOTHROW], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/multiarch.m4 b/gl/m4/multiarch.m4 index 3af29d39..817f01f1 100644 --- a/gl/m4/multiarch.m4 +++ b/gl/m4/multiarch.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # multiarch.m4 | 1 | # multiarch.m4 |
| 2 | # serial 9 | 2 | # serial 9 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Determine whether the compiler is or may be producing universal binaries. | 9 | # Determine whether the compiler is or may be producing universal binaries. |
| 9 | # | 10 | # |
diff --git a/gl/m4/musl.m4 b/gl/m4/musl.m4 index 0d4de892..6ff778cb 100644 --- a/gl/m4/musl.m4 +++ b/gl/m4/musl.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # musl.m4 | 1 | # musl.m4 |
| 2 | # serial 4 | 2 | # serial 4 |
| 3 | dnl Copyright (C) 2019-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Test for musl libc, despite the musl libc authors don't like it | 9 | # Test for musl libc, despite the musl libc authors don't like it |
| 9 | # <https://wiki.musl-libc.org/faq.html> | 10 | # <https://wiki.musl-libc.org/faq.html> |
diff --git a/gl/m4/netdb_h.m4 b/gl/m4/netdb_h.m4 index d8c00217..88512546 100644 --- a/gl/m4/netdb_h.m4 +++ b/gl/m4/netdb_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # netdb_h.m4 | 1 | # netdb_h.m4 |
| 2 | # serial 15 | 2 | # serial 15 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_NETDB_H], | 9 | AC_DEFUN_ONCE([gl_NETDB_H], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/netinet_in_h.m4 b/gl/m4/netinet_in_h.m4 index 926f7f95..b56e354c 100644 --- a/gl/m4/netinet_in_h.m4 +++ b/gl/m4/netinet_in_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # netinet_in_h.m4 | 1 | # netinet_in_h.m4 |
| 2 | # serial 6 | 2 | # serial 6 |
| 3 | dnl Copyright (C) 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_HEADER_NETINET_IN], | 9 | AC_DEFUN([gl_HEADER_NETINET_IN], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/nl_langinfo.m4 b/gl/m4/nl_langinfo.m4 index f38f11bb..9b1e0f32 100644 --- a/gl/m4/nl_langinfo.m4 +++ b/gl/m4/nl_langinfo.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # nl_langinfo.m4 | 1 | # nl_langinfo.m4 |
| 2 | # serial 11 | 2 | # serial 12.1 |
| 3 | dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_NL_LANGINFO], | 9 | AC_DEFUN([gl_FUNC_NL_LANGINFO], |
| 9 | [ | 10 | [ |
| @@ -40,16 +41,18 @@ AC_DEFUN([gl_FUNC_NL_LANGINFO], | |||
| 40 | AC_DEFINE_UNQUOTED([FUNC_NL_LANGINFO_YESEXPR_WORKS], | 41 | AC_DEFINE_UNQUOTED([FUNC_NL_LANGINFO_YESEXPR_WORKS], |
| 41 | [$FUNC_NL_LANGINFO_YESEXPR_WORKS], | 42 | [$FUNC_NL_LANGINFO_YESEXPR_WORKS], |
| 42 | [Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string.]) | 43 | [Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string.]) |
| 43 | # On Solaris 10 and Solaris 11.3, nl_langinfo is not multithread-safe. | 44 | # On macOS 26, Solaris 10, and Solaris 11.3, nl_langinfo is not |
| 45 | # multithread-safe. | ||
| 44 | case "$host_os" in | 46 | case "$host_os" in |
| 45 | solaris*) NL_LANGINFO_MTSAFE=0 ;; | 47 | darwin* | solaris*) NL_LANGINFO_MTSAFE=0 ;; |
| 46 | *) NL_LANGINFO_MTSAFE=1 ;; | 48 | *) NL_LANGINFO_MTSAFE=1 ;; |
| 47 | esac | 49 | esac |
| 48 | AC_DEFINE_UNQUOTED([NL_LANGINFO_MTSAFE], [$NL_LANGINFO_MTSAFE], | 50 | AC_DEFINE_UNQUOTED([NL_LANGINFO_MTSAFE], [$NL_LANGINFO_MTSAFE], |
| 49 | [Define to 1 if nl_langinfo is multithread-safe.]) | 51 | [Define to 1 if nl_langinfo is multithread-safe.]) |
| 50 | if test $HAVE_LANGINFO_CODESET = 1 \ | 52 | if test $HAVE_LANGINFO_CODESET = 1 \ |
| 51 | && test $HAVE_LANGINFO_T_FMT_AMPM = 1 \ | 53 | && test $HAVE_LANGINFO_T_FMT_AMPM = 1 \ |
| 52 | && test $HAVE_LANGINFO_ALTMON = 1 \ | 54 | && test $HAVE_LANGINFO_ALTMON = 1 \ |
| 55 | && test $HAVE_LANGINFO_ABALTMON = 1 \ | ||
| 53 | && test $HAVE_LANGINFO_ERA = 1 \ | 56 | && test $HAVE_LANGINFO_ERA = 1 \ |
| 54 | && test $FUNC_NL_LANGINFO_YESEXPR_WORKS = 1 \ | 57 | && test $FUNC_NL_LANGINFO_YESEXPR_WORKS = 1 \ |
| 55 | && test $NL_LANGINFO_MTSAFE = 1; then | 58 | && test $NL_LANGINFO_MTSAFE = 1; then |
diff --git a/gl/m4/nocrash.m4 b/gl/m4/nocrash.m4 index cbe8fe82..662fb049 100644 --- a/gl/m4/nocrash.m4 +++ b/gl/m4/nocrash.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # nocrash.m4 | 1 | # nocrash.m4 |
| 2 | # serial 5 | 2 | # serial 5 |
| 3 | dnl Copyright (C) 2005, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Based on libsigsegv, from Bruno Haible and Paolo Bonzini. | 9 | dnl Based on libsigsegv, from Bruno Haible and Paolo Bonzini. |
| 9 | 10 | ||
diff --git a/gl/m4/off64_t.m4 b/gl/m4/off64_t.m4 new file mode 100644 index 00000000..963d53e9 --- /dev/null +++ b/gl/m4/off64_t.m4 | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | # off64_t.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright (C) 2024-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl Check whether <sys/types.h> defines the 'off64_t' type. | ||
| 10 | dnl Set HAVE_OFF64_T. | ||
| 11 | |||
| 12 | AC_DEFUN([gl_TYPE_OFF64_T], | ||
| 13 | [ | ||
| 14 | dnl Persuade glibc <sys/types.h>, <stdio.h>, <fcntl.h>, <unistd.h>, <aio.h> | ||
| 15 | dnl to define off64_t. | ||
| 16 | AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) | ||
| 17 | |||
| 18 | AC_CACHE_CHECK([for off64_t], [gl_cv_off64_t], | ||
| 19 | [AC_COMPILE_IFELSE( | ||
| 20 | [AC_LANG_PROGRAM( | ||
| 21 | [[#include <sys/types.h>]], | ||
| 22 | [[int x = sizeof (off64_t *) + sizeof (off64_t); | ||
| 23 | return !x;]])], | ||
| 24 | [gl_cv_off64_t=yes], [gl_cv_off64_t=no])]) | ||
| 25 | |||
| 26 | if test $gl_cv_off64_t != no; then | ||
| 27 | HAVE_OFF64_T=1 | ||
| 28 | else | ||
| 29 | HAVE_OFF64_T=0 | ||
| 30 | fi | ||
| 31 | AC_SUBST([HAVE_OFF64_T]) | ||
| 32 | ]) | ||
diff --git a/gl/m4/off_t.m4 b/gl/m4/off_t.m4 index db6035db..f4f4bbf6 100644 --- a/gl/m4/off_t.m4 +++ b/gl/m4/off_t.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # off_t.m4 | 1 | # off_t.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright (C) 2012-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2012-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Check whether to override the 'off_t' type. | 9 | dnl Check whether to override the 'off_t' type. |
| 9 | dnl Set WINDOWS_64_BIT_OFF_T. | 10 | dnl Set WINDOWS_64_BIT_OFF_T. |
diff --git a/gl/m4/once.m4 b/gl/m4/once.m4 new file mode 100644 index 00000000..7876a8fe --- /dev/null +++ b/gl/m4/once.m4 | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | # once.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright (C) 2024-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl From Bruno Haible. | ||
| 10 | |||
| 11 | AC_DEFUN([gl_ONCE], | ||
| 12 | [ | ||
| 13 | AC_REQUIRE([gl_THREADLIB]) | ||
| 14 | ]) | ||
diff --git a/gl/m4/open-cloexec.m4 b/gl/m4/open-cloexec.m4 index 6defdfb4..860541b0 100644 --- a/gl/m4/open-cloexec.m4 +++ b/gl/m4/open-cloexec.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # open-cloexec.m4 | 1 | # open-cloexec.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright 2017-2024 Free Software Foundation, Inc. | 3 | dnl Copyright 2017-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Test whether O_CLOEXEC is defined. | 9 | # Test whether O_CLOEXEC is defined. |
| 9 | 10 | ||
diff --git a/gl/m4/open-slash.m4 b/gl/m4/open-slash.m4 index 03460e42..2cba48fe 100644 --- a/gl/m4/open-slash.m4 +++ b/gl/m4/open-slash.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # open-slash.m4 | 1 | # open-slash.m4 |
| 2 | # serial 2 | 2 | # serial 2 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Tests whether open() and creat() recognize a trailing slash. | 9 | dnl Tests whether open() and creat() recognize a trailing slash. |
| 9 | dnl Sets gl_cv_func_open_slash. | 10 | dnl Sets gl_cv_func_open_slash. |
diff --git a/gl/m4/open.m4 b/gl/m4/open.m4 index 62a11a11..dd3a805f 100644 --- a/gl/m4/open.m4 +++ b/gl/m4/open.m4 | |||
| @@ -1,14 +1,18 @@ | |||
| 1 | # open.m4 | 1 | # open.m4 |
| 2 | # serial 16 | 2 | # serial 17 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_OPEN], | 9 | AC_DEFUN([gl_FUNC_OPEN], |
| 9 | [ | 10 | [ |
| 10 | AC_REQUIRE([AC_CANONICAL_HOST]) | 11 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 11 | AC_REQUIRE([gl_PREPROC_O_CLOEXEC]) | 12 | AC_REQUIRE([gl_PREPROC_O_CLOEXEC]) |
| 13 | AC_REQUIRE([gl_FCNTL_O_FLAGS]) | ||
| 14 | AS_CASE([$gl_cv_header_working_fcntl_h], | ||
| 15 | [*O_DIRECTORY* | *no], [REPLACE_OPEN=1]) | ||
| 12 | case "$host_os" in | 16 | case "$host_os" in |
| 13 | mingw* | windows* | pw*) | 17 | mingw* | windows* | pw*) |
| 14 | REPLACE_OPEN=1 | 18 | REPLACE_OPEN=1 |
diff --git a/gl/m4/pathmax.m4 b/gl/m4/pathmax.m4 index 4280837f..0c3925df 100644 --- a/gl/m4/pathmax.m4 +++ b/gl/m4/pathmax.m4 | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | # pathmax.m4 | 1 | # pathmax.m4 |
| 2 | # serial 11 | 2 | # serial 11 |
| 3 | dnl Copyright (C) 2002-2003, 2005-2006, 2009-2024 Free Software Foundation, | 3 | dnl Copyright (C) 2002-2003, 2005-2006, 2009-2025 Free Software Foundation, |
| 4 | dnl Inc. | 4 | dnl Inc. |
| 5 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 6 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 7 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 8 | 9 | ||
| 9 | AC_DEFUN([gl_PATHMAX], | 10 | AC_DEFUN([gl_PATHMAX], |
| 10 | [ | 11 | [ |
diff --git a/gl/m4/pid_t.m4 b/gl/m4/pid_t.m4 index 8bedcc6b..a8bdabc2 100644 --- a/gl/m4/pid_t.m4 +++ b/gl/m4/pid_t.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # pid_t.m4 | 1 | # pid_t.m4 |
| 2 | # serial 4 | 2 | # serial 4 |
| 3 | dnl Copyright (C) 2020-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2020-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # The following implementation works around a problem in autoconf <= 2.69. | 9 | # The following implementation works around a problem in autoconf <= 2.69. |
| 9 | m4_version_prereq([2.70], [], [ | 10 | m4_version_prereq([2.70], [], [ |
diff --git a/gl/m4/printf.m4 b/gl/m4/printf.m4 index 0cb14d6f..4619a402 100644 --- a/gl/m4/printf.m4 +++ b/gl/m4/printf.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # printf.m4 | 1 | # printf.m4 |
| 2 | # serial 91 | 2 | # serial 96 |
| 3 | dnl Copyright (C) 2003, 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003, 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Test whether the *printf family of functions supports the 'j', 'z', 't', | 9 | dnl Test whether the *printf family of functions supports the 'j', 'z', 't', |
| 9 | dnl 'L' size specifiers. (ISO C99, POSIX:2001) | 10 | dnl 'L' size specifiers. (ISO C99, POSIX:2001) |
| @@ -616,6 +617,7 @@ static double zero = 0.0; | |||
| 616 | int main () | 617 | int main () |
| 617 | { | 618 | { |
| 618 | int result = 0; | 619 | int result = 0; |
| 620 | /* This fails on FreeBSD 5.2.1, Solaris 11.4. */ | ||
| 619 | if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0 | 621 | if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0 |
| 620 | || (strcmp (buf, "0x1.922p+1 33") != 0 | 622 | || (strcmp (buf, "0x1.922p+1 33") != 0 |
| 621 | && strcmp (buf, "0x3.244p+0 33") != 0 | 623 | && strcmp (buf, "0x3.244p+0 33") != 0 |
| @@ -627,27 +629,29 @@ int main () | |||
| 627 | && strcmp (buf, "-0X3.244P+0 33") != 0 | 629 | && strcmp (buf, "-0X3.244P+0 33") != 0 |
| 628 | && strcmp (buf, "-0X6.488P-1 33") != 0 | 630 | && strcmp (buf, "-0X6.488P-1 33") != 0 |
| 629 | && strcmp (buf, "-0XC.91P-2 33") != 0)) | 631 | && strcmp (buf, "-0XC.91P-2 33") != 0)) |
| 630 | result |= 2; | 632 | result |= 1; |
| 631 | /* This catches a FreeBSD 13.0 bug: it doesn't round. */ | 633 | /* This catches a Mac OS X 10.5, FreeBSD 6.4, NetBSD 10.0 bug: |
| 634 | it doesn't round. */ | ||
| 632 | if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0 | 635 | if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0 |
| 633 | || (strcmp (buf, "0x1.83p+0 33") != 0 | 636 | || (strcmp (buf, "0x1.83p+0 33") != 0 |
| 634 | && strcmp (buf, "0x3.05p-1 33") != 0 | 637 | && strcmp (buf, "0x3.05p-1 33") != 0 |
| 635 | && strcmp (buf, "0x6.0ap-2 33") != 0 | 638 | && strcmp (buf, "0x6.0ap-2 33") != 0 |
| 636 | && strcmp (buf, "0xc.14p-3 33") != 0)) | 639 | && strcmp (buf, "0xc.14p-3 33") != 0)) |
| 637 | result |= 4; | 640 | result |= 2; |
| 638 | /* This catches a Mac OS X 10.12.4 (Darwin 16.5) bug: it doesn't round. */ | 641 | /* This catches a macOS 14 (Darwin 23), FreeBSD 14.0, OpenBSD 7.5, AIX 7.3, |
| 642 | Solaris 11.4 bug: it doesn't round. */ | ||
| 639 | if (sprintf (buf, "%.0a %d", 1.51, 33, 44, 55) < 0 | 643 | if (sprintf (buf, "%.0a %d", 1.51, 33, 44, 55) < 0 |
| 640 | || (strcmp (buf, "0x2p+0 33") != 0 | 644 | || (strcmp (buf, "0x2p+0 33") != 0 |
| 641 | && strcmp (buf, "0x3p-1 33") != 0 | 645 | && strcmp (buf, "0x3p-1 33") != 0 |
| 642 | && strcmp (buf, "0x6p-2 33") != 0 | 646 | && strcmp (buf, "0x6p-2 33") != 0 |
| 643 | && strcmp (buf, "0xcp-3 33") != 0)) | 647 | && strcmp (buf, "0xcp-3 33") != 0)) |
| 644 | result |= 4; | 648 | result |= 4; |
| 645 | /* This catches a FreeBSD 6.1 bug. See | 649 | /* This catches a Mac OS X 10.5, FreeBSD 6.4 bug. See |
| 646 | <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html> */ | 650 | <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html> */ |
| 647 | if (sprintf (buf, "%010a %d", 1.0 / zero, 33, 44, 55) < 0 | 651 | if (sprintf (buf, "%010a %d", 1.0 / zero, 33, 44, 55) < 0 |
| 648 | || buf[0] == '0') | 652 | || buf[0] == '0') |
| 649 | result |= 8; | 653 | result |= 8; |
| 650 | /* This catches a Mac OS X 10.3.9 (Darwin 7.9) bug. */ | 654 | /* This catches a Mac OS X 10.3.9 (Darwin 7.9), FreeBSD 6.4 bug. */ |
| 651 | if (sprintf (buf, "%.1a", 1.999) < 0 | 655 | if (sprintf (buf, "%.1a", 1.999) < 0 |
| 652 | || (strcmp (buf, "0x1.0p+1") != 0 | 656 | || (strcmp (buf, "0x1.0p+1") != 0 |
| 653 | && strcmp (buf, "0x2.0p+0") != 0 | 657 | && strcmp (buf, "0x2.0p+0") != 0 |
| @@ -655,7 +659,8 @@ int main () | |||
| 655 | && strcmp (buf, "0x8.0p-2") != 0)) | 659 | && strcmp (buf, "0x8.0p-2") != 0)) |
| 656 | result |= 16; | 660 | result |= 16; |
| 657 | /* This catches the same Mac OS X 10.3.9 (Darwin 7.9) bug and also a | 661 | /* This catches the same Mac OS X 10.3.9 (Darwin 7.9) bug and also a |
| 658 | glibc 2.4 bug <https://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */ | 662 | glibc 2.4 bug <https://sourceware.org/bugzilla/show_bug.cgi?id=2908> |
| 663 | and a FreeBSD 6.4, NetBSD 10.0 bug. */ | ||
| 659 | if (sprintf (buf, "%.1La", 1.999L) < 0 | 664 | if (sprintf (buf, "%.1La", 1.999L) < 0 |
| 660 | || (strcmp (buf, "0x1.0p+1") != 0 | 665 | || (strcmp (buf, "0x1.0p+1") != 0 |
| 661 | && strcmp (buf, "0x2.0p+0") != 0 | 666 | && strcmp (buf, "0x2.0p+0") != 0 |
| @@ -893,9 +898,14 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_N], | |||
| 893 | [AC_LANG_SOURCE([[ | 898 | [AC_LANG_SOURCE([[ |
| 894 | #include <signal.h> | 899 | #include <signal.h> |
| 895 | #include <stdio.h> | 900 | #include <stdio.h> |
| 896 | #include <stdlib.h> | ||
| 897 | #include <string.h> | 901 | #include <string.h> |
| 902 | #if defined _WIN32 && !defined __CYGWIN__ | ||
| 903 | # include <stdlib.h> | ||
| 904 | #else | ||
| 905 | # include <unistd.h> | ||
| 906 | #endif | ||
| 898 | #ifdef _MSC_VER | 907 | #ifdef _MSC_VER |
| 908 | #include <crtdbg.h> | ||
| 899 | #include <inttypes.h> | 909 | #include <inttypes.h> |
| 900 | /* See page about "Parameter Validation" on msdn.microsoft.com. | 910 | /* See page about "Parameter Validation" on msdn.microsoft.com. |
| 901 | <https://docs.microsoft.com/en-us/cpp/c-runtime-library/parameter-validation> | 911 | <https://docs.microsoft.com/en-us/cpp/c-runtime-library/parameter-validation> |
| @@ -922,6 +932,9 @@ int main () | |||
| 922 | int count = -1; | 932 | int count = -1; |
| 923 | #ifdef _MSC_VER | 933 | #ifdef _MSC_VER |
| 924 | _set_invalid_parameter_handler (invalid_parameter_handler); | 934 | _set_invalid_parameter_handler (invalid_parameter_handler); |
| 935 | /* Also avoid an Abort/Retry/Ignore dialog in debug builds. | ||
| 936 | <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/crtsetreportmode> */ | ||
| 937 | _CrtSetReportMode (_CRT_ASSERT, 0); | ||
| 925 | #endif | 938 | #endif |
| 926 | signal (SIGABRT, abort_handler); | 939 | signal (SIGABRT, abort_handler); |
| 927 | /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2) | 940 | /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2) |
| @@ -1173,6 +1186,112 @@ changequote([,])dnl | |||
| 1173 | ]) | 1186 | ]) |
| 1174 | ]) | 1187 | ]) |
| 1175 | 1188 | ||
| 1189 | dnl Test whether the *printf family of functions supports POSIX/XSI format | ||
| 1190 | dnl strings with the ' flag for grouping of decimal digits on integers, | ||
| 1191 | dnl together with a precision. | ||
| 1192 | dnl Result is gl_cv_func_printf_flag_grouping_int_precision. | ||
| 1193 | |||
| 1194 | AC_DEFUN([gl_PRINTF_FLAG_GROUPING_INT_PRECISION], | ||
| 1195 | [ | ||
| 1196 | AC_REQUIRE([AC_PROG_CC]) | ||
| 1197 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 1198 | AC_CACHE_CHECK([whether printf supports grouping on integers with a precision], | ||
| 1199 | [gl_cv_func_printf_flag_grouping_int_precision], | ||
| 1200 | [ | ||
| 1201 | dnl Prepare a guess, used when cross-compiling or when specific locales | ||
| 1202 | dnl are not available. | ||
| 1203 | case "$host_os" in | ||
| 1204 | # Guess no on FreeBSD, NetBSD, Solaris, Cygwin, Haiku. | ||
| 1205 | freebsd* | dragonfly* | netbsd* | solaris* | cygwin* | haiku*) | ||
| 1206 | gl_cv_func_printf_flag_grouping_int_precision="guessing no";; | ||
| 1207 | *) | ||
| 1208 | gl_cv_func_printf_flag_grouping_int_precision="guessing yes";; | ||
| 1209 | esac | ||
| 1210 | AC_RUN_IFELSE( | ||
| 1211 | [AC_LANG_SOURCE([[ | ||
| 1212 | #include <locale.h> | ||
| 1213 | #include <stdio.h> | ||
| 1214 | #include <string.h> | ||
| 1215 | static char buf[100]; | ||
| 1216 | int main () | ||
| 1217 | { | ||
| 1218 | if (setlocale (LC_ALL, "fr_FR.UTF-8") != NULL | ||
| 1219 | || setlocale (LC_ALL, "fr_FR") != NULL | ||
| 1220 | || setlocale (LC_ALL, "fr_FR.ISO-8859-1") != NULL | ||
| 1221 | || setlocale (LC_ALL, "fr_FR.ISO8859-1") != NULL) | ||
| 1222 | { | ||
| 1223 | if (sprintf (buf, "%'.10d", 1000) < 0) | ||
| 1224 | return 1; | ||
| 1225 | if (strlen (buf) == 10 && strcmp (buf, "0000001000") != 0) | ||
| 1226 | /* The sprintf implementation has produced fewer than 10 digits. */ | ||
| 1227 | return 2; | ||
| 1228 | else | ||
| 1229 | return 0; | ||
| 1230 | } | ||
| 1231 | return 3; | ||
| 1232 | }]])], | ||
| 1233 | [gl_cv_func_printf_flag_grouping_int_precision=yes], | ||
| 1234 | [if test $? = 2; then | ||
| 1235 | gl_cv_func_printf_flag_grouping_int_precision=no | ||
| 1236 | fi | ||
| 1237 | ], | ||
| 1238 | [:]) | ||
| 1239 | ]) | ||
| 1240 | ]) | ||
| 1241 | |||
| 1242 | dnl Test whether the *printf family of functions supports POSIX/XSI format | ||
| 1243 | dnl strings with the ' flag for grouping of decimal digits, when the thousands | ||
| 1244 | dnl separator is a multibyte character (such as U+00A0 or U+202F in a UTF-8 | ||
| 1245 | dnl locale). | ||
| 1246 | dnl Result is gl_cv_func_printf_flag_grouping_multibyte. | ||
| 1247 | |||
| 1248 | AC_DEFUN([gl_PRINTF_FLAG_GROUPING_MULTIBYTE], | ||
| 1249 | [ | ||
| 1250 | AC_REQUIRE([AC_PROG_CC]) | ||
| 1251 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 1252 | AC_CACHE_CHECK([whether printf supports grouping with a multibyte separator], | ||
| 1253 | [gl_cv_func_printf_flag_grouping_multibyte], | ||
| 1254 | [ | ||
| 1255 | dnl Prepare a guess, used when cross-compiling or when specific locales | ||
| 1256 | dnl are not available. | ||
| 1257 | case "$host_os" in | ||
| 1258 | # Guess no on NetBSD and Solaris 11 OpenIndiana. | ||
| 1259 | netbsd* | solaris*) | ||
| 1260 | gl_cv_func_printf_flag_grouping_multibyte="guessing no";; | ||
| 1261 | *) | ||
| 1262 | gl_cv_func_printf_flag_grouping_multibyte="guessing yes";; | ||
| 1263 | esac | ||
| 1264 | AC_RUN_IFELSE( | ||
| 1265 | [AC_LANG_SOURCE([[ | ||
| 1266 | #include <locale.h> | ||
| 1267 | #include <stdio.h> | ||
| 1268 | #include <string.h> | ||
| 1269 | static char buf[100]; | ||
| 1270 | int main () | ||
| 1271 | { | ||
| 1272 | if (setlocale (LC_ALL, "fr_FR.UTF-8") == NULL) | ||
| 1273 | return 0; | ||
| 1274 | if (sprintf (buf, "%'.0f", 1000.0) < 0) | ||
| 1275 | return 1; | ||
| 1276 | if (strlen (localeconv ()->thousands_sep) > 1) | ||
| 1277 | { | ||
| 1278 | if (strlen (buf) <= 4 + 1) | ||
| 1279 | return 2; | ||
| 1280 | else | ||
| 1281 | return 3; | ||
| 1282 | } | ||
| 1283 | return 0; | ||
| 1284 | }]])], | ||
| 1285 | [:], | ||
| 1286 | [case $? in | ||
| 1287 | 2) gl_cv_func_printf_flag_grouping_multibyte=no ;; | ||
| 1288 | 3) gl_cv_func_printf_flag_grouping_multibyte=yes ;; | ||
| 1289 | esac | ||
| 1290 | ], | ||
| 1291 | [:]) | ||
| 1292 | ]) | ||
| 1293 | ]) | ||
| 1294 | |||
| 1176 | dnl Test whether the *printf family of functions supports the - flag correctly. | 1295 | dnl Test whether the *printf family of functions supports the - flag correctly. |
| 1177 | dnl (ISO C99.) See | 1296 | dnl (ISO C99.) See |
| 1178 | dnl <https://lists.gnu.org/r/bug-coreutils/2008-02/msg00035.html> | 1297 | dnl <https://lists.gnu.org/r/bug-coreutils/2008-02/msg00035.html> |
| @@ -1709,6 +1828,11 @@ AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N], | |||
| 1709 | #include <signal.h> | 1828 | #include <signal.h> |
| 1710 | #include <stdio.h> | 1829 | #include <stdio.h> |
| 1711 | #include <string.h> | 1830 | #include <string.h> |
| 1831 | #if defined _WIN32 && !defined __CYGWIN__ | ||
| 1832 | # include <stdlib.h> | ||
| 1833 | #else | ||
| 1834 | # include <unistd.h> | ||
| 1835 | #endif | ||
| 1712 | #if HAVE_SNPRINTF | 1836 | #if HAVE_SNPRINTF |
| 1713 | # define my_snprintf snprintf | 1837 | # define my_snprintf snprintf |
| 1714 | #else | 1838 | #else |
| @@ -2143,20 +2267,22 @@ dnl 11 = gl_PRINTF_DIRECTIVE_LS | |||
| 2143 | dnl 12 = gl_PRINTF_DIRECTIVE_LC | 2267 | dnl 12 = gl_PRINTF_DIRECTIVE_LC |
| 2144 | dnl 13 = gl_PRINTF_POSITIONS | 2268 | dnl 13 = gl_PRINTF_POSITIONS |
| 2145 | dnl 14 = gl_PRINTF_FLAG_GROUPING | 2269 | dnl 14 = gl_PRINTF_FLAG_GROUPING |
| 2146 | dnl 15 = gl_PRINTF_FLAG_LEFTADJUST | 2270 | dnl 15 = gl_PRINTF_FLAG_GROUPING_INT_PRECISION |
| 2147 | dnl 16 = gl_PRINTF_FLAG_ZERO | 2271 | dnl 16 = gl_PRINTF_FLAG_GROUPING_MULTIBYTE |
| 2148 | dnl 17 = gl_PRINTF_FLAG_ALT_PRECISION_ZERO | 2272 | dnl 17 = gl_PRINTF_FLAG_LEFTADJUST |
| 2149 | dnl 18 = gl_PRINTF_PRECISION | 2273 | dnl 18 = gl_PRINTF_FLAG_ZERO |
| 2150 | dnl 19 = gl_PRINTF_ENOMEM | 2274 | dnl 19 = gl_PRINTF_FLAG_ALT_PRECISION_ZERO |
| 2151 | dnl 20 = gl_SNPRINTF_PRESENCE | 2275 | dnl 20 = gl_PRINTF_PRECISION |
| 2152 | dnl 21 = gl_SNPRINTF_TRUNCATION_C99 | 2276 | dnl 21 = gl_PRINTF_ENOMEM |
| 2153 | dnl 22 = gl_SNPRINTF_RETVAL_C99 | 2277 | dnl 22 = gl_SNPRINTF_PRESENCE |
| 2154 | dnl 23 = gl_SNPRINTF_DIRECTIVE_N | 2278 | dnl 23 = gl_SNPRINTF_TRUNCATION_C99 |
| 2155 | dnl 24 = gl_SNPRINTF_SIZE1 | 2279 | dnl 24 = gl_SNPRINTF_RETVAL_C99 |
| 2156 | dnl 25 = gl_VSNPRINTF_ZEROSIZE_C99 | 2280 | dnl 25 = gl_SNPRINTF_DIRECTIVE_N |
| 2157 | dnl 26 = gl_SWPRINTF_WORKS | 2281 | dnl 26 = gl_SNPRINTF_SIZE1 |
| 2158 | dnl 27 = gl_SWPRINTF_DIRECTIVE_LA | 2282 | dnl 27 = gl_VSNPRINTF_ZEROSIZE_C99 |
| 2159 | dnl 28 = gl_SWPRINTF_DIRECTIVE_LC | 2283 | dnl 28 = gl_SWPRINTF_WORKS |
| 2284 | dnl 29 = gl_SWPRINTF_DIRECTIVE_LA | ||
| 2285 | dnl 30 = gl_SWPRINTF_DIRECTIVE_LC | ||
| 2160 | dnl | 2286 | dnl |
| 2161 | dnl 1 = checking whether printf supports size specifiers as in C99... | 2287 | dnl 1 = checking whether printf supports size specifiers as in C99... |
| 2162 | dnl 2 = checking whether printf supports size specifiers as in C23... | 2288 | dnl 2 = checking whether printf supports size specifiers as in C23... |
| @@ -2172,62 +2298,64 @@ dnl 11 = checking whether printf supports the 'ls' directive... | |||
| 2172 | dnl 12 = checking whether printf supports the 'lc' directive correctly... | 2298 | dnl 12 = checking whether printf supports the 'lc' directive correctly... |
| 2173 | dnl 13 = checking whether printf supports POSIX/XSI format strings with positions... | 2299 | dnl 13 = checking whether printf supports POSIX/XSI format strings with positions... |
| 2174 | dnl 14 = checking whether printf supports the grouping flag... | 2300 | dnl 14 = checking whether printf supports the grouping flag... |
| 2175 | dnl 15 = checking whether printf supports the left-adjust flag correctly... | 2301 | dnl 15 = checking whether printf supports grouping on integers with a precision... |
| 2176 | dnl 16 = checking whether printf supports the zero flag correctly... | 2302 | dnl 16 = checking whether printf supports grouping with a multibyte separator... |
| 2177 | dnl 17 = checking whether printf supports the alternative flag with a zero precision... | 2303 | dnl 17 = checking whether printf supports the left-adjust flag correctly... |
| 2178 | dnl 18 = checking whether printf supports large precisions... | 2304 | dnl 18 = checking whether printf supports the zero flag correctly... |
| 2179 | dnl 19 = checking whether printf survives out-of-memory conditions... | 2305 | dnl 19 = checking whether printf supports the alternative flag with a zero precision... |
| 2180 | dnl 20 = checking for snprintf... | 2306 | dnl 20 = checking whether printf supports large precisions... |
| 2181 | dnl 21 = checking whether snprintf truncates the result as in C99... | 2307 | dnl 21 = checking whether printf survives out-of-memory conditions... |
| 2182 | dnl 22 = checking whether snprintf returns a byte count as in C99... | 2308 | dnl 22 = checking for snprintf... |
| 2183 | dnl 23 = checking whether snprintf fully supports the 'n' directive... | 2309 | dnl 23 = checking whether snprintf truncates the result as in C99... |
| 2184 | dnl 24 = checking whether snprintf respects a size of 1... | 2310 | dnl 24 = checking whether snprintf returns a byte count as in C99... |
| 2185 | dnl 25 = checking whether vsnprintf respects a zero size as in C99... | 2311 | dnl 25 = checking whether snprintf fully supports the 'n' directive... |
| 2186 | dnl 26 = checking whether swprintf works... | 2312 | dnl 26 = checking whether snprintf respects a size of 1... |
| 2187 | dnl 27 = checking whether swprintf supports the 'La' and 'LA' directives... | 2313 | dnl 27 = checking whether vsnprintf respects a zero size as in C99... |
| 2188 | dnl 28 = checking whether swprintf supports the 'lc' directive... | 2314 | dnl 28 = checking whether swprintf works... |
| 2315 | dnl 29 = checking whether swprintf supports the 'La' and 'LA' directives... | ||
| 2316 | dnl 30 = checking whether swprintf supports the 'lc' directive... | ||
| 2189 | dnl | 2317 | dnl |
| 2190 | dnl . = yes, # = no. | 2318 | dnl . = yes, # = no. |
| 2191 | dnl | 2319 | dnl |
| 2192 | dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 2320 | dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
| 2193 | dnl musl libc 1.2.3 . # . . . . # # . . . # . . . . ? . . . . . . . . # . # | 2321 | dnl musl libc 1.2.3 . # . . . . # # . . . # . . . . . . . . . . . . . . . # . # |
| 2194 | dnl glibc 2.35 . # . . . . . . . . . . . . . . . . . . . . . . . . . . | 2322 | dnl glibc 2.35 . # . . . . . . . . . . . . # . . . . . . . . . . . . . . . |
| 2195 | dnl glibc 2.5 . # . . . . # # . . . . . . . . . . . . . . . . . . # . | 2323 | dnl glibc 2.5 . # . . . . # # . . . . . . # . . . . . . . . . . . . . # . |
| 2196 | dnl glibc 2.3.6 . # . . . # # # . . . . . . . . . . . . . . . . . . # . | 2324 | dnl glibc 2.3.6 . # . . . # # # . . . . . . . . . . . . . . . . . . . . # . |
| 2197 | dnl FreeBSD 14.0 . . . . . # . . . . . . . . . . . . # . . . . . . # . # | 2325 | dnl FreeBSD 14.0 . . . . . # . . . . . . . . # . . . . . # . . . . . . # . # |
| 2198 | dnl FreeBSD 13.0 . # . . . # # # . . . . . . . . . . # . . . . . . # . # | 2326 | dnl FreeBSD 13.0 . # . . . # # # . . . . . . # . . . . . # . . . . . . # . # |
| 2199 | dnl FreeBSD 5.4, 6.1 . # . . . # # # . . . . . . . # ? . # . . . . . . # ? ? | 2327 | dnl FreeBSD 5.4, 6.1 . # . . . # # # . . . . . . . . . # ? . # . . . . . . # ? ? |
| 2200 | dnl Mac OS X 10.13.5 . # . . # # # # . # . . . . . . . . . . . . # . . # ? ? | 2328 | dnl Mac OS X 10.13.5 . # . . # # # # . # . . . . ? ? . . . . . . . . # . . # ? ? |
| 2201 | dnl Mac OS X 10.5.8 . # . . # # # # . . . . . . . # # . . . . . . . . # ? ? | 2329 | dnl Mac OS X 10.5.8 . # . . # # # # . . . . . . ? ? . # # . . . . . . . . # ? ? |
| 2202 | dnl Mac OS X 10.3.9 . # . . . # # # . . . . . . . # # . # . . . . . . # ? ? | 2330 | dnl Mac OS X 10.3.9 . # . . . # # # . . . . . . ? ? . # # . # . . . . . . # ? ? |
| 2203 | dnl OpenBSD 6.0, 6.7 . # . . . # # # . . . . . . . . . . # . . . . . . # . # | 2331 | dnl OpenBSD 6.0, 6.7 . # . . . # # # . . . . . . . . . . . . # . . . . . . # . # |
| 2204 | dnl OpenBSD 3.9, 4.0 . # . # # # # # # . # . . # . # ? . # . . . . . . # ? ? | 2332 | dnl OpenBSD 3.9, 4.0 . # . # # # # # # . # . . # ? ? . # ? . # . . . . . . # ? ? |
| 2205 | dnl Cygwin 1.7.0 (2009) . # . . # . # # . . ? ? . . . . ? . ? . . . . . . ? ? ? | 2333 | dnl Cygwin 1.7.0 (2009) . # . . # . # # . . ? ? . . ? ? . . ? . ? . . . . . . ? ? ? |
| 2206 | dnl Cygwin 1.5.25 (2008) . # . . # # # # . . # ? . . . . ? . # . . . . . . ? ? ? | 2334 | dnl Cygwin 1.5.25 (2008) . # . . # # # # . . # ? . . ? ? . . ? . # . . . . . . ? ? ? |
| 2207 | dnl Cygwin 1.5.19 (2006) # # . . # # # # # . # ? . # . # ? # # . . . . . . ? ? ? | 2335 | dnl Cygwin 1.5.19 (2006) # # . . # # # # # . # ? . # ? ? . # ? # # . . . . . . ? ? ? |
| 2208 | dnl Solaris 11.4 . # . # # # # # . . # . . . . # . . . . . . . . . . # . | 2336 | dnl Solaris 11.4 . # . # # # # # . . # . . . # # . # . . . . . . . . . . # . |
| 2209 | dnl Solaris 11.3 . # . . . # # # . . # . . . . . . . . . . . . . . . # . | 2337 | dnl Solaris 11.3 . # . . . # # # . . # . . . ? ? . . . . . . . . . . . . # . |
| 2210 | dnl Solaris 11.0 . # . # # # # # . . # . . . . # . . . . . . . . . ? ? ? | 2338 | dnl Solaris 11.0 . # . # # # # # . . # . . . ? ? . # . . . . . . . . . ? ? ? |
| 2211 | dnl Solaris 10 . # . # # # # # . . # . . . . # . # . . . . . . . . # . | 2339 | dnl Solaris 10 . # . # # # # # . . # . . . # # . # . # . . . . . . . . # . |
| 2212 | dnl Solaris 2.6 ... 9 # # . # # # # # # . # . . . . # ? # . . . # . . . ? ? ? | 2340 | dnl Solaris 2.6 ... 9 # # . # # # # # # . # . . . ? ? . # ? # . . . # . . . ? ? ? |
| 2213 | dnl Solaris 2.5.1 # # . # # # # # # . # . . . . # ? . . # # # # # # ? ? ? | 2341 | dnl Solaris 2.5.1 # # . # # # # # # . # . . . ? ? . # ? . . # # # # # # ? ? ? |
| 2214 | dnl AIX 7.1 . # . # # # # # . . . . . . . # . # . . . . . . . # . . | 2342 | dnl AIX 7.1 . # . # # # # # . . . . . . . . . # . # . . . . . . . # . . |
| 2215 | dnl AIX 5.2 . # . # # # # # . . . . . . . # ? . . . . . . . . # ? ? | 2343 | dnl AIX 5.2 . # . # # # # # . . . . . . ? ? . # ? . . . . . . . . # ? ? |
| 2216 | dnl AIX 4.3.2, 5.1 # # . # # # # # # . . . . . . # ? . . . . # . . . # ? ? | 2344 | dnl AIX 4.3.2, 5.1 # # . # # # # # # . . . . . ? ? . # ? . . . . # . . . # ? ? |
| 2217 | dnl HP-UX 11.31 . # . . . # # # . . . ? . . . # ? . . . . # # . . ? ? ? | 2345 | dnl HP-UX 11.31 . # . . . # # # . . . ? . . ? ? . # ? . . . . # # . . ? ? ? |
| 2218 | dnl HP-UX 11.{00,11,23} # # . . . # # # # . . ? . . . # ? . . . . # # . # ? ? ? | 2346 | dnl HP-UX 11.{00,11,23} # # . . . # # # # . . ? . . ? ? . # ? . . . . # # . # ? ? ? |
| 2219 | dnl HP-UX 10.20 # # . # . # # # # . ? ? . . # # ? . . . . # # ? # ? ? ? | 2347 | dnl HP-UX 10.20 # # . # . # # # # . ? ? . . ? ? # # ? . . . . # # ? # ? ? ? |
| 2220 | dnl IRIX 6.5 # # . # # # # # # . # . . . . # ? . . . . # . . . # ? ? | 2348 | dnl IRIX 6.5 # # . # # # # # # . # . . . ? ? . # ? . . . . # . . . # ? ? |
| 2221 | dnl OSF/1 5.1 # # . # # # # # # . . ? . . . # ? . . . . # . . # ? ? ? | 2349 | dnl OSF/1 5.1 # # . # # # # # # . . ? . . ? ? . # ? . . . . # . . # ? ? ? |
| 2222 | dnl OSF/1 4.0d # # . # # # # # # . . ? . . . # ? . . # # # # # # ? ? ? | 2350 | dnl OSF/1 4.0d # # . # # # # # # . . ? . . ? ? . # ? . . # # # # # # ? ? ? |
| 2223 | dnl NetBSD 9.0 . # . . . # # # . . . . . . . . . . . . . . . . . # . # | 2351 | dnl NetBSD 9.0 . # . . . # # # . . . . . . # # . . . . . . . . . . . # . # |
| 2224 | dnl NetBSD 5.0 . # . . # # # # . . . . . . . # ? . # . . . . . . # ? ? | 2352 | dnl NetBSD 5.0 . # . . # # # # . . . . . . ? ? . # ? . # . . . . . . # ? ? |
| 2225 | dnl NetBSD 4.0 . # ? ? ? ? # # ? . ? . . ? ? ? ? ? ? . . . ? ? ? # ? ? | 2353 | dnl NetBSD 4.0 . # ? ? ? ? # # ? . ? . . ? ? ? ? ? ? ? ? . . . ? ? ? # ? ? |
| 2226 | dnl NetBSD 3.0 . # . . . # # # # . ? . # # ? # ? . # . . . . . . # ? ? | 2354 | dnl NetBSD 3.0 . # . . . # # # # . ? . # # ? ? ? # ? . # . . . . . . # ? ? |
| 2227 | dnl Haiku . # . . # # # # # . # ? . . . . ? . ? . . ? . . . . # . | 2355 | dnl Haiku . # . . # # # # # . # ? . . # . . . ? . ? . . ? . . . . # . |
| 2228 | dnl BeOS # # # . # # # # # . ? ? # . ? . ? # ? . . ? . . . ? ? ? | 2356 | dnl BeOS # # # . # # # # # . ? ? # . ? ? ? . ? # ? . . ? . . . ? ? ? |
| 2229 | dnl Android 4.3 . # . # # # # # # # # ? . # . # ? . # . . . # . . ? ? ? | 2357 | dnl Android 4.3 . # . # # # # # # # # ? . # ? ? . # ? . # . . . # . . ? ? ? |
| 2230 | dnl old mingw / msvcrt # # # # # # # # # . . ? # # . # ? # ? . # # # . . # ? ? | 2358 | dnl old mingw / msvcrt # # # # # # # # # . . ? # # ? ? . # ? # ? . # # # . . # ? ? |
| 2231 | dnl MSVC 9 # # # # # # # # # # . ? # # . # ? # ? # # # # . . # ? ? | 2359 | dnl MSVC 9 # # # # # # # # # # . ? # # ? ? . # ? # ? # # # # . . # ? ? |
| 2232 | dnl mingw 2009-2011 . # # . # . # # . . . ? # # . . ? . ? . . . . . . # ? ? | 2360 | dnl mingw 2009-2011 . # # . # . # # . . . ? # # ? ? . . ? . ? . . . . . . # ? ? |
| 2233 | dnl mingw-w64 2011 # # # # # # # # # . . ? # # . # ? # ? . # # # . . # ? ? | 2361 | dnl mingw-w64 2011 # # # # # # # # # . . ? # # ? ? . # ? # ? . # # # . . # ? ? |
diff --git a/gl/m4/pthread-once.m4 b/gl/m4/pthread-once.m4 new file mode 100644 index 00000000..85549254 --- /dev/null +++ b/gl/m4/pthread-once.m4 | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | # pthread-once.m4 | ||
| 2 | # serial 6 | ||
| 3 | dnl Copyright (C) 2019-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN([gl_PTHREAD_ONCE], | ||
| 10 | [ | ||
| 11 | AC_REQUIRE([gl_PTHREAD_H]) | ||
| 12 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 13 | AC_REQUIRE([gl_PTHREADLIB]) | ||
| 14 | |||
| 15 | if { case "$host_os" in mingw* | windows*) true;; *) false;; esac; } \ | ||
| 16 | && test $gl_threads_api = windows; then | ||
| 17 | dnl Choose function names that don't conflict with the mingw-w64 winpthreads | ||
| 18 | dnl library. | ||
| 19 | REPLACE_PTHREAD_ONCE=1 | ||
| 20 | PTHREAD_ONCE_LIB= | ||
| 21 | else | ||
| 22 | if test $HAVE_PTHREAD_H = 0; then | ||
| 23 | HAVE_PTHREAD_ONCE=0 | ||
| 24 | PTHREAD_ONCE_LIB= | ||
| 25 | else | ||
| 26 | dnl Work around Cygwin 3.5.3 bug. | ||
| 27 | AC_CACHE_CHECK([whether pthread_once works], | ||
| 28 | [gl_cv_func_pthread_once_works], | ||
| 29 | [case "$host_os" in | ||
| 30 | cygwin*) gl_cv_func_pthread_once_works="guessing no" ;; | ||
| 31 | *) gl_cv_func_pthread_once_works="yes" ;; | ||
| 32 | esac | ||
| 33 | ]) | ||
| 34 | case "$gl_cv_func_pthread_once_works" in | ||
| 35 | *yes) ;; | ||
| 36 | *) REPLACE_PTHREAD_ONCE=1 ;; | ||
| 37 | esac | ||
| 38 | dnl Determine whether linking requires $(LIBPMULTITHREAD) or only | ||
| 39 | dnl $(LIBPTHREAD). | ||
| 40 | if test -z "$LIBPTHREAD" && test -n "$LIBPMULTITHREAD"; then | ||
| 41 | AC_CACHE_CHECK([whether pthread_once can be used without linking with libpthread], | ||
| 42 | [gl_cv_func_pthread_once_no_lib], | ||
| 43 | [AC_RUN_IFELSE( | ||
| 44 | [AC_LANG_PROGRAM( | ||
| 45 | [[#include <pthread.h> | ||
| 46 | static pthread_once_t a_once = PTHREAD_ONCE_INIT; | ||
| 47 | static int a; | ||
| 48 | static void a_init (void) { a = 8647; } | ||
| 49 | ]], | ||
| 50 | [[if (pthread_once (&a_once, a_init)) return 1; | ||
| 51 | if (a != 8647) return 2; | ||
| 52 | return 0; | ||
| 53 | ]])], | ||
| 54 | [gl_cv_func_pthread_once_no_lib=yes], | ||
| 55 | [gl_cv_func_pthread_once_no_lib=no], | ||
| 56 | [case "$host_os" in | ||
| 57 | # Guess no on glibc. | ||
| 58 | *-gnu* | gnu*) | ||
| 59 | gl_cv_func_pthread_once_no_lib="guessing no" ;; | ||
| 60 | # Guess no on FreeBSD. | ||
| 61 | freebsd* | dragonfly* | midnightbsd*) | ||
| 62 | gl_cv_func_pthread_once_no_lib="guessing no" ;; | ||
| 63 | # Guess yes otherwise. | ||
| 64 | *) | ||
| 65 | gl_cv_func_pthread_once_no_lib="guessing yes" ;; | ||
| 66 | esac | ||
| 67 | ]) | ||
| 68 | ]) | ||
| 69 | case "$gl_cv_func_pthread_once_no_lib" in | ||
| 70 | *yes) PTHREAD_ONCE_LIB="$LIBPTHREAD" ;; | ||
| 71 | *) PTHREAD_ONCE_LIB="$LIBPMULTITHREAD" ;; | ||
| 72 | esac | ||
| 73 | dnl Expected result: | ||
| 74 | dnl PTHREAD_ONCE_LIB is $(LIBPMULTITHREAD) on glibc < 2.34, FreeBSD. | ||
| 75 | dnl PTHREAD_ONCE_LIB is $(LIBPTHREAD) in particular on | ||
| 76 | dnl musl libc, macOS, NetBSD, Solaris, Cygwin, Haiku, Android. | ||
| 77 | else | ||
| 78 | PTHREAD_ONCE_LIB="$LIBPTHREAD" | ||
| 79 | fi | ||
| 80 | fi | ||
| 81 | fi | ||
| 82 | AC_SUBST([PTHREAD_ONCE_LIB]) | ||
| 83 | ]) | ||
diff --git a/gl/m4/pthread-spin.m4 b/gl/m4/pthread-spin.m4 new file mode 100644 index 00000000..aae2fb3b --- /dev/null +++ b/gl/m4/pthread-spin.m4 | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | # pthread-spin.m4 | ||
| 2 | # serial 8 | ||
| 3 | dnl Copyright (C) 2019-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN_ONCE([gl_PTHREAD_SPIN], | ||
| 10 | [ | ||
| 11 | AC_REQUIRE([gl_PTHREAD_H_PART1]) | ||
| 12 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 13 | |||
| 14 | if { case "$host_os" in mingw* | windows*) true;; *) false;; esac; } \ | ||
| 15 | && test $gl_threads_api = windows; then | ||
| 16 | dnl Choose function names that don't conflict with the mingw-w64 winpthreads | ||
| 17 | dnl library. | ||
| 18 | REPLACE_PTHREAD_SPIN_INIT=1 | ||
| 19 | REPLACE_PTHREAD_SPIN_LOCK=1 | ||
| 20 | REPLACE_PTHREAD_SPIN_TRYLOCK=1 | ||
| 21 | REPLACE_PTHREAD_SPIN_UNLOCK=1 | ||
| 22 | REPLACE_PTHREAD_SPIN_DESTROY=1 | ||
| 23 | else | ||
| 24 | if test $HAVE_PTHREAD_H = 0 || test $HAVE_PTHREAD_SPINLOCK_T = 0; then | ||
| 25 | HAVE_PTHREAD_SPIN_INIT=0 | ||
| 26 | HAVE_PTHREAD_SPIN_LOCK=0 | ||
| 27 | HAVE_PTHREAD_SPIN_TRYLOCK=0 | ||
| 28 | HAVE_PTHREAD_SPIN_UNLOCK=0 | ||
| 29 | HAVE_PTHREAD_SPIN_DESTROY=0 | ||
| 30 | else | ||
| 31 | dnl Test whether the gnulib module 'threadlib' is in use. | ||
| 32 | dnl Some packages like Emacs use --avoid=threadlib. | ||
| 33 | dnl Write the symbol in such a way that it does not cause 'aclocal' to pick | ||
| 34 | dnl the threadlib.m4 file that is installed in $PREFIX/share/aclocal/. | ||
| 35 | m4_ifdef([gl_][THREADLIB], [ | ||
| 36 | AC_REQUIRE([gl_][THREADLIB]) | ||
| 37 | dnl Test whether the functions actually exist. | ||
| 38 | dnl FreeBSD 5.2.1 declares them but does not define them. | ||
| 39 | AC_CACHE_CHECK([for pthread_spin_init], | ||
| 40 | [gl_cv_func_pthread_spin_init_in_LIBMULTITHREAD], | ||
| 41 | [gl_saved_LIBS="$LIBS" | ||
| 42 | LIBS="$LIBS $LIBMULTITHREAD" | ||
| 43 | AC_LINK_IFELSE( | ||
| 44 | [AC_LANG_PROGRAM( | ||
| 45 | [[#include <pthread.h> | ||
| 46 | ]], | ||
| 47 | [[pthread_spinlock_t lock; | ||
| 48 | return pthread_spin_init (&lock, 0); | ||
| 49 | ]]) | ||
| 50 | ], | ||
| 51 | [gl_cv_func_pthread_spin_init_in_LIBMULTITHREAD=yes], | ||
| 52 | [gl_cv_func_pthread_spin_init_in_LIBMULTITHREAD=no]) | ||
| 53 | LIBS="$gl_saved_LIBS" | ||
| 54 | ]) | ||
| 55 | if test $gl_cv_func_pthread_spin_init_in_LIBMULTITHREAD != yes; then | ||
| 56 | HAVE_PTHREAD_SPIN_INIT=0 | ||
| 57 | REPLACE_PTHREAD_SPIN_INIT=1 | ||
| 58 | HAVE_PTHREAD_SPIN_LOCK=0 | ||
| 59 | REPLACE_PTHREAD_SPIN_LOCK=1 | ||
| 60 | HAVE_PTHREAD_SPIN_TRYLOCK=0 | ||
| 61 | REPLACE_PTHREAD_SPIN_TRYLOCK=1 | ||
| 62 | HAVE_PTHREAD_SPIN_UNLOCK=0 | ||
| 63 | REPLACE_PTHREAD_SPIN_UNLOCK=1 | ||
| 64 | HAVE_PTHREAD_SPIN_DESTROY=0 | ||
| 65 | REPLACE_PTHREAD_SPIN_DESTROY=1 | ||
| 66 | fi | ||
| 67 | ], [ | ||
| 68 | : | ||
| 69 | ]) | ||
| 70 | fi | ||
| 71 | fi | ||
| 72 | ]) | ||
diff --git a/gl/m4/pthread_h.m4 b/gl/m4/pthread_h.m4 new file mode 100644 index 00000000..bb921386 --- /dev/null +++ b/gl/m4/pthread_h.m4 | |||
| @@ -0,0 +1,293 @@ | |||
| 1 | # pthread_h.m4 | ||
| 2 | # serial 11 | ||
| 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN_ONCE([gl_PTHREAD_H_PART1], | ||
| 10 | [ | ||
| 11 | dnl Ensure to expand the default settings once only, before all statements | ||
| 12 | dnl that occur in other macros. | ||
| 13 | AC_REQUIRE([gl_PTHREAD_H_DEFAULTS]) | ||
| 14 | |||
| 15 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 16 | AC_REQUIRE([gl_PTHREADLIB]) | ||
| 17 | |||
| 18 | gl_CHECK_NEXT_HEADERS([pthread.h]) | ||
| 19 | if test $ac_cv_header_pthread_h = yes; then | ||
| 20 | HAVE_PTHREAD_H=1 | ||
| 21 | dnl On mingw, if --enable-threads=windows or gl_AVOID_WINPTHREAD is used, | ||
| 22 | dnl ignore the <pthread.h> from the mingw-w64 winpthreads library. | ||
| 23 | m4_ifdef([gl_][THREADLIB], [ | ||
| 24 | AC_REQUIRE([gl_][THREADLIB]) | ||
| 25 | if { case "$host_os" in mingw* | windows*) true;; *) false;; esac; } \ | ||
| 26 | && test $gl_threads_api = windows; then | ||
| 27 | HAVE_PTHREAD_H=0 | ||
| 28 | fi | ||
| 29 | ]) | ||
| 30 | else | ||
| 31 | HAVE_PTHREAD_H=0 | ||
| 32 | fi | ||
| 33 | AC_SUBST([HAVE_PTHREAD_H]) | ||
| 34 | |||
| 35 | AC_CHECK_TYPES([pthread_t, pthread_spinlock_t], [], [], | ||
| 36 | [AC_INCLUDES_DEFAULT[ | ||
| 37 | #if HAVE_PTHREAD_H | ||
| 38 | #include <pthread.h> | ||
| 39 | #endif]]) | ||
| 40 | if test $ac_cv_type_pthread_t != yes; then | ||
| 41 | HAVE_PTHREAD_T=0 | ||
| 42 | fi | ||
| 43 | if test $ac_cv_type_pthread_spinlock_t != yes; then | ||
| 44 | HAVE_PTHREAD_SPINLOCK_T=0 | ||
| 45 | fi | ||
| 46 | ]) | ||
| 47 | |||
| 48 | AC_DEFUN([gl_PTHREAD_H], | ||
| 49 | [ | ||
| 50 | AC_REQUIRE([gl_PTHREAD_H_PART1]) | ||
| 51 | |||
| 52 | dnl Set HAVE_PTHREAD_SPIN_INIT, REPLACE_PTHREAD_SPIN_INIT. | ||
| 53 | gl_PTHREAD_SPIN | ||
| 54 | |||
| 55 | dnl Constants may be defined as C preprocessor macros or as enum items. | ||
| 56 | |||
| 57 | AC_CACHE_CHECK([for PTHREAD_CREATE_DETACHED], | ||
| 58 | [gl_cv_const_PTHREAD_CREATE_DETACHED], | ||
| 59 | [AC_COMPILE_IFELSE( | ||
| 60 | [AC_LANG_PROGRAM( | ||
| 61 | [[#include <pthread.h> | ||
| 62 | int x = PTHREAD_CREATE_DETACHED; | ||
| 63 | ]], | ||
| 64 | [[]])], | ||
| 65 | [gl_cv_const_PTHREAD_CREATE_DETACHED=yes], | ||
| 66 | [gl_cv_const_PTHREAD_CREATE_DETACHED=no]) | ||
| 67 | ]) | ||
| 68 | if test $gl_cv_const_PTHREAD_CREATE_DETACHED != yes; then | ||
| 69 | HAVE_PTHREAD_CREATE_DETACHED=0 | ||
| 70 | fi | ||
| 71 | |||
| 72 | AC_CACHE_CHECK([for PTHREAD_MUTEX_RECURSIVE], | ||
| 73 | [gl_cv_const_PTHREAD_MUTEX_RECURSIVE], | ||
| 74 | [AC_COMPILE_IFELSE( | ||
| 75 | [AC_LANG_PROGRAM( | ||
| 76 | [[#include <pthread.h> | ||
| 77 | int x = PTHREAD_MUTEX_RECURSIVE; | ||
| 78 | ]], | ||
| 79 | [[]])], | ||
| 80 | [gl_cv_const_PTHREAD_MUTEX_RECURSIVE=yes], | ||
| 81 | [gl_cv_const_PTHREAD_MUTEX_RECURSIVE=no]) | ||
| 82 | ]) | ||
| 83 | if test $gl_cv_const_PTHREAD_MUTEX_RECURSIVE != yes; then | ||
| 84 | HAVE_PTHREAD_MUTEX_RECURSIVE=0 | ||
| 85 | fi | ||
| 86 | |||
| 87 | AC_CACHE_CHECK([for PTHREAD_MUTEX_ROBUST], | ||
| 88 | [gl_cv_const_PTHREAD_MUTEX_ROBUST], | ||
| 89 | [AC_COMPILE_IFELSE( | ||
| 90 | [AC_LANG_PROGRAM( | ||
| 91 | [[#include <pthread.h> | ||
| 92 | int x = PTHREAD_MUTEX_ROBUST; | ||
| 93 | ]], | ||
| 94 | [[]])], | ||
| 95 | [gl_cv_const_PTHREAD_MUTEX_ROBUST=yes], | ||
| 96 | [gl_cv_const_PTHREAD_MUTEX_ROBUST=no]) | ||
| 97 | ]) | ||
| 98 | if test $gl_cv_const_PTHREAD_MUTEX_ROBUST != yes; then | ||
| 99 | HAVE_PTHREAD_MUTEX_ROBUST=0 | ||
| 100 | fi | ||
| 101 | |||
| 102 | AC_CACHE_CHECK([for PTHREAD_PROCESS_SHARED], | ||
| 103 | [gl_cv_const_PTHREAD_PROCESS_SHARED], | ||
| 104 | [AC_COMPILE_IFELSE( | ||
| 105 | [AC_LANG_PROGRAM( | ||
| 106 | [[#include <pthread.h> | ||
| 107 | int x = PTHREAD_PROCESS_SHARED; | ||
| 108 | ]], | ||
| 109 | [[]])], | ||
| 110 | [gl_cv_const_PTHREAD_PROCESS_SHARED=yes], | ||
| 111 | [gl_cv_const_PTHREAD_PROCESS_SHARED=no]) | ||
| 112 | ]) | ||
| 113 | if test $gl_cv_const_PTHREAD_PROCESS_SHARED != yes; then | ||
| 114 | HAVE_PTHREAD_PROCESS_SHARED=0 | ||
| 115 | fi | ||
| 116 | |||
| 117 | dnl Check for declarations of anything we want to poison if the | ||
| 118 | dnl corresponding gnulib module is not in use, if it is not common | ||
| 119 | dnl enough to be declared everywhere. | ||
| 120 | gl_WARN_ON_USE_PREPARE([[#include <pthread.h> | ||
| 121 | ]], [ | ||
| 122 | pthread_create pthread_attr_init pthread_attr_getdetachstate | ||
| 123 | pthread_attr_setdetachstate pthread_attr_destroy pthread_self pthread_equal | ||
| 124 | pthread_detach pthread_join pthread_exit | ||
| 125 | pthread_once | ||
| 126 | pthread_mutex_init pthread_mutexattr_init pthread_mutexattr_gettype | ||
| 127 | pthread_mutexattr_settype pthread_mutexattr_getrobust | ||
| 128 | pthread_mutexattr_setrobust pthread_mutexattr_destroy pthread_mutex_lock | ||
| 129 | pthread_mutex_trylock pthread_mutex_timedlock pthread_mutex_unlock | ||
| 130 | pthread_mutex_destroy | ||
| 131 | pthread_rwlock_init pthread_rwlockattr_init pthread_rwlockattr_destroy | ||
| 132 | pthread_rwlock_rdlock pthread_rwlock_wrlock pthread_rwlock_tryrdlock | ||
| 133 | pthread_rwlock_trywrlock pthread_rwlock_timedrdlock | ||
| 134 | pthread_rwlock_timedwrlock pthread_rwlock_unlock pthread_rwlock_destroy | ||
| 135 | pthread_cond_init pthread_condattr_init pthread_condattr_destroy | ||
| 136 | pthread_cond_wait pthread_cond_timedwait pthread_cond_signal | ||
| 137 | pthread_cond_broadcast pthread_cond_destroy | ||
| 138 | pthread_key_create pthread_setspecific pthread_getspecific | ||
| 139 | pthread_key_delete | ||
| 140 | pthread_spin_init pthread_spin_lock pthread_spin_trylock pthread_spin_unlock | ||
| 141 | pthread_spin_destroy]) | ||
| 142 | |||
| 143 | AC_REQUIRE([AC_C_RESTRICT]) | ||
| 144 | |||
| 145 | dnl For backward compatibility with gnulib versions <= 2019-07. | ||
| 146 | LIB_PTHREAD="$LIBPMULTITHREAD" | ||
| 147 | AC_SUBST([LIB_PTHREAD]) | ||
| 148 | ]) | ||
| 149 | |||
| 150 | # gl_PTHREAD_MODULE_INDICATOR([modulename]) | ||
| 151 | # sets the shell variable that indicates the presence of the given module | ||
| 152 | # to a C preprocessor expression that will evaluate to 1. | ||
| 153 | # This macro invocation must not occur in macros that are AC_REQUIREd. | ||
| 154 | AC_DEFUN([gl_PTHREAD_MODULE_INDICATOR], | ||
| 155 | [ | ||
| 156 | dnl Ensure to expand the default settings once only. | ||
| 157 | gl_PTHREAD_H_REQUIRE_DEFAULTS | ||
| 158 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) | ||
| 159 | dnl Define it also as a C macro, for the benefit of the unit tests. | ||
| 160 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) | ||
| 161 | ]) | ||
| 162 | |||
| 163 | # Initializes the default values for AC_SUBSTed shell variables. | ||
| 164 | # This macro must not be AC_REQUIREd. It must only be invoked, and only | ||
| 165 | # outside of macros or in macros that are not AC_REQUIREd. | ||
| 166 | AC_DEFUN([gl_PTHREAD_H_REQUIRE_DEFAULTS], | ||
| 167 | [ | ||
| 168 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_PTHREAD_H_MODULE_INDICATOR_DEFAULTS], [ | ||
| 169 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTHREAD_THREAD]) | ||
| 170 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTHREAD_ONCE]) | ||
| 171 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTHREAD_MUTEX]) | ||
| 172 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTHREAD_RWLOCK]) | ||
| 173 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTHREAD_COND]) | ||
| 174 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTHREAD_TSS]) | ||
| 175 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTHREAD_SPIN]) | ||
| 176 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PTHREAD_MUTEX_TIMEDLOCK]) | ||
| 177 | ]) | ||
| 178 | m4_require(GL_MODULE_INDICATOR_PREFIX[_PTHREAD_H_MODULE_INDICATOR_DEFAULTS]) | ||
| 179 | AC_REQUIRE([gl_PTHREAD_H_DEFAULTS]) | ||
| 180 | ]) | ||
| 181 | |||
| 182 | AC_DEFUN([gl_PTHREAD_H_DEFAULTS], | ||
| 183 | [ | ||
| 184 | dnl Assume proper GNU behavior unless another module says otherwise. | ||
| 185 | HAVE_PTHREAD_T=1; AC_SUBST([HAVE_PTHREAD_T]) | ||
| 186 | HAVE_PTHREAD_SPINLOCK_T=1; AC_SUBST([HAVE_PTHREAD_SPINLOCK_T]) | ||
| 187 | HAVE_PTHREAD_CREATE_DETACHED=1; AC_SUBST([HAVE_PTHREAD_CREATE_DETACHED]) | ||
| 188 | HAVE_PTHREAD_MUTEX_RECURSIVE=1; AC_SUBST([HAVE_PTHREAD_MUTEX_RECURSIVE]) | ||
| 189 | HAVE_PTHREAD_MUTEX_ROBUST=1; AC_SUBST([HAVE_PTHREAD_MUTEX_ROBUST]) | ||
| 190 | HAVE_PTHREAD_PROCESS_SHARED=1; AC_SUBST([HAVE_PTHREAD_PROCESS_SHARED]) | ||
| 191 | HAVE_PTHREAD_CREATE=1; AC_SUBST([HAVE_PTHREAD_CREATE]) | ||
| 192 | HAVE_PTHREAD_ATTR_INIT=1; AC_SUBST([HAVE_PTHREAD_ATTR_INIT]) | ||
| 193 | HAVE_PTHREAD_ATTR_GETDETACHSTATE=1; AC_SUBST([HAVE_PTHREAD_ATTR_GETDETACHSTATE]) | ||
| 194 | HAVE_PTHREAD_ATTR_SETDETACHSTATE=1; AC_SUBST([HAVE_PTHREAD_ATTR_SETDETACHSTATE]) | ||
| 195 | HAVE_PTHREAD_ATTR_DESTROY=1; AC_SUBST([HAVE_PTHREAD_ATTR_DESTROY]) | ||
| 196 | HAVE_PTHREAD_SELF=1; AC_SUBST([HAVE_PTHREAD_SELF]) | ||
| 197 | HAVE_PTHREAD_EQUAL=1; AC_SUBST([HAVE_PTHREAD_EQUAL]) | ||
| 198 | HAVE_PTHREAD_DETACH=1; AC_SUBST([HAVE_PTHREAD_DETACH]) | ||
| 199 | HAVE_PTHREAD_JOIN=1; AC_SUBST([HAVE_PTHREAD_JOIN]) | ||
| 200 | HAVE_PTHREAD_EXIT=1; AC_SUBST([HAVE_PTHREAD_EXIT]) | ||
| 201 | HAVE_PTHREAD_ONCE=1; AC_SUBST([HAVE_PTHREAD_ONCE]) | ||
| 202 | HAVE_PTHREAD_MUTEX_INIT=1; AC_SUBST([HAVE_PTHREAD_MUTEX_INIT]) | ||
| 203 | HAVE_PTHREAD_MUTEXATTR_INIT=1; AC_SUBST([HAVE_PTHREAD_MUTEXATTR_INIT]) | ||
| 204 | HAVE_PTHREAD_MUTEXATTR_GETTYPE=1; AC_SUBST([HAVE_PTHREAD_MUTEXATTR_GETTYPE]) | ||
| 205 | HAVE_PTHREAD_MUTEXATTR_SETTYPE=1; AC_SUBST([HAVE_PTHREAD_MUTEXATTR_SETTYPE]) | ||
| 206 | HAVE_PTHREAD_MUTEXATTR_GETROBUST=1; AC_SUBST([HAVE_PTHREAD_MUTEXATTR_GETROBUST]) | ||
| 207 | HAVE_PTHREAD_MUTEXATTR_SETROBUST=1; AC_SUBST([HAVE_PTHREAD_MUTEXATTR_SETROBUST]) | ||
| 208 | HAVE_PTHREAD_MUTEXATTR_DESTROY=1; AC_SUBST([HAVE_PTHREAD_MUTEXATTR_DESTROY]) | ||
| 209 | HAVE_PTHREAD_MUTEX_LOCK=1; AC_SUBST([HAVE_PTHREAD_MUTEX_LOCK]) | ||
| 210 | HAVE_PTHREAD_MUTEX_TRYLOCK=1; AC_SUBST([HAVE_PTHREAD_MUTEX_TRYLOCK]) | ||
| 211 | HAVE_PTHREAD_MUTEX_TIMEDLOCK=1; AC_SUBST([HAVE_PTHREAD_MUTEX_TIMEDLOCK]) | ||
| 212 | HAVE_PTHREAD_MUTEX_UNLOCK=1; AC_SUBST([HAVE_PTHREAD_MUTEX_UNLOCK]) | ||
| 213 | HAVE_PTHREAD_MUTEX_DESTROY=1; AC_SUBST([HAVE_PTHREAD_MUTEX_DESTROY]) | ||
| 214 | HAVE_PTHREAD_RWLOCK_INIT=1; AC_SUBST([HAVE_PTHREAD_RWLOCK_INIT]) | ||
| 215 | HAVE_PTHREAD_RWLOCKATTR_INIT=1; AC_SUBST([HAVE_PTHREAD_RWLOCKATTR_INIT]) | ||
| 216 | HAVE_PTHREAD_RWLOCKATTR_DESTROY=1; AC_SUBST([HAVE_PTHREAD_RWLOCKATTR_DESTROY]) | ||
| 217 | HAVE_PTHREAD_RWLOCK_RDLOCK=1; AC_SUBST([HAVE_PTHREAD_RWLOCK_RDLOCK]) | ||
| 218 | HAVE_PTHREAD_RWLOCK_WRLOCK=1; AC_SUBST([HAVE_PTHREAD_RWLOCK_WRLOCK]) | ||
| 219 | HAVE_PTHREAD_RWLOCK_TRYRDLOCK=1; AC_SUBST([HAVE_PTHREAD_RWLOCK_TRYRDLOCK]) | ||
| 220 | HAVE_PTHREAD_RWLOCK_TRYWRLOCK=1; AC_SUBST([HAVE_PTHREAD_RWLOCK_TRYWRLOCK]) | ||
| 221 | HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK=1; AC_SUBST([HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK]) | ||
| 222 | HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK=1; AC_SUBST([HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK]) | ||
| 223 | HAVE_PTHREAD_RWLOCK_UNLOCK=1; AC_SUBST([HAVE_PTHREAD_RWLOCK_UNLOCK]) | ||
| 224 | HAVE_PTHREAD_RWLOCK_DESTROY=1; AC_SUBST([HAVE_PTHREAD_RWLOCK_DESTROY]) | ||
| 225 | HAVE_PTHREAD_COND_INIT=1; AC_SUBST([HAVE_PTHREAD_COND_INIT]) | ||
| 226 | HAVE_PTHREAD_CONDATTR_INIT=1; AC_SUBST([HAVE_PTHREAD_CONDATTR_INIT]) | ||
| 227 | HAVE_PTHREAD_CONDATTR_DESTROY=1; AC_SUBST([HAVE_PTHREAD_CONDATTR_DESTROY]) | ||
| 228 | HAVE_PTHREAD_COND_WAIT=1; AC_SUBST([HAVE_PTHREAD_COND_WAIT]) | ||
| 229 | HAVE_PTHREAD_COND_TIMEDWAIT=1; AC_SUBST([HAVE_PTHREAD_COND_TIMEDWAIT]) | ||
| 230 | HAVE_PTHREAD_COND_SIGNAL=1; AC_SUBST([HAVE_PTHREAD_COND_SIGNAL]) | ||
| 231 | HAVE_PTHREAD_COND_BROADCAST=1; AC_SUBST([HAVE_PTHREAD_COND_BROADCAST]) | ||
| 232 | HAVE_PTHREAD_COND_DESTROY=1; AC_SUBST([HAVE_PTHREAD_COND_DESTROY]) | ||
| 233 | HAVE_PTHREAD_KEY_CREATE=1; AC_SUBST([HAVE_PTHREAD_KEY_CREATE]) | ||
| 234 | HAVE_PTHREAD_SETSPECIFIC=1; AC_SUBST([HAVE_PTHREAD_SETSPECIFIC]) | ||
| 235 | HAVE_PTHREAD_GETSPECIFIC=1; AC_SUBST([HAVE_PTHREAD_GETSPECIFIC]) | ||
| 236 | HAVE_PTHREAD_KEY_DELETE=1; AC_SUBST([HAVE_PTHREAD_KEY_DELETE]) | ||
| 237 | HAVE_PTHREAD_SPIN_INIT=1; AC_SUBST([HAVE_PTHREAD_SPIN_INIT]) | ||
| 238 | HAVE_PTHREAD_SPIN_LOCK=1; AC_SUBST([HAVE_PTHREAD_SPIN_LOCK]) | ||
| 239 | HAVE_PTHREAD_SPIN_TRYLOCK=1; AC_SUBST([HAVE_PTHREAD_SPIN_TRYLOCK]) | ||
| 240 | HAVE_PTHREAD_SPIN_UNLOCK=1; AC_SUBST([HAVE_PTHREAD_SPIN_UNLOCK]) | ||
| 241 | HAVE_PTHREAD_SPIN_DESTROY=1; AC_SUBST([HAVE_PTHREAD_SPIN_DESTROY]) | ||
| 242 | REPLACE_PTHREAD_CREATE=0; AC_SUBST([REPLACE_PTHREAD_CREATE]) | ||
| 243 | REPLACE_PTHREAD_ATTR_INIT=0; AC_SUBST([REPLACE_PTHREAD_ATTR_INIT]) | ||
| 244 | REPLACE_PTHREAD_ATTR_GETDETACHSTATE=0; AC_SUBST([REPLACE_PTHREAD_ATTR_GETDETACHSTATE]) | ||
| 245 | REPLACE_PTHREAD_ATTR_SETDETACHSTATE=0; AC_SUBST([REPLACE_PTHREAD_ATTR_SETDETACHSTATE]) | ||
| 246 | REPLACE_PTHREAD_ATTR_DESTROY=0; AC_SUBST([REPLACE_PTHREAD_ATTR_DESTROY]) | ||
| 247 | REPLACE_PTHREAD_SELF=0; AC_SUBST([REPLACE_PTHREAD_SELF]) | ||
| 248 | REPLACE_PTHREAD_EQUAL=0; AC_SUBST([REPLACE_PTHREAD_EQUAL]) | ||
| 249 | REPLACE_PTHREAD_DETACH=0; AC_SUBST([REPLACE_PTHREAD_DETACH]) | ||
| 250 | REPLACE_PTHREAD_JOIN=0; AC_SUBST([REPLACE_PTHREAD_JOIN]) | ||
| 251 | REPLACE_PTHREAD_EXIT=0; AC_SUBST([REPLACE_PTHREAD_EXIT]) | ||
| 252 | REPLACE_PTHREAD_ONCE=0; AC_SUBST([REPLACE_PTHREAD_ONCE]) | ||
| 253 | REPLACE_PTHREAD_MUTEX_INIT=0; AC_SUBST([REPLACE_PTHREAD_MUTEX_INIT]) | ||
| 254 | REPLACE_PTHREAD_MUTEXATTR_INIT=0; AC_SUBST([REPLACE_PTHREAD_MUTEXATTR_INIT]) | ||
| 255 | REPLACE_PTHREAD_MUTEXATTR_GETTYPE=0; AC_SUBST([REPLACE_PTHREAD_MUTEXATTR_GETTYPE]) | ||
| 256 | REPLACE_PTHREAD_MUTEXATTR_SETTYPE=0; AC_SUBST([REPLACE_PTHREAD_MUTEXATTR_SETTYPE]) | ||
| 257 | REPLACE_PTHREAD_MUTEXATTR_GETROBUST=0; AC_SUBST([REPLACE_PTHREAD_MUTEXATTR_GETROBUST]) | ||
| 258 | REPLACE_PTHREAD_MUTEXATTR_SETROBUST=0; AC_SUBST([REPLACE_PTHREAD_MUTEXATTR_SETROBUST]) | ||
| 259 | REPLACE_PTHREAD_MUTEXATTR_DESTROY=0; AC_SUBST([REPLACE_PTHREAD_MUTEXATTR_DESTROY]) | ||
| 260 | REPLACE_PTHREAD_MUTEX_LOCK=0; AC_SUBST([REPLACE_PTHREAD_MUTEX_LOCK]) | ||
| 261 | REPLACE_PTHREAD_MUTEX_TRYLOCK=0; AC_SUBST([REPLACE_PTHREAD_MUTEX_TRYLOCK]) | ||
| 262 | REPLACE_PTHREAD_MUTEX_TIMEDLOCK=0; AC_SUBST([REPLACE_PTHREAD_MUTEX_TIMEDLOCK]) | ||
| 263 | REPLACE_PTHREAD_MUTEX_UNLOCK=0; AC_SUBST([REPLACE_PTHREAD_MUTEX_UNLOCK]) | ||
| 264 | REPLACE_PTHREAD_MUTEX_DESTROY=0; AC_SUBST([REPLACE_PTHREAD_MUTEX_DESTROY]) | ||
| 265 | REPLACE_PTHREAD_RWLOCK_INIT=0; AC_SUBST([REPLACE_PTHREAD_RWLOCK_INIT]) | ||
| 266 | REPLACE_PTHREAD_RWLOCKATTR_INIT=0; AC_SUBST([REPLACE_PTHREAD_RWLOCKATTR_INIT]) | ||
| 267 | REPLACE_PTHREAD_RWLOCKATTR_DESTROY=0; AC_SUBST([REPLACE_PTHREAD_RWLOCKATTR_DESTROY]) | ||
| 268 | REPLACE_PTHREAD_RWLOCK_RDLOCK=0; AC_SUBST([REPLACE_PTHREAD_RWLOCK_RDLOCK]) | ||
| 269 | REPLACE_PTHREAD_RWLOCK_WRLOCK=0; AC_SUBST([REPLACE_PTHREAD_RWLOCK_WRLOCK]) | ||
| 270 | REPLACE_PTHREAD_RWLOCK_TRYRDLOCK=0; AC_SUBST([REPLACE_PTHREAD_RWLOCK_TRYRDLOCK]) | ||
| 271 | REPLACE_PTHREAD_RWLOCK_TRYWRLOCK=0; AC_SUBST([REPLACE_PTHREAD_RWLOCK_TRYWRLOCK]) | ||
| 272 | REPLACE_PTHREAD_RWLOCK_TIMEDRDLOCK=0; AC_SUBST([REPLACE_PTHREAD_RWLOCK_TIMEDRDLOCK]) | ||
| 273 | REPLACE_PTHREAD_RWLOCK_TIMEDWRLOCK=0; AC_SUBST([REPLACE_PTHREAD_RWLOCK_TIMEDWRLOCK]) | ||
| 274 | REPLACE_PTHREAD_RWLOCK_UNLOCK=0; AC_SUBST([REPLACE_PTHREAD_RWLOCK_UNLOCK]) | ||
| 275 | REPLACE_PTHREAD_RWLOCK_DESTROY=0; AC_SUBST([REPLACE_PTHREAD_RWLOCK_DESTROY]) | ||
| 276 | REPLACE_PTHREAD_COND_INIT=0; AC_SUBST([REPLACE_PTHREAD_COND_INIT]) | ||
| 277 | REPLACE_PTHREAD_CONDATTR_INIT=0; AC_SUBST([REPLACE_PTHREAD_CONDATTR_INIT]) | ||
| 278 | REPLACE_PTHREAD_CONDATTR_DESTROY=0; AC_SUBST([REPLACE_PTHREAD_CONDATTR_DESTROY]) | ||
| 279 | REPLACE_PTHREAD_COND_WAIT=0; AC_SUBST([REPLACE_PTHREAD_COND_WAIT]) | ||
| 280 | REPLACE_PTHREAD_COND_TIMEDWAIT=0; AC_SUBST([REPLACE_PTHREAD_COND_TIMEDWAIT]) | ||
| 281 | REPLACE_PTHREAD_COND_SIGNAL=0; AC_SUBST([REPLACE_PTHREAD_COND_SIGNAL]) | ||
| 282 | REPLACE_PTHREAD_COND_BROADCAST=0; AC_SUBST([REPLACE_PTHREAD_COND_BROADCAST]) | ||
| 283 | REPLACE_PTHREAD_COND_DESTROY=0; AC_SUBST([REPLACE_PTHREAD_COND_DESTROY]) | ||
| 284 | REPLACE_PTHREAD_KEY_CREATE=0; AC_SUBST([REPLACE_PTHREAD_KEY_CREATE]) | ||
| 285 | REPLACE_PTHREAD_SETSPECIFIC=0; AC_SUBST([REPLACE_PTHREAD_SETSPECIFIC]) | ||
| 286 | REPLACE_PTHREAD_GETSPECIFIC=0; AC_SUBST([REPLACE_PTHREAD_GETSPECIFIC]) | ||
| 287 | REPLACE_PTHREAD_KEY_DELETE=0; AC_SUBST([REPLACE_PTHREAD_KEY_DELETE]) | ||
| 288 | REPLACE_PTHREAD_SPIN_INIT=0; AC_SUBST([REPLACE_PTHREAD_SPIN_INIT]) | ||
| 289 | REPLACE_PTHREAD_SPIN_LOCK=0; AC_SUBST([REPLACE_PTHREAD_SPIN_LOCK]) | ||
| 290 | REPLACE_PTHREAD_SPIN_TRYLOCK=0; AC_SUBST([REPLACE_PTHREAD_SPIN_TRYLOCK]) | ||
| 291 | REPLACE_PTHREAD_SPIN_UNLOCK=0; AC_SUBST([REPLACE_PTHREAD_SPIN_UNLOCK]) | ||
| 292 | REPLACE_PTHREAD_SPIN_DESTROY=0; AC_SUBST([REPLACE_PTHREAD_SPIN_DESTROY]) | ||
| 293 | ]) | ||
diff --git a/gl/m4/pthread_rwlock_rdlock.m4 b/gl/m4/pthread_rwlock_rdlock.m4 index b8b5b117..aec9f076 100644 --- a/gl/m4/pthread_rwlock_rdlock.m4 +++ b/gl/m4/pthread_rwlock_rdlock.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # pthread_rwlock_rdlock.m4 | 1 | # pthread_rwlock_rdlock.m4 |
| 2 | # serial 8 | 2 | # serial 8 |
| 3 | dnl Copyright (C) 2017-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | dnl Inspired by | 10 | dnl Inspired by |
diff --git a/gl/m4/realloc.m4 b/gl/m4/realloc.m4 index eb90d588..67c1476b 100644 --- a/gl/m4/realloc.m4 +++ b/gl/m4/realloc.m4 | |||
| @@ -1,54 +1,22 @@ | |||
| 1 | # realloc.m4 | 1 | # realloc.m4 |
| 2 | # serial 29 | 2 | # serial 39.1 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # This is adapted with modifications from upstream Autoconf here: | 9 | # An an experimental option, the user can request a sanitized realloc() |
| 9 | # https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n1455 | 10 | # implementation, i.e. one that aborts upon undefined behaviour, |
| 10 | AC_DEFUN([_AC_FUNC_REALLOC_IF], | 11 | # by setting |
| 12 | # gl_cv_func_realloc_sanitize=yes | ||
| 13 | # at configure time. | ||
| 14 | AC_DEFUN([gl_FUNC_REALLOC_SANITIZED], | ||
| 11 | [ | 15 | [ |
| 12 | AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles | 16 | AC_CACHE_CHECK([whether realloc should abort upon undefined behaviour], |
| 13 | AC_CACHE_CHECK([whether realloc (0, 0) returns nonnull], | 17 | [gl_cv_func_realloc_sanitize], |
| 14 | [ac_cv_func_realloc_0_nonnull], | 18 | [test -n "$gl_cv_func_realloc_sanitize" || gl_cv_func_realloc_sanitize=no]) |
| 15 | [AC_RUN_IFELSE( | 19 | ]) |
| 16 | [AC_LANG_PROGRAM( | ||
| 17 | [[#include <stdlib.h> | ||
| 18 | ]], | ||
| 19 | [[void *p = realloc (0, 0); | ||
| 20 | void * volatile vp = p; | ||
| 21 | int result = !vp; | ||
| 22 | free (p); | ||
| 23 | return result;]]) | ||
| 24 | ], | ||
| 25 | [ac_cv_func_realloc_0_nonnull=yes], | ||
| 26 | [ac_cv_func_realloc_0_nonnull=no], | ||
| 27 | [case "$host_os" in | ||
| 28 | # Guess yes on platforms where we know the result. | ||
| 29 | *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \ | ||
| 30 | | gnu* | *-musl* | midipix* | midnightbsd* \ | ||
| 31 | | hpux* | solaris* | cygwin* | mingw* | windows* | msys* ) | ||
| 32 | ac_cv_func_realloc_0_nonnull="guessing yes" ;; | ||
| 33 | # If we don't know, obey --enable-cross-guesses. | ||
| 34 | *) ac_cv_func_realloc_0_nonnull="$gl_cross_guess_normal" ;; | ||
| 35 | esac | ||
| 36 | ]) | ||
| 37 | ]) | ||
| 38 | AS_CASE([$ac_cv_func_realloc_0_nonnull], [*yes], [$1], [$2]) | ||
| 39 | ])# AC_FUNC_REALLOC | ||
| 40 | |||
| 41 | # gl_FUNC_REALLOC_GNU | ||
| 42 | # ------------------- | ||
| 43 | # Replace realloc if it is not compatible with GNU libc. | ||
| 44 | AC_DEFUN([gl_FUNC_REALLOC_GNU], | ||
| 45 | [ | ||
| 46 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | ||
| 47 | AC_REQUIRE([gl_FUNC_REALLOC_POSIX]) | ||
| 48 | if test $REPLACE_REALLOC_FOR_REALLOC_GNU = 0; then | ||
| 49 | _AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC_FOR_REALLOC_GNU=1]) | ||
| 50 | fi | ||
| 51 | ])# gl_FUNC_REALLOC_GNU | ||
| 52 | 20 | ||
| 53 | # gl_FUNC_REALLOC_POSIX | 21 | # gl_FUNC_REALLOC_POSIX |
| 54 | # --------------------- | 22 | # --------------------- |
| @@ -59,7 +27,100 @@ AC_DEFUN([gl_FUNC_REALLOC_POSIX], | |||
| 59 | [ | 27 | [ |
| 60 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 28 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
| 61 | AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) | 29 | AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) |
| 62 | if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then | 30 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 31 | AC_CACHE_CHECK([whether realloc sets errno on failure], | ||
| 32 | [gl_cv_func_realloc_posix], | ||
| 33 | [ | ||
| 34 | dnl FreeBSD 15.0 realloc() does not set errno when asked for more than | ||
| 35 | dnl 0x7000000000000000 bytes. | ||
| 36 | case "$host_os" in | ||
| 37 | darwin* | freebsd* | dragonfly* | midnightbsd* | netbsd* | openbsd*) | ||
| 38 | AC_RUN_IFELSE( | ||
| 39 | [AC_LANG_SOURCE( | ||
| 40 | [[#include <errno.h> | ||
| 41 | #include <stdlib.h> | ||
| 42 | int main (int argc, char **argv) | ||
| 43 | { | ||
| 44 | void *p; | ||
| 45 | errno = 1729; | ||
| 46 | p = realloc (malloc (1), (size_t)(-1) / 100 * 49); | ||
| 47 | return (!p && errno == 1729); | ||
| 48 | } | ||
| 49 | ]]) | ||
| 50 | ], | ||
| 51 | [gl_cv_func_realloc_posix=yes], | ||
| 52 | [gl_cv_func_realloc_posix=no], | ||
| 53 | [case "$host_os" in | ||
| 54 | freebsd*) gl_cv_func_realloc_posix="guessing no" ;; | ||
| 55 | *) gl_cv_func_realloc_posix="guessing yes" ;; | ||
| 56 | esac | ||
| 57 | ]) | ||
| 58 | ;; | ||
| 59 | *) | ||
| 60 | gl_cv_func_realloc_posix="$gl_cv_func_malloc_posix" | ||
| 61 | ;; | ||
| 62 | esac | ||
| 63 | ]) | ||
| 64 | case "$gl_cv_func_realloc_posix" in | ||
| 65 | *yes) | ||
| 66 | AC_DEFINE([HAVE_REALLOC_POSIX], [1], | ||
| 67 | [Define if realloc sets errno on allocation failure.]) | ||
| 68 | ;; | ||
| 69 | *) | ||
| 70 | REPLACE_REALLOC_FOR_REALLOC_POSIX=1 | ||
| 71 | ;; | ||
| 72 | esac | ||
| 73 | AC_REQUIRE([gl_FUNC_REALLOC_SANITIZED]) | ||
| 74 | if test "$gl_cv_func_realloc_sanitize" != no; then | ||
| 63 | REPLACE_REALLOC_FOR_REALLOC_POSIX=1 | 75 | REPLACE_REALLOC_FOR_REALLOC_POSIX=1 |
| 76 | AC_DEFINE([NEED_SANITIZED_REALLOC], [1], | ||
| 77 | [Define to 1 if realloc should abort upon undefined behaviour.]) | ||
| 64 | fi | 78 | fi |
| 65 | ]) | 79 | ]) |
| 80 | |||
| 81 | # gl_FUNC_REALLOC_0_NONNULL | ||
| 82 | # ------------------------- | ||
| 83 | # Replace realloc if realloc (..., 0) returns null. | ||
| 84 | # Modules that use this macro directly or indirectly should depend | ||
| 85 | # on extensions-aix, so that _LINUX_SOURCE_COMPAT gets defined | ||
| 86 | # before this macro gets invoked. This helps if !(__VEC__ || __AIXVEC), | ||
| 87 | # and doesn't hurt otherwise. | ||
| 88 | AC_DEFUN([gl_FUNC_REALLOC_0_NONNULL], | ||
| 89 | [ | ||
| 90 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | ||
| 91 | AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles | ||
| 92 | AC_REQUIRE([gl_FUNC_REALLOC_POSIX]) | ||
| 93 | AC_CACHE_CHECK([whether realloc (..., 0) returns nonnull], | ||
| 94 | [gl_cv_func_realloc_0_nonnull], | ||
| 95 | [AC_RUN_IFELSE( | ||
| 96 | [AC_LANG_PROGRAM( | ||
| 97 | [[#include <stdlib.h> | ||
| 98 | /* Use prealloc to test; "volatile" prevents the compiler | ||
| 99 | from optimizing the realloc call away. */ | ||
| 100 | void *(*volatile prealloc) (void *, size_t) = realloc;]], | ||
| 101 | [[void *p = prealloc (0, 0); | ||
| 102 | int result = !p; | ||
| 103 | p = prealloc (p, 0); | ||
| 104 | result |= !p; | ||
| 105 | free (p); | ||
| 106 | return result;]])], | ||
| 107 | [gl_cv_func_realloc_0_nonnull=yes], | ||
| 108 | [gl_cv_func_realloc_0_nonnull=no], | ||
| 109 | [AS_CASE([$host_os], | ||
| 110 | [# Guess yes on platforms where we know the result. | ||
| 111 | freebsd* | netbsd* | openbsd* | darwin* | bitrig* \ | ||
| 112 | | *-musl* | midipix* | midnightbsd* \ | ||
| 113 | | hpux* | solaris* | cygwin*], | ||
| 114 | [gl_cv_func_realloc_0_nonnull="guessing yes"], | ||
| 115 | [# Guess as follows if we don't know. | ||
| 116 | gl_cv_func_realloc_0_nonnull=$gl_cross_guess_normal])])]) | ||
| 117 | AS_CASE([$gl_cv_func_realloc_0_nonnull], | ||
| 118 | [*yes], | ||
| 119 | [AC_DEFINE([HAVE_REALLOC_0_NONNULL], [1], | ||
| 120 | [Define to 1 if realloc (..., 0) returns nonnull.])], | ||
| 121 | [AS_CASE([$gl_cv_func_realloc_sanitize,$gl_cv_malloc_ptrdiff,$gl_cv_func_malloc_posix,$host], | ||
| 122 | [yes,*,*,* | *,no,*,* | *,*,*no,* | *,*,*,aarch64c-*-freebsd*], | ||
| 123 | [REPLACE_REALLOC_FOR_REALLOC_POSIX=1], | ||
| 124 | [# Optimize for common case of glibc 2.1.1+ and compatibles. | ||
| 125 | REPLACE_REALLOC_FOR_REALLOC_POSIX=2])]) | ||
| 126 | ]) | ||
diff --git a/gl/m4/reallocarray.m4 b/gl/m4/reallocarray.m4 index 958095e1..3970d9e1 100644 --- a/gl/m4/reallocarray.m4 +++ b/gl/m4/reallocarray.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # reallocarray.m4 | 1 | # reallocarray.m4 |
| 2 | # serial 5 | 2 | # serial 7 |
| 3 | dnl Copyright (C) 2017-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_REALLOCARRAY], | 9 | AC_DEFUN([gl_FUNC_REALLOCARRAY], |
| 9 | [ | 10 | [ |
| @@ -12,14 +13,21 @@ AC_DEFUN([gl_FUNC_REALLOCARRAY], | |||
| 12 | 13 | ||
| 13 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 14 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
| 14 | AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF]) | 15 | AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF]) |
| 16 | AC_REQUIRE([gl_FUNC_REALLOC_0_NONNULL]) | ||
| 15 | gl_CHECK_FUNCS_ANDROID([reallocarray], [[#include <stdlib.h>]]) | 17 | gl_CHECK_FUNCS_ANDROID([reallocarray], [[#include <stdlib.h>]]) |
| 16 | if test "$ac_cv_func_reallocarray" = no; then | 18 | if test "$ac_cv_func_reallocarray" = no; then |
| 17 | HAVE_REALLOCARRAY=0 | 19 | HAVE_REALLOCARRAY=0 |
| 18 | case "$gl_cv_onwards_func_reallocarray" in | 20 | case "$gl_cv_onwards_func_reallocarray" in |
| 19 | future*) REPLACE_REALLOCARRAY=1 ;; | 21 | future*) REPLACE_REALLOCARRAY=1 ;; |
| 20 | esac | 22 | esac |
| 21 | elif test "$gl_cv_malloc_ptrdiff" = no; then | 23 | else |
| 22 | REPLACE_REALLOCARRAY=1 | 24 | if test "$gl_cv_malloc_ptrdiff" = no; then |
| 25 | REPLACE_REALLOCARRAY=1 | ||
| 26 | fi | ||
| 27 | case "$gl_cv_func_realloc_0_nonnull" in | ||
| 28 | *yes) ;; | ||
| 29 | *) REPLACE_REALLOCARRAY=1 ;; | ||
| 30 | esac | ||
| 23 | fi | 31 | fi |
| 24 | ]) | 32 | ]) |
| 25 | 33 | ||
diff --git a/gl/m4/regex.m4 b/gl/m4/regex.m4 index f0101fe6..49a8059f 100644 --- a/gl/m4/regex.m4 +++ b/gl/m4/regex.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # regex.m4 | 1 | # regex.m4 |
| 2 | # serial 75 | 2 | # serial 81 |
| 3 | dnl Copyright (C) 1996-2001, 2003-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 1996-2001, 2003-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Initially derived from code in GNU grep. | 9 | dnl Initially derived from code in GNU grep. |
| 9 | dnl Mostly written by Jim Meyering. | 10 | dnl Mostly written by Jim Meyering. |
| @@ -39,19 +40,24 @@ AC_DEFUN([gl_REGEX], | |||
| 39 | #include <limits.h> | 40 | #include <limits.h> |
| 40 | #include <string.h> | 41 | #include <string.h> |
| 41 | 42 | ||
| 42 | #if defined M_CHECK_ACTION || HAVE_DECL_ALARM | 43 | #if HAVE_MALLOC_H |
| 43 | # include <signal.h> | 44 | # include <malloc.h> /* defines M_CHECK_ACTION on glibc */ |
| 44 | # include <unistd.h> | ||
| 45 | #endif | 45 | #endif |
| 46 | 46 | ||
| 47 | #if HAVE_MALLOC_H | 47 | #if defined __HAIKU__ || defined M_CHECK_ACTION || HAVE_DECL_ALARM |
| 48 | # include <malloc.h> | 48 | # include <signal.h> |
| 49 | # include <unistd.h> | ||
| 49 | #endif | 50 | #endif |
| 50 | 51 | ||
| 51 | #ifdef M_CHECK_ACTION | 52 | #if defined __HAIKU__ || defined M_CHECK_ACTION |
| 52 | /* Exit with distinguishable exit code. */ | 53 | /* Exit with distinguishable exit code. */ |
| 53 | static void sigabrt_no_core (int sig) { raise (SIGTERM); } | 54 | static void sigabrt_no_core (int sig) { raise (SIGTERM); } |
| 54 | #endif | 55 | #endif |
| 56 | |||
| 57 | /* There is no need to check whether RE_SYNTAX_EMACS is | ||
| 58 | (RE_CHAR_CLASSES | RE_INTERVALS), corresponding to | ||
| 59 | Emacs 21 (2001) and later, because Gnulib's lib/regex.h | ||
| 60 | is always used and has this value. */ | ||
| 55 | ]], | 61 | ]], |
| 56 | [[int result = 0; | 62 | [[int result = 0; |
| 57 | static struct re_pattern_buffer regex; | 63 | static struct re_pattern_buffer regex; |
| @@ -67,6 +73,9 @@ AC_DEFUN([gl_REGEX], | |||
| 67 | signal (SIGALRM, SIG_DFL); | 73 | signal (SIGALRM, SIG_DFL); |
| 68 | alarm (2); | 74 | alarm (2); |
| 69 | #endif | 75 | #endif |
| 76 | #ifdef __HAIKU__ | ||
| 77 | signal (SIGABRT, sigabrt_no_core); | ||
| 78 | #endif | ||
| 70 | #ifdef M_CHECK_ACTION | 79 | #ifdef M_CHECK_ACTION |
| 71 | signal (SIGABRT, sigabrt_no_core); | 80 | signal (SIGABRT, sigabrt_no_core); |
| 72 | mallopt (M_CHECK_ACTION, 2); | 81 | mallopt (M_CHECK_ACTION, 2); |
| @@ -388,7 +397,6 @@ AC_DEFUN([gl_PREREQ_REGEX], | |||
| 388 | AC_REQUIRE([AC_C_INLINE]) | 397 | AC_REQUIRE([AC_C_INLINE]) |
| 389 | AC_REQUIRE([AC_C_RESTRICT]) | 398 | AC_REQUIRE([AC_C_RESTRICT]) |
| 390 | AC_REQUIRE([AC_TYPE_MBSTATE_T]) | 399 | AC_REQUIRE([AC_TYPE_MBSTATE_T]) |
| 391 | AC_REQUIRE([gl_EEMALLOC]) | ||
| 392 | AC_CHECK_HEADERS([libintl.h]) | 400 | AC_CHECK_HEADERS([libintl.h]) |
| 393 | AC_CHECK_FUNCS_ONCE([isblank iswctype]) | 401 | AC_CHECK_FUNCS_ONCE([isblank iswctype]) |
| 394 | AC_CHECK_DECLS([isblank], [], [], [[#include <ctype.h>]]) | 402 | AC_CHECK_DECLS([isblank], [], [], [[#include <ctype.h>]]) |
diff --git a/gl/m4/sched_h.m4 b/gl/m4/sched_h.m4 new file mode 100644 index 00000000..1ffd465f --- /dev/null +++ b/gl/m4/sched_h.m4 | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | # sched_h.m4 | ||
| 2 | # serial 16 | ||
| 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl Written by Bruno Haible. | ||
| 10 | |||
| 11 | AC_DEFUN_ONCE([gl_SCHED_H], | ||
| 12 | [ | ||
| 13 | dnl Ensure to expand the default settings once only, before all statements | ||
| 14 | dnl that occur in other macros. | ||
| 15 | AC_REQUIRE([gl_SCHED_H_DEFAULTS]) | ||
| 16 | |||
| 17 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 18 | |||
| 19 | AC_REQUIRE([gl_CHECK_HEADER_SYS_CDEFS_H]) | ||
| 20 | |||
| 21 | AC_CHECK_HEADERS([sched.h], [], [], | ||
| 22 | [[#if HAVE_SYS_CDEFS_H | ||
| 23 | #include <sys/cdefs.h> | ||
| 24 | #endif | ||
| 25 | ]]) | ||
| 26 | gl_NEXT_HEADERS([sched.h]) | ||
| 27 | |||
| 28 | if test "$ac_cv_header_sched_h" = yes; then | ||
| 29 | HAVE_SCHED_H=1 | ||
| 30 | else | ||
| 31 | HAVE_SCHED_H=0 | ||
| 32 | fi | ||
| 33 | AC_SUBST([HAVE_SCHED_H]) | ||
| 34 | |||
| 35 | if test "$HAVE_SCHED_H" = 1; then | ||
| 36 | AC_CHECK_TYPE([struct sched_param], | ||
| 37 | [HAVE_STRUCT_SCHED_PARAM=1], [HAVE_STRUCT_SCHED_PARAM=0], | ||
| 38 | [[#if HAVE_SYS_CDEFS_H | ||
| 39 | #include <sys/cdefs.h> | ||
| 40 | #endif | ||
| 41 | #include <sched.h> | ||
| 42 | ]]) | ||
| 43 | else | ||
| 44 | HAVE_STRUCT_SCHED_PARAM=0 | ||
| 45 | case "$host_os" in | ||
| 46 | os2*) | ||
| 47 | dnl On OS/2 kLIBC, struct sched_param is in spawn.h. | ||
| 48 | AC_CHECK_TYPE([struct sched_param], | ||
| 49 | [HAVE_STRUCT_SCHED_PARAM=1], [], | ||
| 50 | [#include <spawn.h>]) | ||
| 51 | ;; | ||
| 52 | vms) | ||
| 53 | dnl On OpenVMS 7.2 or newer, struct sched_param is in pthread.h. | ||
| 54 | AC_CHECK_TYPE([struct sched_param], | ||
| 55 | [HAVE_STRUCT_SCHED_PARAM=1], [], | ||
| 56 | [#include <pthread.h>]) | ||
| 57 | ;; | ||
| 58 | esac | ||
| 59 | fi | ||
| 60 | AC_SUBST([HAVE_STRUCT_SCHED_PARAM]) | ||
| 61 | |||
| 62 | dnl Ensure the type pid_t gets defined. | ||
| 63 | AC_REQUIRE([AC_TYPE_PID_T]) | ||
| 64 | |||
| 65 | dnl Check for declarations of anything we want to poison if the | ||
| 66 | dnl corresponding gnulib module is not in use, if it is not common | ||
| 67 | dnl enough to be declared everywhere. | ||
| 68 | gl_WARN_ON_USE_PREPARE([[#include <sched.h> | ||
| 69 | ]], [sched_yield]) | ||
| 70 | ]) | ||
| 71 | |||
| 72 | # gl_SCHED_MODULE_INDICATOR([modulename]) | ||
| 73 | # sets the shell variable that indicates the presence of the given module | ||
| 74 | # to a C preprocessor expression that will evaluate to 1. | ||
| 75 | # This macro invocation must not occur in macros that are AC_REQUIREd. | ||
| 76 | AC_DEFUN([gl_SCHED_MODULE_INDICATOR], | ||
| 77 | [ | ||
| 78 | dnl Ensure to expand the default settings once only. | ||
| 79 | gl_SCHED_H_REQUIRE_DEFAULTS | ||
| 80 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) | ||
| 81 | dnl Define it also as a C macro, for the benefit of the unit tests. | ||
| 82 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) | ||
| 83 | ]) | ||
| 84 | |||
| 85 | # Initializes the default values for AC_SUBSTed shell variables. | ||
| 86 | # This macro must not be AC_REQUIREd. It must only be invoked, and only | ||
| 87 | # outside of macros or in macros that are not AC_REQUIREd. | ||
| 88 | AC_DEFUN([gl_SCHED_H_REQUIRE_DEFAULTS], | ||
| 89 | [ | ||
| 90 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_SCHED_H_MODULE_INDICATOR_DEFAULTS], [ | ||
| 91 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SCHED_YIELD]) | ||
| 92 | ]) | ||
| 93 | m4_require(GL_MODULE_INDICATOR_PREFIX[_SCHED_H_MODULE_INDICATOR_DEFAULTS]) | ||
| 94 | AC_REQUIRE([gl_SCHED_H_DEFAULTS]) | ||
| 95 | ]) | ||
| 96 | |||
| 97 | AC_DEFUN([gl_SCHED_H_DEFAULTS], | ||
| 98 | [ | ||
| 99 | dnl Assume proper GNU behavior unless another module says otherwise. | ||
| 100 | HAVE_SCHED_YIELD=1; AC_SUBST([HAVE_SCHED_YIELD]) | ||
| 101 | REPLACE_SCHED_YIELD=0; AC_SUBST([REPLACE_SCHED_YIELD]) | ||
| 102 | ]) | ||
diff --git a/gl/m4/servent.m4 b/gl/m4/servent.m4 index 422003b4..ba6ebd1d 100644 --- a/gl/m4/servent.m4 +++ b/gl/m4/servent.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # servent.m4 | 1 | # servent.m4 |
| 2 | # serial 5 | 2 | # serial 5 |
| 3 | dnl Copyright (C) 2008, 2010-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008, 2010-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_SERVENT], | 9 | AC_DEFUN([gl_SERVENT], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/setenv.m4 b/gl/m4/setenv.m4 index e7f00f39..727e35af 100644 --- a/gl/m4/setenv.m4 +++ b/gl/m4/setenv.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # setenv.m4 | 1 | # setenv.m4 |
| 2 | # serial 33 | 2 | # serial 35 |
| 3 | dnl Copyright (C) 2001-2004, 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2001-2004, 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_SETENV], | 9 | AC_DEFUN([gl_FUNC_SETENV], |
| 9 | [ | 10 | [ |
| @@ -155,6 +156,7 @@ AC_DEFUN([gl_PREREQ_SETENV], | |||
| 155 | AC_REQUIRE([gl_ENVIRON]) | 156 | AC_REQUIRE([gl_ENVIRON]) |
| 156 | AC_CHECK_HEADERS_ONCE([unistd.h]) | 157 | AC_CHECK_HEADERS_ONCE([unistd.h]) |
| 157 | AC_CHECK_HEADERS([search.h]) | 158 | AC_CHECK_HEADERS([search.h]) |
| 159 | AC_CHECK_DECLS_ONCE([_putenv]) | ||
| 158 | gl_CHECK_FUNCS_ANDROID([tsearch], [[#include <search.h>]]) | 160 | gl_CHECK_FUNCS_ANDROID([tsearch], [[#include <search.h>]]) |
| 159 | ]) | 161 | ]) |
| 160 | 162 | ||
| @@ -163,4 +165,5 @@ AC_DEFUN([gl_PREREQ_UNSETENV], | |||
| 163 | [ | 165 | [ |
| 164 | AC_REQUIRE([gl_ENVIRON]) | 166 | AC_REQUIRE([gl_ENVIRON]) |
| 165 | AC_CHECK_HEADERS_ONCE([unistd.h]) | 167 | AC_CHECK_HEADERS_ONCE([unistd.h]) |
| 168 | AC_CHECK_DECLS_ONCE([_putenv]) | ||
| 166 | ]) | 169 | ]) |
diff --git a/gl/m4/setlocale_null.m4 b/gl/m4/setlocale_null.m4 index e5b7d28b..3c8b693e 100644 --- a/gl/m4/setlocale_null.m4 +++ b/gl/m4/setlocale_null.m4 | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | # setlocale_null.m4 | 1 | # setlocale_null.m4 |
| 2 | # serial 9 | 2 | # serial 10 |
| 3 | dnl Copyright (C) 2019-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_SETLOCALE_NULL], | 9 | AC_DEFUN_ONCE([gl_FUNC_SETLOCALE_NULL], |
| 9 | [ | 10 | [ |
| 10 | AC_REQUIRE([AC_CANONICAL_HOST]) | 11 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 11 | AC_REQUIRE([gl_PTHREADLIB]) | 12 | AC_REQUIRE([gl_PTHREADLIB]) |
diff --git a/gl/m4/sha256.m4 b/gl/m4/sha256.m4 index ad5596a4..30e8deeb 100644 --- a/gl/m4/sha256.m4 +++ b/gl/m4/sha256.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # sha256.m4 | 1 | # sha256.m4 |
| 2 | # serial 8 | 2 | # serial 8 |
| 3 | dnl Copyright (C) 2005, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_SHA256], | 9 | AC_DEFUN([gl_SHA256], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/size_max.m4 b/gl/m4/size_max.m4 index df91cf06..b0460d45 100644 --- a/gl/m4/size_max.m4 +++ b/gl/m4/size_max.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # size_max.m4 | 1 | # size_max.m4 |
| 2 | # serial 12 | 2 | # serial 12 |
| 3 | dnl Copyright (C) 2003, 2005-2006, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003, 2005-2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | 10 | ||
diff --git a/gl/m4/snprintf.m4 b/gl/m4/snprintf.m4 index 6dbe146f..2c50cee9 100644 --- a/gl/m4/snprintf.m4 +++ b/gl/m4/snprintf.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # snprintf.m4 | 1 | # snprintf.m4 |
| 2 | # serial 7 | 2 | # serial 7 |
| 3 | dnl Copyright (C) 2002-2004, 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2004, 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Libintl 0.17 will replace snprintf only if it does not support %1$s, | 9 | dnl Libintl 0.17 will replace snprintf only if it does not support %1$s, |
| 9 | dnl but defers to any gnulib snprintf replacements. Therefore, gnulib | 10 | dnl but defers to any gnulib snprintf replacements. Therefore, gnulib |
diff --git a/gl/m4/socketlib.m4 b/gl/m4/socketlib.m4 index 09f01161..e3509f81 100644 --- a/gl/m4/socketlib.m4 +++ b/gl/m4/socketlib.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # socketlib.m4 | 1 | # socketlib.m4 |
| 2 | # serial 4 | 2 | # serial 4 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl gl_SOCKETLIB | 9 | dnl gl_SOCKETLIB |
| 9 | dnl Determines the library to use for socket functions. | 10 | dnl Determines the library to use for socket functions. |
diff --git a/gl/m4/sockets.m4 b/gl/m4/sockets.m4 index a3dfe92f..54f4dc79 100644 --- a/gl/m4/sockets.m4 +++ b/gl/m4/sockets.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # sockets.m4 | 1 | # sockets.m4 |
| 2 | # serial 7 | 2 | # serial 7 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_SOCKETS], | 9 | AC_DEFUN([gl_SOCKETS], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/socklen.m4 b/gl/m4/socklen.m4 index 9ece0abb..a8ac25b1 100644 --- a/gl/m4/socklen.m4 +++ b/gl/m4/socklen.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # socklen.m4 | 1 | # socklen.m4 |
| 2 | # serial 11 | 2 | # serial 11 |
| 3 | dnl Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Albert Chin, Windows fixes from Simon Josefsson. | 9 | dnl From Albert Chin, Windows fixes from Simon Josefsson. |
| 9 | 10 | ||
diff --git a/gl/m4/sockpfaf.m4 b/gl/m4/sockpfaf.m4 index c68b3abb..08ce843d 100644 --- a/gl/m4/sockpfaf.m4 +++ b/gl/m4/sockpfaf.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # sockpfaf.m4 | 1 | # sockpfaf.m4 |
| 2 | # serial 10 | 2 | # serial 11 |
| 3 | dnl Copyright (C) 2004, 2006, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2004, 2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Test for some common socket protocol families (PF_INET, PF_INET6, ...) | 9 | dnl Test for some common socket protocol families (PF_INET, PF_INET6, ...) |
| 9 | dnl and some common address families (AF_INET, AF_INET6, ...). | 10 | dnl and some common address families (AF_INET, AF_INET6, ...). |
| @@ -64,6 +65,13 @@ AC_DEFUN([gl_SOCKET_FAMILY_UNIX], | |||
| 64 | AC_REQUIRE([gl_SYS_SOCKET_H]) | 65 | AC_REQUIRE([gl_SYS_SOCKET_H]) |
| 65 | AC_CHECK_HEADERS_ONCE([sys/un.h]) | 66 | AC_CHECK_HEADERS_ONCE([sys/un.h]) |
| 66 | 67 | ||
| 68 | dnl Windows versions released after 2017 may have support for AF_UNIX. | ||
| 69 | dnl Including it requires types from <winsock2.h> to be defined. | ||
| 70 | dnl <https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/>. | ||
| 71 | if test "$ac_cv_header_winsock2_h" = yes; then | ||
| 72 | AC_CHECK_HEADERS([afunix.h], [], [], [#include <winsock2.h>]) | ||
| 73 | fi | ||
| 74 | |||
| 67 | AC_CACHE_CHECK([for UNIX domain sockets], | 75 | AC_CACHE_CHECK([for UNIX domain sockets], |
| 68 | [gl_cv_socket_unix], | 76 | [gl_cv_socket_unix], |
| 69 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> | 77 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h> |
| @@ -75,6 +83,9 @@ AC_DEFUN([gl_SOCKET_FAMILY_UNIX], | |||
| 75 | #endif | 83 | #endif |
| 76 | #ifdef HAVE_WINSOCK2_H | 84 | #ifdef HAVE_WINSOCK2_H |
| 77 | #include <winsock2.h> | 85 | #include <winsock2.h> |
| 86 | #endif | ||
| 87 | #ifdef HAVE_AFUNIX_H | ||
| 88 | #include <afunix.h> | ||
| 78 | #endif]], | 89 | #endif]], |
| 79 | [[int x = AF_UNIX; struct sockaddr_un y; | 90 | [[int x = AF_UNIX; struct sockaddr_un y; |
| 80 | if (&x && &y) return 0;]])], | 91 | if (&x && &y) return 0;]])], |
diff --git a/gl/m4/ssize_t.m4 b/gl/m4/ssize_t.m4 index c15f948a..a2ffd6fc 100644 --- a/gl/m4/ssize_t.m4 +++ b/gl/m4/ssize_t.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # ssize_t.m4 | 1 | # ssize_t.m4 |
| 2 | # serial 6 | 2 | # serial 6 |
| 3 | dnl Copyright (C) 2001-2003, 2006, 2010-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2001-2003, 2006, 2010-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | dnl Define ssize_t if it does not already exist. | 10 | dnl Define ssize_t if it does not already exist. |
diff --git a/gl/m4/stat-time.m4 b/gl/m4/stat-time.m4 index e8ee7d51..4aa24e7f 100644 --- a/gl/m4/stat-time.m4 +++ b/gl/m4/stat-time.m4 | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | # stat-time.m4 | 1 | # stat-time.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2025 Free Software |
| 4 | dnl Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 9 | ||
| 8 | # Checks for stat-related time functions. | 10 | # Checks for stat-related time functions. |
| 9 | 11 | ||
diff --git a/gl/m4/stat.m4 b/gl/m4/stat.m4 index fabd360c..66876305 100644 --- a/gl/m4/stat.m4 +++ b/gl/m4/stat.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # stat.m4 | 1 | # stat.m4 |
| 2 | # serial 21 | 2 | # serial 21 |
| 3 | dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_STAT], | 9 | AC_DEFUN([gl_FUNC_STAT], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/std-gnu11.m4 b/gl/m4/std-gnu11.m4 index 37324c15..762764e0 100644 --- a/gl/m4/std-gnu11.m4 +++ b/gl/m4/std-gnu11.m4 | |||
| @@ -1,22 +1,27 @@ | |||
| 1 | # std-gnu11.m4 | 1 | # std-gnu11.m4 |
| 2 | # serial 1 | 2 | # serial 3 |
| 3 | 3 | ||
| 4 | # Prefer GNU C11 and C++11 to earlier versions. -*- coding: utf-8 -*- | 4 | # Prefer GNU C11 and C++11 to earlier versions. -*- coding: utf-8 -*- |
| 5 | 5 | ||
| 6 | # The std-gnu23 module, which defines _AC_C_C23_OPTIONS, supersedes us. | ||
| 7 | m4_ifndef([_AC_C_C23_OPTIONS], [ | ||
| 8 | |||
| 6 | # This implementation is taken from GNU Autoconf lib/autoconf/c.m4 | 9 | # This implementation is taken from GNU Autoconf lib/autoconf/c.m4 |
| 7 | # commit 017d5ddd82854911f0119691d91ea8a1438824d6 | 10 | # commit 017d5ddd82854911f0119691d91ea8a1438824d6 |
| 8 | # dated Sun Apr 3 13:57:17 2016 -0700 | 11 | # dated Sun Apr 3 13:57:17 2016 -0700 |
| 12 | # with minor changes to commentary. | ||
| 9 | # This implementation will be obsolete once we can assume Autoconf 2.70 | 13 | # This implementation will be obsolete once we can assume Autoconf 2.70 |
| 10 | # or later is installed everywhere a Gnulib program might be developed. | 14 | # or later is installed everywhere a Gnulib program might be developed. |
| 11 | 15 | ||
| 12 | m4_version_prereq([2.70], [], [ | 16 | m4_version_prereq([2.70], [], [ |
| 13 | 17 | ||
| 14 | 18 | ||
| 15 | # Copyright (C) 2001-2024 Free Software Foundation, Inc. | 19 | # Copyright (C) 2001-2025 Free Software Foundation, Inc. |
| 16 | 20 | ||
| 17 | # This program is free software; you can redistribute it and/or modify | 21 | # This file is part of Autoconf. This program is free |
| 18 | # it under the terms of the GNU General Public License as published by | 22 | # software; you can redistribute it and/or modify it under the |
| 19 | # the Free Software Foundation, either version 3 of the License, or | 23 | # terms of the GNU General Public License as published by the |
| 24 | # Free Software Foundation, either version 3 of the License, or | ||
| 20 | # (at your option) any later version. | 25 | # (at your option) any later version. |
| 21 | # | 26 | # |
| 22 | # This program is distributed in the hope that it will be useful, | 27 | # This program is distributed in the hope that it will be useful, |
| @@ -24,8 +29,15 @@ m4_version_prereq([2.70], [], [ | |||
| 24 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 29 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 25 | # GNU General Public License for more details. | 30 | # GNU General Public License for more details. |
| 26 | # | 31 | # |
| 32 | # Under Section 7 of GPL version 3, you are granted additional | ||
| 33 | # permissions described in the Autoconf Configure Script Exception, | ||
| 34 | # version 3.0, as published by the Free Software Foundation. | ||
| 35 | # | ||
| 27 | # You should have received a copy of the GNU General Public License | 36 | # You should have received a copy of the GNU General Public License |
| 28 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | 37 | # and a copy of the Autoconf Configure Script Exception along with |
| 38 | # this program; see the files COPYINGv3 and COPYING.EXCEPTION | ||
| 39 | # respectively. If not, see <https://www.gnu.org/licenses/> and | ||
| 40 | # <https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob_plain;f=COPYING.EXCEPTION>. | ||
| 29 | 41 | ||
| 30 | # Written by David MacKenzie, with help from | 42 | # Written by David MacKenzie, with help from |
| 31 | # Akim Demaille, Paul Eggert, | 43 | # Akim Demaille, Paul Eggert, |
| @@ -38,7 +50,7 @@ m4_version_prereq([2.70], [], [ | |||
| 38 | # COMPILER ... is a space separated list of C compilers to search for. | 50 | # COMPILER ... is a space separated list of C compilers to search for. |
| 39 | # This just gives the user an opportunity to specify an alternative | 51 | # This just gives the user an opportunity to specify an alternative |
| 40 | # search list for the C compiler. | 52 | # search list for the C compiler. |
| 41 | AC_DEFUN_ONCE([AC_PROG_CC], | 53 | AC_DEFUN([AC_PROG_CC], |
| 42 | [AC_LANG_PUSH(C)dnl | 54 | [AC_LANG_PUSH(C)dnl |
| 43 | AC_ARG_VAR([CC], [C compiler command])dnl | 55 | AC_ARG_VAR([CC], [C compiler command])dnl |
| 44 | AC_ARG_VAR([CFLAGS], [C compiler flags])dnl | 56 | AC_ARG_VAR([CFLAGS], [C compiler flags])dnl |
| @@ -830,3 +842,4 @@ dnl with extended modes being tried first. | |||
| 830 | 842 | ||
| 831 | 843 | ||
| 832 | ])# m4_version_prereq | 844 | ])# m4_version_prereq |
| 845 | ])# !_AC_C_C23_OPTIONS | ||
diff --git a/gl/m4/stdalign.m4 b/gl/m4/stdalign.m4 index 2b4762f3..885feafd 100644 --- a/gl/m4/stdalign.m4 +++ b/gl/m4/stdalign.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # stdalign.m4 | 1 | # stdalign.m4 |
| 2 | # serial 1 | 2 | # serial 3 |
| 3 | dnl Copyright 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Check for alignas and alignof that conform to C23. | 9 | # Check for alignas and alignof that conform to C23. |
| 9 | 10 | ||
| @@ -81,10 +82,10 @@ AC_DEFUN([gl_ALIGNASOF], | |||
| 81 | 82 | ||
| 82 | References: | 83 | References: |
| 83 | ISO C23 (latest free draft | 84 | ISO C23 (latest free draft |
| 84 | <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n3047.pdf>) | 85 | <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf>) |
| 85 | sections 6.5.3.4, 6.7.5, 7.15. | 86 | sections 6.5.3.4, 6.7.5, 7.15. |
| 86 | C++11 (latest free draft | 87 | C++11 (latest free draft |
| 87 | <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf>) | 88 | <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf>) |
| 88 | section 18.10. */ | 89 | section 18.10. */ |
| 89 | 90 | ||
| 90 | /* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment | 91 | /* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment |
| @@ -103,11 +104,13 @@ AC_DEFUN([gl_ALIGNASOF], | |||
| 103 | 104 | ||
| 104 | /* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023 | 105 | /* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023 |
| 105 | <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>. | 106 | <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>. |
| 106 | clang versions < 8.0.0 have the same bug. */ | 107 | clang versions < 8.0.0 have the same bug. |
| 108 | IBM XL C V16.1.0 cc (non-clang) has the same bug. */ | ||
| 107 | # if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \ | 109 | # if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \ |
| 108 | || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \ | 110 | || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \ |
| 109 | && !defined __clang__) \ | 111 | && !defined __clang__) \ |
| 110 | || (defined __clang__ && __clang_major__ < 8)) | 112 | || (defined __clang__ && __clang_major__ < 8) \ |
| 113 | || defined __xlC__) | ||
| 111 | # undef/**/_Alignof | 114 | # undef/**/_Alignof |
| 112 | # ifdef __cplusplus | 115 | # ifdef __cplusplus |
| 113 | # if (201103 <= __cplusplus || defined _MSC_VER) | 116 | # if (201103 <= __cplusplus || defined _MSC_VER) |
| @@ -178,7 +181,8 @@ AC_DEFUN([gl_ALIGNASOF], | |||
| 178 | # if ((defined _Alignas \ | 181 | # if ((defined _Alignas \ |
| 179 | && !(defined __cplusplus \ | 182 | && !(defined __cplusplus \ |
| 180 | && (201103 <= __cplusplus || defined _MSC_VER))) \ | 183 | && (201103 <= __cplusplus || defined _MSC_VER))) \ |
| 181 | || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__)) | 184 | || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__ \ |
| 185 | && !defined __xlC__)) | ||
| 182 | # define alignas _Alignas | 186 | # define alignas _Alignas |
| 183 | # endif | 187 | # endif |
| 184 | # endif | 188 | # endif |
diff --git a/gl/m4/stdckdint_h.m4 b/gl/m4/stdckdint_h.m4 new file mode 100644 index 00000000..d269faa5 --- /dev/null +++ b/gl/m4/stdckdint_h.m4 | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | # stdckdint_h.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright 2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl Written by Collin Funk. | ||
| 10 | |||
| 11 | AC_DEFUN_ONCE([gl_STDCKDINT_H], | ||
| 12 | [ | ||
| 13 | gl_CHECK_NEXT_HEADERS([stdckdint.h]) | ||
| 14 | if test $ac_cv_header_stdckdint_h = yes; then | ||
| 15 | HAVE_STDCKDINT_H=1 | ||
| 16 | else | ||
| 17 | HAVE_STDCKDINT_H=0 | ||
| 18 | fi | ||
| 19 | AC_SUBST([HAVE_STDCKDINT_H]) | ||
| 20 | |||
| 21 | if test $HAVE_STDCKDINT_H = 1; then | ||
| 22 | AC_CACHE_CHECK([whether stdckdint.h can be included in C], | ||
| 23 | [gl_cv_header_c_stdckdint_h], | ||
| 24 | [AC_COMPILE_IFELSE( | ||
| 25 | [AC_LANG_PROGRAM( | ||
| 26 | [[#include <stdckdint.h> | ||
| 27 | ]])], | ||
| 28 | [gl_cv_header_c_stdckdint_h=yes], | ||
| 29 | [gl_cv_header_c_stdckdint_h=no])]) | ||
| 30 | if test $gl_cv_header_c_stdckdint_h = yes; then | ||
| 31 | HAVE_C_STDCKDINT_H=1 | ||
| 32 | AC_CACHE_CHECK([checking for an ISO C23 compliant stdckdint.h in C], | ||
| 33 | [gl_cv_header_c_stdckdint_h_works], | ||
| 34 | [AC_COMPILE_IFELSE( | ||
| 35 | [AC_LANG_PROGRAM( | ||
| 36 | [[#include <stdckdint.h> | ||
| 37 | ]], | ||
| 38 | [[int r; | ||
| 39 | int a = 1; | ||
| 40 | int b = 1; | ||
| 41 | return !!(ckd_add (&r, a, b) || ckd_sub (&r, a, b) | ||
| 42 | || ckd_mul (&r, a, b)); | ||
| 43 | ]])], | ||
| 44 | [gl_cv_header_c_stdckdint_h_works=yes], | ||
| 45 | [gl_cv_header_c_stdckdint_h_works=no])]) | ||
| 46 | if test $gl_cv_header_c_stdckdint_h_works = yes; then | ||
| 47 | HAVE_WORKING_C_STDCKDINT_H=1 | ||
| 48 | else | ||
| 49 | HAVE_WORKING_C_STDCKDINT_H=0 | ||
| 50 | fi | ||
| 51 | else | ||
| 52 | HAVE_C_STDCKDINT_H=0 | ||
| 53 | HAVE_WORKING_C_STDCKDINT_H=0 | ||
| 54 | fi | ||
| 55 | if test "$CXX" != no; then | ||
| 56 | AC_CACHE_CHECK([whether stdckdint.h can be included in C++], | ||
| 57 | [gl_cv_header_cxx_stdckdint_h], | ||
| 58 | [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to | ||
| 59 | dnl an autoconf bug <https://savannah.gnu.org/support/?110294>. | ||
| 60 | cat > conftest.cpp <<\EOF | ||
| 61 | #include <stdckdint.h> | ||
| 62 | EOF | ||
| 63 | gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp" | ||
| 64 | if AC_TRY_EVAL([gl_command]); then | ||
| 65 | gl_cv_header_cxx_stdckdint_h=yes | ||
| 66 | else | ||
| 67 | gl_cv_header_cxx_stdckdint_h=no | ||
| 68 | fi | ||
| 69 | rm -fr conftest* | ||
| 70 | ]) | ||
| 71 | if test $gl_cv_header_cxx_stdckdint_h = yes; then | ||
| 72 | HAVE_CXX_STDCKDINT_H=1 | ||
| 73 | AC_CACHE_CHECK([checking for an ISO C++26 compliant stdckdint.h in C++], | ||
| 74 | [gl_cv_header_cxx_stdckdint_h_works], | ||
| 75 | [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to | ||
| 76 | dnl an autoconf bug <https://savannah.gnu.org/support/?110294>. | ||
| 77 | cat > conftest.cpp <<\EOF | ||
| 78 | #include <stdckdint.h> | ||
| 79 | int | ||
| 80 | main (void) | ||
| 81 | { | ||
| 82 | int r; | ||
| 83 | int a = 1; | ||
| 84 | int b = 1; | ||
| 85 | return !!(ckd_add (&r, a, b) || ckd_sub (&r, a, b) || ckd_mul (&r, a, b)); | ||
| 86 | } | ||
| 87 | EOF | ||
| 88 | gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp" | ||
| 89 | if AC_TRY_EVAL([gl_command]); then | ||
| 90 | gl_cv_header_cxx_stdckdint_h_works=yes | ||
| 91 | else | ||
| 92 | gl_cv_header_cxx_stdckdint_h_works=no | ||
| 93 | fi | ||
| 94 | rm -fr conftest* | ||
| 95 | ]) | ||
| 96 | if test $gl_cv_header_cxx_stdckdint_h_works = yes; then | ||
| 97 | HAVE_WORKING_CXX_STDCKDINT_H=1 | ||
| 98 | else | ||
| 99 | HAVE_WORKING_CXX_STDCKDINT_H=0 | ||
| 100 | fi | ||
| 101 | else | ||
| 102 | HAVE_CXX_STDCKDINT_H=0 | ||
| 103 | HAVE_WORKING_CXX_STDCKDINT_H=0 | ||
| 104 | fi | ||
| 105 | fi | ||
| 106 | else | ||
| 107 | HAVE_C_STDCKDINT_H=0 | ||
| 108 | HAVE_WORKING_C_STDCKDINT_H=0 | ||
| 109 | HAVE_CXX_STDCKDINT_H=0 | ||
| 110 | HAVE_WORKING_CXX_STDCKDINT_H=0 | ||
| 111 | fi | ||
| 112 | AC_SUBST([HAVE_C_STDCKDINT_H]) | ||
| 113 | AC_SUBST([HAVE_WORKING_C_STDCKDINT_H]) | ||
| 114 | AC_SUBST([HAVE_CXX_STDCKDINT_H]) | ||
| 115 | AC_SUBST([HAVE_WORKING_CXX_STDCKDINT_H]) | ||
| 116 | |||
| 117 | if test "$CXX" != no; then | ||
| 118 | dnl We might need the header for C or C++. | ||
| 119 | if test $HAVE_C_STDCKDINT_H = 1 \ | ||
| 120 | && test $HAVE_WORKING_C_STDCKDINT_H = 1 \ | ||
| 121 | && test $HAVE_CXX_STDCKDINT_H = 1 \ | ||
| 122 | && test $HAVE_WORKING_CXX_STDCKDINT_H = 1; then | ||
| 123 | GL_GENERATE_STDCKDINT_H=false | ||
| 124 | else | ||
| 125 | GL_GENERATE_STDCKDINT_H=true | ||
| 126 | fi | ||
| 127 | else | ||
| 128 | dnl We don't care about C++ here. | ||
| 129 | if test $HAVE_C_STDCKDINT_H = 1 \ | ||
| 130 | && test $HAVE_WORKING_C_STDCKDINT_H = 1; then | ||
| 131 | GL_GENERATE_STDCKDINT_H=false | ||
| 132 | else | ||
| 133 | GL_GENERATE_STDCKDINT_H=true | ||
| 134 | fi | ||
| 135 | fi | ||
| 136 | ]) | ||
diff --git a/gl/m4/stddef_h.m4 b/gl/m4/stddef_h.m4 index 84d3bae8..127ec05b 100644 --- a/gl/m4/stddef_h.m4 +++ b/gl/m4/stddef_h.m4 | |||
| @@ -1,16 +1,16 @@ | |||
| 1 | # stddef_h.m4 | 1 | # stddef_h.m4 |
| 2 | # serial 14 | 2 | # serial 23 |
| 3 | dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl A placeholder for <stddef.h>, for platforms that have issues. | 9 | dnl A placeholder for <stddef.h>, for platforms that have issues. |
| 9 | 10 | ||
| 10 | AC_DEFUN_ONCE([gl_STDDEF_H], | 11 | AC_DEFUN_ONCE([gl_STDDEF_H], |
| 11 | [ | 12 | [ |
| 12 | AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) | 13 | AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) |
| 13 | AC_REQUIRE([gt_TYPE_WCHAR_T]) | ||
| 14 | 14 | ||
| 15 | dnl Persuade OpenBSD <stddef.h> to declare max_align_t. | 15 | dnl Persuade OpenBSD <stddef.h> to declare max_align_t. |
| 16 | AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) | 16 | AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) |
| @@ -52,11 +52,6 @@ AC_DEFUN_ONCE([gl_STDDEF_H], | |||
| 52 | GL_GENERATE_STDDEF_H=true | 52 | GL_GENERATE_STDDEF_H=true |
| 53 | fi | 53 | fi |
| 54 | 54 | ||
| 55 | if test $gt_cv_c_wchar_t = no; then | ||
| 56 | HAVE_WCHAR_T=0 | ||
| 57 | GL_GENERATE_STDDEF_H=true | ||
| 58 | fi | ||
| 59 | |||
| 60 | AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions], | 55 | AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions], |
| 61 | [gl_cv_decl_null_works], | 56 | [gl_cv_decl_null_works], |
| 62 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h> | 57 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h> |
| @@ -69,21 +64,60 @@ AC_DEFUN_ONCE([gl_STDDEF_H], | |||
| 69 | GL_GENERATE_STDDEF_H=true | 64 | GL_GENERATE_STDDEF_H=true |
| 70 | fi | 65 | fi |
| 71 | 66 | ||
| 72 | AC_CACHE_CHECK([for unreachable], | 67 | AC_CACHE_CHECK([for unreachable in C], |
| 73 | [gl_cv_func_unreachable], | 68 | [gl_cv_c_func_unreachable], |
| 74 | [AC_LINK_IFELSE( | 69 | [AC_LINK_IFELSE( |
| 75 | [AC_LANG_PROGRAM( | 70 | [AC_LANG_PROGRAM( |
| 76 | [[#include <stddef.h> | 71 | [[#include <stddef.h> |
| 77 | ]], | 72 | ]], |
| 78 | [[unreachable (); | 73 | [[unreachable (); |
| 79 | ]])], | 74 | ]])], |
| 80 | [gl_cv_func_unreachable=yes], | 75 | [gl_cv_c_func_unreachable=yes], |
| 81 | [gl_cv_func_unreachable=no]) | 76 | [gl_cv_c_func_unreachable=no]) |
| 82 | ]) | 77 | ]) |
| 83 | if test $gl_cv_func_unreachable = no; then | 78 | if test $gl_cv_c_func_unreachable = no; then |
| 79 | GL_GENERATE_STDDEF_H=true | ||
| 80 | HAVE_C_UNREACHABLE=0 | ||
| 81 | else | ||
| 82 | HAVE_C_UNREACHABLE=1 | ||
| 83 | fi | ||
| 84 | AC_SUBST([HAVE_C_UNREACHABLE]) | ||
| 85 | dnl Provide gl_unreachable() unconditionally. | ||
| 86 | GL_GENERATE_STDDEF_H=true | ||
| 87 | |||
| 88 | dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114869 | ||
| 89 | AC_CACHE_CHECK([whether nullptr_t needs <stddef.h>], | ||
| 90 | [gl_cv_nullptr_t_needs_stddef], | ||
| 91 | [AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[nullptr_t x;]], | ||
| 92 | [gl_cv_nullptr_t_needs_stddef=no], | ||
| 93 | [gl_cv_nullptr_t_needs_stddef=yes])]) | ||
| 94 | if test "$gl_cv_nullptr_t_needs_stddef" = no; then | ||
| 95 | NULLPTR_T_NEEDS_STDDEF=0 | ||
| 84 | GL_GENERATE_STDDEF_H=true | 96 | GL_GENERATE_STDDEF_H=true |
| 85 | fi | 97 | fi |
| 86 | 98 | ||
| 99 | dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114870 | ||
| 100 | dnl affects GCC 13.3 and 14.2. | ||
| 101 | AC_CACHE_CHECK([whether <stddef.h> is idempotent], | ||
| 102 | [gl_cv_stddef_idempotent], | ||
| 103 | [AC_COMPILE_IFELSE([AC_LANG_SOURCE( | ||
| 104 | [[ | ||
| 105 | #if \ | ||
| 106 | ((__GNUC__ == 13 && __GNUC_MINOR__ <= 3) \ | ||
| 107 | || (__GNUC__ == 14 && __GNUC_MINOR__ <= 2)) | ||
| 108 | #error "bug 114870 is present" | ||
| 109 | #endif | ||
| 110 | ]])], | ||
| 111 | [gl_cv_stddef_idempotent="guessing yes"], | ||
| 112 | [gl_cv_stddef_idempotent="guessing no"]) | ||
| 113 | ]) | ||
| 114 | case "$gl_cv_stddef_idempotent" in | ||
| 115 | *yes) ;; | ||
| 116 | *) STDDEF_NOT_IDEMPOTENT=1 | ||
| 117 | GL_GENERATE_STDDEF_H=true | ||
| 118 | ;; | ||
| 119 | esac | ||
| 120 | |||
| 87 | if $GL_GENERATE_STDDEF_H; then | 121 | if $GL_GENERATE_STDDEF_H; then |
| 88 | gl_NEXT_HEADERS([stddef.h]) | 122 | gl_NEXT_HEADERS([stddef.h]) |
| 89 | fi | 123 | fi |
| @@ -114,7 +148,8 @@ AC_DEFUN([gl_STDDEF_H_REQUIRE_DEFAULTS], | |||
| 114 | AC_DEFUN([gl_STDDEF_H_DEFAULTS], | 148 | AC_DEFUN([gl_STDDEF_H_DEFAULTS], |
| 115 | [ | 149 | [ |
| 116 | dnl Assume proper GNU behavior unless another module says otherwise. | 150 | dnl Assume proper GNU behavior unless another module says otherwise. |
| 151 | NULLPTR_T_NEEDS_STDDEF=1; AC_SUBST([NULLPTR_T_NEEDS_STDDEF]) | ||
| 152 | STDDEF_NOT_IDEMPOTENT=0; AC_SUBST([STDDEF_NOT_IDEMPOTENT]) | ||
| 117 | REPLACE_NULL=0; AC_SUBST([REPLACE_NULL]) | 153 | REPLACE_NULL=0; AC_SUBST([REPLACE_NULL]) |
| 118 | HAVE_MAX_ALIGN_T=1; AC_SUBST([HAVE_MAX_ALIGN_T]) | 154 | HAVE_MAX_ALIGN_T=1; AC_SUBST([HAVE_MAX_ALIGN_T]) |
| 119 | HAVE_WCHAR_T=1; AC_SUBST([HAVE_WCHAR_T]) | ||
| 120 | ]) | 155 | ]) |
diff --git a/gl/m4/stdint.m4 b/gl/m4/stdint.m4 index 2dea8469..2d69088b 100644 --- a/gl/m4/stdint.m4 +++ b/gl/m4/stdint.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # stdint.m4 | 1 | # stdint.m4 |
| 2 | # serial 63 | 2 | # serial 64 |
| 3 | dnl Copyright (C) 2001-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2001-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Paul Eggert and Bruno Haible. | 9 | dnl From Paul Eggert and Bruno Haible. |
| 9 | dnl Test whether <stdint.h> is supported or must be substituted. | 10 | dnl Test whether <stdint.h> is supported or must be substituted. |
| @@ -157,7 +158,7 @@ uintmax_t j = UINTMAX_MAX; | |||
| 157 | || defined __clang__) | 158 | || defined __clang__) |
| 158 | int k = _Generic (SIZE_MAX, size_t: 0); | 159 | int k = _Generic (SIZE_MAX, size_t: 0); |
| 159 | #elif (2 <= __GNUC__ || 4 <= __clang_major__ || defined __IBM__TYPEOF__ \ | 160 | #elif (2 <= __GNUC__ || 4 <= __clang_major__ || defined __IBM__TYPEOF__ \ |
| 160 | || (0x5110 <= __SUNPRO_C && !__STDC__)) | 161 | || (0x5110 <= __SUNPRO_C && !__STDC__) || 1939 <= _MSC_VER) |
| 161 | extern size_t k; | 162 | extern size_t k; |
| 162 | extern __typeof__ (SIZE_MAX) k; | 163 | extern __typeof__ (SIZE_MAX) k; |
| 163 | #endif | 164 | #endif |
diff --git a/gl/m4/stdint_h.m4 b/gl/m4/stdint_h.m4 index 29f42160..d4f1acdd 100644 --- a/gl/m4/stdint_h.m4 +++ b/gl/m4/stdint_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # stdint_h.m4 | 1 | # stdint_h.m4 |
| 2 | # serial 9 | 2 | # serial 9 |
| 3 | dnl Copyright (C) 1997-2004, 2006, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 1997-2004, 2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Paul Eggert. | 9 | dnl From Paul Eggert. |
| 9 | 10 | ||
diff --git a/gl/m4/stdio_h.m4 b/gl/m4/stdio_h.m4 index 8eb5816a..71d86180 100644 --- a/gl/m4/stdio_h.m4 +++ b/gl/m4/stdio_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # stdio_h.m4 | 1 | # stdio_h.m4 |
| 2 | # serial 63 | 2 | # serial 75 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_STDIO_H_EARLY], | 9 | AC_DEFUN([gl_STDIO_H_EARLY], |
| 9 | [ | 10 | [ |
| @@ -133,6 +134,7 @@ AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS], | |||
| 133 | [ | 134 | [ |
| 134 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDIO_H_MODULE_INDICATOR_DEFAULTS], [ | 135 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDIO_H_MODULE_INDICATOR_DEFAULTS], [ |
| 135 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DPRINTF]) | 136 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DPRINTF]) |
| 137 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_DZPRINTF]) | ||
| 136 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCLOSE]) | 138 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCLOSE]) |
| 137 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FDOPEN]) | 139 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FDOPEN]) |
| 138 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFLUSH]) | 140 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFLUSH]) |
| @@ -153,12 +155,14 @@ AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS], | |||
| 153 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTELL]) | 155 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTELL]) |
| 154 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTELLO]) | 156 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FTELLO]) |
| 155 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FWRITE]) | 157 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FWRITE]) |
| 158 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FZPRINTF]) | ||
| 156 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETC]) | 159 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETC]) |
| 157 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETCHAR]) | 160 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETCHAR]) |
| 158 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDELIM]) | 161 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETDELIM]) |
| 159 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLINE]) | 162 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLINE]) |
| 160 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF]) | 163 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF]) |
| 161 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF_POSIX]) | 164 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF_POSIX]) |
| 165 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_ZPRINTF]) | ||
| 162 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PCLOSE]) | 166 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PCLOSE]) |
| 163 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PERROR]) | 167 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PERROR]) |
| 164 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POPEN]) | 168 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POPEN]) |
| @@ -172,20 +176,29 @@ AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS], | |||
| 172 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RENAMEAT]) | 176 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RENAMEAT]) |
| 173 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SCANF]) | 177 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SCANF]) |
| 174 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SNPRINTF]) | 178 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SNPRINTF]) |
| 179 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SNZPRINTF]) | ||
| 175 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SPRINTF_POSIX]) | 180 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SPRINTF_POSIX]) |
| 176 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_NONBLOCKING]) | 181 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_NONBLOCKING]) |
| 177 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_SIGPIPE]) | 182 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_SIGPIPE]) |
| 183 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SZPRINTF]) | ||
| 178 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TMPFILE]) | 184 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TMPFILE]) |
| 179 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VASPRINTF]) | 185 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VASPRINTF]) |
| 186 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VASZPRINTF]) | ||
| 180 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFSCANF]) | 187 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFSCANF]) |
| 181 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSCANF]) | 188 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSCANF]) |
| 182 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VDPRINTF]) | 189 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VDPRINTF]) |
| 190 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VDZPRINTF]) | ||
| 183 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF]) | 191 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF]) |
| 184 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF_POSIX]) | 192 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFPRINTF_POSIX]) |
| 193 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFZPRINTF]) | ||
| 185 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF]) | 194 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF]) |
| 186 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF_POSIX]) | 195 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF_POSIX]) |
| 187 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSNPRINTF]) | 196 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSNPRINTF]) |
| 197 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSNZPRINTF]) | ||
| 188 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSPRINTF_POSIX]) | 198 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSPRINTF_POSIX]) |
| 199 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSZPRINTF]) | ||
| 200 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VZPRINTF]) | ||
| 201 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ZPRINTF]) | ||
| 189 | dnl Support Microsoft deprecated alias function names by default. | 202 | dnl Support Microsoft deprecated alias function names by default. |
| 190 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FCLOSEALL], [1]) | 203 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FCLOSEALL], [1]) |
| 191 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FDOPEN], [1]) | 204 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FDOPEN], [1]) |
diff --git a/gl/m4/stdlib_h.m4 b/gl/m4/stdlib_h.m4 index a4662f29..2d25da37 100644 --- a/gl/m4/stdlib_h.m4 +++ b/gl/m4/stdlib_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # stdlib_h.m4 | 1 | # stdlib_h.m4 |
| 2 | # serial 77 | 2 | # serial 84 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_STDLIB_H], | 9 | AC_DEFUN_ONCE([gl_STDLIB_H], |
| 9 | [ | 10 | [ |
| @@ -37,44 +38,51 @@ AC_DEFUN_ONCE([gl_STDLIB_H], | |||
| 37 | dnl On Solaris 10, in UTF-8 locales, its value is 3 but needs to be 4. | 38 | dnl On Solaris 10, in UTF-8 locales, its value is 3 but needs to be 4. |
| 38 | dnl Fortunately, we can do this because on this platform MB_LEN_MAX is 5. | 39 | dnl Fortunately, we can do this because on this platform MB_LEN_MAX is 5. |
| 39 | AC_REQUIRE([AC_CANONICAL_HOST]) | 40 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 40 | AC_REQUIRE([gt_LOCALE_FR_UTF8]) | 41 | AC_REQUIRE([gt_LOCALE_EN_UTF8]) |
| 41 | AC_CACHE_CHECK([whether MB_CUR_MAX is correct], | 42 | AC_CACHE_CHECK([whether MB_CUR_MAX is correct], |
| 42 | [gl_cv_macro_MB_CUR_MAX_good], | 43 | [gl_cv_macro_MB_CUR_MAX_good], |
| 43 | [ | 44 | [AC_LINK_IFELSE( |
| 44 | dnl Initial guess, used when cross-compiling or when no suitable locale | 45 | [AC_LANG_PROGRAM([[#include <stdlib.h> |
| 45 | dnl is present. | 46 | ]], |
| 46 | changequote(,)dnl | 47 | [[return !!MB_CUR_MAX;]]) |
| 47 | case "$host_os" in | 48 | ], |
| 48 | # Guess no on Solaris. | 49 | [dnl Initial guess, used when cross-compiling or when no suitable locale |
| 49 | solaris*) gl_cv_macro_MB_CUR_MAX_good="guessing no" ;; | 50 | dnl is present. |
| 50 | # Guess yes otherwise. | 51 | # Guess no on Solaris and Haiku, yes otherwise. |
| 51 | *) gl_cv_macro_MB_CUR_MAX_good="guessing yes" ;; | 52 | AS_CASE([$host_os], |
| 52 | esac | 53 | [solaris* | haiku*], |
| 53 | changequote([,])dnl | 54 | [gl_cv_macro_MB_CUR_MAX_good="guessing no"], |
| 54 | if test $LOCALE_FR_UTF8 != none; then | 55 | [gl_cv_macro_MB_CUR_MAX_good="guessing yes"]) |
| 55 | AC_RUN_IFELSE( | 56 | if test "$LOCALE_EN_UTF8" != none; then |
| 56 | [AC_LANG_SOURCE([[ | 57 | AC_RUN_IFELSE( |
| 58 | [AC_LANG_SOURCE([[ | ||
| 57 | #include <locale.h> | 59 | #include <locale.h> |
| 58 | #include <stdlib.h> | 60 | #include <stdlib.h> |
| 59 | int main () | 61 | int main () |
| 60 | { | 62 | { |
| 61 | int result = 0; | 63 | int result = 0; |
| 62 | if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) | 64 | if (setlocale (LC_ALL, "$LOCALE_EN_UTF8") != NULL) |
| 63 | { | 65 | { |
| 64 | if (MB_CUR_MAX < 4) | 66 | if (MB_CUR_MAX < 4) |
| 65 | result |= 1; | 67 | result |= 1; |
| 66 | } | 68 | } |
| 67 | return result; | 69 | return result; |
| 68 | }]])], | 70 | }]])], |
| 69 | [gl_cv_macro_MB_CUR_MAX_good=yes], | 71 | [gl_cv_macro_MB_CUR_MAX_good=yes], |
| 70 | [gl_cv_macro_MB_CUR_MAX_good=no], | 72 | [gl_cv_macro_MB_CUR_MAX_good=no], |
| 71 | [:]) | 73 | [:]) |
| 72 | fi | 74 | fi |
| 75 | ], | ||
| 76 | [gl_cv_macro_MB_CUR_MAX_good="link failed - so no"]) | ||
| 73 | ]) | 77 | ]) |
| 74 | case "$gl_cv_macro_MB_CUR_MAX_good" in | 78 | AS_CASE([$gl_cv_macro_MB_CUR_MAX_good], |
| 75 | *yes) ;; | 79 | [*yes], |
| 76 | *) REPLACE_MB_CUR_MAX=1 ;; | 80 | [], |
| 77 | esac | 81 | ["link failed - so no"], |
| 82 | [# 4 suffices as a workaround in Android NDK 16, | ||
| 83 | # the only known platform with the bug. | ||
| 84 | REPLACE_MB_CUR_MAX=4], | ||
| 85 | [REPLACE_MB_CUR_MAX="(-1)"]) | ||
| 78 | 86 | ||
| 79 | AC_CHECK_DECLS_ONCE([ecvt]) | 87 | AC_CHECK_DECLS_ONCE([ecvt]) |
| 80 | if test $ac_cv_have_decl_ecvt = no; then | 88 | if test $ac_cv_have_decl_ecvt = no; then |
| @@ -110,6 +118,7 @@ AC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS], | |||
| 110 | [ | 118 | [ |
| 111 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS], [ | 119 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_STDLIB_H_MODULE_INDICATOR_DEFAULTS], [ |
| 112 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB__EXIT]) | 120 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB__EXIT]) |
| 121 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ABORT_DEBUG]) | ||
| 113 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ALIGNED_ALLOC]) | 122 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ALIGNED_ALLOC]) |
| 114 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATOLL]) | 123 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ATOLL]) |
| 115 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALLOC_GNU]) | 124 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CALLOC_GNU]) |
| @@ -139,12 +148,12 @@ AC_DEFUN([gl_STDLIB_H_REQUIRE_DEFAULTS], | |||
| 139 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM]) | 148 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM]) |
| 140 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM_R]) | 149 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RANDOM_R]) |
| 141 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOCARRAY]) | 150 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOCARRAY]) |
| 142 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOC_GNU]) | ||
| 143 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOC_POSIX]) | 151 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALLOC_POSIX]) |
| 144 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALPATH]) | 152 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_REALPATH]) |
| 145 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RPMATCH]) | 153 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_RPMATCH]) |
| 146 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SECURE_GETENV]) | 154 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SECURE_GETENV]) |
| 147 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETENV]) | 155 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SETENV]) |
| 156 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STACK_TRACE]) | ||
| 148 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOD]) | 157 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOD]) |
| 149 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOF]) | 158 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOF]) |
| 150 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOL]) | 159 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOL]) |
| @@ -218,6 +227,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], | |||
| 218 | HAVE_UNLOCKPT=1; AC_SUBST([HAVE_UNLOCKPT]) | 227 | HAVE_UNLOCKPT=1; AC_SUBST([HAVE_UNLOCKPT]) |
| 219 | HAVE_DECL_UNSETENV=1; AC_SUBST([HAVE_DECL_UNSETENV]) | 228 | HAVE_DECL_UNSETENV=1; AC_SUBST([HAVE_DECL_UNSETENV]) |
| 220 | REPLACE__EXIT=0; AC_SUBST([REPLACE__EXIT]) | 229 | REPLACE__EXIT=0; AC_SUBST([REPLACE__EXIT]) |
| 230 | REPLACE_ABORT=0; AC_SUBST([REPLACE_ABORT]) | ||
| 221 | REPLACE_ALIGNED_ALLOC=0; AC_SUBST([REPLACE_ALIGNED_ALLOC]) | 231 | REPLACE_ALIGNED_ALLOC=0; AC_SUBST([REPLACE_ALIGNED_ALLOC]) |
| 222 | REPLACE_CALLOC_FOR_CALLOC_GNU=0; AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_GNU]) | 232 | REPLACE_CALLOC_FOR_CALLOC_GNU=0; AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_GNU]) |
| 223 | REPLACE_CALLOC_FOR_CALLOC_POSIX=0; AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_POSIX]) | 233 | REPLACE_CALLOC_FOR_CALLOC_POSIX=0; AC_SUBST([REPLACE_CALLOC_FOR_CALLOC_POSIX]) |
| @@ -244,7 +254,6 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], | |||
| 244 | REPLACE_RAND=0; AC_SUBST([REPLACE_RAND]) | 254 | REPLACE_RAND=0; AC_SUBST([REPLACE_RAND]) |
| 245 | REPLACE_RANDOM=0; AC_SUBST([REPLACE_RANDOM]) | 255 | REPLACE_RANDOM=0; AC_SUBST([REPLACE_RANDOM]) |
| 246 | REPLACE_RANDOM_R=0; AC_SUBST([REPLACE_RANDOM_R]) | 256 | REPLACE_RANDOM_R=0; AC_SUBST([REPLACE_RANDOM_R]) |
| 247 | REPLACE_REALLOC_FOR_REALLOC_GNU=0; AC_SUBST([REPLACE_REALLOC_FOR_REALLOC_GNU]) | ||
| 248 | REPLACE_REALLOC_FOR_REALLOC_POSIX=0; AC_SUBST([REPLACE_REALLOC_FOR_REALLOC_POSIX]) | 257 | REPLACE_REALLOC_FOR_REALLOC_POSIX=0; AC_SUBST([REPLACE_REALLOC_FOR_REALLOC_POSIX]) |
| 249 | REPLACE_REALLOCARRAY=0; AC_SUBST([REPLACE_REALLOCARRAY]) | 258 | REPLACE_REALLOCARRAY=0; AC_SUBST([REPLACE_REALLOCARRAY]) |
| 250 | REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH]) | 259 | REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH]) |
| @@ -259,4 +268,5 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], | |||
| 259 | REPLACE_STRTOULL=0; AC_SUBST([REPLACE_STRTOULL]) | 268 | REPLACE_STRTOULL=0; AC_SUBST([REPLACE_STRTOULL]) |
| 260 | REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV]) | 269 | REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV]) |
| 261 | REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB]) | 270 | REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB]) |
| 271 | CAN_PRINT_STACK_TRACE=0; AC_SUBST([CAN_PRINT_STACK_TRACE]) | ||
| 262 | ]) | 272 | ]) |
diff --git a/gl/m4/strcasecmp.m4 b/gl/m4/strcasecmp.m4 new file mode 100644 index 00000000..eb4345d9 --- /dev/null +++ b/gl/m4/strcasecmp.m4 | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | # strcasecmp.m4 | ||
| 2 | # serial 3 | ||
| 3 | dnl Copyright (C) 2002-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN([gl_FUNC_STRCASECMP], | ||
| 10 | [ | ||
| 11 | AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) | ||
| 12 | AC_CHECK_FUNCS([strcasecmp]) | ||
| 13 | if test $ac_cv_func_strcasecmp = yes; then | ||
| 14 | gl_STRCASECMP_WORKS | ||
| 15 | case "$gl_cv_func_strcasecmp_works" in | ||
| 16 | *yes) ;; | ||
| 17 | *) REPLACE_STRCASECMP=1 ;; | ||
| 18 | esac | ||
| 19 | else | ||
| 20 | HAVE_STRCASECMP=0 | ||
| 21 | fi | ||
| 22 | ]) | ||
| 23 | |||
| 24 | AC_DEFUN([gl_STRCASECMP_WORKS], | ||
| 25 | [ | ||
| 26 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 27 | AC_CACHE_CHECK([whether strcasecmp works], | ||
| 28 | [gl_cv_func_strcasecmp_works], | ||
| 29 | [dnl Prepare a guess, used when cross-compiling or when specific locales | ||
| 30 | dnl are not available. | ||
| 31 | case "$host_os" in | ||
| 32 | solaris* | cygwin*) | ||
| 33 | gl_cv_func_strcasecmp_works="guessing no" ;; | ||
| 34 | *) | ||
| 35 | gl_cv_func_strcasecmp_works="guessing yes" ;; | ||
| 36 | esac | ||
| 37 | AC_RUN_IFELSE( | ||
| 38 | [AC_LANG_SOURCE([[ | ||
| 39 | #include <stdio.h> | ||
| 40 | #include <ctype.h> | ||
| 41 | #include <locale.h> | ||
| 42 | #include <strings.h> | ||
| 43 | int main () | ||
| 44 | { | ||
| 45 | if (setlocale (LC_ALL, "fr_FR.ISO-8859-1") != NULL | ||
| 46 | || setlocale (LC_ALL, "fr_FR.ISO8859-1") != NULL) | ||
| 47 | { | ||
| 48 | int c1 = (unsigned char) '\311'; | ||
| 49 | int c2 = (unsigned char) '\351'; | ||
| 50 | if (tolower (c1) == c2 && toupper (c2) == c1) | ||
| 51 | return strcasecmp ("Fej\311r", "Fej\351r") != 0; | ||
| 52 | } | ||
| 53 | return 2; | ||
| 54 | }]])], | ||
| 55 | [gl_cv_func_strcasecmp_works=yes], | ||
| 56 | [if test $? = 1; then | ||
| 57 | gl_cv_func_strcasecmp_works=no | ||
| 58 | fi | ||
| 59 | ], | ||
| 60 | [:]) | ||
| 61 | ]) | ||
| 62 | ]) | ||
| 63 | |||
| 64 | # Prerequisites of lib/strcasecmp.c. | ||
| 65 | AC_DEFUN([gl_PREREQ_STRCASECMP], [ | ||
| 66 | : | ||
| 67 | ]) | ||
diff --git a/gl/m4/strcasestr.m4 b/gl/m4/strcasestr.m4 index d2548716..eb2862f1 100644 --- a/gl/m4/strcasestr.m4 +++ b/gl/m4/strcasestr.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # strcasestr.m4 | 1 | # strcasestr.m4 |
| 2 | # serial 28 | 2 | # serial 29 |
| 3 | dnl Copyright (C) 2005, 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005, 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Check that strcasestr is present and works. | 9 | dnl Check that strcasestr is present and works. |
| 9 | AC_DEFUN([gl_FUNC_STRCASESTR_SIMPLE], | 10 | AC_DEFUN([gl_FUNC_STRCASESTR_SIMPLE], |
| @@ -98,7 +99,7 @@ static void quit (int sig) { _exit (sig + 128); } | |||
| 98 | char *haystack = (char *) malloc (2 * m + 2); | 99 | char *haystack = (char *) malloc (2 * m + 2); |
| 99 | char *needle = (char *) malloc (m + 2); | 100 | char *needle = (char *) malloc (m + 2); |
| 100 | /* Failure to compile this test due to missing alarm is okay, | 101 | /* Failure to compile this test due to missing alarm is okay, |
| 101 | since all such platforms (mingw) also lack strcasestr. */ | 102 | since all such platforms (mingw, MSVC) also lack strcasestr. */ |
| 102 | signal (SIGALRM, quit); | 103 | signal (SIGALRM, quit); |
| 103 | alarm (5); | 104 | alarm (5); |
| 104 | /* Check for quadratic performance. */ | 105 | /* Check for quadratic performance. */ |
diff --git a/gl/m4/strerror.m4 b/gl/m4/strerror.m4 index 0272c6f4..c8b3b207 100644 --- a/gl/m4/strerror.m4 +++ b/gl/m4/strerror.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # strerror.m4 | 1 | # strerror.m4 |
| 2 | # serial 25 | 2 | # serial 25 |
| 3 | dnl Copyright (C) 2002, 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002, 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_STRERROR], | 9 | AC_DEFUN([gl_FUNC_STRERROR], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/string_h.m4 b/gl/m4/string_h.m4 index f31264ae..fc73603a 100644 --- a/gl/m4/string_h.m4 +++ b/gl/m4/string_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # string_h.m4 | 1 | # string_h.m4 |
| 2 | # serial 39 | 2 | # serial 44.1 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Configure a GNU-like replacement for <string.h>. | 9 | # Configure a GNU-like replacement for <string.h>. |
| 9 | 10 | ||
| @@ -23,8 +24,9 @@ AC_DEFUN_ONCE([gl_STRING_H], | |||
| 23 | ]], | 24 | ]], |
| 24 | [explicit_bzero ffsl ffsll memmem mempcpy memrchr memset_explicit | 25 | [explicit_bzero ffsl ffsll memmem mempcpy memrchr memset_explicit |
| 25 | rawmemchr stpcpy stpncpy strchrnul | 26 | rawmemchr stpcpy stpncpy strchrnul |
| 26 | strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r | 27 | strdup strncat strncpy strndup strnlen strpbrk strsep strcasestr strtok_r |
| 27 | strerror_r strerrorname_np sigabbrev_np sigdescr_np strsignal strverscmp]) | 28 | strerror_l strerror_r strerrorname_np |
| 29 | sigabbrev_np sigdescr_np strsignal strverscmp]) | ||
| 28 | 30 | ||
| 29 | AC_REQUIRE([AC_C_RESTRICT]) | 31 | AC_REQUIRE([AC_C_RESTRICT]) |
| 30 | ]) | 32 | ]) |
| @@ -62,6 +64,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], | |||
| 62 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCHRNUL]) | 64 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCHRNUL]) |
| 63 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRDUP]) | 65 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRDUP]) |
| 64 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNCAT]) | 66 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNCAT]) |
| 67 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNCPY]) | ||
| 65 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNDUP]) | 68 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNDUP]) |
| 66 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNLEN]) | 69 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNLEN]) |
| 67 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRPBRK]) | 70 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRPBRK]) |
| @@ -69,6 +72,8 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], | |||
| 69 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR]) | 72 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR]) |
| 70 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR]) | 73 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR]) |
| 71 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R]) | 74 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R]) |
| 75 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH]) | ||
| 76 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_ENDSWITH]) | ||
| 72 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN]) | 77 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN]) |
| 73 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN]) | 78 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN]) |
| 74 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR]) | 79 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR]) |
| @@ -83,8 +88,11 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS], | |||
| 83 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSPN]) | 88 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSPN]) |
| 84 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSEP]) | 89 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSSEP]) |
| 85 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSTOK_R]) | 90 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSTOK_R]) |
| 91 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBS_STARTSWITH]) | ||
| 92 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBS_ENDSWITH]) | ||
| 86 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR]) | 93 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR]) |
| 87 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR_R]) | 94 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR_R]) |
| 95 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERROR_L]) | ||
| 88 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERRORNAME_NP]) | 96 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRERRORNAME_NP]) |
| 89 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGABBREV_NP]) | 97 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGABBREV_NP]) |
| 90 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGDESCR_NP]) | 98 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_SIGDESCR_NP]) |
| @@ -123,6 +131,7 @@ AC_DEFUN([gl_STRING_H_DEFAULTS], | |||
| 123 | HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR]) | 131 | HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR]) |
| 124 | HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R]) | 132 | HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R]) |
| 125 | HAVE_DECL_STRERROR_R=1; AC_SUBST([HAVE_DECL_STRERROR_R]) | 133 | HAVE_DECL_STRERROR_R=1; AC_SUBST([HAVE_DECL_STRERROR_R]) |
| 134 | HAVE_STRERROR_L=1; AC_SUBST([HAVE_STRERROR_L]) | ||
| 126 | HAVE_STRERRORNAME_NP=1; AC_SUBST([HAVE_STRERRORNAME_NP]) | 135 | HAVE_STRERRORNAME_NP=1; AC_SUBST([HAVE_STRERRORNAME_NP]) |
| 127 | HAVE_SIGABBREV_NP=1; AC_SUBST([HAVE_SIGABBREV_NP]) | 136 | HAVE_SIGABBREV_NP=1; AC_SUBST([HAVE_SIGABBREV_NP]) |
| 128 | HAVE_SIGDESCR_NP=1; AC_SUBST([HAVE_SIGDESCR_NP]) | 137 | HAVE_SIGDESCR_NP=1; AC_SUBST([HAVE_SIGDESCR_NP]) |
| @@ -138,6 +147,7 @@ AC_DEFUN([gl_STRING_H_DEFAULTS], | |||
| 138 | REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL]) | 147 | REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL]) |
| 139 | REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) | 148 | REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) |
| 140 | REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT]) | 149 | REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT]) |
| 150 | REPLACE_STRNCPY=0; AC_SUBST([REPLACE_STRNCPY]) | ||
| 141 | REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP]) | 151 | REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP]) |
| 142 | REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN]) | 152 | REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN]) |
| 143 | REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) | 153 | REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) |
| @@ -145,6 +155,7 @@ AC_DEFUN([gl_STRING_H_DEFAULTS], | |||
| 145 | REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R]) | 155 | REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R]) |
| 146 | REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) | 156 | REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) |
| 147 | REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R]) | 157 | REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R]) |
| 158 | REPLACE_STRERROR_L=0; AC_SUBST([REPLACE_STRERROR_L]) | ||
| 148 | REPLACE_STRERRORNAME_NP=0; AC_SUBST([REPLACE_STRERRORNAME_NP]) | 159 | REPLACE_STRERRORNAME_NP=0; AC_SUBST([REPLACE_STRERRORNAME_NP]) |
| 149 | REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL]) | 160 | REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL]) |
| 150 | REPLACE_STRVERSCMP=0; AC_SUBST([REPLACE_STRVERSCMP]) | 161 | REPLACE_STRVERSCMP=0; AC_SUBST([REPLACE_STRVERSCMP]) |
diff --git a/gl/m4/strings_h.m4 b/gl/m4/strings_h.m4 index aaafb559..18f30d4a 100644 --- a/gl/m4/strings_h.m4 +++ b/gl/m4/strings_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # strings_h.m4 | 1 | # strings_h.m4 |
| 2 | # serial 9 | 2 | # serial 14 |
| 3 | dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Configure a replacement for <strings.h>. | 9 | # Configure a replacement for <strings.h>. |
| 9 | 10 | ||
| @@ -28,7 +29,7 @@ AC_DEFUN_ONCE([gl_STRINGS_H], | |||
| 28 | <strings.h>. */ | 29 | <strings.h>. */ |
| 29 | #include <sys/types.h> | 30 | #include <sys/types.h> |
| 30 | #include <strings.h> | 31 | #include <strings.h> |
| 31 | ]], [ffs strcasecmp strncasecmp]) | 32 | ]], [ffs strcasecmp strcasecmp_l strncasecmp strncasecmp_l]) |
| 32 | ]) | 33 | ]) |
| 33 | 34 | ||
| 34 | # gl_STRINGS_MODULE_INDICATOR([modulename]) | 35 | # gl_STRINGS_MODULE_INDICATOR([modulename]) |
| @@ -49,6 +50,10 @@ AC_DEFUN([gl_STRINGS_H_REQUIRE_DEFAULTS], | |||
| 49 | [ | 50 | [ |
| 50 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_STRINGS_H_MODULE_INDICATOR_DEFAULTS], [ | 51 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_STRINGS_H_MODULE_INDICATOR_DEFAULTS], [ |
| 51 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFS]) | 52 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FFS]) |
| 53 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASECMP]) | ||
| 54 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASECMP_L]) | ||
| 55 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNCASECMP]) | ||
| 56 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRNCASECMP_L]) | ||
| 52 | ]) | 57 | ]) |
| 53 | m4_require(GL_MODULE_INDICATOR_PREFIX[_STRINGS_H_MODULE_INDICATOR_DEFAULTS]) | 58 | m4_require(GL_MODULE_INDICATOR_PREFIX[_STRINGS_H_MODULE_INDICATOR_DEFAULTS]) |
| 54 | AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) | 59 | AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) |
| @@ -59,5 +64,12 @@ AC_DEFUN([gl_STRINGS_H_DEFAULTS], | |||
| 59 | dnl Assume proper GNU behavior unless another module says otherwise. | 64 | dnl Assume proper GNU behavior unless another module says otherwise. |
| 60 | HAVE_FFS=1; AC_SUBST([HAVE_FFS]) | 65 | HAVE_FFS=1; AC_SUBST([HAVE_FFS]) |
| 61 | HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP]) | 66 | HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP]) |
| 67 | HAVE_STRCASECMP_L=1; AC_SUBST([HAVE_STRCASECMP_L]) | ||
| 68 | HAVE_STRNCASECMP=1; AC_SUBST([HAVE_STRNCASECMP]) | ||
| 69 | HAVE_STRNCASECMP_L=1; AC_SUBST([HAVE_STRNCASECMP_L]) | ||
| 62 | HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP]) | 70 | HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP]) |
| 71 | REPLACE_STRCASECMP=0; AC_SUBST([REPLACE_STRCASECMP]) | ||
| 72 | REPLACE_STRCASECMP_L=0; AC_SUBST([REPLACE_STRCASECMP_L]) | ||
| 73 | REPLACE_STRNCASECMP=0; AC_SUBST([REPLACE_STRNCASECMP]) | ||
| 74 | REPLACE_STRNCASECMP_L=0; AC_SUBST([REPLACE_STRNCASECMP_L]) | ||
| 63 | ]) | 75 | ]) |
diff --git a/gl/m4/strcase.m4 b/gl/m4/strncasecmp.m4 index 63021733..c7c8b240 100644 --- a/gl/m4/strcase.m4 +++ b/gl/m4/strncasecmp.m4 | |||
| @@ -1,31 +1,22 @@ | |||
| 1 | # strcase.m4 | 1 | # strncasecmp.m4 |
| 2 | # serial 12 | 2 | # serial 2 |
| 3 | dnl Copyright (C) 2002, 2005-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | 7 | dnl This file is offered as-is, without any warranty. | |
| 8 | AC_DEFUN([gl_STRCASE], | ||
| 9 | [ | ||
| 10 | gl_FUNC_STRCASECMP | ||
| 11 | gl_FUNC_STRNCASECMP | ||
| 12 | ]) | ||
| 13 | |||
| 14 | AC_DEFUN([gl_FUNC_STRCASECMP], | ||
| 15 | [ | ||
| 16 | AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) | ||
| 17 | AC_CHECK_FUNCS([strcasecmp]) | ||
| 18 | if test $ac_cv_func_strcasecmp = no; then | ||
| 19 | HAVE_STRCASECMP=0 | ||
| 20 | fi | ||
| 21 | ]) | ||
| 22 | 8 | ||
| 23 | AC_DEFUN([gl_FUNC_STRNCASECMP], | 9 | AC_DEFUN([gl_FUNC_STRNCASECMP], |
| 24 | [ | 10 | [ |
| 25 | AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) | 11 | AC_REQUIRE([gl_STRINGS_H_DEFAULTS]) |
| 26 | AC_CHECK_FUNCS([strncasecmp]) | 12 | AC_CHECK_FUNCS([strncasecmp]) |
| 27 | if test $ac_cv_func_strncasecmp = yes; then | 13 | if test $ac_cv_func_strncasecmp = yes; then |
| 28 | HAVE_STRNCASECMP=1 | 14 | dnl Assume that strncasecmp and strcasecmp share the same bugs. |
| 15 | gl_STRCASECMP_WORKS | ||
| 16 | case "$gl_cv_func_strcasecmp_works" in | ||
| 17 | *yes) ;; | ||
| 18 | *) REPLACE_STRNCASECMP=1 ;; | ||
| 19 | esac | ||
| 29 | else | 20 | else |
| 30 | HAVE_STRNCASECMP=0 | 21 | HAVE_STRNCASECMP=0 |
| 31 | fi | 22 | fi |
| @@ -35,11 +26,6 @@ AC_DEFUN([gl_FUNC_STRNCASECMP], | |||
| 35 | fi | 26 | fi |
| 36 | ]) | 27 | ]) |
| 37 | 28 | ||
| 38 | # Prerequisites of lib/strcasecmp.c. | ||
| 39 | AC_DEFUN([gl_PREREQ_STRCASECMP], [ | ||
| 40 | : | ||
| 41 | ]) | ||
| 42 | |||
| 43 | # Prerequisites of lib/strncasecmp.c. | 29 | # Prerequisites of lib/strncasecmp.c. |
| 44 | AC_DEFUN([gl_PREREQ_STRNCASECMP], [ | 30 | AC_DEFUN([gl_PREREQ_STRNCASECMP], [ |
| 45 | : | 31 | : |
diff --git a/gl/m4/strncpy.m4 b/gl/m4/strncpy.m4 new file mode 100644 index 00000000..57876171 --- /dev/null +++ b/gl/m4/strncpy.m4 | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | # strncpy.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright (C) 2002-2004, 2009-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN_ONCE([gl_FUNC_STRNCPY], | ||
| 10 | [ | ||
| 11 | AC_REQUIRE([gl_STRING_H_DEFAULTS]) | ||
| 12 | AC_REQUIRE([AC_PROG_CC]) | ||
| 13 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 14 | |||
| 15 | dnl Check for prerequisites for memory fence checks. | ||
| 16 | gl_FUNC_MMAP_ANON | ||
| 17 | AC_CHECK_HEADERS_ONCE([sys/mman.h]) | ||
| 18 | AC_CHECK_FUNCS_ONCE([mprotect]) | ||
| 19 | |||
| 20 | dnl Detect bug in FreeBSD 15.0 on x86_64: | ||
| 21 | dnl strncpy should not dereference more than n bytes, but always dereferences | ||
| 22 | dnl n+1 bytes if the first n bytes don't contain a NUL byte. | ||
| 23 | dnl Assume that strncpy works on platforms that lack mprotect. | ||
| 24 | AC_CACHE_CHECK([whether strncpy works], [gl_cv_func_strncpy_works], | ||
| 25 | [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ | ||
| 26 | #include <string.h> | ||
| 27 | #if HAVE_SYS_MMAN_H | ||
| 28 | # include <fcntl.h> | ||
| 29 | # include <unistd.h> | ||
| 30 | # include <sys/types.h> | ||
| 31 | # include <sys/mman.h> | ||
| 32 | #endif | ||
| 33 | ]GL_MDA_DEFINES], | ||
| 34 | [[ | ||
| 35 | char *fence = NULL; | ||
| 36 | #if HAVE_SYS_MMAN_H && HAVE_MPROTECT | ||
| 37 | { | ||
| 38 | long int pagesize = sysconf (_SC_PAGESIZE); | ||
| 39 | char *two_pages = | ||
| 40 | (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE, | ||
| 41 | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
| 42 | if (two_pages != (char *)(-1) | ||
| 43 | && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0) | ||
| 44 | fence = two_pages + pagesize; | ||
| 45 | } | ||
| 46 | #endif | ||
| 47 | if (fence) | ||
| 48 | { | ||
| 49 | char dest[8]; | ||
| 50 | |||
| 51 | dest[0] = 'a'; | ||
| 52 | dest[1] = 'b'; | ||
| 53 | dest[2] = 'c'; | ||
| 54 | dest[3] = 'd'; | ||
| 55 | dest[4] = 'e'; | ||
| 56 | dest[5] = 'f'; | ||
| 57 | dest[6] = 'g'; | ||
| 58 | |||
| 59 | *(fence - 3) = '7'; | ||
| 60 | *(fence - 2) = '2'; | ||
| 61 | *(fence - 1) = '9'; | ||
| 62 | |||
| 63 | if (strncpy (dest + 1, fence - 3, 3) != dest + 1) | ||
| 64 | return 1; | ||
| 65 | if (dest[0] != 'a') | ||
| 66 | return 2; | ||
| 67 | if (dest[1] != '7' || dest[2] != '2' || dest[3] != '9') | ||
| 68 | return 3; | ||
| 69 | if (dest[4] != 'e') | ||
| 70 | return 4; | ||
| 71 | } | ||
| 72 | return 0; | ||
| 73 | ]])], [gl_cv_func_strncpy_works=yes], [gl_cv_func_strncpy_works=no], | ||
| 74 | [ | ||
| 75 | case "$host_os" in | ||
| 76 | # Guess no on FreeBSD. | ||
| 77 | freebsd* | dragonfly*) gl_cv_func_strncpy_works="guessing no" ;; | ||
| 78 | # Guess yes on native Windows. | ||
| 79 | mingw* | windows*) gl_cv_func_strncpy_works="guessing yes" ;; | ||
| 80 | # Guess yes otherwise. | ||
| 81 | *) gl_cv_func_strncpy_works="guessing yes" ;; | ||
| 82 | esac | ||
| 83 | ]) | ||
| 84 | ]) | ||
| 85 | case "$gl_cv_func_strncpy_works" in | ||
| 86 | *yes) ;; | ||
| 87 | *) REPLACE_STRNCPY=1 ;; | ||
| 88 | esac | ||
| 89 | ]) | ||
| 90 | |||
| 91 | # Prerequisites of lib/strncpy.c. | ||
| 92 | AC_DEFUN([gl_PREREQ_STRNCPY], [ | ||
| 93 | : | ||
| 94 | ]) | ||
diff --git a/gl/m4/strsep.m4 b/gl/m4/strsep.m4 index cfde87a5..b018ff88 100644 --- a/gl/m4/strsep.m4 +++ b/gl/m4/strsep.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # strsep.m4 | 1 | # strsep.m4 |
| 2 | # serial 11 | 2 | # serial 11 |
| 3 | dnl Copyright (C) 2002-2004, 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2004, 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_STRSEP], | 9 | AC_DEFUN([gl_FUNC_STRSEP], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/strstr.m4 b/gl/m4/strstr.m4 index 957ed2e3..1b5ef6c1 100644 --- a/gl/m4/strstr.m4 +++ b/gl/m4/strstr.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # strstr.m4 | 1 | # strstr.m4 |
| 2 | # serial 24 | 2 | # serial 25 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Check that strstr works. | 9 | dnl Check that strstr works. |
| 9 | AC_DEFUN([gl_FUNC_STRSTR_SIMPLE], | 10 | AC_DEFUN([gl_FUNC_STRSTR_SIMPLE], |
| @@ -95,7 +96,7 @@ static void quit (int sig) { _exit (sig + 128); } | |||
| 95 | char *haystack = (char *) malloc (2 * m + 2); | 96 | char *haystack = (char *) malloc (2 * m + 2); |
| 96 | char *needle = (char *) malloc (m + 2); | 97 | char *needle = (char *) malloc (m + 2); |
| 97 | /* Failure to compile this test due to missing alarm is okay, | 98 | /* Failure to compile this test due to missing alarm is okay, |
| 98 | since all such platforms (mingw) also have quadratic strstr. */ | 99 | since all such platforms (mingw, MSVC) also have quadratic strstr. */ |
| 99 | signal (SIGALRM, quit); | 100 | signal (SIGALRM, quit); |
| 100 | alarm (5); | 101 | alarm (5); |
| 101 | /* Check for quadratic performance. */ | 102 | /* Check for quadratic performance. */ |
diff --git a/gl/m4/sys_cdefs_h.m4 b/gl/m4/sys_cdefs_h.m4 new file mode 100644 index 00000000..d72796ca --- /dev/null +++ b/gl/m4/sys_cdefs_h.m4 | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | # sys_cdefs_h.m4 - Is <sys/cdefs.h> compatible enough with glibc? | ||
| 2 | # serial 2 | ||
| 3 | dnl Copyright 2024-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl Written by Paul Eggert. | ||
| 10 | |||
| 11 | AC_DEFUN_ONCE([gl_CHECK_HEADER_SYS_CDEFS_H], | ||
| 12 | [AC_CACHE_CHECK([for glibc-compatible sys/cdefs.h], | ||
| 13 | [gl_cv_header_sys_cdefs_h], | ||
| 14 | [AC_COMPILE_IFELSE( | ||
| 15 | [AC_LANG_DEFINES_PROVIDED | ||
| 16 | [#include <sys/cdefs.h> | ||
| 17 | enum { foo = __GNUC_PREREQ (14, 1) } bar; | ||
| 18 | ]], | ||
| 19 | [gl_cv_header_sys_cdefs_h=yes], | ||
| 20 | [gl_cv_header_sys_cdefs_h=no])]) | ||
| 21 | if test "$gl_cv_header_sys_cdefs_h" = yes; then | ||
| 22 | HAVE_SYS_CDEFS_H=1 | ||
| 23 | else | ||
| 24 | HAVE_SYS_CDEFS_H=0 | ||
| 25 | fi | ||
| 26 | AC_SUBST([HAVE_SYS_CDEFS_H])]) | ||
diff --git a/gl/m4/sys_socket_h.m4 b/gl/m4/sys_socket_h.m4 index 3bf3cb47..fb69209b 100644 --- a/gl/m4/sys_socket_h.m4 +++ b/gl/m4/sys_socket_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # sys_socket_h.m4 | 1 | # sys_socket_h.m4 |
| 2 | # serial 29 | 2 | # serial 31 |
| 3 | dnl Copyright (C) 2005-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Simon Josefsson. | 9 | dnl From Simon Josefsson. |
| 9 | 10 | ||
| @@ -52,24 +53,10 @@ AC_DEFUN_ONCE([gl_SYS_SOCKET_H], | |||
| 52 | fi | 53 | fi |
| 53 | # We need to check for ws2tcpip.h now. | 54 | # We need to check for ws2tcpip.h now. |
| 54 | gl_PREREQ_SYS_H_SOCKET | 55 | gl_PREREQ_SYS_H_SOCKET |
| 55 | AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[ | 56 | gl_PREREQ_SYS_SA_FAMILY |
| 56 | /* sys/types.h is not needed according to POSIX, but the | ||
| 57 | sys/socket.h in i386-unknown-freebsd4.10 and | ||
| 58 | powerpc-apple-darwin5.5 required it. */ | ||
| 59 | #include <sys/types.h> | ||
| 60 | #ifdef HAVE_SYS_SOCKET_H | ||
| 61 | #include <sys/socket.h> | ||
| 62 | #endif | ||
| 63 | #ifdef HAVE_WS2TCPIP_H | ||
| 64 | #include <ws2tcpip.h> | ||
| 65 | #endif | ||
| 66 | ]) | ||
| 67 | if test $ac_cv_type_struct_sockaddr_storage = no; then | 57 | if test $ac_cv_type_struct_sockaddr_storage = no; then |
| 68 | HAVE_STRUCT_SOCKADDR_STORAGE=0 | 58 | HAVE_STRUCT_SOCKADDR_STORAGE=0 |
| 69 | fi | 59 | fi |
| 70 | if test $ac_cv_type_sa_family_t = no; then | ||
| 71 | HAVE_SA_FAMILY_T=0 | ||
| 72 | fi | ||
| 73 | if test $ac_cv_type_struct_sockaddr_storage != no; then | 60 | if test $ac_cv_type_struct_sockaddr_storage != no; then |
| 74 | AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], | 61 | AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], |
| 75 | [], | 62 | [], |
| @@ -158,6 +145,32 @@ AC_DEFUN([gl_PREREQ_SYS_H_WS2TCPIP], | |||
| 158 | AC_SUBST([HAVE_WS2TCPIP_H]) | 145 | AC_SUBST([HAVE_WS2TCPIP_H]) |
| 159 | ]) | 146 | ]) |
| 160 | 147 | ||
| 148 | # Common prerequisites of the <sys/socket.h> replacement and of the <sys/un.h> | ||
| 149 | # replacement. | ||
| 150 | # Sets and substitutes HAVE_SA_FAMILY_T. | ||
| 151 | AC_DEFUN([gl_PREREQ_SYS_SA_FAMILY], | ||
| 152 | [ | ||
| 153 | AC_REQUIRE([gl_CHECK_SOCKET_HEADERS]) | ||
| 154 | AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[ | ||
| 155 | /* sys/types.h is not needed according to POSIX, but the | ||
| 156 | sys/socket.h in i386-unknown-freebsd4.10 and | ||
| 157 | powerpc-apple-darwin5.5 required it. */ | ||
| 158 | #include <sys/types.h> | ||
| 159 | #ifdef HAVE_SYS_SOCKET_H | ||
| 160 | #include <sys/socket.h> | ||
| 161 | #endif | ||
| 162 | #ifdef HAVE_WS2TCPIP_H | ||
| 163 | #include <ws2tcpip.h> | ||
| 164 | #endif | ||
| 165 | ]) | ||
| 166 | if test $ac_cv_type_sa_family_t = yes; then | ||
| 167 | HAVE_SA_FAMILY_T=1 | ||
| 168 | else | ||
| 169 | HAVE_SA_FAMILY_T=0 | ||
| 170 | fi | ||
| 171 | AC_SUBST([HAVE_SA_FAMILY_T]) | ||
| 172 | ]) | ||
| 173 | |||
| 161 | # gl_SYS_SOCKET_MODULE_INDICATOR([modulename]) | 174 | # gl_SYS_SOCKET_MODULE_INDICATOR([modulename]) |
| 162 | # sets the shell variable that indicates the presence of the given module | 175 | # sets the shell variable that indicates the presence of the given module |
| 163 | # to a C preprocessor expression that will evaluate to 1. | 176 | # to a C preprocessor expression that will evaluate to 1. |
| @@ -202,6 +215,5 @@ AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS], | |||
| 202 | HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE]) | 215 | HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE]) |
| 203 | HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1; | 216 | HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1; |
| 204 | AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY]) | 217 | AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY]) |
| 205 | HAVE_SA_FAMILY_T=1; AC_SUBST([HAVE_SA_FAMILY_T]) | ||
| 206 | HAVE_ACCEPT4=1; AC_SUBST([HAVE_ACCEPT4]) | 218 | HAVE_ACCEPT4=1; AC_SUBST([HAVE_ACCEPT4]) |
| 207 | ]) | 219 | ]) |
diff --git a/gl/m4/sys_stat_h.m4 b/gl/m4/sys_stat_h.m4 index 3cc50ce6..fdcc8954 100644 --- a/gl/m4/sys_stat_h.m4 +++ b/gl/m4/sys_stat_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # sys_stat_h.m4 | 1 | # sys_stat_h.m4 |
| 2 | # serial 42 -*- Autoconf -*- | 2 | # serial 42 -*- Autoconf -*- |
| 3 | dnl Copyright (C) 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Eric Blake. | 9 | dnl From Eric Blake. |
| 9 | dnl Provide a GNU-like <sys/stat.h>. | 10 | dnl Provide a GNU-like <sys/stat.h>. |
diff --git a/gl/m4/sys_types_h.m4 b/gl/m4/sys_types_h.m4 index 00d2437b..e99fdcc6 100644 --- a/gl/m4/sys_types_h.m4 +++ b/gl/m4/sys_types_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # sys_types_h.m4 | 1 | # sys_types_h.m4 |
| 2 | # serial 13 | 2 | # serial 15 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_SYS_TYPES_H], | 9 | AC_DEFUN_ONCE([gl_SYS_TYPES_H], |
| 9 | [ | 10 | [ |
| @@ -23,6 +24,9 @@ AC_DEFUN_ONCE([gl_SYS_TYPES_H], | |||
| 23 | dnl Whether to override the 'off_t' type. | 24 | dnl Whether to override the 'off_t' type. |
| 24 | AC_REQUIRE([gl_TYPE_OFF_T]) | 25 | AC_REQUIRE([gl_TYPE_OFF_T]) |
| 25 | 26 | ||
| 27 | dnl Whether to define the 'off64_t' type. | ||
| 28 | AC_REQUIRE([gl_TYPE_OFF64_T]) | ||
| 29 | |||
| 26 | dnl Whether to override the 'dev_t' and 'ino_t' types. | 30 | dnl Whether to override the 'dev_t' and 'ino_t' types. |
| 27 | m4_ifdef([gl_WINDOWS_STAT_INODES], [ | 31 | m4_ifdef([gl_WINDOWS_STAT_INODES], [ |
| 28 | AC_REQUIRE([gl_WINDOWS_STAT_INODES]) | 32 | AC_REQUIRE([gl_WINDOWS_STAT_INODES]) |
| @@ -30,6 +34,14 @@ AC_DEFUN_ONCE([gl_SYS_TYPES_H], | |||
| 30 | WINDOWS_STAT_INODES=0 | 34 | WINDOWS_STAT_INODES=0 |
| 31 | ]) | 35 | ]) |
| 32 | AC_SUBST([WINDOWS_STAT_INODES]) | 36 | AC_SUBST([WINDOWS_STAT_INODES]) |
| 37 | |||
| 38 | dnl Test whether the 'blksize_t' type is defined. | ||
| 39 | AC_CHECK_TYPE([blksize_t], [HAVE_BLKSIZE_T=1], [HAVE_BLKSIZE_T=0]) | ||
| 40 | AC_SUBST([HAVE_BLKSIZE_T]) | ||
| 41 | |||
| 42 | dnl Test whether the 'blkcnt_t' type is defined. | ||
| 43 | AC_CHECK_TYPE([blkcnt_t], [HAVE_BLKCNT_T=1], [HAVE_BLKCNT_T=0]) | ||
| 44 | AC_SUBST([HAVE_BLKCNT_T]) | ||
| 33 | ]) | 45 | ]) |
| 34 | 46 | ||
| 35 | # Initializes the default values for AC_SUBSTed shell variables. | 47 | # Initializes the default values for AC_SUBSTed shell variables. |
diff --git a/gl/m4/sys_uio_h.m4 b/gl/m4/sys_uio_h.m4 index a471c720..eb0e8424 100644 --- a/gl/m4/sys_uio_h.m4 +++ b/gl/m4/sys_uio_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # sys_uio_h.m4 | 1 | # sys_uio_h.m4 |
| 2 | # serial 3 | 2 | # serial 3 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_SYS_UIO_H], | 9 | AC_DEFUN_ONCE([gl_SYS_UIO_H], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/threadlib.m4 b/gl/m4/threadlib.m4 index f5e81479..333c8fe0 100644 --- a/gl/m4/threadlib.m4 +++ b/gl/m4/threadlib.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # threadlib.m4 | 1 | # threadlib.m4 |
| 2 | # serial 42 | 2 | # serial 45.1 |
| 3 | dnl Copyright (C) 2005-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | 10 | ||
| @@ -56,24 +57,22 @@ AC_DEFUN([gl_ANYTHREADLIB_EARLY], | |||
| 56 | [ | 57 | [ |
| 57 | AC_REQUIRE([AC_CANONICAL_HOST]) | 58 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 58 | if test -z "$gl_anythreadlib_early_done"; then | 59 | if test -z "$gl_anythreadlib_early_done"; then |
| 59 | case "$host_os" in | 60 | AS_CASE([$host_os], |
| 60 | osf*) | 61 | [osf*], |
| 61 | # On OSF/1, the compiler needs the flag -D_REENTRANT so that it | 62 | [# On OSF/1, the compiler needs the flag -D_REENTRANT so that it |
| 62 | # groks <pthread.h>. cc also understands the flag -pthread, but | 63 | # groks <pthread.h>. cc also understands the flag -pthread, but |
| 63 | # we don't use it because 1. gcc-2.95 doesn't understand -pthread, | 64 | # we do not use it because 1. gcc-2.95 does not understand -pthread, |
| 64 | # 2. putting a flag into CPPFLAGS that has an effect on the linker | 65 | # 2. putting a flag into CPPFLAGS that has an effect on the linker |
| 65 | # causes the AC_LINK_IFELSE test below to succeed unexpectedly, | 66 | # causes the AC_LINK_IFELSE test below to succeed unexpectedly, |
| 66 | # leading to wrong values of LIBTHREAD and LTLIBTHREAD. | 67 | # leading to wrong values of LIBTHREAD and LTLIBTHREAD. |
| 67 | CPPFLAGS="$CPPFLAGS -D_REENTRANT" | 68 | CPPFLAGS="$CPPFLAGS -D_REENTRANT" |
| 68 | ;; | 69 | ]) |
| 69 | esac | ||
| 70 | # Some systems optimize for single-threaded programs by default, and | 70 | # Some systems optimize for single-threaded programs by default, and |
| 71 | # need special flags to disable these optimizations. For example, the | 71 | # need special flags to disable these optimizations. For example, the |
| 72 | # definition of 'errno' in <errno.h>. | 72 | # definition of errno in <errno.h>. |
| 73 | case "$host_os" in | 73 | AS_CASE([$host_os], |
| 74 | aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; | 74 | [aix* | freebsd*], [CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"], |
| 75 | solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; | 75 | [hpux* | solaris*], [CPPFLAGS="$CPPFLAGS -D_REENTRANT"]) |
| 76 | esac | ||
| 77 | gl_anythreadlib_early_done=done | 76 | gl_anythreadlib_early_done=done |
| 78 | fi | 77 | fi |
| 79 | ]) | 78 | ]) |
| @@ -85,24 +84,26 @@ AC_DEFUN([gl_WEAK_SYMBOLS], | |||
| 85 | AC_REQUIRE([AC_CANONICAL_HOST]) | 84 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 86 | AC_CACHE_CHECK([whether imported symbols can be declared weak], | 85 | AC_CACHE_CHECK([whether imported symbols can be declared weak], |
| 87 | [gl_cv_have_weak], | 86 | [gl_cv_have_weak], |
| 88 | [case "$host_os" in | 87 | [AS_CASE([$host_os], |
| 89 | cygwin* | mingw* | windows*) | 88 | [cygwin* | mingw* | windows*], |
| 89 | [ | ||
| 90 | dnl On Cygwin 3.2.0 with gcc 10.2, and likewise on mingw 10.0.0 with | 90 | dnl On Cygwin 3.2.0 with gcc 10.2, and likewise on mingw 10.0.0 with |
| 91 | dnl gcc 11.3, the test below would succeed, but programs that use | 91 | dnl gcc 11.3, the test below would succeed, but programs that use |
| 92 | dnl pthread_in_use() with weak symbol references crash miserably at | 92 | dnl pthread_in_use() with weak symbol references crash miserably at |
| 93 | dnl runtime. | 93 | dnl runtime. |
| 94 | gl_cv_have_weak="guessing no" | 94 | gl_cv_have_weak="guessing no" |
| 95 | ;; | 95 | ], |
| 96 | *) | 96 | [ |
| 97 | gl_cv_have_weak=no | 97 | gl_cv_have_weak=no |
| 98 | dnl First, test whether the compiler accepts it syntactically. | 98 | dnl First, test whether the compiler accepts it syntactically. |
| 99 | AC_LINK_IFELSE( | 99 | AC_LINK_IFELSE( |
| 100 | [AC_LANG_PROGRAM( | 100 | [AC_LANG_PROGRAM( |
| 101 | [[extern void xyzzy (); | 101 | [[extern void xyzzy (); |
| 102 | #pragma weak xyzzy]], | 102 | #pragma weak xyzzy |
| 103 | ]], | ||
| 103 | [[xyzzy();]])], | 104 | [[xyzzy();]])], |
| 104 | [gl_cv_have_weak=maybe]) | 105 | [gl_cv_have_weak=maybe]) |
| 105 | if test $gl_cv_have_weak = maybe; then | 106 | AS_IF([test $gl_cv_have_weak = maybe], [ |
| 106 | dnl Second, test whether it actually works. On Cygwin 1.7.2, with | 107 | dnl Second, test whether it actually works. On Cygwin 1.7.2, with |
| 107 | dnl gcc 4.3, symbols declared weak always evaluate to the address 0. | 108 | dnl gcc 4.3, symbols declared weak always evaluate to the address 0. |
| 108 | AC_RUN_IFELSE( | 109 | AC_RUN_IFELSE( |
| @@ -125,20 +126,19 @@ int main () | |||
| 125 | [gl_cv_have_weak="guessing yes"], | 126 | [gl_cv_have_weak="guessing yes"], |
| 126 | [gl_cv_have_weak="guessing no"]) | 127 | [gl_cv_have_weak="guessing no"]) |
| 127 | ]) | 128 | ]) |
| 128 | fi | 129 | ]) |
| 129 | ;; | 130 | ]) |
| 130 | esac | 131 | dnl But when linking statically, weak symbols do not work. |
| 131 | dnl But when linking statically, weak symbols don't work. | 132 | AS_CASE([" $LDFLAGS "], |
| 132 | case " $LDFLAGS " in | 133 | [*" -static "*], [gl_cv_have_weak=no]) |
| 133 | *" -static "*) gl_cv_have_weak=no ;; | ||
| 134 | esac | ||
| 135 | dnl Test for a bug in FreeBSD 11: A link error occurs when using a weak | 134 | dnl Test for a bug in FreeBSD 11: A link error occurs when using a weak |
| 136 | dnl symbol and linking against a shared library that has a dependency on | 135 | dnl symbol and linking against a shared library that has a dependency on |
| 137 | dnl the shared library that defines the symbol. | 136 | dnl the shared library that defines the symbol. |
| 138 | case "$gl_cv_have_weak" in | 137 | AS_CASE([$gl_cv_have_weak], |
| 139 | *yes) | 138 | [*yes], |
| 140 | case "$host_os" in | 139 | [AS_CASE([$host_os], |
| 141 | freebsd* | dragonfly* | midnightbsd*) | 140 | [freebsd* | dragonfly* | midnightbsd*], |
| 141 | [ | ||
| 142 | : > conftest1.c | 142 | : > conftest1.c |
| 143 | $CC $CPPFLAGS $CFLAGS $LDFLAGS -fPIC -shared -o libempty.so conftest1.c -lpthread >&AS_MESSAGE_LOG_FD 2>&1 | 143 | $CC $CPPFLAGS $CFLAGS $LDFLAGS -fPIC -shared -o libempty.so conftest1.c -lpthread >&AS_MESSAGE_LOG_FD 2>&1 |
| 144 | cat <<EOF > conftest2.c | 144 | cat <<EOF > conftest2.c |
| @@ -152,17 +152,15 @@ EOF | |||
| 152 | $CC $CPPFLAGS $CFLAGS $LDFLAGS -o conftest conftest2.c libempty.so >&AS_MESSAGE_LOG_FD 2>&1 \ | 152 | $CC $CPPFLAGS $CFLAGS $LDFLAGS -o conftest conftest2.c libempty.so >&AS_MESSAGE_LOG_FD 2>&1 \ |
| 153 | || gl_cv_have_weak=no | 153 | || gl_cv_have_weak=no |
| 154 | rm -f conftest1.c libempty.so conftest2.c conftest | 154 | rm -f conftest1.c libempty.so conftest2.c conftest |
| 155 | ;; | 155 | ]) |
| 156 | esac | 156 | ]) |
| 157 | ;; | ||
| 158 | esac | ||
| 159 | ]) | 157 | ]) |
| 160 | case "$gl_cv_have_weak" in | 158 | AS_CASE([$gl_cv_have_weak], |
| 161 | *yes) | 159 | [*yes], |
| 160 | [ | ||
| 162 | AC_DEFINE([HAVE_WEAK_SYMBOLS], [1], | 161 | AC_DEFINE([HAVE_WEAK_SYMBOLS], [1], |
| 163 | [Define to 1 if the compiler and linker support weak declarations of symbols.]) | 162 | [Define to 1 if the compiler and linker support weak declarations of symbols.]) |
| 164 | ;; | 163 | ]) |
| 165 | esac | ||
| 166 | ]) | 164 | ]) |
| 167 | 165 | ||
| 168 | dnl ============================================================================ | 166 | dnl ============================================================================ |
| @@ -188,15 +186,15 @@ dnl The guts of gl_PTHREADLIB. Needs to be expanded only once. | |||
| 188 | AC_DEFUN([gl_PTHREADLIB_BODY], | 186 | AC_DEFUN([gl_PTHREADLIB_BODY], |
| 189 | [ | 187 | [ |
| 190 | AC_REQUIRE([gl_ANYTHREADLIB_EARLY]) | 188 | AC_REQUIRE([gl_ANYTHREADLIB_EARLY]) |
| 191 | if test -z "$gl_pthreadlib_body_done"; then | 189 | AS_IF([test -z "$gl_pthreadlib_body_done"], [ |
| 192 | gl_pthread_api=no | 190 | gl_pthread_api=no |
| 193 | LIBPTHREAD= | 191 | LIBPTHREAD= |
| 194 | LIBPMULTITHREAD= | 192 | LIBPMULTITHREAD= |
| 195 | # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that | 193 | # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that |
| 196 | # it groks <pthread.h>. It's added above, in gl_ANYTHREADLIB_EARLY. | 194 | # it groks <pthread.h>. It is added above, in gl_ANYTHREADLIB_EARLY. |
| 197 | AC_CHECK_HEADER([pthread.h], | 195 | AC_CHECK_HEADER([pthread.h], |
| 198 | [gl_have_pthread_h=yes], [gl_have_pthread_h=no]) | 196 | [gl_have_pthread_h=yes], [gl_have_pthread_h=no]) |
| 199 | if test "$gl_have_pthread_h" = yes; then | 197 | AS_IF([test "$gl_have_pthread_h" = yes], [ |
| 200 | # Other possible tests: | 198 | # Other possible tests: |
| 201 | # -lpthreads (FSU threads, PCthreads) | 199 | # -lpthreads (FSU threads, PCthreads) |
| 202 | # -lgthreads | 200 | # -lgthreads |
| @@ -208,7 +206,7 @@ AC_DEFUN([gl_PTHREADLIB_BODY], | |||
| 208 | # needs -pthread for some reason. See: | 206 | # needs -pthread for some reason. See: |
| 209 | # https://lists.gnu.org/r/bug-gnulib/2014-09/msg00023.html | 207 | # https://lists.gnu.org/r/bug-gnulib/2014-09/msg00023.html |
| 210 | saved_LIBS="$LIBS" | 208 | saved_LIBS="$LIBS" |
| 211 | for gl_pthread in '' '-pthread'; do | 209 | for gl_pthread in "" "-pthread"; do |
| 212 | LIBS="$LIBS $gl_pthread" | 210 | LIBS="$LIBS $gl_pthread" |
| 213 | AC_LINK_IFELSE( | 211 | AC_LINK_IFELSE( |
| 214 | [AC_LANG_PROGRAM( | 212 | [AC_LANG_PROGRAM( |
| @@ -230,8 +228,9 @@ AC_DEFUN([gl_PTHREADLIB_BODY], | |||
| 230 | gl_pthread_in_glibc=no | 228 | gl_pthread_in_glibc=no |
| 231 | # On Linux with glibc >= 2.34, libc contains the fully functional | 229 | # On Linux with glibc >= 2.34, libc contains the fully functional |
| 232 | # pthread functions. | 230 | # pthread functions. |
| 233 | case "$host_os" in | 231 | AS_CASE([$host_os], |
| 234 | linux*) | 232 | [linux*], |
| 233 | [ | ||
| 235 | AC_EGREP_CPP([Lucky user], | 234 | AC_EGREP_CPP([Lucky user], |
| 236 | [#include <features.h> | 235 | [#include <features.h> |
| 237 | #ifdef __GNU_LIBRARY__ | 236 | #ifdef __GNU_LIBRARY__ |
| @@ -242,19 +241,18 @@ AC_DEFUN([gl_PTHREADLIB_BODY], | |||
| 242 | ], | 241 | ], |
| 243 | [gl_pthread_in_glibc=yes], | 242 | [gl_pthread_in_glibc=yes], |
| 244 | []) | 243 | []) |
| 245 | ;; | 244 | ]) |
| 246 | esac | ||
| 247 | echo "$as_me:__oline__: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&AS_MESSAGE_LOG_FD | 245 | echo "$as_me:__oline__: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&AS_MESSAGE_LOG_FD |
| 248 | 246 | ||
| 249 | # Test for libpthread by looking for pthread_kill. (Not pthread_self, | 247 | # Test for libpthread by looking for pthread_kill. (Not pthread_self, |
| 250 | # since it is defined as a macro on OSF/1.) | 248 | # since it is defined as a macro on OSF/1.) |
| 251 | if test $gl_pthread_api = yes && test -z "$LIBPTHREAD"; then | 249 | AS_IF([test $gl_pthread_api = yes && test -z "$LIBPTHREAD"], [ |
| 252 | # The program links fine without libpthread. But it may actually | 250 | # The program links fine without libpthread. But it may actually |
| 253 | # need to link with libpthread in order to create multiple threads. | 251 | # need to link with libpthread in order to create multiple threads. |
| 254 | AC_CHECK_LIB([pthread], [pthread_kill], | 252 | AC_CHECK_LIB([pthread], [pthread_kill], |
| 255 | [if test $gl_pthread_in_glibc = yes; then | 253 | [AS_IF([test $gl_pthread_in_glibc = yes], [ |
| 256 | LIBPMULTITHREAD= | 254 | LIBPMULTITHREAD= |
| 257 | else | 255 | ], [ |
| 258 | LIBPMULTITHREAD=-lpthread | 256 | LIBPMULTITHREAD=-lpthread |
| 259 | # On Solaris and HP-UX, most pthread functions exist also in libc. | 257 | # On Solaris and HP-UX, most pthread functions exist also in libc. |
| 260 | # Therefore pthread_in_use() needs to actually try to create a | 258 | # Therefore pthread_in_use() needs to actually try to create a |
| @@ -262,14 +260,13 @@ AC_DEFUN([gl_PTHREADLIB_BODY], | |||
| 262 | # pthread_create will actually create a thread. | 260 | # pthread_create will actually create a thread. |
| 263 | # On Solaris 10 or newer, this test is no longer needed, because | 261 | # On Solaris 10 or newer, this test is no longer needed, because |
| 264 | # libc contains the fully functional pthread functions. | 262 | # libc contains the fully functional pthread functions. |
| 265 | case "$host_os" in | 263 | AS_CASE([$host_os], |
| 266 | changequote(,)dnl | 264 | [[solaris | solaris2.[1-9] | solaris2.[1-9].* | hpux*]], |
| 267 | solaris | solaris2.[1-9] | solaris2.[1-9].* | hpux*) | 265 | [ |
| 268 | changequote([,])dnl | 266 | AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], |
| 269 | AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], | 267 | [Define if the pthread_in_use() detection is hard.]) |
| 270 | [Define if the pthread_in_use() detection is hard.]) | 268 | ]) |
| 271 | esac | 269 | ]) |
| 272 | fi | ||
| 273 | ], | 270 | ], |
| 274 | [dnl This is needed on FreeBSD 5.2.1. | 271 | [dnl This is needed on FreeBSD 5.2.1. |
| 275 | AC_CHECK_LIB([thr], [pthread_kill], | 272 | AC_CHECK_LIB([thr], [pthread_kill], |
| @@ -280,35 +277,36 @@ changequote([,])dnl | |||
| 280 | fi | 277 | fi |
| 281 | ]) | 278 | ]) |
| 282 | ]) | 279 | ]) |
| 283 | elif test $gl_pthread_api != yes; then | 280 | ], [test $gl_pthread_api != yes], [ |
| 284 | # Some library is needed. Try libpthread and libc_r. | 281 | # Some library is needed. Try libpthread and libc_r. |
| 285 | AC_CHECK_LIB([pthread], [pthread_kill], | 282 | AC_CHECK_LIB([pthread], [pthread_kill], |
| 286 | [gl_pthread_api=yes | 283 | [gl_pthread_api=yes |
| 287 | LIBPTHREAD=-lpthread | 284 | LIBPTHREAD=-lpthread |
| 288 | LIBPMULTITHREAD=-lpthread]) | 285 | LIBPMULTITHREAD=-lpthread]) |
| 289 | if test $gl_pthread_api != yes; then | 286 | AS_IF([test $gl_pthread_api != yes], [ |
| 290 | # For FreeBSD 4. | 287 | # For FreeBSD 4. |
| 291 | AC_CHECK_LIB([c_r], [pthread_kill], | 288 | AC_CHECK_LIB([c_r], [pthread_kill], |
| 292 | [gl_pthread_api=yes | 289 | [gl_pthread_api=yes |
| 293 | LIBPTHREAD=-lc_r | 290 | LIBPTHREAD=-lc_r |
| 294 | LIBPMULTITHREAD=-lc_r]) | 291 | LIBPMULTITHREAD=-lc_r]) |
| 295 | fi | 292 | ]) |
| 296 | fi | 293 | ]) |
| 297 | echo "$as_me:__oline__: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&AS_MESSAGE_LOG_FD | 294 | echo "$as_me:__oline__: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&AS_MESSAGE_LOG_FD |
| 298 | fi | 295 | ]) |
| 299 | AC_MSG_CHECKING([whether POSIX threads API is available]) | 296 | AC_MSG_CHECKING([whether POSIX threads API is available]) |
| 300 | AC_MSG_RESULT([$gl_pthread_api]) | 297 | AC_MSG_RESULT([$gl_pthread_api]) |
| 301 | AC_SUBST([LIBPTHREAD]) | 298 | AC_SUBST([LIBPTHREAD]) |
| 302 | AC_SUBST([LIBPMULTITHREAD]) | 299 | AC_SUBST([LIBPMULTITHREAD]) |
| 303 | if test $gl_pthread_api = yes; then | 300 | AS_IF([test $gl_pthread_api = yes], [ |
| 304 | AC_DEFINE([HAVE_PTHREAD_API], [1], | 301 | AC_DEFINE([HAVE_PTHREAD_API], [1], |
| 305 | [Define if you have the <pthread.h> header and the POSIX threads API.]) | 302 | [Define if you have the <pthread.h> header and the POSIX threads API.]) |
| 306 | fi | 303 | ]) |
| 307 | 304 | ||
| 308 | dnl On some systems, sched_yield is in librt, rather than in libpthread. | 305 | dnl On some systems, sched_yield is in librt, rather than in libpthread. |
| 309 | AC_LINK_IFELSE( | 306 | AC_LINK_IFELSE( |
| 310 | [AC_LANG_PROGRAM( | 307 | [AC_LANG_PROGRAM( |
| 311 | [[#include <sched.h>]], | 308 | [[#include <sched.h> |
| 309 | ]], | ||
| 312 | [[sched_yield ();]])], | 310 | [[sched_yield ();]])], |
| 313 | [SCHED_YIELD_LIB= | 311 | [SCHED_YIELD_LIB= |
| 314 | ], | 312 | ], |
| @@ -323,7 +321,7 @@ changequote([,])dnl | |||
| 323 | AC_SUBST([LIB_SCHED_YIELD]) | 321 | AC_SUBST([LIB_SCHED_YIELD]) |
| 324 | 322 | ||
| 325 | gl_pthreadlib_body_done=done | 323 | gl_pthreadlib_body_done=done |
| 326 | fi | 324 | ]) |
| 327 | ]) | 325 | ]) |
| 328 | 326 | ||
| 329 | AC_DEFUN([gl_PTHREADLIB], | 327 | AC_DEFUN([gl_PTHREADLIB], |
| @@ -350,44 +348,45 @@ AC_DEFUN([gl_STDTHREADLIB_BODY], | |||
| 350 | [ | 348 | [ |
| 351 | AC_REQUIRE([gl_ANYTHREADLIB_EARLY]) | 349 | AC_REQUIRE([gl_ANYTHREADLIB_EARLY]) |
| 352 | AC_REQUIRE([AC_CANONICAL_HOST]) | 350 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 353 | if test -z "$gl_stdthreadlib_body_done"; then | 351 | AS_IF([test -z "$gl_stdthreadlib_body_done"], [ |
| 354 | AC_CHECK_HEADERS_ONCE([threads.h]) | 352 | AC_CHECK_HEADERS_ONCE([threads.h]) |
| 355 | 353 | ||
| 356 | case "$host_os" in | 354 | AS_CASE([$host_os], |
| 357 | mingw* | windows*) | 355 | [mingw* | windows*], |
| 356 | [ | ||
| 358 | LIBSTDTHREAD= | 357 | LIBSTDTHREAD= |
| 359 | ;; | 358 | ], |
| 360 | *) | 359 | [ |
| 361 | gl_PTHREADLIB_BODY | 360 | gl_PTHREADLIB_BODY |
| 362 | if test $ac_cv_header_threads_h = yes; then | 361 | AS_IF([test $ac_cv_header_threads_h = yes], [ |
| 363 | dnl glibc >= 2.29 has thrd_create in libpthread. | 362 | dnl glibc >= 2.29 has thrd_create in libpthread. |
| 364 | dnl FreeBSD >= 10 has thrd_create in libstdthreads; this library depends | 363 | dnl FreeBSD >= 10 has thrd_create in libstdthreads; this library depends |
| 365 | dnl on libpthread (for the symbol 'pthread_mutexattr_gettype'). | 364 | dnl on libpthread (for the symbol pthread_mutexattr_gettype). |
| 366 | dnl glibc >= 2.34, AIX >= 7.1, and Solaris >= 11.4 have thrd_create in | 365 | dnl glibc >= 2.34, AIX >= 7.1, and Solaris >= 11.4 have thrd_create in |
| 367 | dnl libc. | 366 | dnl libc. |
| 368 | gl_CHECK_FUNCS_ANDROID([thrd_create], [[#include <threads.h>]]) | 367 | gl_CHECK_FUNCS_ANDROID([thrd_create], [[#include <threads.h> |
| 369 | if test $ac_cv_func_thrd_create = yes; then | 368 | ]]) |
| 369 | AS_IF([test $ac_cv_func_thrd_create = yes], [ | ||
| 370 | LIBSTDTHREAD= | 370 | LIBSTDTHREAD= |
| 371 | else | 371 | ], [ |
| 372 | AC_CHECK_LIB([stdthreads], [thrd_create], [ | 372 | AC_CHECK_LIB([stdthreads], [thrd_create], [ |
| 373 | LIBSTDTHREAD='-lstdthreads -lpthread' | 373 | LIBSTDTHREAD="-lstdthreads -lpthread" |
| 374 | ], [ | 374 | ], [ |
| 375 | dnl Guess that thrd_create is in libpthread. | 375 | dnl Guess that thrd_create is in libpthread. |
| 376 | LIBSTDTHREAD="$LIBPMULTITHREAD" | 376 | LIBSTDTHREAD="$LIBPMULTITHREAD" |
| 377 | ]) | 377 | ]) |
| 378 | fi | 378 | ]) |
| 379 | else | 379 | ], [ |
| 380 | dnl Libraries needed by thrd.c, mtx.c, cnd.c, tss.c. | 380 | dnl Libraries needed by thrd.c, mtx.c, cnd.c, tss.c. |
| 381 | LIBSTDTHREAD="$LIBPMULTITHREAD $SCHED_YIELD_LIB" | 381 | LIBSTDTHREAD="$LIBPMULTITHREAD $SCHED_YIELD_LIB" |
| 382 | fi | 382 | ]) |
| 383 | ;; | 383 | ]) |
| 384 | esac | ||
| 385 | AC_SUBST([LIBSTDTHREAD]) | 384 | AC_SUBST([LIBSTDTHREAD]) |
| 386 | 385 | ||
| 387 | AC_MSG_CHECKING([whether ISO C threads API is available]) | 386 | AC_MSG_CHECKING([whether ISO C threads API is available]) |
| 388 | AC_MSG_RESULT([$ac_cv_header_threads_h]) | 387 | AC_MSG_RESULT([$ac_cv_header_threads_h]) |
| 389 | gl_stdthreadlib_body_done=done | 388 | gl_stdthreadlib_body_done=done |
| 390 | fi | 389 | ]) |
| 391 | ]) | 390 | ]) |
| 392 | 391 | ||
| 393 | AC_DEFUN([gl_STDTHREADLIB], | 392 | AC_DEFUN([gl_STDTHREADLIB], |
| @@ -404,7 +403,7 @@ dnl ------------ | |||
| 404 | dnl Tests for a multithreading library to be used. | 403 | dnl Tests for a multithreading library to be used. |
| 405 | dnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO | 404 | dnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO |
| 406 | dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the | 405 | dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the |
| 407 | dnl default is 'no', otherwise it is system dependent. In both cases, the user | 406 | dnl default is "no", otherwise it is system dependent. In both cases, the user |
| 408 | dnl can change the choice through the options --enable-threads=choice or | 407 | dnl can change the choice through the options --enable-threads=choice or |
| 409 | dnl --disable-threads. | 408 | dnl --disable-threads. |
| 410 | dnl Defines at most one of the macros USE_ISOC_THREADS, USE_POSIX_THREADS, | 409 | dnl Defines at most one of the macros USE_ISOC_THREADS, USE_POSIX_THREADS, |
| @@ -449,7 +448,7 @@ AC_DEFUN([gl_THREADLIB_EARLY_BODY], | |||
| 449 | m4_ifdef([gl_THREADLIB_DEFAULT_NO], | 448 | m4_ifdef([gl_THREADLIB_DEFAULT_NO], |
| 450 | [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])], | 449 | [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])], |
| 451 | [m4_divert_text([DEFAULTS], [gl_use_threads_default=])]) | 450 | [m4_divert_text([DEFAULTS], [gl_use_threads_default=])]) |
| 452 | dnl gl_use_winpthreads_default defaults to 'no', because in mingw 10, like | 451 | dnl gl_use_winpthreads_default defaults to "no", because in mingw 10, like |
| 453 | dnl in mingw 5, the use of libwinpthread still makes test-pthread-tss crash. | 452 | dnl in mingw 5, the use of libwinpthread still makes test-pthread-tss crash. |
| 454 | m4_divert_text([DEFAULTS], [gl_use_winpthreads_default=no]) | 453 | m4_divert_text([DEFAULTS], [gl_use_winpthreads_default=no]) |
| 455 | AC_ARG_ENABLE([threads], | 454 | AC_ARG_ENABLE([threads], |
| @@ -459,41 +458,35 @@ AS_HELP_STRING([[--disable-threads]], [build without multithread safety])]), | |||
| 459 | [if test -n "$gl_use_threads_default"; then | 458 | [if test -n "$gl_use_threads_default"; then |
| 460 | gl_use_threads="$gl_use_threads_default" | 459 | gl_use_threads="$gl_use_threads_default" |
| 461 | else | 460 | else |
| 462 | changequote(,)dnl | 461 | AS_CASE([$host_os], |
| 463 | case "$host_os" in | ||
| 464 | dnl Disable multithreading by default on OSF/1, because it interferes | 462 | dnl Disable multithreading by default on OSF/1, because it interferes |
| 465 | dnl with fork()/exec(): When msgexec is linked with -lpthread, its | 463 | dnl with fork()/exec(): When msgexec is linked with -lpthread, its |
| 466 | dnl child process gets an endless segmentation fault inside execvp(). | 464 | dnl child process gets an endless segmentation fault inside execvp(). |
| 467 | osf*) gl_use_threads=no ;; | 465 | [osf*], [gl_use_threads=no], |
| 468 | dnl Disable multithreading by default on Cygwin 1.5.x, because it has | 466 | dnl Disable multithreading by default on Cygwin 1.5.x, because it has |
| 469 | dnl bugs that lead to endless loops or crashes. See | 467 | dnl bugs that lead to endless loops or crashes. See |
| 470 | dnl <https://cygwin.com/ml/cygwin/2009-08/msg00283.html>. | 468 | dnl <https://cygwin.com/ml/cygwin/2009-08/msg00283.html>. |
| 471 | cygwin*) | 469 | [cygwin*], |
| 472 | case `uname -r` in | 470 | [AS_CASE([$(uname -r)], |
| 473 | 1.[0-5].*) gl_use_threads=no ;; | 471 | [[1.[0-5].*]], [gl_use_threads=no], |
| 474 | *) gl_use_threads=yes ;; | 472 | [gl_use_threads=yes]) |
| 475 | esac | 473 | ], |
| 476 | ;; | ||
| 477 | dnl Obey gl_AVOID_WINPTHREAD on mingw. | 474 | dnl Obey gl_AVOID_WINPTHREAD on mingw. |
| 478 | mingw* | windows*) | 475 | [mingw* | windows*], |
| 479 | case "$gl_use_winpthreads_default" in | 476 | [AS_CASE([$gl_use_winpthreads_default], |
| 480 | yes) gl_use_threads=posix ;; | 477 | [yes], [gl_use_threads=posix], |
| 481 | no) gl_use_threads=windows ;; | 478 | [no], [gl_use_threads=windows], |
| 482 | *) gl_use_threads=yes ;; | 479 | [gl_use_threads=yes]) |
| 483 | esac | 480 | ], |
| 484 | ;; | 481 | [gl_use_threads=yes]) |
| 485 | *) gl_use_threads=yes ;; | ||
| 486 | esac | ||
| 487 | changequote([,])dnl | ||
| 488 | fi | 482 | fi |
| 489 | ]) | 483 | ]) |
| 490 | if test "$gl_use_threads" = yes \ | 484 | AS_CASE([$gl_use_threads], |
| 491 | || test "$gl_use_threads" = isoc \ | 485 | [yes | isoc | posix | isoc+posix], |
| 492 | || test "$gl_use_threads" = posix \ | 486 | [ |
| 493 | || test "$gl_use_threads" = isoc+posix; then | 487 | # For using <threads.h> or <pthread.h>: |
| 494 | # For using <threads.h> or <pthread.h>: | 488 | gl_ANYTHREADLIB_EARLY |
| 495 | gl_ANYTHREADLIB_EARLY | 489 | ]) |
| 496 | fi | ||
| 497 | ]) | 490 | ]) |
| 498 | 491 | ||
| 499 | dnl The guts of gl_THREADLIB. Needs to be expanded only once. | 492 | dnl The guts of gl_THREADLIB. Needs to be expanded only once. |
| @@ -506,90 +499,95 @@ AC_DEFUN([gl_THREADLIB_BODY], | |||
| 506 | LTLIBTHREAD= | 499 | LTLIBTHREAD= |
| 507 | LIBMULTITHREAD= | 500 | LIBMULTITHREAD= |
| 508 | LTLIBMULTITHREAD= | 501 | LTLIBMULTITHREAD= |
| 509 | if test "$gl_use_threads" != no; then | 502 | AS_IF([test "$gl_use_threads" = no], |
| 503 | [AC_DEFINE([AVOID_ANY_THREADS], [1], | ||
| 504 | [Define if no multithread safety and no multithreading is desired.])], | ||
| 505 | [ | ||
| 510 | dnl Check whether the compiler and linker support weak declarations. | 506 | dnl Check whether the compiler and linker support weak declarations. |
| 511 | gl_WEAK_SYMBOLS | 507 | gl_WEAK_SYMBOLS |
| 512 | if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then | 508 | AS_CASE([$gl_cv_have_weak], |
| 513 | dnl If we use weak symbols to implement pthread_in_use / pth_in_use / | 509 | [*yes], |
| 514 | dnl thread_in_use, we also need to test whether the ISO C 11 thrd_create | 510 | [ |
| 515 | dnl facility is in use. | 511 | dnl If we use weak symbols to implement pthread_in_use / pth_in_use / |
| 516 | AC_CHECK_HEADERS_ONCE([threads.h]) | 512 | dnl thread_in_use, we also need to test whether the ISO C 11 thrd_create |
| 517 | : | 513 | dnl facility is in use. |
| 518 | fi | 514 | AC_CHECK_HEADERS_ONCE([threads.h]) |
| 519 | if test "$gl_use_threads" = isoc || test "$gl_use_threads" = isoc+posix; then | 515 | : |
| 520 | AC_CHECK_HEADERS_ONCE([threads.h]) | 516 | ]) |
| 521 | gl_have_isoc_threads="$ac_cv_header_threads_h" | 517 | AS_CASE([$gl_use_threads], |
| 522 | fi | 518 | [isoc | isoc+posix], |
| 523 | if test "$gl_use_threads" = yes \ | 519 | [ |
| 524 | || test "$gl_use_threads" = posix \ | 520 | AC_CHECK_HEADERS_ONCE([threads.h]) |
| 525 | || test "$gl_use_threads" = isoc+posix; then | 521 | gl_have_isoc_threads="$ac_cv_header_threads_h" |
| 526 | gl_PTHREADLIB_BODY | 522 | ]) |
| 527 | LIBTHREAD=$LIBPTHREAD LTLIBTHREAD=$LIBPTHREAD | 523 | AS_CASE([$gl_use_threads], |
| 528 | LIBMULTITHREAD=$LIBPMULTITHREAD LTLIBMULTITHREAD=$LIBPMULTITHREAD | 524 | [yes | posix | isoc+posix], |
| 529 | if test $gl_pthread_api = yes; then | 525 | [ |
| 530 | if test "$gl_use_threads" = isoc+posix && test "$gl_have_isoc_threads" = yes; then | 526 | gl_PTHREADLIB_BODY |
| 531 | gl_threads_api='isoc+posix' | 527 | LIBTHREAD=$LIBPTHREAD LTLIBTHREAD=$LIBPTHREAD |
| 532 | AC_DEFINE([USE_ISOC_AND_POSIX_THREADS], [1], | 528 | LIBMULTITHREAD=$LIBPMULTITHREAD LTLIBMULTITHREAD=$LIBPMULTITHREAD |
| 533 | [Define if the combination of the ISO C and POSIX multithreading APIs can be used.]) | 529 | AS_IF([test $gl_pthread_api = yes], [ |
| 534 | LIBTHREAD= LTLIBTHREAD= | 530 | AS_IF([test "$gl_use_threads" = isoc+posix && |
| 535 | else | 531 | test "$gl_have_isoc_threads" = yes], [ |
| 536 | gl_threads_api=posix | 532 | gl_threads_api="isoc+posix" |
| 537 | AC_DEFINE([USE_POSIX_THREADS], [1], | 533 | AC_DEFINE([USE_ISOC_AND_POSIX_THREADS], [1], |
| 538 | [Define if the POSIX multithreading library can be used.]) | 534 | [Define if the combination of the ISO C and POSIX multithreading APIs can be used.]) |
| 539 | if test -z "$LIBMULTITHREAD" && test -z "$LTLIBMULTITHREAD"; then | 535 | LIBTHREAD= LTLIBTHREAD= |
| 540 | AC_DEFINE([USE_POSIX_THREADS_FROM_LIBC], [1], | 536 | ], [ |
| 541 | [Define if references to the POSIX multithreading library are satisfied by libc.]) | 537 | gl_threads_api=posix |
| 542 | else | 538 | AC_DEFINE([USE_POSIX_THREADS], [1], |
| 543 | if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then | 539 | [Define if the POSIX multithreading library can be used.]) |
| 544 | AC_DEFINE([USE_POSIX_THREADS_WEAK], [1], | 540 | AS_IF([test -z "$LIBMULTITHREAD" && test -z "$LTLIBMULTITHREAD"], [ |
| 545 | [Define if references to the POSIX multithreading library should be made weak.]) | 541 | AC_DEFINE([USE_POSIX_THREADS_FROM_LIBC], [1], |
| 546 | LIBTHREAD= LTLIBTHREAD= | 542 | [Define if references to the POSIX multithreading library are satisfied by libc.]) |
| 547 | else | 543 | ], [ |
| 548 | case "$host_os" in | 544 | AS_CASE([$gl_cv_have_weak], |
| 549 | freebsd* | dragonfly* | midnightbsd*) | 545 | [*yes], |
| 550 | if test "x$LIBTHREAD" != "x$LIBMULTITHREAD"; then | 546 | [ |
| 551 | dnl If weak symbols can't tell whether pthread_create(), pthread_key_create() | 547 | AC_DEFINE([USE_POSIX_THREADS_WEAK], [1], |
| 552 | dnl etc. will succeed, we need a runtime test. | 548 | [Define if references to the POSIX multithreading library should be made weak.]) |
| 553 | AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], | 549 | LIBTHREAD= LTLIBTHREAD= |
| 554 | [Define if the pthread_in_use() detection is hard.]) | 550 | ], |
| 555 | fi | 551 | [AS_CASE([$host_os], |
| 556 | ;; | 552 | [freebsd* | dragonfly* | midnightbsd*], |
| 557 | esac | 553 | [ |
| 558 | fi | 554 | AS_IF([test "x$LIBTHREAD" != "x$LIBMULTITHREAD"], [ |
| 559 | fi | 555 | dnl If weak symbols cannot tell whether |
| 560 | fi | 556 | dnl pthread_create(), dnl pthread_key_create() |
| 561 | fi | 557 | dnl etc. will succeed, we need a runtime test. |
| 562 | fi | 558 | AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], |
| 563 | if test $gl_threads_api = none; then | 559 | [Define if the pthread_in_use() detection is hard.]) |
| 564 | if test "$gl_use_threads" = isoc && test "$gl_have_isoc_threads" = yes; then | 560 | ]) |
| 561 | ]) | ||
| 562 | ]) | ||
| 563 | ]) | ||
| 564 | ]) | ||
| 565 | ]) | ||
| 566 | ]) | ||
| 567 | AS_IF([test $gl_threads_api = none], [ | ||
| 568 | AS_IF([test "$gl_use_threads" = isoc && test "$gl_have_isoc_threads" = yes], [ | ||
| 565 | gl_STDTHREADLIB_BODY | 569 | gl_STDTHREADLIB_BODY |
| 566 | LIBTHREAD=$LIBSTDTHREAD LTLIBTHREAD=$LIBSTDTHREAD | 570 | LIBTHREAD=$LIBSTDTHREAD LTLIBTHREAD=$LIBSTDTHREAD |
| 567 | LIBMULTITHREAD=$LIBSTDTHREAD LTLIBMULTITHREAD=$LIBSTDTHREAD | 571 | LIBMULTITHREAD=$LIBSTDTHREAD LTLIBMULTITHREAD=$LIBSTDTHREAD |
| 568 | gl_threads_api=isoc | 572 | gl_threads_api=isoc |
| 569 | AC_DEFINE([USE_ISOC_THREADS], [1], | 573 | AC_DEFINE([USE_ISOC_THREADS], [1], |
| 570 | [Define if the ISO C multithreading library can be used.]) | 574 | [Define if the ISO C multithreading library can be used.]) |
| 571 | fi | 575 | ]) |
| 572 | fi | 576 | ]) |
| 573 | if test $gl_threads_api = none; then | 577 | AS_IF([test $gl_threads_api = none], [ |
| 574 | case "$gl_use_threads" in | 578 | # The "win32" is for backward compatibility. |
| 575 | yes | windows | win32) # The 'win32' is for backward compatibility. | 579 | AS_CASE([$gl_use_threads], |
| 576 | if { case "$host_os" in | 580 | [yes | windows | win32], |
| 577 | mingw* | windows*) true;; | 581 | [AS_CASE([$host_os], |
| 578 | *) false;; | 582 | [mingw* | windows*], |
| 579 | esac | 583 | [ |
| 580 | }; then | 584 | gl_threads_api=windows |
| 581 | gl_threads_api=windows | 585 | AC_DEFINE([USE_WINDOWS_THREADS], [1], |
| 582 | AC_DEFINE([USE_WINDOWS_THREADS], [1], | 586 | [Define if the native Windows multithreading API can be used.]) |
| 583 | [Define if the native Windows multithreading API can be used.]) | 587 | ]) |
| 584 | fi | 588 | ]) |
| 585 | ;; | 589 | ]) |
| 586 | esac | 590 | ]) |
| 587 | fi | ||
| 588 | else | ||
| 589 | dnl "$gl_use_threads" is "no". | ||
| 590 | AC_DEFINE([AVOID_ANY_THREADS], [1], | ||
| 591 | [Define if no multithread safety and no multithreading is desired.]) | ||
| 592 | fi | ||
| 593 | AC_MSG_CHECKING([for multithread API to use]) | 591 | AC_MSG_CHECKING([for multithread API to use]) |
| 594 | AC_MSG_RESULT([$gl_threads_api]) | 592 | AC_MSG_RESULT([$gl_threads_api]) |
| 595 | AC_SUBST([LIBTHREAD]) | 593 | AC_SUBST([LIBTHREAD]) |
| @@ -609,7 +607,7 @@ dnl gl_DISABLE_THREADS | |||
| 609 | dnl ------------------ | 607 | dnl ------------------ |
| 610 | dnl Sets the gl_THREADLIB default so that threads are not used by default. | 608 | dnl Sets the gl_THREADLIB default so that threads are not used by default. |
| 611 | dnl The user can still override it at installation time, by using the | 609 | dnl The user can still override it at installation time, by using the |
| 612 | dnl configure option '--enable-threads'. | 610 | dnl configure option "--enable-threads". |
| 613 | 611 | ||
| 614 | AC_DEFUN([gl_DISABLE_THREADS], [ | 612 | AC_DEFUN([gl_DISABLE_THREADS], [ |
| 615 | m4_divert_text([INIT_PREPARE], [gl_use_threads_default=no]) | 613 | m4_divert_text([INIT_PREPARE], [gl_use_threads_default=no]) |
| @@ -621,7 +619,7 @@ dnl ------------------- | |||
| 621 | dnl Sets the gl_THREADLIB default so that on mingw, a dependency to the | 619 | dnl Sets the gl_THREADLIB default so that on mingw, a dependency to the |
| 622 | dnl libwinpthread DLL (mingw-w64 winpthreads library) is avoided. | 620 | dnl libwinpthread DLL (mingw-w64 winpthreads library) is avoided. |
| 623 | dnl The user can still override it at installation time, by using the | 621 | dnl The user can still override it at installation time, by using the |
| 624 | dnl configure option '--enable-threads=posix'. | 622 | dnl configure option "--enable-threads=posix". |
| 625 | dnl As of 2023, this is now the default. | 623 | dnl As of 2023, this is now the default. |
| 626 | 624 | ||
| 627 | AC_DEFUN([gl_AVOID_WINPTHREAD], [ | 625 | AC_DEFUN([gl_AVOID_WINPTHREAD], [ |
diff --git a/gl/m4/time_h.m4 b/gl/m4/time_h.m4 index d2f3c970..f4d8e20f 100644 --- a/gl/m4/time_h.m4 +++ b/gl/m4/time_h.m4 | |||
| @@ -1,9 +1,11 @@ | |||
| 1 | # time_h.m4 | 1 | # time_h.m4 |
| 2 | # serial 25 | 2 | # serial 27 |
| 3 | dnl Copyright (C) 2000-2001, 2003-2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2000-2001, 2003-2007, 2009-2025 Free Software Foundation, |
| 4 | dnl Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 9 | ||
| 8 | # Configure a more-standard replacement for <time.h>. | 10 | # Configure a more-standard replacement for <time.h>. |
| 9 | 11 | ||
| @@ -145,6 +147,7 @@ AC_DEFUN([gl_TIME_H_REQUIRE_DEFAULTS], | |||
| 145 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GETRES]) | 147 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GETRES]) |
| 146 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_R]) | 148 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_R]) |
| 147 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_RZ]) | 149 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_RZ]) |
| 150 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TZNAME]) | ||
| 148 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TZSET]) | 151 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TZSET]) |
| 149 | dnl Support Microsoft deprecated alias function names by default. | 152 | dnl Support Microsoft deprecated alias function names by default. |
| 150 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_TZSET], [1]) | 153 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_TZSET], [1]) |
| @@ -162,13 +165,16 @@ AC_DEFUN([gl_TIME_H_DEFAULTS], | |||
| 162 | HAVE_TIMEGM=1; AC_SUBST([HAVE_TIMEGM]) | 165 | HAVE_TIMEGM=1; AC_SUBST([HAVE_TIMEGM]) |
| 163 | HAVE_TIMESPEC_GET=1; AC_SUBST([HAVE_TIMESPEC_GET]) | 166 | HAVE_TIMESPEC_GET=1; AC_SUBST([HAVE_TIMESPEC_GET]) |
| 164 | HAVE_TIMESPEC_GETRES=1; AC_SUBST([HAVE_TIMESPEC_GETRES]) | 167 | HAVE_TIMESPEC_GETRES=1; AC_SUBST([HAVE_TIMESPEC_GETRES]) |
| 165 | dnl Even GNU libc does not have timezone_t yet. | 168 | dnl Even GNU libc does not have timezone_t and tzalloc() yet. |
| 166 | HAVE_TIMEZONE_T=0; AC_SUBST([HAVE_TIMEZONE_T]) | 169 | HAVE_TIMEZONE_T=0; AC_SUBST([HAVE_TIMEZONE_T]) |
| 170 | HAVE_TZALLOC=0; AC_SUBST([HAVE_TZALLOC]) | ||
| 167 | REPLACE_CTIME=0; AC_SUBST([REPLACE_CTIME]) | 171 | REPLACE_CTIME=0; AC_SUBST([REPLACE_CTIME]) |
| 168 | REPLACE_GMTIME=0; AC_SUBST([REPLACE_GMTIME]) | 172 | REPLACE_GMTIME=0; AC_SUBST([REPLACE_GMTIME]) |
| 169 | REPLACE_LOCALTIME=0; AC_SUBST([REPLACE_LOCALTIME]) | 173 | REPLACE_LOCALTIME=0; AC_SUBST([REPLACE_LOCALTIME]) |
| 170 | REPLACE_LOCALTIME_R=0; AC_SUBST([REPLACE_LOCALTIME_R]) | 174 | REPLACE_LOCALTIME_R=0; AC_SUBST([REPLACE_LOCALTIME_R]) |
| 175 | REPLACE_LOCALTIME_RZ=0; AC_SUBST([REPLACE_LOCALTIME_RZ]) | ||
| 171 | REPLACE_MKTIME=0; AC_SUBST([REPLACE_MKTIME]) | 176 | REPLACE_MKTIME=0; AC_SUBST([REPLACE_MKTIME]) |
| 177 | REPLACE_MKTIME_Z=0; AC_SUBST([REPLACE_MKTIME_Z]) | ||
| 172 | REPLACE_NANOSLEEP=0; AC_SUBST([REPLACE_NANOSLEEP]) | 178 | REPLACE_NANOSLEEP=0; AC_SUBST([REPLACE_NANOSLEEP]) |
| 173 | REPLACE_STRFTIME=0; AC_SUBST([REPLACE_STRFTIME]) | 179 | REPLACE_STRFTIME=0; AC_SUBST([REPLACE_STRFTIME]) |
| 174 | REPLACE_TIME=0; AC_SUBST([REPLACE_TIME]) | 180 | REPLACE_TIME=0; AC_SUBST([REPLACE_TIME]) |
diff --git a/gl/m4/time_r.m4 b/gl/m4/time_r.m4 index 3675390e..96f5c5b5 100644 --- a/gl/m4/time_r.m4 +++ b/gl/m4/time_r.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # time_r.m4 | 1 | # time_r.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright (C) 2003, 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003, 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Reentrant time functions: localtime_r, gmtime_r. | 9 | dnl Reentrant time functions: localtime_r, gmtime_r. |
| 9 | 10 | ||
diff --git a/gl/m4/timegm.m4 b/gl/m4/timegm.m4 index c1ff2677..cb6da6da 100644 --- a/gl/m4/timegm.m4 +++ b/gl/m4/timegm.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # timegm.m4 | 1 | # timegm.m4 |
| 2 | # serial 16 | 2 | # serial 16 |
| 3 | dnl Copyright (C) 2003, 2007, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003, 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_TIMEGM], | 9 | AC_DEFUN([gl_FUNC_TIMEGM], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/uchar_h.m4 b/gl/m4/uchar_h.m4 new file mode 100644 index 00000000..b2309385 --- /dev/null +++ b/gl/m4/uchar_h.m4 | |||
| @@ -0,0 +1,279 @@ | |||
| 1 | # uchar_h.m4 | ||
| 2 | # serial 32 | ||
| 3 | dnl Copyright (C) 2019-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | dnl From Bruno Haible. | ||
| 10 | dnl Prepare the overridden <uchar.h>. | ||
| 11 | |||
| 12 | AC_DEFUN_ONCE([gl_UCHAR_H], | ||
| 13 | [ | ||
| 14 | AC_REQUIRE([gl_UCHAR_H_DEFAULTS]) | ||
| 15 | |||
| 16 | gl_CHECK_NEXT_HEADERS([uchar.h]) | ||
| 17 | if test $ac_cv_header_uchar_h = yes; then | ||
| 18 | HAVE_UCHAR_H=1 | ||
| 19 | else | ||
| 20 | HAVE_UCHAR_H=0 | ||
| 21 | fi | ||
| 22 | AC_SUBST([HAVE_UCHAR_H]) | ||
| 23 | |||
| 24 | dnl On macOS 15, in C mode, <uchar.h> does not exist. But in C++ mode, | ||
| 25 | dnl it exists, and we need to #include_next it, otherwise we get an error | ||
| 26 | dnl "<cuchar> tried including <uchar.h> but didn't find libc++'s <uchar.h> | ||
| 27 | dnl header." | ||
| 28 | m4_ifdef([gl_ANSI_CXX], [AC_REQUIRE([gl_ANSI_CXX])]) | ||
| 29 | CXX_HAVE_UCHAR_H=0 | ||
| 30 | if test "$CXX" != no; then | ||
| 31 | AC_CACHE_CHECK([whether the C++ compiler has <uchar.h>], | ||
| 32 | [gl_cv_cxx_have_uchar_h], | ||
| 33 | [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to | ||
| 34 | dnl an autoconf bug <https://savannah.gnu.org/support/?110294>. | ||
| 35 | cat > conftest.cpp <<\EOF | ||
| 36 | #include <uchar.h> | ||
| 37 | EOF | ||
| 38 | gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp" | ||
| 39 | if AC_TRY_EVAL([gl_command]); then | ||
| 40 | gl_cv_cxx_have_uchar_h=yes | ||
| 41 | else | ||
| 42 | gl_cv_cxx_have_uchar_h=no | ||
| 43 | fi | ||
| 44 | rm -fr conftest* | ||
| 45 | ]) | ||
| 46 | if test $gl_cv_cxx_have_uchar_h = yes; then | ||
| 47 | CXX_HAVE_UCHAR_H=1 | ||
| 48 | fi | ||
| 49 | fi | ||
| 50 | AC_SUBST([CXX_HAVE_UCHAR_H]) | ||
| 51 | |||
| 52 | gl_TYPE_CHAR8_T | ||
| 53 | gl_TYPE_CHAR16_T | ||
| 54 | gl_TYPE_CHAR32_T | ||
| 55 | |||
| 56 | dnl In C++ mode, clang defines 'char16_t' and 'char32_t' as built-in types | ||
| 57 | dnl on some platforms (e.g. OpenBSD 6.7), and as types defined by many | ||
| 58 | dnl header files (<limits.h>, <stddef.h>, <stdint.h>, <stdio.h>, <stdlib.h> | ||
| 59 | dnl and others) on some platforms (e.g. Mac OS X 10.13). | ||
| 60 | dnl The same thing may also happen for 'char8_t'; so, be prepared for it. | ||
| 61 | m4_ifdef([gl_ANSI_CXX], [AC_REQUIRE([gl_ANSI_CXX])]) | ||
| 62 | CXX_HAS_UCHAR_TYPES=0 | ||
| 63 | if test $HAVE_UCHAR_H = 0; then | ||
| 64 | if test "$CXX" != no; then | ||
| 65 | AC_CACHE_CHECK([whether the C++ compiler predefines the <uchar.h> types], | ||
| 66 | [gl_cv_cxx_has_uchar_types], | ||
| 67 | [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to | ||
| 68 | dnl an autoconf bug <https://savannah.gnu.org/support/?110294>. | ||
| 69 | cat > conftest.cpp <<\EOF | ||
| 70 | #include <stddef.h> | ||
| 71 | char16_t a; | ||
| 72 | char32_t b; | ||
| 73 | EOF | ||
| 74 | gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp" | ||
| 75 | if AC_TRY_EVAL([gl_command]); then | ||
| 76 | gl_cv_cxx_has_uchar_types=yes | ||
| 77 | else | ||
| 78 | gl_cv_cxx_has_uchar_types=no | ||
| 79 | fi | ||
| 80 | rm -fr conftest* | ||
| 81 | ]) | ||
| 82 | if test $gl_cv_cxx_has_uchar_types = yes; then | ||
| 83 | CXX_HAS_UCHAR_TYPES=1 | ||
| 84 | fi | ||
| 85 | fi | ||
| 86 | fi | ||
| 87 | AC_SUBST([CXX_HAS_UCHAR_TYPES]) | ||
| 88 | CXX_HAS_CHAR8_TYPE=0 | ||
| 89 | if test $HAVE_UCHAR_H = 0; then | ||
| 90 | if test "$CXX" != no; then | ||
| 91 | AC_CACHE_CHECK([whether the C++ compiler predefines the char8_t type], | ||
| 92 | [gl_cv_cxx_has_char8_type], | ||
| 93 | [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to | ||
| 94 | dnl an autoconf bug <https://savannah.gnu.org/support/?110294>. | ||
| 95 | cat > conftest.cpp <<\EOF | ||
| 96 | #include <stddef.h> | ||
| 97 | char8_t a; | ||
| 98 | EOF | ||
| 99 | gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp" | ||
| 100 | if AC_TRY_EVAL([gl_command]); then | ||
| 101 | gl_cv_cxx_has_char8_type=yes | ||
| 102 | else | ||
| 103 | gl_cv_cxx_has_char8_type=no | ||
| 104 | fi | ||
| 105 | rm -fr conftest* | ||
| 106 | ]) | ||
| 107 | if test $gl_cv_cxx_has_char8_type = yes; then | ||
| 108 | CXX_HAS_CHAR8_TYPE=1 | ||
| 109 | fi | ||
| 110 | fi | ||
| 111 | fi | ||
| 112 | AC_SUBST([CXX_HAS_CHAR8_TYPE]) | ||
| 113 | |||
| 114 | dnl Test whether a 'char32_t' can hold more characters than a 'wchar_t'. | ||
| 115 | gl_STDINT_BITSIZEOF([wchar_t], [gl_STDINT_INCLUDES]) | ||
| 116 | if test $BITSIZEOF_WCHAR_T -lt 32; then | ||
| 117 | SMALL_WCHAR_T=1 | ||
| 118 | else | ||
| 119 | SMALL_WCHAR_T=0 | ||
| 120 | fi | ||
| 121 | dnl SMALL_WCHAR_T is expected to be 1 on 32-bit AIX, Cygwin, native Windows. | ||
| 122 | AC_SUBST([SMALL_WCHAR_T]) | ||
| 123 | |||
| 124 | dnl Check for declarations of anything we want to poison if the | ||
| 125 | dnl corresponding gnulib module is not in use, and which is not | ||
| 126 | dnl guaranteed by C11. | ||
| 127 | gl_WARN_ON_USE_PREPARE([[ | ||
| 128 | #ifdef __HAIKU__ | ||
| 129 | #include <stdint.h> | ||
| 130 | #endif | ||
| 131 | #include <uchar.h> | ||
| 132 | ]], [c32rtomb mbrtoc16 mbrtoc32]) | ||
| 133 | ]) | ||
| 134 | |||
| 135 | AC_DEFUN_ONCE([gl_TYPE_CHAR8_T], | ||
| 136 | [ | ||
| 137 | dnl Determine whether gnulib's <uchar.h> would, if present, override char8_t. | ||
| 138 | AC_CACHE_CHECK([whether char8_t is correctly defined], | ||
| 139 | [gl_cv_type_char8_t_works], | ||
| 140 | [AC_COMPILE_IFELSE( | ||
| 141 | [AC_LANG_PROGRAM([[ | ||
| 142 | #ifdef __HAIKU__ | ||
| 143 | #include <stdint.h> | ||
| 144 | #endif | ||
| 145 | #include <uchar.h> | ||
| 146 | int verify[(char8_t)(-1) >= 0 && sizeof (char8_t) == sizeof (unsigned char) ? 1 : -1]; | ||
| 147 | ]]) | ||
| 148 | ], | ||
| 149 | [gl_cv_type_char8_t_works=yes], | ||
| 150 | [gl_cv_type_char8_t_works=no]) | ||
| 151 | ]) | ||
| 152 | if test $gl_cv_type_char8_t_works = no; then | ||
| 153 | GNULIBHEADERS_OVERRIDE_CHAR8_T=1 | ||
| 154 | else | ||
| 155 | GNULIBHEADERS_OVERRIDE_CHAR8_T=0 | ||
| 156 | fi | ||
| 157 | AC_SUBST([GNULIBHEADERS_OVERRIDE_CHAR8_T]) | ||
| 158 | ]) | ||
| 159 | |||
| 160 | dnl On Haiku 2020, char16_t and char32_t are incorrectly defined. | ||
| 161 | dnl See <https://dev.haiku-os.org/ticket/15990>. | ||
| 162 | AC_DEFUN_ONCE([gl_TYPE_CHAR16_T], | ||
| 163 | [ | ||
| 164 | dnl Determine whether gnulib's <uchar.h> would, if present, override char16_t. | ||
| 165 | AC_CACHE_CHECK([whether char16_t is correctly defined], | ||
| 166 | [gl_cv_type_char16_t_works], | ||
| 167 | [AC_COMPILE_IFELSE( | ||
| 168 | [AC_LANG_PROGRAM([[ | ||
| 169 | #ifdef __HAIKU__ | ||
| 170 | #include <stdint.h> | ||
| 171 | #endif | ||
| 172 | #include <uchar.h> | ||
| 173 | /* For simplicity, assume that uint16_least_t is equivalent to | ||
| 174 | 'unsigned short'. */ | ||
| 175 | int verify[(char16_t)(-1) >= 0 && sizeof (char16_t) == sizeof (unsigned short) ? 1 : -1]; | ||
| 176 | ]]) | ||
| 177 | ], | ||
| 178 | [gl_cv_type_char16_t_works=yes], | ||
| 179 | [gl_cv_type_char16_t_works=no]) | ||
| 180 | ]) | ||
| 181 | if test $gl_cv_type_char16_t_works = no; then | ||
| 182 | GNULIBHEADERS_OVERRIDE_CHAR16_T=1 | ||
| 183 | else | ||
| 184 | GNULIBHEADERS_OVERRIDE_CHAR16_T=0 | ||
| 185 | fi | ||
| 186 | AC_SUBST([GNULIBHEADERS_OVERRIDE_CHAR16_T]) | ||
| 187 | ]) | ||
| 188 | AC_DEFUN_ONCE([gl_TYPE_CHAR32_T], | ||
| 189 | [ | ||
| 190 | dnl Determine whether gnulib's <uchar.h> would, if present, override char32_t. | ||
| 191 | AC_CACHE_CHECK([whether char32_t is correctly defined], | ||
| 192 | [gl_cv_type_char32_t_works], | ||
| 193 | [AC_COMPILE_IFELSE( | ||
| 194 | [AC_LANG_PROGRAM([[ | ||
| 195 | #ifdef __HAIKU__ | ||
| 196 | #include <stdint.h> | ||
| 197 | #endif | ||
| 198 | #include <uchar.h> | ||
| 199 | /* For simplicity, assume that uint32_least_t is equivalent to | ||
| 200 | 'unsigned int'. */ | ||
| 201 | int verify[(char32_t)(-1) >= 0 && sizeof (char32_t) == sizeof (unsigned int) ? 1 : -1]; | ||
| 202 | ]]) | ||
| 203 | ], | ||
| 204 | [gl_cv_type_char32_t_works=yes], | ||
| 205 | [gl_cv_type_char32_t_works=no]) | ||
| 206 | ]) | ||
| 207 | if test $gl_cv_type_char32_t_works = no; then | ||
| 208 | GNULIBHEADERS_OVERRIDE_CHAR32_T=1 | ||
| 209 | else | ||
| 210 | GNULIBHEADERS_OVERRIDE_CHAR32_T=0 | ||
| 211 | fi | ||
| 212 | AC_SUBST([GNULIBHEADERS_OVERRIDE_CHAR32_T]) | ||
| 213 | ]) | ||
| 214 | |||
| 215 | # gl_UCHAR_MODULE_INDICATOR([modulename]) | ||
| 216 | # sets the shell variable that indicates the presence of the given module | ||
| 217 | # to a C preprocessor expression that will evaluate to 1. | ||
| 218 | # This macro invocation must not occur in macros that are AC_REQUIREd. | ||
| 219 | AC_DEFUN([gl_UCHAR_MODULE_INDICATOR], | ||
| 220 | [ | ||
| 221 | dnl Ensure to expand the default settings once only. | ||
| 222 | gl_UCHAR_H_REQUIRE_DEFAULTS | ||
| 223 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) | ||
| 224 | dnl Define it also as a C macro, for the benefit of the unit tests. | ||
| 225 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) | ||
| 226 | ]) | ||
| 227 | |||
| 228 | # Initializes the default values for AC_SUBSTed shell variables. | ||
| 229 | # This macro must not be AC_REQUIREd. It must only be invoked, and only | ||
| 230 | # outside of macros or in macros that are not AC_REQUIREd. | ||
| 231 | AC_DEFUN([gl_UCHAR_H_REQUIRE_DEFAULTS], | ||
| 232 | [ | ||
| 233 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_UCHAR_H_MODULE_INDICATOR_DEFAULTS], [ | ||
| 234 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_BTOC32]) | ||
| 235 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISALNUM]) | ||
| 236 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISALPHA]) | ||
| 237 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISBLANK]) | ||
| 238 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISCNTRL]) | ||
| 239 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISDIGIT]) | ||
| 240 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISGRAPH]) | ||
| 241 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISLOWER]) | ||
| 242 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISPRINT]) | ||
| 243 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISPUNCT]) | ||
| 244 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISSPACE]) | ||
| 245 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISUPPER]) | ||
| 246 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32ISXDIGIT]) | ||
| 247 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32TOLOWER]) | ||
| 248 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32TOUPPER]) | ||
| 249 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32WIDTH]) | ||
| 250 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32RTOMB]) | ||
| 251 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32SNRTOMBS]) | ||
| 252 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32SRTOMBS]) | ||
| 253 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32STOMBS]) | ||
| 254 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32SWIDTH]) | ||
| 255 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32TOB]) | ||
| 256 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32_APPLY_MAPPING]) | ||
| 257 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32_APPLY_TYPE_TEST]) | ||
| 258 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32_GET_MAPPING]) | ||
| 259 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_C32_GET_TYPE_TEST]) | ||
| 260 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBRTOC16]) | ||
| 261 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBRTOC32]) | ||
| 262 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNRTOC32S]) | ||
| 263 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSRTOC32S]) | ||
| 264 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSTOC32S]) | ||
| 265 | ]) | ||
| 266 | m4_require(GL_MODULE_INDICATOR_PREFIX[_UCHAR_H_MODULE_INDICATOR_DEFAULTS]) | ||
| 267 | AC_REQUIRE([gl_UCHAR_H_DEFAULTS]) | ||
| 268 | ]) | ||
| 269 | |||
| 270 | AC_DEFUN([gl_UCHAR_H_DEFAULTS], | ||
| 271 | [ | ||
| 272 | dnl Assume proper GNU behavior unless another module says otherwise. | ||
| 273 | HAVE_C32RTOMB=1; AC_SUBST([HAVE_C32RTOMB]) | ||
| 274 | HAVE_MBRTOC16=1; AC_SUBST([HAVE_MBRTOC16]) | ||
| 275 | HAVE_MBRTOC32=1; AC_SUBST([HAVE_MBRTOC32]) | ||
| 276 | REPLACE_C32RTOMB=0; AC_SUBST([REPLACE_C32RTOMB]) | ||
| 277 | REPLACE_MBRTOC16=0; AC_SUBST([REPLACE_MBRTOC16]) | ||
| 278 | REPLACE_MBRTOC32=0; AC_SUBST([REPLACE_MBRTOC32]) | ||
| 279 | ]) | ||
diff --git a/gl/m4/ungetc.m4 b/gl/m4/ungetc.m4 index 42f7ec32..969b60e8 100644 --- a/gl/m4/ungetc.m4 +++ b/gl/m4/ungetc.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # ungetc.m4 | 1 | # ungetc.m4 |
| 2 | # serial 12 | 2 | # serial 12 |
| 3 | dnl Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_FUNC_UNGETC_WORKS], | 9 | AC_DEFUN_ONCE([gl_FUNC_UNGETC_WORKS], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/unicase_h.m4 b/gl/m4/unicase_h.m4 new file mode 100644 index 00000000..bf5d4c2e --- /dev/null +++ b/gl/m4/unicase_h.m4 | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | # unicase_h.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright (C) 2023-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN_ONCE([gl_UNICASE_H], | ||
| 10 | [ | ||
| 11 | dnl Ensure to expand the default settings once only, before all statements | ||
| 12 | dnl that occur in other macros. | ||
| 13 | AC_REQUIRE([gl_UNICASE_H_DEFAULTS]) | ||
| 14 | ]) | ||
| 15 | |||
| 16 | # gl_UNICASE_MODULE_INDICATOR([modulename]) | ||
| 17 | # sets the shell variable that indicates the presence of the given module | ||
| 18 | # to a C preprocessor expression that will evaluate to 1. | ||
| 19 | # This macro invocation must not occur in macros that are AC_REQUIREd. | ||
| 20 | AC_DEFUN([gl_UNICASE_MODULE_INDICATOR], | ||
| 21 | [ | ||
| 22 | dnl Ensure to expand the default settings once only. | ||
| 23 | gl_UNICASE_H_REQUIRE_DEFAULTS | ||
| 24 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) | ||
| 25 | dnl Define it also as a C macro, for the benefit of the unit tests. | ||
| 26 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) | ||
| 27 | ]) | ||
| 28 | |||
| 29 | # Initializes the default values for AC_SUBSTed shell variables. | ||
| 30 | # This macro must not be AC_REQUIREd. It must only be invoked, and only | ||
| 31 | # outside of macros or in macros that are not AC_REQUIREd. | ||
| 32 | AC_DEFUN([gl_UNICASE_H_REQUIRE_DEFAULTS], | ||
| 33 | [ | ||
| 34 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_UNICASE_H_MODULE_INDICATOR_DEFAULTS], [ | ||
| 35 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICASE_EMPTY_PREFIX_CONTEXT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 36 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICASE_EMPTY_SUFFIX_CONTEXT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 37 | ]) | ||
| 38 | m4_require(GL_MODULE_INDICATOR_PREFIX[_UNICASE_H_MODULE_INDICATOR_DEFAULTS]) | ||
| 39 | AC_REQUIRE([gl_UNICASE_H_DEFAULTS]) | ||
| 40 | ]) | ||
| 41 | |||
| 42 | AC_DEFUN([gl_UNICASE_H_DEFAULTS], | ||
| 43 | [ | ||
| 44 | dnl Assume proper GNU behavior unless another module says otherwise. | ||
| 45 | ]) | ||
diff --git a/gl/m4/unictype_h.m4 b/gl/m4/unictype_h.m4 new file mode 100644 index 00000000..68ddaf6c --- /dev/null +++ b/gl/m4/unictype_h.m4 | |||
| @@ -0,0 +1,179 @@ | |||
| 1 | # unictype_h.m4 | ||
| 2 | # serial 4 | ||
| 3 | dnl Copyright (C) 2023-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN_ONCE([gl_UNICTYPE_H], | ||
| 10 | [ | ||
| 11 | dnl Ensure to expand the default settings once only, before all statements | ||
| 12 | dnl that occur in other macros. | ||
| 13 | AC_REQUIRE([gl_UNICTYPE_H_DEFAULTS]) | ||
| 14 | ]) | ||
| 15 | |||
| 16 | # gl_UNICTYPE_MODULE_INDICATOR([modulename]) | ||
| 17 | # sets the shell variable that indicates the presence of the given module | ||
| 18 | # to a C preprocessor expression that will evaluate to 1. | ||
| 19 | # This macro invocation must not occur in macros that are AC_REQUIREd. | ||
| 20 | AC_DEFUN([gl_UNICTYPE_MODULE_INDICATOR], | ||
| 21 | [ | ||
| 22 | dnl Ensure to expand the default settings once only. | ||
| 23 | gl_UNICTYPE_H_REQUIRE_DEFAULTS | ||
| 24 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) | ||
| 25 | dnl Define it also as a C macro, for the benefit of the unit tests. | ||
| 26 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) | ||
| 27 | ]) | ||
| 28 | |||
| 29 | # Initializes the default values for AC_SUBSTed shell variables. | ||
| 30 | # This macro must not be AC_REQUIREd. It must only be invoked, and only | ||
| 31 | # outside of macros or in macros that are not AC_REQUIREd. | ||
| 32 | AC_DEFUN([gl_UNICTYPE_H_REQUIRE_DEFAULTS], | ||
| 33 | [ | ||
| 34 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_UNICTYPE_H_MODULE_INDICATOR_DEFAULTS], [ | ||
| 35 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_L_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 36 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_LC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 37 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_LU_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 38 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_LL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 39 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_LT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 40 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_LM_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 41 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_LO_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 42 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_M_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 43 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_MN_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 44 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_MC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 45 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_ME_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 46 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_N_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 47 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_ND_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 48 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_NL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 49 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_NO_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 50 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_P_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 51 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_PC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 52 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_PD_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 53 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_PS_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 54 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_PE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 55 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_PI_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 56 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_PF_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 57 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_PO_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 58 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_S_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 59 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_SM_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 60 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_SC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 61 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_SK_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 62 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_SO_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 63 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_Z_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 64 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_ZS_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 65 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_ZL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 66 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_ZP_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 67 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_C_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 68 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_CC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 69 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_CF_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 70 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_CS_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 71 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_CO_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 72 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_CATEGORY_CN_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 73 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_WHITE_SPACE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 74 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_ALPHABETIC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 75 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_OTHER_ALPHABETIC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 76 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_NOT_A_CHARACTER_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 77 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 78 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_OTHER_DEFAULT_IGNORABLE_CODE_POINT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 79 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_DEPRECATED_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 80 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_LOGICAL_ORDER_EXCEPTION_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 81 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_VARIATION_SELECTOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 82 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_PRIVATE_USE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 83 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_UNASSIGNED_CODE_VALUE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 84 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_UPPERCASE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 85 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_OTHER_UPPERCASE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 86 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_LOWERCASE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 87 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_OTHER_LOWERCASE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 88 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_TITLECASE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 89 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_CASED_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 90 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_CASE_IGNORABLE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 91 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_LOWERCASED_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 92 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_UPPERCASED_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 93 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_TITLECASED_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 94 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_CASEFOLDED_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 95 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_CASEMAPPED_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 96 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_SOFT_DOTTED_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 97 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_ID_START_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 98 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_OTHER_ID_START_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 99 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_ID_CONTINUE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 100 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_OTHER_ID_CONTINUE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 101 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_XID_START_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 102 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_XID_CONTINUE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 103 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_ID_COMPAT_MATH_START_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 104 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_ID_COMPAT_MATH_CONTINUE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 105 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_PATTERN_WHITE_SPACE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 106 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_PATTERN_SYNTAX_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 107 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_JOIN_CONTROL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 108 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_GRAPHEME_BASE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 109 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_GRAPHEME_EXTEND_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 110 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_OTHER_GRAPHEME_EXTEND_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 111 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_GRAPHEME_LINK_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 112 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_MODIFIER_COMBINING_MARK_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 113 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_CONTROL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 114 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_LEFT_TO_RIGHT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 115 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_HEBREW_RIGHT_TO_LEFT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 116 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_ARABIC_RIGHT_TO_LEFT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 117 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_EUROPEAN_DIGIT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 118 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_EUR_NUM_SEPARATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 119 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_EUR_NUM_TERMINATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 120 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_ARABIC_DIGIT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 121 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_COMMON_SEPARATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 122 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_BLOCK_SEPARATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 123 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_SEGMENT_SEPARATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 124 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_WHITESPACE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 125 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_NON_SPACING_MARK_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 126 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_BOUNDARY_NEUTRAL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 127 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_PDF_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 128 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_EMBEDDING_OR_OVERRIDE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 129 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_BIDI_OTHER_NEUTRAL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 130 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_HEX_DIGIT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 131 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_ASCII_HEX_DIGIT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 132 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_IDEOGRAPHIC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 133 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_UNIFIED_IDEOGRAPH_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 134 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_RADICAL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 135 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_IDS_UNARY_OPERATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 136 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_IDS_BINARY_OPERATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 137 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_IDS_TRINARY_OPERATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 138 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_EMOJI_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 139 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_EMOJI_PRESENTATION_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 140 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_EMOJI_MODIFIER_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 141 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_EMOJI_MODIFIER_BASE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 142 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_EMOJI_COMPONENT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 143 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_EXTENDED_PICTOGRAPHIC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 144 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_ZERO_WIDTH_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 145 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_SPACE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 146 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_NON_BREAK_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 147 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_ISO_CONTROL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 148 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_FORMAT_CONTROL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 149 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_PREPENDED_CONCATENATION_MARK_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 150 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_DASH_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 151 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_HYPHEN_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 152 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_PUNCTUATION_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 153 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_LINE_SEPARATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 154 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_PARAGRAPH_SEPARATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 155 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_QUOTATION_MARK_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 156 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_SENTENCE_TERMINAL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 157 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_TERMINAL_PUNCTUATION_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 158 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_CURRENCY_SYMBOL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 159 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_MATH_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 160 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_OTHER_MATH_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 161 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_PAIRED_PUNCTUATION_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 162 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_LEFT_OF_PAIR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 163 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_COMBINING_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 164 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_COMPOSITE_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 165 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_DECIMAL_DIGIT_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 166 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_NUMERIC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 167 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_DIACRITIC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 168 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_EXTENDER_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 169 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_IGNORABLE_CONTROL_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 170 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNICTYPE_PROPERTY_REGIONAL_INDICATOR_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 171 | ]) | ||
| 172 | m4_require(GL_MODULE_INDICATOR_PREFIX[_UNICTYPE_H_MODULE_INDICATOR_DEFAULTS]) | ||
| 173 | AC_REQUIRE([gl_UNICTYPE_H_DEFAULTS]) | ||
| 174 | ]) | ||
| 175 | |||
| 176 | AC_DEFUN([gl_UNICTYPE_H_DEFAULTS], | ||
| 177 | [ | ||
| 178 | dnl Assume proper GNU behavior unless another module says otherwise. | ||
| 179 | ]) | ||
diff --git a/gl/m4/uninorm_h.m4 b/gl/m4/uninorm_h.m4 new file mode 100644 index 00000000..d416f73b --- /dev/null +++ b/gl/m4/uninorm_h.m4 | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | # uninorm_h.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright (C) 2023-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN_ONCE([gl_UNINORM_H], | ||
| 10 | [ | ||
| 11 | dnl Ensure to expand the default settings once only, before all statements | ||
| 12 | dnl that occur in other macros. | ||
| 13 | AC_REQUIRE([gl_UNINORM_H_DEFAULTS]) | ||
| 14 | ]) | ||
| 15 | |||
| 16 | # gl_UNINORM_MODULE_INDICATOR([modulename]) | ||
| 17 | # sets the shell variable that indicates the presence of the given module | ||
| 18 | # to a C preprocessor expression that will evaluate to 1. | ||
| 19 | # This macro invocation must not occur in macros that are AC_REQUIREd. | ||
| 20 | AC_DEFUN([gl_UNINORM_MODULE_INDICATOR], | ||
| 21 | [ | ||
| 22 | dnl Ensure to expand the default settings once only. | ||
| 23 | gl_UNINORM_H_REQUIRE_DEFAULTS | ||
| 24 | gl_MODULE_INDICATOR_SET_VARIABLE([$1]) | ||
| 25 | dnl Define it also as a C macro, for the benefit of the unit tests. | ||
| 26 | gl_MODULE_INDICATOR_FOR_TESTS([$1]) | ||
| 27 | ]) | ||
| 28 | |||
| 29 | # Initializes the default values for AC_SUBSTed shell variables. | ||
| 30 | # This macro must not be AC_REQUIREd. It must only be invoked, and only | ||
| 31 | # outside of macros or in macros that are not AC_REQUIREd. | ||
| 32 | AC_DEFUN([gl_UNINORM_H_REQUIRE_DEFAULTS], | ||
| 33 | [ | ||
| 34 | m4_defun(GL_MODULE_INDICATOR_PREFIX[_UNINORM_H_MODULE_INDICATOR_DEFAULTS], [ | ||
| 35 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNINORM_NFD_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 36 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNINORM_NFC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 37 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNINORM_NFKD_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 38 | gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_UNINORM_NFKC_DLL_VARIABLE], ['LIBUNISTRING_DLL_VARIABLE']) | ||
| 39 | ]) | ||
| 40 | m4_require(GL_MODULE_INDICATOR_PREFIX[_UNINORM_H_MODULE_INDICATOR_DEFAULTS]) | ||
| 41 | AC_REQUIRE([gl_UNINORM_H_DEFAULTS]) | ||
| 42 | ]) | ||
| 43 | |||
| 44 | AC_DEFUN([gl_UNINORM_H_DEFAULTS], | ||
| 45 | [ | ||
| 46 | dnl Assume proper GNU behavior unless another module says otherwise. | ||
| 47 | ]) | ||
diff --git a/gl/m4/unistd_h.m4 b/gl/m4/unistd_h.m4 index 81d1b9f6..6ec16286 100644 --- a/gl/m4/unistd_h.m4 +++ b/gl/m4/unistd_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # unistd_h.m4 | 1 | # unistd_h.m4 |
| 2 | # serial 95 | 2 | # serial 97 |
| 3 | dnl Copyright (C) 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Written by Simon Josefsson, Bruno Haible. | 9 | dnl Written by Simon Josefsson, Bruno Haible. |
| 9 | 10 | ||
| @@ -243,11 +244,13 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], | |||
| 243 | REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME]) | 244 | REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME]) |
| 244 | REPLACE_GETDTABLESIZE=0; AC_SUBST([REPLACE_GETDTABLESIZE]) | 245 | REPLACE_GETDTABLESIZE=0; AC_SUBST([REPLACE_GETDTABLESIZE]) |
| 245 | REPLACE_GETENTROPY=0; AC_SUBST([REPLACE_GETENTROPY]) | 246 | REPLACE_GETENTROPY=0; AC_SUBST([REPLACE_GETENTROPY]) |
| 247 | REPLACE_GETLOGIN=0; AC_SUBST([REPLACE_GETLOGIN]) | ||
| 246 | REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R]) | 248 | REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R]) |
| 247 | REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS]) | 249 | REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS]) |
| 248 | REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) | 250 | REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) |
| 249 | REPLACE_GETPASS=0; AC_SUBST([REPLACE_GETPASS]) | 251 | REPLACE_GETPASS=0; AC_SUBST([REPLACE_GETPASS]) |
| 250 | REPLACE_GETPASS_FOR_GETPASS_GNU=0; AC_SUBST([REPLACE_GETPASS_FOR_GETPASS_GNU]) | 252 | REPLACE_GETPASS_FOR_GETPASS_GNU=0; AC_SUBST([REPLACE_GETPASS_FOR_GETPASS_GNU]) |
| 253 | REPLACE_GETUSERSHELL=0; AC_SUBST([REPLACE_GETUSERSHELL]) | ||
| 251 | REPLACE_ISATTY=0; AC_SUBST([REPLACE_ISATTY]) | 254 | REPLACE_ISATTY=0; AC_SUBST([REPLACE_ISATTY]) |
| 252 | REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) | 255 | REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) |
| 253 | REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) | 256 | REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) |
diff --git a/gl/m4/unitypes_h.m4 b/gl/m4/unitypes_h.m4 new file mode 100644 index 00000000..264e61be --- /dev/null +++ b/gl/m4/unitypes_h.m4 | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | # unitypes_h.m4 | ||
| 2 | # serial 1 | ||
| 3 | dnl Copyright (C) 2021-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN_ONCE([gl_UNITYPES_H], | ||
| 10 | [ | ||
| 11 | AH_VERBATIM([unitypes_restrict], [ | ||
| 12 | /* This definition is a duplicate of the one in unitypes.h. | ||
| 13 | It is here so that we can cope with an older version of unitypes.h | ||
| 14 | that does not contain this definition and that is pre-installed among | ||
| 15 | the public header files. */ | ||
| 16 | # if defined __restrict \ | ||
| 17 | || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \ | ||
| 18 | || __clang_major__ >= 3 | ||
| 19 | # define _UC_RESTRICT __restrict | ||
| 20 | # elif 199901L <= __STDC_VERSION__ || defined restrict | ||
| 21 | # define _UC_RESTRICT restrict | ||
| 22 | # else | ||
| 23 | # define _UC_RESTRICT | ||
| 24 | # endif | ||
| 25 | ]) | ||
| 26 | ]) | ||
diff --git a/gl/m4/unlocked-io.m4 b/gl/m4/unlocked-io.m4 index e96cf5f8..97f43f4b 100644 --- a/gl/m4/unlocked-io.m4 +++ b/gl/m4/unlocked-io.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # unlocked-io.m4 | 1 | # unlocked-io.m4 |
| 2 | # serial 16 | 2 | # serial 16 |
| 3 | dnl Copyright (C) 1998-2006, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 1998-2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Jim Meyering. | 9 | dnl From Jim Meyering. |
| 9 | dnl | 10 | dnl |
diff --git a/gl/m4/vararrays.m4 b/gl/m4/vararrays.m4 index 9211f69d..086e409f 100644 --- a/gl/m4/vararrays.m4 +++ b/gl/m4/vararrays.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # vararrays.m4 | 1 | # vararrays.m4 |
| 2 | # serial 6 | 2 | # serial 6 |
| 3 | dnl Copyright (C) 2001, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2001, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # Check for variable-length arrays. | 9 | # Check for variable-length arrays. |
| 9 | 10 | ||
diff --git a/gl/m4/vasnprintf.m4 b/gl/m4/vasnprintf.m4 index 1ea2055e..1d040d6e 100644 --- a/gl/m4/vasnprintf.m4 +++ b/gl/m4/vasnprintf.m4 | |||
| @@ -1,14 +1,47 @@ | |||
| 1 | # vasnprintf.m4 | 1 | # vasnprintf.m4 |
| 2 | # serial 52 | 2 | # serial 56 |
| 3 | dnl Copyright (C) 2002-2004, 2006-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2004, 2006-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_VASNPRINTF], | 9 | AC_DEFUN([gl_FUNC_VASNPRINTF], |
| 9 | [ | 10 | [ |
| 11 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 10 | AC_CHECK_FUNCS_ONCE([vasnprintf]) | 12 | AC_CHECK_FUNCS_ONCE([vasnprintf]) |
| 11 | if test $ac_cv_func_vasnprintf = no; then | 13 | if test $ac_cv_func_vasnprintf = yes; then |
| 14 | dnl On Cygwin, in directives with a huge width, the width is ignored, and | ||
| 15 | dnl the function returns a wrong result. | ||
| 16 | AC_CACHE_CHECK([whether vasnprintf works], | ||
| 17 | [gl_cv_func_vasnprintf_works], | ||
| 18 | [AC_RUN_IFELSE( | ||
| 19 | [AC_LANG_SOURCE( | ||
| 20 | [[#include <stdio.h> | ||
| 21 | ]], | ||
| 22 | [[size_t len; | ||
| 23 | char *res = vasnprintf (NULL, &len, "x%03000000000dy\n", -17); | ||
| 24 | /* On Cygwin 3.4.6, res is "x-17y\n" and len == 6: wrong. */ | ||
| 25 | return (res != NULL && len < 10); | ||
| 26 | ]]) | ||
| 27 | ], | ||
| 28 | [gl_cv_func_vasnprintf_works=yes], | ||
| 29 | [gl_cv_func_vasnprintf_works=no], | ||
| 30 | [case "$host_os" in | ||
| 31 | # Guess no on Cygwin. | ||
| 32 | cygwin*) gl_cv_func_vasnprintf_works="guessing no";; | ||
| 33 | # If we don't know, obey --enable-cross-guesses. | ||
| 34 | *) gl_cv_func_vasnprintf_works="$gl_cross_guess_normal";; | ||
| 35 | esac | ||
| 36 | ]) | ||
| 37 | ]) | ||
| 38 | fi | ||
| 39 | if test $ac_cv_func_vasnprintf != yes \ | ||
| 40 | || case "$gl_cv_func_vasnprintf_works" in | ||
| 41 | *yes) false;; | ||
| 42 | *) true;; | ||
| 43 | esac | ||
| 44 | then | ||
| 12 | gl_REPLACE_VASNPRINTF | 45 | gl_REPLACE_VASNPRINTF |
| 13 | fi | 46 | fi |
| 14 | ]) | 47 | ]) |
| @@ -42,7 +75,6 @@ AC_DEFUN([gl_FUNC_VASNWPRINTF], | |||
| 42 | # Prerequisites of lib/printf-args.h, lib/printf-args.c. | 75 | # Prerequisites of lib/printf-args.h, lib/printf-args.c. |
| 43 | AC_DEFUN([gl_PREREQ_PRINTF_ARGS], | 76 | AC_DEFUN([gl_PREREQ_PRINTF_ARGS], |
| 44 | [ | 77 | [ |
| 45 | AC_REQUIRE([gt_TYPE_WCHAR_T]) | ||
| 46 | AC_REQUIRE([gt_TYPE_WINT_T]) | 78 | AC_REQUIRE([gt_TYPE_WINT_T]) |
| 47 | ]) | 79 | ]) |
| 48 | 80 | ||
| @@ -51,7 +83,6 @@ AC_DEFUN([gl_PREREQ_PRINTF_ARGS], | |||
| 51 | AC_DEFUN([gl_PREREQ_PRINTF_PARSE], | 83 | AC_DEFUN([gl_PREREQ_PRINTF_PARSE], |
| 52 | [ | 84 | [ |
| 53 | AC_REQUIRE([gl_FEATURES_H]) | 85 | AC_REQUIRE([gl_FEATURES_H]) |
| 54 | AC_REQUIRE([gt_TYPE_WCHAR_T]) | ||
| 55 | AC_REQUIRE([gt_TYPE_WINT_T]) | 86 | AC_REQUIRE([gt_TYPE_WINT_T]) |
| 56 | AC_REQUIRE([AC_TYPE_SIZE_T]) | 87 | AC_REQUIRE([AC_TYPE_SIZE_T]) |
| 57 | AC_CHECK_TYPE([ptrdiff_t], , | 88 | AC_CHECK_TYPE([ptrdiff_t], , |
| @@ -185,7 +216,6 @@ int main() | |||
| 185 | AC_DEFUN_ONCE([gl_PREREQ_VASNXPRINTF], | 216 | AC_DEFUN_ONCE([gl_PREREQ_VASNXPRINTF], |
| 186 | [ | 217 | [ |
| 187 | AC_REQUIRE([AC_FUNC_ALLOCA]) | 218 | AC_REQUIRE([AC_FUNC_ALLOCA]) |
| 188 | AC_REQUIRE([gt_TYPE_WCHAR_T]) | ||
| 189 | AC_REQUIRE([gt_TYPE_WINT_T]) | 219 | AC_REQUIRE([gt_TYPE_WINT_T]) |
| 190 | AC_CHECK_FUNCS([wcslen]) | 220 | AC_CHECK_FUNCS([wcslen]) |
| 191 | dnl Knowing DBL_EXPBIT0_WORD and DBL_EXPBIT0_BIT enables an optimization | 221 | dnl Knowing DBL_EXPBIT0_WORD and DBL_EXPBIT0_BIT enables an optimization |
| @@ -327,15 +357,39 @@ AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_LC], | |||
| 327 | # Extra prerequisites of lib/vasnprintf.c for supporting the ' flag. | 357 | # Extra prerequisites of lib/vasnprintf.c for supporting the ' flag. |
| 328 | AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING], | 358 | AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING], |
| 329 | [ | 359 | [ |
| 360 | AC_REQUIRE([AC_CANONICAL_HOST]) | ||
| 330 | AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) | 361 | AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) |
| 331 | case "$gl_cv_func_printf_flag_grouping" in | 362 | AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_INT_PRECISION]) |
| 332 | *yes) | 363 | AC_REQUIRE([gl_PRINTF_FLAG_GROUPING_MULTIBYTE]) |
| 333 | ;; | 364 | case "$host_os" in |
| 334 | *) | 365 | mingw* | windows*) |
| 366 | dnl MSVC does not support the ' flag at all. | ||
| 367 | dnl mingw does not support it, unless __USE_MINGW_ANSI_STDIO is defined. | ||
| 368 | dnl mingw also has other bugs regarding the ' flag. | ||
| 335 | AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1], | 369 | AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1], |
| 336 | [Define if the vasnprintf implementation needs special code for the | 370 | [Define if the vasnprintf implementation needs special code for the |
| 337 | ' flag.]) | 371 | ' flag.]) |
| 338 | ;; | 372 | ;; |
| 373 | *) | ||
| 374 | case "$gl_cv_func_printf_flag_grouping,$gl_cv_func_printf_flag_grouping_multibyte" in | ||
| 375 | *yes,*yes) | ||
| 376 | case "$gl_cv_func_printf_flag_grouping_int_precision" in | ||
| 377 | *yes) | ||
| 378 | ;; | ||
| 379 | *) | ||
| 380 | AC_DEFINE([NEED_PRINTF_FLAG_GROUPING_INT], [1], | ||
| 381 | [Define if the vasnprintf implementation needs special code for the | ||
| 382 | ' flag, for integer directives only.]) | ||
| 383 | ;; | ||
| 384 | esac | ||
| 385 | ;; | ||
| 386 | *) | ||
| 387 | AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1], | ||
| 388 | [Define if the vasnprintf implementation needs special code for the | ||
| 389 | ' flag.]) | ||
| 390 | ;; | ||
| 391 | esac | ||
| 392 | ;; | ||
| 339 | esac | 393 | esac |
| 340 | ]) | 394 | ]) |
| 341 | 395 | ||
diff --git a/gl/m4/vasprintf.m4 b/gl/m4/vasprintf.m4 index 73f7b807..6ea602bd 100644 --- a/gl/m4/vasprintf.m4 +++ b/gl/m4/vasprintf.m4 | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | # vasprintf.m4 | 1 | # vasprintf.m4 |
| 2 | # serial 6 | 2 | # serial 6 |
| 3 | dnl Copyright (C) 2002-2003, 2006-2007, 2009-2024 Free Software Foundation, | 3 | dnl Copyright (C) 2002-2003, 2006-2007, 2009-2025 Free Software Foundation, |
| 4 | dnl Inc. | 4 | dnl Inc. |
| 5 | dnl This file is free software; the Free Software Foundation | 5 | dnl This file is free software; the Free Software Foundation |
| 6 | dnl gives unlimited permission to copy and/or distribute it, | 6 | dnl gives unlimited permission to copy and/or distribute it, |
| 7 | dnl with or without modifications, as long as this notice is preserved. | 7 | dnl with or without modifications, as long as this notice is preserved. |
| 8 | dnl This file is offered as-is, without any warranty. | ||
| 8 | 9 | ||
| 9 | AC_DEFUN([gl_FUNC_VASPRINTF], | 10 | AC_DEFUN([gl_FUNC_VASPRINTF], |
| 10 | [ | 11 | [ |
diff --git a/gl/m4/visibility.m4 b/gl/m4/visibility.m4 index ecf09686..c2cd38d0 100644 --- a/gl/m4/visibility.m4 +++ b/gl/m4/visibility.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # visibility.m4 | 1 | # visibility.m4 |
| 2 | # serial 9 | 2 | # serial 9 |
| 3 | dnl Copyright (C) 2005, 2008, 2010-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2005, 2008, 2010-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | 10 | ||
diff --git a/gl/m4/vsnprintf.m4 b/gl/m4/vsnprintf.m4 index 9f321f3f..68ab757d 100644 --- a/gl/m4/vsnprintf.m4 +++ b/gl/m4/vsnprintf.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # vsnprintf.m4 | 1 | # vsnprintf.m4 |
| 2 | # serial 7 | 2 | # serial 7 |
| 3 | dnl Copyright (C) 2002-2004, 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2004, 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl Libintl 0.17 will replace vsnprintf only if it does not support %1$s, | 9 | dnl Libintl 0.17 will replace vsnprintf only if it does not support %1$s, |
| 9 | dnl but defers to any gnulib vsnprintf replacements. Therefore, gnulib | 10 | dnl but defers to any gnulib vsnprintf replacements. Therefore, gnulib |
diff --git a/gl/m4/warn-on-use.m4 b/gl/m4/warn-on-use.m4 index 6c8c76b8..73cf16fb 100644 --- a/gl/m4/warn-on-use.m4 +++ b/gl/m4/warn-on-use.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # warn-on-use.m4 | 1 | # warn-on-use.m4 |
| 2 | # serial 11 | 2 | # serial 11 |
| 3 | dnl Copyright (C) 2010-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2010-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | # gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES) | 9 | # gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES) |
| 9 | # --------------------------------------- | 10 | # --------------------------------------- |
diff --git a/gl/m4/wchar_h.m4 b/gl/m4/wchar_h.m4 index 995bdc65..722fcfc2 100644 --- a/gl/m4/wchar_h.m4 +++ b/gl/m4/wchar_h.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # wchar_h.m4 | 1 | # wchar_h.m4 |
| 2 | # serial 64 | 2 | # serial 65 |
| 3 | dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl A placeholder for ISO C99 <wchar.h>, for platforms that have issues. | 9 | dnl A placeholder for ISO C99 <wchar.h>, for platforms that have issues. |
| 9 | 10 | ||
| @@ -256,6 +257,7 @@ AC_DEFUN([gl_WCHAR_H_DEFAULTS], | |||
| 256 | REPLACE_WCSWIDTH=0; AC_SUBST([REPLACE_WCSWIDTH]) | 257 | REPLACE_WCSWIDTH=0; AC_SUBST([REPLACE_WCSWIDTH]) |
| 257 | REPLACE_WCSFTIME=0; AC_SUBST([REPLACE_WCSFTIME]) | 258 | REPLACE_WCSFTIME=0; AC_SUBST([REPLACE_WCSFTIME]) |
| 258 | REPLACE_WCSCMP=0; AC_SUBST([REPLACE_WCSCMP]) | 259 | REPLACE_WCSCMP=0; AC_SUBST([REPLACE_WCSCMP]) |
| 260 | REPLACE_WCSNCAT=0; AC_SUBST([REPLACE_WCSNCAT]) | ||
| 259 | REPLACE_WCSNCMP=0; AC_SUBST([REPLACE_WCSNCMP]) | 261 | REPLACE_WCSNCMP=0; AC_SUBST([REPLACE_WCSNCMP]) |
| 260 | REPLACE_WCSSTR=0; AC_SUBST([REPLACE_WCSSTR]) | 262 | REPLACE_WCSSTR=0; AC_SUBST([REPLACE_WCSSTR]) |
| 261 | REPLACE_WCSTOK=0; AC_SUBST([REPLACE_WCSTOK]) | 263 | REPLACE_WCSTOK=0; AC_SUBST([REPLACE_WCSTOK]) |
diff --git a/gl/m4/wchar_t.m4 b/gl/m4/wchar_t.m4 deleted file mode 100644 index 968832cb..00000000 --- a/gl/m4/wchar_t.m4 +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | # wchar_t.m4 | ||
| 2 | # serial 4 (gettext-0.18.2) | ||
| 3 | dnl Copyright (C) 2002-2003, 2008-2024 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | |||
| 8 | dnl From Bruno Haible. | ||
| 9 | dnl Test whether <stddef.h> has the 'wchar_t' type. | ||
| 10 | dnl Prerequisite: AC_PROG_CC | ||
| 11 | |||
| 12 | AC_DEFUN([gt_TYPE_WCHAR_T], | ||
| 13 | [ | ||
| 14 | AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t], | ||
| 15 | [AC_COMPILE_IFELSE( | ||
| 16 | [AC_LANG_PROGRAM( | ||
| 17 | [[#include <stddef.h> | ||
| 18 | wchar_t foo = (wchar_t)'\0';]], | ||
| 19 | [[]])], | ||
| 20 | [gt_cv_c_wchar_t=yes], | ||
| 21 | [gt_cv_c_wchar_t=no])]) | ||
| 22 | if test $gt_cv_c_wchar_t = yes; then | ||
| 23 | AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.]) | ||
| 24 | fi | ||
| 25 | ]) | ||
diff --git a/gl/m4/wcrtomb.m4 b/gl/m4/wcrtomb.m4 index 35dff6f0..91530176 100644 --- a/gl/m4/wcrtomb.m4 +++ b/gl/m4/wcrtomb.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # wcrtomb.m4 | 1 | # wcrtomb.m4 |
| 2 | # serial 19 | 2 | # serial 21 |
| 3 | dnl Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_FUNC_WCRTOMB], | 9 | AC_DEFUN([gl_FUNC_WCRTOMB], |
| 9 | [ | 10 | [ |
| @@ -36,7 +37,7 @@ AC_DEFUN([gl_FUNC_WCRTOMB], | |||
| 36 | dnl sometimes returns 0 instead of 1. | 37 | dnl sometimes returns 0 instead of 1. |
| 37 | AC_REQUIRE([AC_PROG_CC]) | 38 | AC_REQUIRE([AC_PROG_CC]) |
| 38 | AC_REQUIRE([gt_LOCALE_FR]) | 39 | AC_REQUIRE([gt_LOCALE_FR]) |
| 39 | AC_REQUIRE([gt_LOCALE_FR_UTF8]) | 40 | AC_REQUIRE([gt_LOCALE_EN_UTF8]) |
| 40 | AC_REQUIRE([gt_LOCALE_JA]) | 41 | AC_REQUIRE([gt_LOCALE_JA]) |
| 41 | AC_REQUIRE([gt_LOCALE_ZH_CN]) | 42 | AC_REQUIRE([gt_LOCALE_ZH_CN]) |
| 42 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | 43 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles |
| @@ -90,7 +91,7 @@ changequote(,)dnl | |||
| 90 | gl_cv_func_wcrtomb_retval="guessing yes" ;; | 91 | gl_cv_func_wcrtomb_retval="guessing yes" ;; |
| 91 | esac | 92 | esac |
| 92 | changequote([,])dnl | 93 | changequote([,])dnl |
| 93 | if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then | 94 | if test $LOCALE_FR != none || test "$LOCALE_EN_UTF8" != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then |
| 94 | AC_RUN_IFELSE( | 95 | AC_RUN_IFELSE( |
| 95 | [AC_LANG_SOURCE([[ | 96 | [AC_LANG_SOURCE([[ |
| 96 | #include <locale.h> | 97 | #include <locale.h> |
| @@ -106,8 +107,8 @@ int main () | |||
| 106 | if (wcrtomb (NULL, 0, NULL) != 1) | 107 | if (wcrtomb (NULL, 0, NULL) != 1) |
| 107 | result |= 1; | 108 | result |= 1; |
| 108 | } | 109 | } |
| 109 | if (strcmp ("$LOCALE_FR_UTF8", "none") != 0 | 110 | if (strcmp ("$LOCALE_EN_UTF8", "none") != 0 |
| 110 | && setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) | 111 | && setlocale (LC_ALL, "$LOCALE_EN_UTF8") != NULL) |
| 111 | { | 112 | { |
| 112 | if (wcrtomb (NULL, 0, NULL) != 1) | 113 | if (wcrtomb (NULL, 0, NULL) != 1) |
| 113 | result |= 2; | 114 | result |= 2; |
diff --git a/gl/m4/wctype.m4 b/gl/m4/wctype.m4 index e5d70740..56593cd5 100644 --- a/gl/m4/wctype.m4 +++ b/gl/m4/wctype.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # wctype.m4 | 1 | # wctype.m4 |
| 2 | # serial 6 | 2 | # serial 6 |
| 3 | dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN_ONCE([gl_FUNC_WCTYPE], | 9 | AC_DEFUN_ONCE([gl_FUNC_WCTYPE], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/wctype_h.m4 b/gl/m4/wctype_h.m4 index a3b07c2a..8e54678d 100644 --- a/gl/m4/wctype_h.m4 +++ b/gl/m4/wctype_h.m4 | |||
| @@ -3,10 +3,11 @@ | |||
| 3 | 3 | ||
| 4 | dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it. | 4 | dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it. |
| 5 | 5 | ||
| 6 | dnl Copyright (C) 2006-2024 Free Software Foundation, Inc. | 6 | dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 7 | dnl This file is free software; the Free Software Foundation | 7 | dnl This file is free software; the Free Software Foundation |
| 8 | dnl gives unlimited permission to copy and/or distribute it, | 8 | dnl gives unlimited permission to copy and/or distribute it, |
| 9 | dnl with or without modifications, as long as this notice is preserved. | 9 | dnl with or without modifications, as long as this notice is preserved. |
| 10 | dnl This file is offered as-is, without any warranty. | ||
| 10 | 11 | ||
| 11 | dnl Written by Paul Eggert. | 12 | dnl Written by Paul Eggert. |
| 12 | 13 | ||
diff --git a/gl/m4/wcwidth.m4 b/gl/m4/wcwidth.m4 new file mode 100644 index 00000000..2cc6ebb1 --- /dev/null +++ b/gl/m4/wcwidth.m4 | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | # wcwidth.m4 | ||
| 2 | # serial 38 | ||
| 3 | dnl Copyright (C) 2006-2025 Free Software Foundation, Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 8 | |||
| 9 | AC_DEFUN([gl_FUNC_WCWIDTH], | ||
| 10 | [ | ||
| 11 | AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) | ||
| 12 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
| 13 | |||
| 14 | dnl Persuade glibc <wchar.h> to declare wcwidth(). | ||
| 15 | AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) | ||
| 16 | |||
| 17 | AC_REQUIRE([gt_TYPE_WINT_T]) | ||
| 18 | |||
| 19 | AC_CHECK_HEADERS_ONCE([wchar.h]) | ||
| 20 | AC_CHECK_FUNCS_ONCE([wcwidth]) | ||
| 21 | |||
| 22 | AC_CHECK_DECLS([wcwidth], [], [], [[ | ||
| 23 | #include <wchar.h> | ||
| 24 | ]]) | ||
| 25 | if test $ac_cv_have_decl_wcwidth != yes; then | ||
| 26 | HAVE_DECL_WCWIDTH=0 | ||
| 27 | fi | ||
| 28 | |||
| 29 | if test $ac_cv_func_wcwidth != yes; then | ||
| 30 | AC_CACHE_CHECK([whether wcwidth is a macro], | ||
| 31 | [gl_cv_func_wcwidth_macro], | ||
| 32 | [AC_EGREP_CPP([wchar_header_defines_wcwidth], [ | ||
| 33 | #include <wchar.h> | ||
| 34 | #ifdef wcwidth | ||
| 35 | wchar_header_defines_wcwidth | ||
| 36 | #endif], | ||
| 37 | [gl_cv_func_wcwidth_macro=yes], | ||
| 38 | [gl_cv_func_wcwidth_macro=no]) | ||
| 39 | ]) | ||
| 40 | fi | ||
| 41 | |||
| 42 | if test $ac_cv_func_wcwidth = yes || test $gl_cv_func_wcwidth_macro = yes; then | ||
| 43 | HAVE_WCWIDTH=1 | ||
| 44 | dnl On Mac OS X 10.3, wcwidth(0x0301) (COMBINING ACUTE ACCENT) returns 1. | ||
| 45 | dnl On macOS 12.5, NetBSD 9.3, OpenBSD 5.0, MidnightBSD 1.1, | ||
| 46 | dnl wcwidth(0x05B0) (HEBREW POINT SHEVA) returns 1. | ||
| 47 | dnl On macOS 12.5, NetBSD 9.3, MidnightBSD 1.1, OSF/1 5.1, | ||
| 48 | dnl wcwidth(0x200B) (ZERO WIDTH SPACE) returns 1. | ||
| 49 | dnl On OpenBSD 5.8, wcwidth(0xFF1A) (FULLWIDTH COLON) returns 0. | ||
| 50 | dnl This leads to bugs in 'ls' (coreutils). | ||
| 51 | dnl On Solaris 11.4, wcwidth(0x2202) (PARTIAL DIFFERENTIAL) returns 2, | ||
| 52 | dnl even in Western locales. | ||
| 53 | AC_CACHE_CHECK([whether wcwidth works reasonably in UTF-8 locales], | ||
| 54 | [gl_cv_func_wcwidth_works], | ||
| 55 | [ | ||
| 56 | AC_RUN_IFELSE( | ||
| 57 | [AC_LANG_SOURCE([[ | ||
| 58 | #include <locale.h> | ||
| 59 | #include <wchar.h> | ||
| 60 | #if !HAVE_DECL_WCWIDTH | ||
| 61 | extern | ||
| 62 | # ifdef __cplusplus | ||
| 63 | "C" | ||
| 64 | # endif | ||
| 65 | int wcwidth (int); | ||
| 66 | #endif | ||
| 67 | int main () | ||
| 68 | { | ||
| 69 | int result = 0; | ||
| 70 | if (setlocale (LC_ALL, "en_US.UTF-8") != NULL) | ||
| 71 | { | ||
| 72 | if (wcwidth (0x0301) > 0) | ||
| 73 | result |= 1; | ||
| 74 | if (wcwidth (0x05B0) > 0) | ||
| 75 | result |= 2; | ||
| 76 | if (wcwidth (0x200B) > 0) | ||
| 77 | result |= 4; | ||
| 78 | if (wcwidth (0xFF1A) == 0) | ||
| 79 | result |= 8; | ||
| 80 | if (wcwidth (0x2202) > 1) | ||
| 81 | result |= 16; | ||
| 82 | } | ||
| 83 | return result; | ||
| 84 | }]])], | ||
| 85 | [gl_cv_func_wcwidth_works=yes], | ||
| 86 | [gl_cv_func_wcwidth_works=no], | ||
| 87 | [ | ||
| 88 | changequote(,)dnl | ||
| 89 | case "$host_os" in | ||
| 90 | # Guess yes on glibc systems. | ||
| 91 | *-gnu* | gnu*) gl_cv_func_wcwidth_works="guessing yes";; | ||
| 92 | # Guess yes on musl systems. | ||
| 93 | *-musl* | midipix*) gl_cv_func_wcwidth_works="guessing yes";; | ||
| 94 | # Guess yes on AIX 7 systems. | ||
| 95 | aix[7-9]*) gl_cv_func_wcwidth_works="guessing yes";; | ||
| 96 | *) gl_cv_func_wcwidth_works="$gl_cross_guess_normal";; | ||
| 97 | esac | ||
| 98 | changequote([,])dnl | ||
| 99 | ]) | ||
| 100 | ]) | ||
| 101 | case "$gl_cv_func_wcwidth_works" in | ||
| 102 | *yes) ;; | ||
| 103 | *no) REPLACE_WCWIDTH=1 ;; | ||
| 104 | esac | ||
| 105 | else | ||
| 106 | HAVE_WCWIDTH=0 | ||
| 107 | fi | ||
| 108 | dnl We don't substitute HAVE_WCWIDTH. We assume that if the system does not | ||
| 109 | dnl have the wcwidth function, then it does not declare it. | ||
| 110 | ]) | ||
| 111 | |||
| 112 | # Prerequisites of lib/wcwidth.c. | ||
| 113 | AC_DEFUN([gl_PREREQ_WCWIDTH], [ | ||
| 114 | AC_REQUIRE([AC_C_INLINE]) | ||
| 115 | : | ||
| 116 | ]) | ||
diff --git a/gl/m4/wint_t.m4 b/gl/m4/wint_t.m4 index 883fac28..8a3c7944 100644 --- a/gl/m4/wint_t.m4 +++ b/gl/m4/wint_t.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # wint_t.m4 | 1 | # wint_t.m4 |
| 2 | # serial 11 | 2 | # serial 11 |
| 3 | dnl Copyright (C) 2003, 2007-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003, 2007-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl From Bruno Haible. | 9 | dnl From Bruno Haible. |
| 9 | dnl Test whether <wchar.h> has the 'wint_t' type and whether gnulib's | 10 | dnl Test whether <wchar.h> has the 'wint_t' type and whether gnulib's |
diff --git a/gl/m4/xalloc.m4 b/gl/m4/xalloc.m4 index d44d0f08..c10c4189 100644 --- a/gl/m4/xalloc.m4 +++ b/gl/m4/xalloc.m4 | |||
| @@ -1,8 +1,9 @@ | |||
| 1 | # xalloc.m4 | 1 | # xalloc.m4 |
| 2 | # serial 18 | 2 | # serial 18 |
| 3 | dnl Copyright (C) 2002-2006, 2009-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2002-2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_XALLOC], [:]) | 9 | AC_DEFUN([gl_XALLOC], [:]) |
diff --git a/gl/m4/xsize.m4 b/gl/m4/xsize.m4 index e5784973..157d635c 100644 --- a/gl/m4/xsize.m4 +++ b/gl/m4/xsize.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # xsize.m4 | 1 | # xsize.m4 |
| 2 | # serial 5 | 2 | # serial 5 |
| 3 | dnl Copyright (C) 2003-2004, 2008-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2003-2004, 2008-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | AC_DEFUN([gl_XSIZE], | 9 | AC_DEFUN([gl_XSIZE], |
| 9 | [ | 10 | [ |
diff --git a/gl/m4/zzgnulib.m4 b/gl/m4/zzgnulib.m4 index 710fba4e..343bda5c 100644 --- a/gl/m4/zzgnulib.m4 +++ b/gl/m4/zzgnulib.m4 | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # zzgnulib.m4 | 1 | # zzgnulib.m4 |
| 2 | # serial 1 | 2 | # serial 1 |
| 3 | dnl Copyright (C) 2020-2024 Free Software Foundation, Inc. | 3 | dnl Copyright (C) 2020-2025 Free Software Foundation, Inc. |
| 4 | dnl This file is free software; the Free Software Foundation | 4 | dnl This file is free software; the Free Software Foundation |
| 5 | dnl gives unlimited permission to copy and/or distribute it, | 5 | dnl gives unlimited permission to copy and/or distribute it, |
| 6 | dnl with or without modifications, as long as this notice is preserved. | 6 | dnl with or without modifications, as long as this notice is preserved. |
| 7 | dnl This file is offered as-is, without any warranty. | ||
| 7 | 8 | ||
| 8 | dnl This file must be named something that sorts after all other | 9 | dnl This file must be named something that sorts after all other |
| 9 | dnl package- or gnulib-provided .m4 files - at least for those packages | 10 | dnl package- or gnulib-provided .m4 files - at least for those packages |
diff --git a/gl/malloc.c b/gl/malloc.c index 2a7867a1..5642c83c 100644 --- a/gl/malloc.c +++ b/gl/malloc.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* malloc() function that is glibc compatible. | 1 | /* malloc() function that is glibc compatible. |
| 2 | 2 | ||
| 3 | Copyright (C) 1997-1998, 2006-2007, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1997-1998, 2006-2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -17,28 +17,33 @@ | |||
| 17 | 17 | ||
| 18 | /* written by Jim Meyering and Bruno Haible */ | 18 | /* written by Jim Meyering and Bruno Haible */ |
| 19 | 19 | ||
| 20 | /* Ensure that we call the system's malloc() below. */ | ||
| 20 | #define _GL_USE_STDLIB_ALLOC 1 | 21 | #define _GL_USE_STDLIB_ALLOC 1 |
| 21 | #include <config.h> | 22 | #include <config.h> |
| 22 | 23 | ||
| 23 | #include <stdlib.h> | 24 | #include <stdlib.h> |
| 24 | 25 | ||
| 25 | #include <errno.h> | 26 | #include <errno.h> |
| 26 | 27 | #include <stdckdint.h> | |
| 27 | #include "xalloc-oversized.h" | ||
| 28 | 28 | ||
| 29 | /* Allocate an N-byte block of memory from the heap, even if N is 0. */ | 29 | /* Allocate an N-byte block of memory from the heap, even if N is 0. */ |
| 30 | 30 | ||
| 31 | void * | 31 | void * |
| 32 | rpl_malloc (size_t n) | 32 | rpl_malloc (size_t n) |
| 33 | { | 33 | { |
| 34 | #if !HAVE_MALLOC_0_NONNULL | ||
| 34 | if (n == 0) | 35 | if (n == 0) |
| 35 | n = 1; | 36 | n = 1; |
| 37 | #endif | ||
| 36 | 38 | ||
| 37 | if (xalloc_oversized (n, 1)) | 39 | #if !HAVE_MALLOC_PTRDIFF |
| 40 | ptrdiff_t signed_n; | ||
| 41 | if (ckd_add (&signed_n, n, 0)) | ||
| 38 | { | 42 | { |
| 39 | errno = ENOMEM; | 43 | errno = ENOMEM; |
| 40 | return NULL; | 44 | return NULL; |
| 41 | } | 45 | } |
| 46 | #endif | ||
| 42 | 47 | ||
| 43 | void *result = malloc (n); | 48 | void *result = malloc (n); |
| 44 | 49 | ||
diff --git a/gl/malloc/dynarray-skeleton.c b/gl/malloc/dynarray-skeleton.c index a95241ab..6b0585c1 100644 --- a/gl/malloc/dynarray-skeleton.c +++ b/gl/malloc/dynarray-skeleton.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Type-safe arrays which grow dynamically. | 1 | /* Type-safe arrays which grow dynamically. |
| 2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
diff --git a/gl/malloc/dynarray.h b/gl/malloc/dynarray.h index 3163e278..6cbbe50e 100644 --- a/gl/malloc/dynarray.h +++ b/gl/malloc/dynarray.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Type-safe arrays which grow dynamically. Shared definitions. | 1 | /* Type-safe arrays which grow dynamically. Shared definitions. |
| 2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
diff --git a/gl/malloc/dynarray_at_failure.c b/gl/malloc/dynarray_at_failure.c index 95e34e7a..b94ac3df 100644 --- a/gl/malloc/dynarray_at_failure.c +++ b/gl/malloc/dynarray_at_failure.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Report an dynamic array index out of bounds condition. | 1 | /* Report an dynamic array index out of bounds condition. |
| 2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
diff --git a/gl/malloc/dynarray_emplace_enlarge.c b/gl/malloc/dynarray_emplace_enlarge.c index 7bdba159..53126863 100644 --- a/gl/malloc/dynarray_emplace_enlarge.c +++ b/gl/malloc/dynarray_emplace_enlarge.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Increase the size of a dynamic array in preparation of an emplace operation. | 1 | /* Increase the size of a dynamic array in preparation of an emplace operation. |
| 2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
diff --git a/gl/malloc/dynarray_finalize.c b/gl/malloc/dynarray_finalize.c index 52764f73..3178c687 100644 --- a/gl/malloc/dynarray_finalize.c +++ b/gl/malloc/dynarray_finalize.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Copy the dynamically-allocated area to an explicitly-sized heap allocation. | 1 | /* Copy the dynamically-allocated area to an explicitly-sized heap allocation. |
| 2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
diff --git a/gl/malloc/dynarray_resize.c b/gl/malloc/dynarray_resize.c index 7323f8ee..3cd1626a 100644 --- a/gl/malloc/dynarray_resize.c +++ b/gl/malloc/dynarray_resize.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Increase the size of a dynamic array. | 1 | /* Increase the size of a dynamic array. |
| 2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
diff --git a/gl/malloc/dynarray_resize_clear.c b/gl/malloc/dynarray_resize_clear.c index aa17f740..7bfc0005 100644 --- a/gl/malloc/dynarray_resize_clear.c +++ b/gl/malloc/dynarray_resize_clear.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Increase the size of a dynamic array and clear the new part. | 1 | /* Increase the size of a dynamic array and clear the new part. |
| 2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | 5 | The GNU C Library is free software; you can redistribute it and/or |
diff --git a/gl/malloca.c b/gl/malloca.c index e75c72df..4bce9a3d 100644 --- a/gl/malloca.c +++ b/gl/malloca.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Safe automatic memory allocation. | 1 | /* Safe automatic memory allocation. |
| 2 | Copyright (C) 2003, 2006-2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2003, 2006-2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2003, 2018. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2003, 2018. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -93,7 +93,7 @@ mmalloca (size_t n) | |||
| 93 | /* Out of memory. */ | 93 | /* Out of memory. */ |
| 94 | return NULL; | 94 | return NULL; |
| 95 | #else | 95 | #else |
| 96 | # if !MALLOC_0_IS_NONNULL | 96 | # if !HAVE_MALLOC_0_NONNULL |
| 97 | if (n == 0) | 97 | if (n == 0) |
| 98 | n = 1; | 98 | n = 1; |
| 99 | # endif | 99 | # endif |
| @@ -118,7 +118,7 @@ freea (void *p) | |||
| 118 | char *cp = p; | 118 | char *cp = p; |
| 119 | small_t *sp = p; | 119 | small_t *sp = p; |
| 120 | # if defined __CHERI_PURE_CAPABILITY__ | 120 | # if defined __CHERI_PURE_CAPABILITY__ |
| 121 | void *mem = sp[-1]; | 121 | void *mem = (void *) sp[-1]; |
| 122 | # else | 122 | # else |
| 123 | void *mem = cp - sp[-1]; | 123 | void *mem = cp - sp[-1]; |
| 124 | # endif | 124 | # endif |
diff --git a/gl/malloca.h b/gl/malloca.h index c5208421..f131fd5a 100644 --- a/gl/malloca.h +++ b/gl/malloca.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Safe automatic memory allocation. | 1 | /* Safe automatic memory allocation. |
| 2 | Copyright (C) 2003-2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2003-2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2003. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2003. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Inline functions for <math.h>. | 1 | /* Inline functions for <math.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2012-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -15,8 +15,8 @@ | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | 15 | You should have received a copy of the GNU Lesser General Public License |
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
| 17 | 17 | ||
| 18 | #define _GL_MATH_INLINE _GL_EXTERN_INLINE | ||
| 18 | #include <config.h> | 19 | #include <config.h> |
| 19 | 20 | ||
| 20 | #define _GL_MATH_INLINE _GL_EXTERN_INLINE | ||
| 21 | #include <math.h> | 21 | #include <math.h> |
| 22 | typedef int dummy; | 22 | typedef int dummy; |
diff --git a/gl/math.in.h b/gl/math.in.h index 96d0da44..f4e80c53 100644 --- a/gl/math.in.h +++ b/gl/math.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A GNU-like <math.h>. | 1 | /* A GNU-like <math.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2002-2003, 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2002-2003, 2007-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -160,12 +160,23 @@ static void (*_gl_math_fix_itold) (long double *, int) = _Qp_itoq; | |||
| 160 | #endif | 160 | #endif |
| 161 | 161 | ||
| 162 | 162 | ||
| 163 | /* Ensure that INFINITY is a constant expression, of type 'float'. */ | ||
| 164 | #if !defined INFINITY || (defined __FreeBSD__ && __FreeBSD__ < 8) || defined _AIX || defined __MINGW32__ | ||
| 165 | # undef INFINITY | ||
| 166 | # if defined __GNUC__ || defined __clang__ | ||
| 167 | # define INFINITY (__builtin_inff ()) | ||
| 168 | # else | ||
| 169 | # define INFINITY (1.0f / 0.0f) | ||
| 170 | # endif | ||
| 171 | #endif | ||
| 172 | |||
| 163 | /* POSIX allows platforms that don't support NAN. But all major | 173 | /* POSIX allows platforms that don't support NAN. But all major |
| 164 | machines in the past 15 years have supported something close to | 174 | machines in the past 15 years have supported something close to |
| 165 | IEEE NaN, so we define this unconditionally. We also must define | 175 | IEEE NaN, so we define this unconditionally. We also must define |
| 166 | it on platforms like Solaris 10, where NAN is present but defined | 176 | it on platforms like Solaris 10, where NAN is present but defined |
| 167 | as a function pointer rather than a floating point constant. */ | 177 | as a function pointer rather than a floating point constant. |
| 168 | #if !defined NAN || @REPLACE_NAN@ | 178 | Also ensure that it is a constant expression, of type 'float'. */ |
| 179 | #if !defined NAN || @REPLACE_NAN@ || (defined __FreeBSD__ && __FreeBSD__ < 8) || defined _AIX || defined __MINGW32__ | ||
| 169 | # if !GNULIB_defined_NAN | 180 | # if !GNULIB_defined_NAN |
| 170 | # undef NAN | 181 | # undef NAN |
| 171 | /* The Compaq (ex-DEC) C 6.4 compiler and the Microsoft MSVC 9 compiler | 182 | /* The Compaq (ex-DEC) C 6.4 compiler and the Microsoft MSVC 9 compiler |
| @@ -178,6 +189,8 @@ _NaN () | |||
| 178 | return zero / zero; | 189 | return zero / zero; |
| 179 | } | 190 | } |
| 180 | # define NAN (_NaN()) | 191 | # define NAN (_NaN()) |
| 192 | # elif defined __GNUC__ || defined __clang__ | ||
| 193 | # define NAN (__builtin_nanf ("")) | ||
| 181 | # else | 194 | # else |
| 182 | # define NAN (0.0f / 0.0f) | 195 | # define NAN (0.0f / 0.0f) |
| 183 | # endif | 196 | # endif |
| @@ -197,46 +210,46 @@ _NaN () | |||
| 197 | #endif | 210 | #endif |
| 198 | 211 | ||
| 199 | /* HUGE_VALF is a 'float' Infinity. */ | 212 | /* HUGE_VALF is a 'float' Infinity. */ |
| 200 | #ifndef HUGE_VALF | 213 | #if !defined HUGE_VALF || (defined __FreeBSD__ && __FreeBSD__ < 6) |
| 214 | # undef HUGE_VALF | ||
| 201 | # if defined _MSC_VER | 215 | # if defined _MSC_VER |
| 202 | /* The Microsoft MSVC 9 compiler chokes on the expression 1.0f / 0.0f. */ | 216 | /* The Microsoft MSVC 9 compiler chokes on the expression 1.0f / 0.0f. */ |
| 203 | # define HUGE_VALF (1e25f * 1e25f) | 217 | # define HUGE_VALF (1e25f * 1e25f) |
| 218 | # elif defined __GNUC__ || defined __clang__ | ||
| 219 | # define HUGE_VALF (__builtin_inff ()) | ||
| 204 | # else | 220 | # else |
| 205 | # define HUGE_VALF (1.0f / 0.0f) | 221 | # define HUGE_VALF (1.0f / 0.0f) |
| 206 | # endif | 222 | # endif |
| 207 | #endif | 223 | #endif |
| 208 | 224 | ||
| 209 | /* HUGE_VAL is a 'double' Infinity. */ | 225 | /* HUGE_VAL is a 'double' Infinity. */ |
| 210 | #ifndef HUGE_VAL | 226 | #if !defined HUGE_VAL || (defined __FreeBSD__ && __FreeBSD__ < 6) || defined _AIX |
| 227 | # undef HUGE_VAL | ||
| 211 | # if defined _MSC_VER | 228 | # if defined _MSC_VER |
| 212 | /* The Microsoft MSVC 9 compiler chokes on the expression 1.0 / 0.0. */ | 229 | /* The Microsoft MSVC 9 compiler chokes on the expression 1.0 / 0.0. */ |
| 213 | # define HUGE_VAL (1e250 * 1e250) | 230 | # define HUGE_VAL (1e250 * 1e250) |
| 231 | # elif defined __GNUC__ || defined __clang__ | ||
| 232 | # define HUGE_VAL (__builtin_inf ()) | ||
| 214 | # else | 233 | # else |
| 215 | # define HUGE_VAL (1.0 / 0.0) | 234 | # define HUGE_VAL (1.0 / 0.0) |
| 216 | # endif | 235 | # endif |
| 217 | #endif | 236 | #endif |
| 218 | 237 | ||
| 219 | /* HUGE_VALL is a 'long double' Infinity. */ | 238 | /* HUGE_VALL is a 'long double' Infinity. */ |
| 220 | #ifndef HUGE_VALL | 239 | #if !defined HUGE_VALL || (defined __FreeBSD__ && __FreeBSD__ < 6) || defined _AIX |
| 240 | # undef HUGE_VALL | ||
| 221 | # if defined _MSC_VER | 241 | # if defined _MSC_VER |
| 222 | /* The Microsoft MSVC 9 compiler chokes on the expression 1.0L / 0.0L. */ | 242 | /* The Microsoft MSVC 9 compiler chokes on the expression 1.0L / 0.0L. */ |
| 223 | # define HUGE_VALL (1e250L * 1e250L) | 243 | # define HUGE_VALL (1e250L * 1e250L) |
| 244 | # elif defined __GNUC__ || defined __clang__ | ||
| 245 | # define HUGE_VALL (__builtin_infl ()) | ||
| 224 | # else | 246 | # else |
| 225 | # define HUGE_VALL (1.0L / 0.0L) | 247 | # define HUGE_VALL (1.0L / 0.0L) |
| 226 | # endif | 248 | # endif |
| 227 | #endif | 249 | #endif |
| 228 | 250 | ||
| 229 | 251 | ||
| 230 | #if defined FP_ILOGB0 && defined FP_ILOGBNAN | 252 | #if !(defined FP_ILOGB0 && defined FP_ILOGBNAN) |
| 231 | /* Ensure FP_ILOGB0 and FP_ILOGBNAN are correct. */ | ||
| 232 | # if defined __HAIKU__ | ||
| 233 | /* Haiku: match what ilogb() does */ | ||
| 234 | # undef FP_ILOGB0 | ||
| 235 | # undef FP_ILOGBNAN | ||
| 236 | # define FP_ILOGB0 (- 2147483647 - 1) /* INT_MIN */ | ||
| 237 | # define FP_ILOGBNAN (- 2147483647 - 1) /* INT_MIN */ | ||
| 238 | # endif | ||
| 239 | #else | ||
| 240 | /* Ensure FP_ILOGB0 and FP_ILOGBNAN are defined. */ | 253 | /* Ensure FP_ILOGB0 and FP_ILOGBNAN are defined. */ |
| 241 | # if defined __NetBSD__ || defined __sgi | 254 | # if defined __NetBSD__ || defined __sgi |
| 242 | /* NetBSD, IRIX 6.5: match what ilogb() does */ | 255 | /* NetBSD, IRIX 6.5: match what ilogb() does */ |
| @@ -264,12 +277,12 @@ _NaN () | |||
| 264 | # undef acosf | 277 | # undef acosf |
| 265 | # define acosf rpl_acosf | 278 | # define acosf rpl_acosf |
| 266 | # endif | 279 | # endif |
| 267 | _GL_FUNCDECL_RPL (acosf, float, (float x)); | 280 | _GL_FUNCDECL_RPL (acosf, float, (float x), ); |
| 268 | _GL_CXXALIAS_RPL (acosf, float, (float x)); | 281 | _GL_CXXALIAS_RPL (acosf, float, (float x)); |
| 269 | # else | 282 | # else |
| 270 | # if !@HAVE_ACOSF@ | 283 | # if !@HAVE_ACOSF@ |
| 271 | # undef acosf | 284 | # undef acosf |
| 272 | _GL_FUNCDECL_SYS (acosf, float, (float x)); | 285 | _GL_FUNCDECL_SYS (acosf, float, (float x), ); |
| 273 | # endif | 286 | # endif |
| 274 | _GL_CXXALIAS_SYS (acosf, float, (float x)); | 287 | _GL_CXXALIAS_SYS (acosf, float, (float x)); |
| 275 | # endif | 288 | # endif |
| @@ -285,7 +298,7 @@ _GL_WARN_ON_USE (acosf, "acosf is unportable - " | |||
| 285 | #if @GNULIB_ACOSL@ | 298 | #if @GNULIB_ACOSL@ |
| 286 | # if !@HAVE_ACOSL@ || !@HAVE_DECL_ACOSL@ | 299 | # if !@HAVE_ACOSL@ || !@HAVE_DECL_ACOSL@ |
| 287 | # undef acosl | 300 | # undef acosl |
| 288 | _GL_FUNCDECL_SYS (acosl, long double, (long double x)); | 301 | _GL_FUNCDECL_SYS (acosl, long double, (long double x), ); |
| 289 | # endif | 302 | # endif |
| 290 | _GL_CXXALIAS_SYS (acosl, long double, (long double x)); | 303 | _GL_CXXALIAS_SYS (acosl, long double, (long double x)); |
| 291 | # if __GLIBC__ >= 2 | 304 | # if __GLIBC__ >= 2 |
| @@ -306,12 +319,12 @@ _GL_WARN_ON_USE (acosl, "acosl is unportable - " | |||
| 306 | # undef asinf | 319 | # undef asinf |
| 307 | # define asinf rpl_asinf | 320 | # define asinf rpl_asinf |
| 308 | # endif | 321 | # endif |
| 309 | _GL_FUNCDECL_RPL (asinf, float, (float x)); | 322 | _GL_FUNCDECL_RPL (asinf, float, (float x), ); |
| 310 | _GL_CXXALIAS_RPL (asinf, float, (float x)); | 323 | _GL_CXXALIAS_RPL (asinf, float, (float x)); |
| 311 | # else | 324 | # else |
| 312 | # if !@HAVE_ASINF@ | 325 | # if !@HAVE_ASINF@ |
| 313 | # undef asinf | 326 | # undef asinf |
| 314 | _GL_FUNCDECL_SYS (asinf, float, (float x)); | 327 | _GL_FUNCDECL_SYS (asinf, float, (float x), ); |
| 315 | # endif | 328 | # endif |
| 316 | _GL_CXXALIAS_SYS (asinf, float, (float x)); | 329 | _GL_CXXALIAS_SYS (asinf, float, (float x)); |
| 317 | # endif | 330 | # endif |
| @@ -327,7 +340,7 @@ _GL_WARN_ON_USE (asinf, "asinf is unportable - " | |||
| 327 | #if @GNULIB_ASINL@ | 340 | #if @GNULIB_ASINL@ |
| 328 | # if !@HAVE_ASINL@ || !@HAVE_DECL_ASINL@ | 341 | # if !@HAVE_ASINL@ || !@HAVE_DECL_ASINL@ |
| 329 | # undef asinl | 342 | # undef asinl |
| 330 | _GL_FUNCDECL_SYS (asinl, long double, (long double x)); | 343 | _GL_FUNCDECL_SYS (asinl, long double, (long double x), ); |
| 331 | # endif | 344 | # endif |
| 332 | _GL_CXXALIAS_SYS (asinl, long double, (long double x)); | 345 | _GL_CXXALIAS_SYS (asinl, long double, (long double x)); |
| 333 | # if __GLIBC__ >= 2 | 346 | # if __GLIBC__ >= 2 |
| @@ -348,12 +361,12 @@ _GL_WARN_ON_USE (asinl, "asinl is unportable - " | |||
| 348 | # undef atanf | 361 | # undef atanf |
| 349 | # define atanf rpl_atanf | 362 | # define atanf rpl_atanf |
| 350 | # endif | 363 | # endif |
| 351 | _GL_FUNCDECL_RPL (atanf, float, (float x)); | 364 | _GL_FUNCDECL_RPL (atanf, float, (float x), ); |
| 352 | _GL_CXXALIAS_RPL (atanf, float, (float x)); | 365 | _GL_CXXALIAS_RPL (atanf, float, (float x)); |
| 353 | # else | 366 | # else |
| 354 | # if !@HAVE_ATANF@ | 367 | # if !@HAVE_ATANF@ |
| 355 | # undef atanf | 368 | # undef atanf |
| 356 | _GL_FUNCDECL_SYS (atanf, float, (float x)); | 369 | _GL_FUNCDECL_SYS (atanf, float, (float x), ); |
| 357 | # endif | 370 | # endif |
| 358 | _GL_CXXALIAS_SYS (atanf, float, (float x)); | 371 | _GL_CXXALIAS_SYS (atanf, float, (float x)); |
| 359 | # endif | 372 | # endif |
| @@ -369,7 +382,7 @@ _GL_WARN_ON_USE (atanf, "atanf is unportable - " | |||
| 369 | #if @GNULIB_ATANL@ | 382 | #if @GNULIB_ATANL@ |
| 370 | # if !@HAVE_ATANL@ || !@HAVE_DECL_ATANL@ | 383 | # if !@HAVE_ATANL@ || !@HAVE_DECL_ATANL@ |
| 371 | # undef atanl | 384 | # undef atanl |
| 372 | _GL_FUNCDECL_SYS (atanl, long double, (long double x)); | 385 | _GL_FUNCDECL_SYS (atanl, long double, (long double x), ); |
| 373 | # endif | 386 | # endif |
| 374 | _GL_CXXALIAS_SYS (atanl, long double, (long double x)); | 387 | _GL_CXXALIAS_SYS (atanl, long double, (long double x)); |
| 375 | # if __GLIBC__ >= 2 | 388 | # if __GLIBC__ >= 2 |
| @@ -390,12 +403,12 @@ _GL_WARN_ON_USE (atanl, "atanl is unportable - " | |||
| 390 | # undef atan2f | 403 | # undef atan2f |
| 391 | # define atan2f rpl_atan2f | 404 | # define atan2f rpl_atan2f |
| 392 | # endif | 405 | # endif |
| 393 | _GL_FUNCDECL_RPL (atan2f, float, (float y, float x)); | 406 | _GL_FUNCDECL_RPL (atan2f, float, (float y, float x), ); |
| 394 | _GL_CXXALIAS_RPL (atan2f, float, (float y, float x)); | 407 | _GL_CXXALIAS_RPL (atan2f, float, (float y, float x)); |
| 395 | # else | 408 | # else |
| 396 | # if !@HAVE_ATAN2F@ | 409 | # if !@HAVE_ATAN2F@ |
| 397 | # undef atan2f | 410 | # undef atan2f |
| 398 | _GL_FUNCDECL_SYS (atan2f, float, (float y, float x)); | 411 | _GL_FUNCDECL_SYS (atan2f, float, (float y, float x), ); |
| 399 | # endif | 412 | # endif |
| 400 | _GL_CXXALIAS_SYS (atan2f, float, (float y, float x)); | 413 | _GL_CXXALIAS_SYS (atan2f, float, (float y, float x)); |
| 401 | # endif | 414 | # endif |
| @@ -415,11 +428,11 @@ _GL_WARN_ON_USE (atan2f, "atan2f is unportable - " | |||
| 415 | # undef cbrtf | 428 | # undef cbrtf |
| 416 | # define cbrtf rpl_cbrtf | 429 | # define cbrtf rpl_cbrtf |
| 417 | # endif | 430 | # endif |
| 418 | _GL_FUNCDECL_RPL (cbrtf, float, (float x)); | 431 | _GL_FUNCDECL_RPL (cbrtf, float, (float x), ); |
| 419 | _GL_CXXALIAS_RPL (cbrtf, float, (float x)); | 432 | _GL_CXXALIAS_RPL (cbrtf, float, (float x)); |
| 420 | # else | 433 | # else |
| 421 | # if !@HAVE_DECL_CBRTF@ | 434 | # if !@HAVE_DECL_CBRTF@ |
| 422 | _GL_FUNCDECL_SYS (cbrtf, float, (float x)); | 435 | _GL_FUNCDECL_SYS (cbrtf, float, (float x), ); |
| 423 | # endif | 436 | # endif |
| 424 | _GL_CXXALIAS_SYS (cbrtf, float, (float x)); | 437 | _GL_CXXALIAS_SYS (cbrtf, float, (float x)); |
| 425 | # endif | 438 | # endif |
| @@ -434,7 +447,7 @@ _GL_WARN_ON_USE (cbrtf, "cbrtf is unportable - " | |||
| 434 | 447 | ||
| 435 | #if @GNULIB_CBRT@ | 448 | #if @GNULIB_CBRT@ |
| 436 | # if !@HAVE_CBRT@ | 449 | # if !@HAVE_CBRT@ |
| 437 | _GL_FUNCDECL_SYS (cbrt, double, (double x)); | 450 | _GL_FUNCDECL_SYS (cbrt, double, (double x), ); |
| 438 | # endif | 451 | # endif |
| 439 | _GL_CXXALIAS_SYS (cbrt, double, (double x)); | 452 | _GL_CXXALIAS_SYS (cbrt, double, (double x)); |
| 440 | # if __GLIBC__ >= 2 | 453 | # if __GLIBC__ >= 2 |
| @@ -454,11 +467,11 @@ _GL_WARN_ON_USE (cbrt, "cbrt is unportable - " | |||
| 454 | # undef cbrtl | 467 | # undef cbrtl |
| 455 | # define cbrtl rpl_cbrtl | 468 | # define cbrtl rpl_cbrtl |
| 456 | # endif | 469 | # endif |
| 457 | _GL_FUNCDECL_RPL (cbrtl, long double, (long double x)); | 470 | _GL_FUNCDECL_RPL (cbrtl, long double, (long double x), ); |
| 458 | _GL_CXXALIAS_RPL (cbrtl, long double, (long double x)); | 471 | _GL_CXXALIAS_RPL (cbrtl, long double, (long double x)); |
| 459 | # else | 472 | # else |
| 460 | # if !@HAVE_DECL_CBRTL@ | 473 | # if !@HAVE_DECL_CBRTL@ |
| 461 | _GL_FUNCDECL_SYS (cbrtl, long double, (long double x)); | 474 | _GL_FUNCDECL_SYS (cbrtl, long double, (long double x), ); |
| 462 | # endif | 475 | # endif |
| 463 | _GL_CXXALIAS_SYS (cbrtl, long double, (long double x)); | 476 | _GL_CXXALIAS_SYS (cbrtl, long double, (long double x)); |
| 464 | # endif | 477 | # endif |
| @@ -480,12 +493,12 @@ _GL_WARN_ON_USE (cbrtl, "cbrtl is unportable - " | |||
| 480 | # undef ceilf | 493 | # undef ceilf |
| 481 | # define ceilf rpl_ceilf | 494 | # define ceilf rpl_ceilf |
| 482 | # endif | 495 | # endif |
| 483 | _GL_FUNCDECL_RPL (ceilf, float, (float x)); | 496 | _GL_FUNCDECL_RPL (ceilf, float, (float x), ); |
| 484 | _GL_CXXALIAS_RPL (ceilf, float, (float x)); | 497 | _GL_CXXALIAS_RPL (ceilf, float, (float x)); |
| 485 | # else | 498 | # else |
| 486 | # if !@HAVE_DECL_CEILF@ | 499 | # if !@HAVE_DECL_CEILF@ |
| 487 | # undef ceilf | 500 | # undef ceilf |
| 488 | _GL_FUNCDECL_SYS (ceilf, float, (float x)); | 501 | _GL_FUNCDECL_SYS (ceilf, float, (float x), ); |
| 489 | # endif | 502 | # endif |
| 490 | _GL_CXXALIAS_SYS (ceilf, float, (float x)); | 503 | _GL_CXXALIAS_SYS (ceilf, float, (float x)); |
| 491 | # endif | 504 | # endif |
| @@ -504,7 +517,7 @@ _GL_WARN_ON_USE (ceilf, "ceilf is unportable - " | |||
| 504 | # undef ceil | 517 | # undef ceil |
| 505 | # define ceil rpl_ceil | 518 | # define ceil rpl_ceil |
| 506 | # endif | 519 | # endif |
| 507 | _GL_FUNCDECL_RPL (ceil, double, (double x)); | 520 | _GL_FUNCDECL_RPL (ceil, double, (double x), ); |
| 508 | _GL_CXXALIAS_RPL (ceil, double, (double x)); | 521 | _GL_CXXALIAS_RPL (ceil, double, (double x)); |
| 509 | # else | 522 | # else |
| 510 | _GL_CXXALIAS_SYS (ceil, double, (double x)); | 523 | _GL_CXXALIAS_SYS (ceil, double, (double x)); |
| @@ -520,12 +533,12 @@ _GL_CXXALIASWARN1 (ceil, double, (double x)); | |||
| 520 | # undef ceill | 533 | # undef ceill |
| 521 | # define ceill rpl_ceill | 534 | # define ceill rpl_ceill |
| 522 | # endif | 535 | # endif |
| 523 | _GL_FUNCDECL_RPL (ceill, long double, (long double x)); | 536 | _GL_FUNCDECL_RPL (ceill, long double, (long double x), ); |
| 524 | _GL_CXXALIAS_RPL (ceill, long double, (long double x)); | 537 | _GL_CXXALIAS_RPL (ceill, long double, (long double x)); |
| 525 | # else | 538 | # else |
| 526 | # if !@HAVE_DECL_CEILL@ | 539 | # if !@HAVE_DECL_CEILL@ |
| 527 | # undef ceill | 540 | # undef ceill |
| 528 | _GL_FUNCDECL_SYS (ceill, long double, (long double x)); | 541 | _GL_FUNCDECL_SYS (ceill, long double, (long double x), ); |
| 529 | # endif | 542 | # endif |
| 530 | _GL_CXXALIAS_SYS (ceill, long double, (long double x)); | 543 | _GL_CXXALIAS_SYS (ceill, long double, (long double x)); |
| 531 | # endif | 544 | # endif |
| @@ -544,7 +557,7 @@ _GL_WARN_ON_USE (ceill, "ceill is unportable - " | |||
| 544 | #if @GNULIB_COPYSIGNF@ | 557 | #if @GNULIB_COPYSIGNF@ |
| 545 | # if !@HAVE_DECL_COPYSIGNF@ | 558 | # if !@HAVE_DECL_COPYSIGNF@ |
| 546 | # undef copysignf | 559 | # undef copysignf |
| 547 | _GL_FUNCDECL_SYS (copysignf, float, (float x, float y)); | 560 | _GL_FUNCDECL_SYS (copysignf, float, (float x, float y), ); |
| 548 | # endif | 561 | # endif |
| 549 | _GL_CXXALIAS_SYS (copysignf, float, (float x, float y)); | 562 | _GL_CXXALIAS_SYS (copysignf, float, (float x, float y)); |
| 550 | _GL_CXXALIASWARN (copysignf); | 563 | _GL_CXXALIASWARN (copysignf); |
| @@ -558,7 +571,7 @@ _GL_WARN_ON_USE (copysignf, "copysignf is unportable - " | |||
| 558 | 571 | ||
| 559 | #if @GNULIB_COPYSIGN@ | 572 | #if @GNULIB_COPYSIGN@ |
| 560 | # if !@HAVE_COPYSIGN@ | 573 | # if !@HAVE_COPYSIGN@ |
| 561 | _GL_FUNCDECL_SYS (copysign, double, (double x, double y)); | 574 | _GL_FUNCDECL_SYS (copysign, double, (double x, double y), ); |
| 562 | # endif | 575 | # endif |
| 563 | _GL_CXXALIAS_SYS (copysign, double, (double x, double y)); | 576 | _GL_CXXALIAS_SYS (copysign, double, (double x, double y)); |
| 564 | # if __GLIBC__ >= 2 | 577 | # if __GLIBC__ >= 2 |
| @@ -574,7 +587,7 @@ _GL_WARN_ON_USE (copysign, "copysign is unportable - " | |||
| 574 | 587 | ||
| 575 | #if @GNULIB_COPYSIGNL@ | 588 | #if @GNULIB_COPYSIGNL@ |
| 576 | # if !@HAVE_COPYSIGNL@ | 589 | # if !@HAVE_COPYSIGNL@ |
| 577 | _GL_FUNCDECL_SYS (copysignl, long double, (long double x, long double y)); | 590 | _GL_FUNCDECL_SYS (copysignl, long double, (long double x, long double y), ); |
| 578 | # endif | 591 | # endif |
| 579 | _GL_CXXALIAS_SYS (copysignl, long double, (long double x, long double y)); | 592 | _GL_CXXALIAS_SYS (copysignl, long double, (long double x, long double y)); |
| 580 | # if __GLIBC__ >= 2 | 593 | # if __GLIBC__ >= 2 |
| @@ -595,12 +608,12 @@ _GL_WARN_ON_USE (copysign, "copysignl is unportable - " | |||
| 595 | # undef cosf | 608 | # undef cosf |
| 596 | # define cosf rpl_cosf | 609 | # define cosf rpl_cosf |
| 597 | # endif | 610 | # endif |
| 598 | _GL_FUNCDECL_RPL (cosf, float, (float x)); | 611 | _GL_FUNCDECL_RPL (cosf, float, (float x), ); |
| 599 | _GL_CXXALIAS_RPL (cosf, float, (float x)); | 612 | _GL_CXXALIAS_RPL (cosf, float, (float x)); |
| 600 | # else | 613 | # else |
| 601 | # if !@HAVE_COSF@ | 614 | # if !@HAVE_COSF@ |
| 602 | # undef cosf | 615 | # undef cosf |
| 603 | _GL_FUNCDECL_SYS (cosf, float, (float x)); | 616 | _GL_FUNCDECL_SYS (cosf, float, (float x), ); |
| 604 | # endif | 617 | # endif |
| 605 | _GL_CXXALIAS_SYS (cosf, float, (float x)); | 618 | _GL_CXXALIAS_SYS (cosf, float, (float x)); |
| 606 | # endif | 619 | # endif |
| @@ -616,7 +629,7 @@ _GL_WARN_ON_USE (cosf, "cosf is unportable - " | |||
| 616 | #if @GNULIB_COSL@ | 629 | #if @GNULIB_COSL@ |
| 617 | # if !@HAVE_COSL@ || !@HAVE_DECL_COSL@ | 630 | # if !@HAVE_COSL@ || !@HAVE_DECL_COSL@ |
| 618 | # undef cosl | 631 | # undef cosl |
| 619 | _GL_FUNCDECL_SYS (cosl, long double, (long double x)); | 632 | _GL_FUNCDECL_SYS (cosl, long double, (long double x), ); |
| 620 | # endif | 633 | # endif |
| 621 | _GL_CXXALIAS_SYS (cosl, long double, (long double x)); | 634 | _GL_CXXALIAS_SYS (cosl, long double, (long double x)); |
| 622 | # if __GLIBC__ >= 2 | 635 | # if __GLIBC__ >= 2 |
| @@ -637,12 +650,12 @@ _GL_WARN_ON_USE (cosl, "cosl is unportable - " | |||
| 637 | # undef coshf | 650 | # undef coshf |
| 638 | # define coshf rpl_coshf | 651 | # define coshf rpl_coshf |
| 639 | # endif | 652 | # endif |
| 640 | _GL_FUNCDECL_RPL (coshf, float, (float x)); | 653 | _GL_FUNCDECL_RPL (coshf, float, (float x), ); |
| 641 | _GL_CXXALIAS_RPL (coshf, float, (float x)); | 654 | _GL_CXXALIAS_RPL (coshf, float, (float x)); |
| 642 | # else | 655 | # else |
| 643 | # if !@HAVE_COSHF@ | 656 | # if !@HAVE_COSHF@ |
| 644 | # undef coshf | 657 | # undef coshf |
| 645 | _GL_FUNCDECL_SYS (coshf, float, (float x)); | 658 | _GL_FUNCDECL_SYS (coshf, float, (float x), ); |
| 646 | # endif | 659 | # endif |
| 647 | _GL_CXXALIAS_SYS (coshf, float, (float x)); | 660 | _GL_CXXALIAS_SYS (coshf, float, (float x)); |
| 648 | # endif | 661 | # endif |
| @@ -662,12 +675,12 @@ _GL_WARN_ON_USE (coshf, "coshf is unportable - " | |||
| 662 | # undef expf | 675 | # undef expf |
| 663 | # define expf rpl_expf | 676 | # define expf rpl_expf |
| 664 | # endif | 677 | # endif |
| 665 | _GL_FUNCDECL_RPL (expf, float, (float x)); | 678 | _GL_FUNCDECL_RPL (expf, float, (float x), ); |
| 666 | _GL_CXXALIAS_RPL (expf, float, (float x)); | 679 | _GL_CXXALIAS_RPL (expf, float, (float x)); |
| 667 | # else | 680 | # else |
| 668 | # if !@HAVE_EXPF@ | 681 | # if !@HAVE_EXPF@ |
| 669 | # undef expf | 682 | # undef expf |
| 670 | _GL_FUNCDECL_SYS (expf, float, (float x)); | 683 | _GL_FUNCDECL_SYS (expf, float, (float x), ); |
| 671 | # endif | 684 | # endif |
| 672 | _GL_CXXALIAS_SYS (expf, float, (float x)); | 685 | _GL_CXXALIAS_SYS (expf, float, (float x)); |
| 673 | # endif | 686 | # endif |
| @@ -686,12 +699,12 @@ _GL_WARN_ON_USE (expf, "expf is unportable - " | |||
| 686 | # undef expl | 699 | # undef expl |
| 687 | # define expl rpl_expl | 700 | # define expl rpl_expl |
| 688 | # endif | 701 | # endif |
| 689 | _GL_FUNCDECL_RPL (expl, long double, (long double x)); | 702 | _GL_FUNCDECL_RPL (expl, long double, (long double x), ); |
| 690 | _GL_CXXALIAS_RPL (expl, long double, (long double x)); | 703 | _GL_CXXALIAS_RPL (expl, long double, (long double x)); |
| 691 | # else | 704 | # else |
| 692 | # if !@HAVE_EXPL@ || !@HAVE_DECL_EXPL@ | 705 | # if !@HAVE_EXPL@ || !@HAVE_DECL_EXPL@ |
| 693 | # undef expl | 706 | # undef expl |
| 694 | _GL_FUNCDECL_SYS (expl, long double, (long double x)); | 707 | _GL_FUNCDECL_SYS (expl, long double, (long double x), ); |
| 695 | # endif | 708 | # endif |
| 696 | _GL_CXXALIAS_SYS (expl, long double, (long double x)); | 709 | _GL_CXXALIAS_SYS (expl, long double, (long double x)); |
| 697 | # endif | 710 | # endif |
| @@ -709,7 +722,7 @@ _GL_WARN_ON_USE (expl, "expl is unportable - " | |||
| 709 | 722 | ||
| 710 | #if @GNULIB_EXP2F@ | 723 | #if @GNULIB_EXP2F@ |
| 711 | # if !@HAVE_DECL_EXP2F@ | 724 | # if !@HAVE_DECL_EXP2F@ |
| 712 | _GL_FUNCDECL_SYS (exp2f, float, (float x)); | 725 | _GL_FUNCDECL_SYS (exp2f, float, (float x), ); |
| 713 | # endif | 726 | # endif |
| 714 | _GL_CXXALIAS_SYS (exp2f, float, (float x)); | 727 | _GL_CXXALIAS_SYS (exp2f, float, (float x)); |
| 715 | _GL_CXXALIASWARN (exp2f); | 728 | _GL_CXXALIASWARN (exp2f); |
| @@ -727,11 +740,11 @@ _GL_WARN_ON_USE (exp2f, "exp2f is unportable - " | |||
| 727 | # undef exp2 | 740 | # undef exp2 |
| 728 | # define exp2 rpl_exp2 | 741 | # define exp2 rpl_exp2 |
| 729 | # endif | 742 | # endif |
| 730 | _GL_FUNCDECL_RPL (exp2, double, (double x)); | 743 | _GL_FUNCDECL_RPL (exp2, double, (double x), ); |
| 731 | _GL_CXXALIAS_RPL (exp2, double, (double x)); | 744 | _GL_CXXALIAS_RPL (exp2, double, (double x)); |
| 732 | # else | 745 | # else |
| 733 | # if !@HAVE_DECL_EXP2@ | 746 | # if !@HAVE_DECL_EXP2@ |
| 734 | _GL_FUNCDECL_SYS (exp2, double, (double x)); | 747 | _GL_FUNCDECL_SYS (exp2, double, (double x), ); |
| 735 | # endif | 748 | # endif |
| 736 | _GL_CXXALIAS_SYS (exp2, double, (double x)); | 749 | _GL_CXXALIAS_SYS (exp2, double, (double x)); |
| 737 | # endif | 750 | # endif |
| @@ -752,12 +765,12 @@ _GL_WARN_ON_USE (exp2, "exp2 is unportable - " | |||
| 752 | # undef exp2l | 765 | # undef exp2l |
| 753 | # define exp2l rpl_exp2l | 766 | # define exp2l rpl_exp2l |
| 754 | # endif | 767 | # endif |
| 755 | _GL_FUNCDECL_RPL (exp2l, long double, (long double x)); | 768 | _GL_FUNCDECL_RPL (exp2l, long double, (long double x), ); |
| 756 | _GL_CXXALIAS_RPL (exp2l, long double, (long double x)); | 769 | _GL_CXXALIAS_RPL (exp2l, long double, (long double x)); |
| 757 | # else | 770 | # else |
| 758 | # if !@HAVE_DECL_EXP2L@ | 771 | # if !@HAVE_DECL_EXP2L@ |
| 759 | # undef exp2l | 772 | # undef exp2l |
| 760 | _GL_FUNCDECL_SYS (exp2l, long double, (long double x)); | 773 | _GL_FUNCDECL_SYS (exp2l, long double, (long double x), ); |
| 761 | # endif | 774 | # endif |
| 762 | _GL_CXXALIAS_SYS (exp2l, long double, (long double x)); | 775 | _GL_CXXALIAS_SYS (exp2l, long double, (long double x)); |
| 763 | # endif | 776 | # endif |
| @@ -779,11 +792,11 @@ _GL_WARN_ON_USE (exp2l, "exp2l is unportable - " | |||
| 779 | # undef expm1f | 792 | # undef expm1f |
| 780 | # define expm1f rpl_expm1f | 793 | # define expm1f rpl_expm1f |
| 781 | # endif | 794 | # endif |
| 782 | _GL_FUNCDECL_RPL (expm1f, float, (float x)); | 795 | _GL_FUNCDECL_RPL (expm1f, float, (float x), ); |
| 783 | _GL_CXXALIAS_RPL (expm1f, float, (float x)); | 796 | _GL_CXXALIAS_RPL (expm1f, float, (float x)); |
| 784 | # else | 797 | # else |
| 785 | # if !@HAVE_EXPM1F@ | 798 | # if !@HAVE_EXPM1F@ |
| 786 | _GL_FUNCDECL_SYS (expm1f, float, (float x)); | 799 | _GL_FUNCDECL_SYS (expm1f, float, (float x), ); |
| 787 | # endif | 800 | # endif |
| 788 | _GL_CXXALIAS_SYS (expm1f, float, (float x)); | 801 | _GL_CXXALIAS_SYS (expm1f, float, (float x)); |
| 789 | # endif | 802 | # endif |
| @@ -802,11 +815,11 @@ _GL_WARN_ON_USE (expm1f, "expm1f is unportable - " | |||
| 802 | # undef expm1 | 815 | # undef expm1 |
| 803 | # define expm1 rpl_expm1 | 816 | # define expm1 rpl_expm1 |
| 804 | # endif | 817 | # endif |
| 805 | _GL_FUNCDECL_RPL (expm1, double, (double x)); | 818 | _GL_FUNCDECL_RPL (expm1, double, (double x), ); |
| 806 | _GL_CXXALIAS_RPL (expm1, double, (double x)); | 819 | _GL_CXXALIAS_RPL (expm1, double, (double x)); |
| 807 | # else | 820 | # else |
| 808 | # if !@HAVE_EXPM1@ | 821 | # if !@HAVE_EXPM1@ |
| 809 | _GL_FUNCDECL_SYS (expm1, double, (double x)); | 822 | _GL_FUNCDECL_SYS (expm1, double, (double x), ); |
| 810 | # endif | 823 | # endif |
| 811 | _GL_CXXALIAS_SYS (expm1, double, (double x)); | 824 | _GL_CXXALIAS_SYS (expm1, double, (double x)); |
| 812 | # endif | 825 | # endif |
| @@ -827,13 +840,13 @@ _GL_WARN_ON_USE (expm1, "expm1 is unportable - " | |||
| 827 | # undef expm1l | 840 | # undef expm1l |
| 828 | # define expm1l rpl_expm1l | 841 | # define expm1l rpl_expm1l |
| 829 | # endif | 842 | # endif |
| 830 | _GL_FUNCDECL_RPL (expm1l, long double, (long double x)); | 843 | _GL_FUNCDECL_RPL (expm1l, long double, (long double x), ); |
| 831 | _GL_CXXALIAS_RPL (expm1l, long double, (long double x)); | 844 | _GL_CXXALIAS_RPL (expm1l, long double, (long double x)); |
| 832 | # else | 845 | # else |
| 833 | # if !@HAVE_DECL_EXPM1L@ | 846 | # if !@HAVE_DECL_EXPM1L@ |
| 834 | # undef expm1l | 847 | # undef expm1l |
| 835 | # if !(defined __cplusplus && defined _AIX) | 848 | # if !(defined __cplusplus && defined _AIX) |
| 836 | _GL_FUNCDECL_SYS (expm1l, long double, (long double x)); | 849 | _GL_FUNCDECL_SYS (expm1l, long double, (long double x), ); |
| 837 | # endif | 850 | # endif |
| 838 | # endif | 851 | # endif |
| 839 | _GL_CXXALIAS_SYS (expm1l, long double, (long double x)); | 852 | _GL_CXXALIAS_SYS (expm1l, long double, (long double x)); |
| @@ -853,7 +866,7 @@ _GL_WARN_ON_USE (expm1l, "expm1l is unportable - " | |||
| 853 | #if @GNULIB_FABSF@ | 866 | #if @GNULIB_FABSF@ |
| 854 | # if !@HAVE_FABSF@ | 867 | # if !@HAVE_FABSF@ |
| 855 | # undef fabsf | 868 | # undef fabsf |
| 856 | _GL_FUNCDECL_SYS (fabsf, float, (float x)); | 869 | _GL_FUNCDECL_SYS (fabsf, float, (float x), ); |
| 857 | # endif | 870 | # endif |
| 858 | _GL_CXXALIAS_SYS (fabsf, float, (float x)); | 871 | _GL_CXXALIAS_SYS (fabsf, float, (float x)); |
| 859 | # if __GLIBC__ >= 2 | 872 | # if __GLIBC__ >= 2 |
| @@ -873,12 +886,12 @@ _GL_WARN_ON_USE (fabsf, "fabsf is unportable - " | |||
| 873 | # undef fabsl | 886 | # undef fabsl |
| 874 | # define fabsl rpl_fabsl | 887 | # define fabsl rpl_fabsl |
| 875 | # endif | 888 | # endif |
| 876 | _GL_FUNCDECL_RPL (fabsl, long double, (long double x)); | 889 | _GL_FUNCDECL_RPL (fabsl, long double, (long double x), ); |
| 877 | _GL_CXXALIAS_RPL (fabsl, long double, (long double x)); | 890 | _GL_CXXALIAS_RPL (fabsl, long double, (long double x)); |
| 878 | # else | 891 | # else |
| 879 | # if !@HAVE_FABSL@ | 892 | # if !@HAVE_FABSL@ |
| 880 | # undef fabsl | 893 | # undef fabsl |
| 881 | _GL_FUNCDECL_SYS (fabsl, long double, (long double x)); | 894 | _GL_FUNCDECL_SYS (fabsl, long double, (long double x), ); |
| 882 | # endif | 895 | # endif |
| 883 | _GL_CXXALIAS_SYS (fabsl, long double, (long double x)); | 896 | _GL_CXXALIAS_SYS (fabsl, long double, (long double x)); |
| 884 | # endif | 897 | # endif |
| @@ -900,12 +913,12 @@ _GL_WARN_ON_USE (fabsl, "fabsl is unportable - " | |||
| 900 | # undef floorf | 913 | # undef floorf |
| 901 | # define floorf rpl_floorf | 914 | # define floorf rpl_floorf |
| 902 | # endif | 915 | # endif |
| 903 | _GL_FUNCDECL_RPL (floorf, float, (float x)); | 916 | _GL_FUNCDECL_RPL (floorf, float, (float x), ); |
| 904 | _GL_CXXALIAS_RPL (floorf, float, (float x)); | 917 | _GL_CXXALIAS_RPL (floorf, float, (float x)); |
| 905 | # else | 918 | # else |
| 906 | # if !@HAVE_DECL_FLOORF@ | 919 | # if !@HAVE_DECL_FLOORF@ |
| 907 | # undef floorf | 920 | # undef floorf |
| 908 | _GL_FUNCDECL_SYS (floorf, float, (float x)); | 921 | _GL_FUNCDECL_SYS (floorf, float, (float x), ); |
| 909 | # endif | 922 | # endif |
| 910 | _GL_CXXALIAS_SYS (floorf, float, (float x)); | 923 | _GL_CXXALIAS_SYS (floorf, float, (float x)); |
| 911 | # endif | 924 | # endif |
| @@ -924,7 +937,7 @@ _GL_WARN_ON_USE (floorf, "floorf is unportable - " | |||
| 924 | # undef floor | 937 | # undef floor |
| 925 | # define floor rpl_floor | 938 | # define floor rpl_floor |
| 926 | # endif | 939 | # endif |
| 927 | _GL_FUNCDECL_RPL (floor, double, (double x)); | 940 | _GL_FUNCDECL_RPL (floor, double, (double x), ); |
| 928 | _GL_CXXALIAS_RPL (floor, double, (double x)); | 941 | _GL_CXXALIAS_RPL (floor, double, (double x)); |
| 929 | # else | 942 | # else |
| 930 | _GL_CXXALIAS_SYS (floor, double, (double x)); | 943 | _GL_CXXALIAS_SYS (floor, double, (double x)); |
| @@ -940,12 +953,12 @@ _GL_CXXALIASWARN1 (floor, double, (double x)); | |||
| 940 | # undef floorl | 953 | # undef floorl |
| 941 | # define floorl rpl_floorl | 954 | # define floorl rpl_floorl |
| 942 | # endif | 955 | # endif |
| 943 | _GL_FUNCDECL_RPL (floorl, long double, (long double x)); | 956 | _GL_FUNCDECL_RPL (floorl, long double, (long double x), ); |
| 944 | _GL_CXXALIAS_RPL (floorl, long double, (long double x)); | 957 | _GL_CXXALIAS_RPL (floorl, long double, (long double x)); |
| 945 | # else | 958 | # else |
| 946 | # if !@HAVE_DECL_FLOORL@ | 959 | # if !@HAVE_DECL_FLOORL@ |
| 947 | # undef floorl | 960 | # undef floorl |
| 948 | _GL_FUNCDECL_SYS (floorl, long double, (long double x)); | 961 | _GL_FUNCDECL_SYS (floorl, long double, (long double x), ); |
| 949 | # endif | 962 | # endif |
| 950 | _GL_CXXALIAS_SYS (floorl, long double, (long double x)); | 963 | _GL_CXXALIAS_SYS (floorl, long double, (long double x)); |
| 951 | # endif | 964 | # endif |
| @@ -967,12 +980,12 @@ _GL_WARN_ON_USE (floorl, "floorl is unportable - " | |||
| 967 | # undef fmaf | 980 | # undef fmaf |
| 968 | # define fmaf rpl_fmaf | 981 | # define fmaf rpl_fmaf |
| 969 | # endif | 982 | # endif |
| 970 | _GL_FUNCDECL_RPL (fmaf, float, (float x, float y, float z)); | 983 | _GL_FUNCDECL_RPL (fmaf, float, (float x, float y, float z), ); |
| 971 | _GL_CXXALIAS_RPL (fmaf, float, (float x, float y, float z)); | 984 | _GL_CXXALIAS_RPL (fmaf, float, (float x, float y, float z)); |
| 972 | # else | 985 | # else |
| 973 | # if !@HAVE_FMAF@ | 986 | # if !@HAVE_FMAF@ |
| 974 | # undef fmaf | 987 | # undef fmaf |
| 975 | _GL_FUNCDECL_SYS (fmaf, float, (float x, float y, float z)); | 988 | _GL_FUNCDECL_SYS (fmaf, float, (float x, float y, float z), ); |
| 976 | # endif | 989 | # endif |
| 977 | _GL_CXXALIAS_SYS (fmaf, float, (float x, float y, float z)); | 990 | _GL_CXXALIAS_SYS (fmaf, float, (float x, float y, float z)); |
| 978 | # endif | 991 | # endif |
| @@ -991,12 +1004,12 @@ _GL_WARN_ON_USE (fmaf, "fmaf is unportable - " | |||
| 991 | # undef fma | 1004 | # undef fma |
| 992 | # define fma rpl_fma | 1005 | # define fma rpl_fma |
| 993 | # endif | 1006 | # endif |
| 994 | _GL_FUNCDECL_RPL (fma, double, (double x, double y, double z)); | 1007 | _GL_FUNCDECL_RPL (fma, double, (double x, double y, double z), ); |
| 995 | _GL_CXXALIAS_RPL (fma, double, (double x, double y, double z)); | 1008 | _GL_CXXALIAS_RPL (fma, double, (double x, double y, double z)); |
| 996 | # else | 1009 | # else |
| 997 | # if !@HAVE_FMA@ | 1010 | # if !@HAVE_FMA@ |
| 998 | # undef fma | 1011 | # undef fma |
| 999 | _GL_FUNCDECL_SYS (fma, double, (double x, double y, double z)); | 1012 | _GL_FUNCDECL_SYS (fma, double, (double x, double y, double z), ); |
| 1000 | # endif | 1013 | # endif |
| 1001 | _GL_CXXALIAS_SYS (fma, double, (double x, double y, double z)); | 1014 | _GL_CXXALIAS_SYS (fma, double, (double x, double y, double z)); |
| 1002 | # endif | 1015 | # endif |
| @@ -1018,7 +1031,7 @@ _GL_WARN_ON_USE (fma, "fma is unportable - " | |||
| 1018 | # define fmal rpl_fmal | 1031 | # define fmal rpl_fmal |
| 1019 | # endif | 1032 | # endif |
| 1020 | _GL_FUNCDECL_RPL (fmal, long double, | 1033 | _GL_FUNCDECL_RPL (fmal, long double, |
| 1021 | (long double x, long double y, long double z)); | 1034 | (long double x, long double y, long double z), ); |
| 1022 | _GL_CXXALIAS_RPL (fmal, long double, | 1035 | _GL_CXXALIAS_RPL (fmal, long double, |
| 1023 | (long double x, long double y, long double z)); | 1036 | (long double x, long double y, long double z)); |
| 1024 | # else | 1037 | # else |
| @@ -1026,7 +1039,7 @@ _GL_CXXALIAS_RPL (fmal, long double, | |||
| 1026 | # undef fmal | 1039 | # undef fmal |
| 1027 | # if !(defined __cplusplus && defined _AIX) | 1040 | # if !(defined __cplusplus && defined _AIX) |
| 1028 | _GL_FUNCDECL_SYS (fmal, long double, | 1041 | _GL_FUNCDECL_SYS (fmal, long double, |
| 1029 | (long double x, long double y, long double z)); | 1042 | (long double x, long double y, long double z), ); |
| 1030 | # endif | 1043 | # endif |
| 1031 | # endif | 1044 | # endif |
| 1032 | _GL_CXXALIAS_SYS (fmal, long double, | 1045 | _GL_CXXALIAS_SYS (fmal, long double, |
| @@ -1050,12 +1063,12 @@ _GL_WARN_ON_USE (fmal, "fmal is unportable - " | |||
| 1050 | # undef fmodf | 1063 | # undef fmodf |
| 1051 | # define fmodf rpl_fmodf | 1064 | # define fmodf rpl_fmodf |
| 1052 | # endif | 1065 | # endif |
| 1053 | _GL_FUNCDECL_RPL (fmodf, float, (float x, float y)); | 1066 | _GL_FUNCDECL_RPL (fmodf, float, (float x, float y), ); |
| 1054 | _GL_CXXALIAS_RPL (fmodf, float, (float x, float y)); | 1067 | _GL_CXXALIAS_RPL (fmodf, float, (float x, float y)); |
| 1055 | # else | 1068 | # else |
| 1056 | # if !@HAVE_FMODF@ | 1069 | # if !@HAVE_FMODF@ |
| 1057 | # undef fmodf | 1070 | # undef fmodf |
| 1058 | _GL_FUNCDECL_SYS (fmodf, float, (float x, float y)); | 1071 | _GL_FUNCDECL_SYS (fmodf, float, (float x, float y), ); |
| 1059 | # endif | 1072 | # endif |
| 1060 | _GL_CXXALIAS_SYS (fmodf, float, (float x, float y)); | 1073 | _GL_CXXALIAS_SYS (fmodf, float, (float x, float y)); |
| 1061 | # endif | 1074 | # endif |
| @@ -1074,7 +1087,7 @@ _GL_WARN_ON_USE (fmodf, "fmodf is unportable - " | |||
| 1074 | # undef fmod | 1087 | # undef fmod |
| 1075 | # define fmod rpl_fmod | 1088 | # define fmod rpl_fmod |
| 1076 | # endif | 1089 | # endif |
| 1077 | _GL_FUNCDECL_RPL (fmod, double, (double x, double y)); | 1090 | _GL_FUNCDECL_RPL (fmod, double, (double x, double y), ); |
| 1078 | _GL_CXXALIAS_RPL (fmod, double, (double x, double y)); | 1091 | _GL_CXXALIAS_RPL (fmod, double, (double x, double y)); |
| 1079 | # else | 1092 | # else |
| 1080 | _GL_CXXALIAS_SYS (fmod, double, (double x, double y)); | 1093 | _GL_CXXALIAS_SYS (fmod, double, (double x, double y)); |
| @@ -1096,12 +1109,12 @@ _GL_WARN_ON_USE (fmod, "fmod has portability problems - " | |||
| 1096 | # undef fmodl | 1109 | # undef fmodl |
| 1097 | # define fmodl rpl_fmodl | 1110 | # define fmodl rpl_fmodl |
| 1098 | # endif | 1111 | # endif |
| 1099 | _GL_FUNCDECL_RPL (fmodl, long double, (long double x, long double y)); | 1112 | _GL_FUNCDECL_RPL (fmodl, long double, (long double x, long double y), ); |
| 1100 | _GL_CXXALIAS_RPL (fmodl, long double, (long double x, long double y)); | 1113 | _GL_CXXALIAS_RPL (fmodl, long double, (long double x, long double y)); |
| 1101 | # else | 1114 | # else |
| 1102 | # if !@HAVE_FMODL@ | 1115 | # if !@HAVE_FMODL@ |
| 1103 | # undef fmodl | 1116 | # undef fmodl |
| 1104 | _GL_FUNCDECL_SYS (fmodl, long double, (long double x, long double y)); | 1117 | _GL_FUNCDECL_SYS (fmodl, long double, (long double x, long double y), ); |
| 1105 | # endif | 1118 | # endif |
| 1106 | _GL_CXXALIAS_SYS (fmodl, long double, (long double x, long double y)); | 1119 | _GL_CXXALIAS_SYS (fmodl, long double, (long double x, long double y)); |
| 1107 | # endif | 1120 | # endif |
| @@ -1130,12 +1143,12 @@ _GL_WARN_ON_USE (fmodl, "fmodl is unportable - " | |||
| 1130 | # undef frexpf | 1143 | # undef frexpf |
| 1131 | # define frexpf rpl_frexpf | 1144 | # define frexpf rpl_frexpf |
| 1132 | # endif | 1145 | # endif |
| 1133 | _GL_FUNCDECL_RPL (frexpf, float, (float x, int *expptr) _GL_ARG_NONNULL ((2))); | 1146 | _GL_FUNCDECL_RPL (frexpf, float, (float x, int *expptr), _GL_ARG_NONNULL ((2))); |
| 1134 | _GL_CXXALIAS_RPL (frexpf, float, (float x, int *expptr)); | 1147 | _GL_CXXALIAS_RPL (frexpf, float, (float x, int *expptr)); |
| 1135 | # else | 1148 | # else |
| 1136 | # if !@HAVE_FREXPF@ | 1149 | # if !@HAVE_FREXPF@ |
| 1137 | # undef frexpf | 1150 | # undef frexpf |
| 1138 | _GL_FUNCDECL_SYS (frexpf, float, (float x, int *expptr) _GL_ARG_NONNULL ((2))); | 1151 | _GL_FUNCDECL_SYS (frexpf, float, (float x, int *expptr), _GL_ARG_NONNULL ((2))); |
| 1139 | # endif | 1152 | # endif |
| 1140 | _GL_CXXALIAS_SYS (frexpf, float, (float x, int *expptr)); | 1153 | _GL_CXXALIAS_SYS (frexpf, float, (float x, int *expptr)); |
| 1141 | # endif | 1154 | # endif |
| @@ -1163,7 +1176,8 @@ _GL_WARN_ON_USE (frexpf, "frexpf is unportable - " | |||
| 1163 | # undef frexp | 1176 | # undef frexp |
| 1164 | # define frexp rpl_frexp | 1177 | # define frexp rpl_frexp |
| 1165 | # endif | 1178 | # endif |
| 1166 | _GL_FUNCDECL_RPL (frexp, double, (double x, int *expptr) _GL_ARG_NONNULL ((2))); | 1179 | _GL_FUNCDECL_RPL (frexp, double, (double x, int *expptr), |
| 1180 | _GL_ARG_NONNULL ((2))); | ||
| 1167 | _GL_CXXALIAS_RPL (frexp, double, (double x, int *expptr)); | 1181 | _GL_CXXALIAS_RPL (frexp, double, (double x, int *expptr)); |
| 1168 | # else | 1182 | # else |
| 1169 | _GL_CXXALIAS_SYS (frexp, double, (double x, int *expptr)); | 1183 | _GL_CXXALIAS_SYS (frexp, double, (double x, int *expptr)); |
| @@ -1174,8 +1188,10 @@ _GL_CXXALIASWARN1 (frexp, double, (double x, int *expptr)); | |||
| 1174 | #elif defined GNULIB_POSIXCHECK | 1188 | #elif defined GNULIB_POSIXCHECK |
| 1175 | # undef frexp | 1189 | # undef frexp |
| 1176 | /* Assume frexp is always declared. */ | 1190 | /* Assume frexp is always declared. */ |
| 1177 | _GL_WARN_ON_USE (frexp, "frexp is unportable - " | 1191 | _GL_WARN_ON_USE_CXX (frexp, |
| 1178 | "use gnulib module frexp for portability"); | 1192 | double, double, (double, int *), |
| 1193 | "frexp is unportable - " | ||
| 1194 | "use gnulib module frexp for portability"); | ||
| 1179 | #endif | 1195 | #endif |
| 1180 | 1196 | ||
| 1181 | /* Write x as | 1197 | /* Write x as |
| @@ -1191,12 +1207,12 @@ _GL_WARN_ON_USE (frexp, "frexp is unportable - " | |||
| 1191 | # define frexpl rpl_frexpl | 1207 | # define frexpl rpl_frexpl |
| 1192 | # endif | 1208 | # endif |
| 1193 | _GL_FUNCDECL_RPL (frexpl, long double, | 1209 | _GL_FUNCDECL_RPL (frexpl, long double, |
| 1194 | (long double x, int *expptr) _GL_ARG_NONNULL ((2))); | 1210 | (long double x, int *expptr), _GL_ARG_NONNULL ((2))); |
| 1195 | _GL_CXXALIAS_RPL (frexpl, long double, (long double x, int *expptr)); | 1211 | _GL_CXXALIAS_RPL (frexpl, long double, (long double x, int *expptr)); |
| 1196 | #else | 1212 | #else |
| 1197 | # if !@HAVE_DECL_FREXPL@ | 1213 | # if !@HAVE_DECL_FREXPL@ |
| 1198 | _GL_FUNCDECL_SYS (frexpl, long double, | 1214 | _GL_FUNCDECL_SYS (frexpl, long double, |
| 1199 | (long double x, int *expptr) _GL_ARG_NONNULL ((2))); | 1215 | (long double x, int *expptr), _GL_ARG_NONNULL ((2))); |
| 1200 | # endif | 1216 | # endif |
| 1201 | # if @GNULIB_FREXPL@ | 1217 | # if @GNULIB_FREXPL@ |
| 1202 | _GL_CXXALIAS_SYS (frexpl, long double, (long double x, int *expptr)); | 1218 | _GL_CXXALIAS_SYS (frexpl, long double, (long double x, int *expptr)); |
| @@ -1223,11 +1239,11 @@ _GL_WARN_ON_USE (frexpl, "frexpl is unportable - " | |||
| 1223 | # undef hypotf | 1239 | # undef hypotf |
| 1224 | # define hypotf rpl_hypotf | 1240 | # define hypotf rpl_hypotf |
| 1225 | # endif | 1241 | # endif |
| 1226 | _GL_FUNCDECL_RPL (hypotf, float, (float x, float y)); | 1242 | _GL_FUNCDECL_RPL (hypotf, float, (float x, float y), ); |
| 1227 | _GL_CXXALIAS_RPL (hypotf, float, (float x, float y)); | 1243 | _GL_CXXALIAS_RPL (hypotf, float, (float x, float y)); |
| 1228 | # else | 1244 | # else |
| 1229 | # if !@HAVE_HYPOTF@ | 1245 | # if !@HAVE_HYPOTF@ |
| 1230 | _GL_FUNCDECL_SYS (hypotf, float, (float x, float y)); | 1246 | _GL_FUNCDECL_SYS (hypotf, float, (float x, float y), ); |
| 1231 | # endif | 1247 | # endif |
| 1232 | _GL_CXXALIAS_SYS (hypotf, float, (float x, float y)); | 1248 | _GL_CXXALIAS_SYS (hypotf, float, (float x, float y)); |
| 1233 | # endif | 1249 | # endif |
| @@ -1249,7 +1265,7 @@ _GL_WARN_ON_USE (hypotf, "hypotf is unportable - " | |||
| 1249 | # undef hypot | 1265 | # undef hypot |
| 1250 | # define hypot rpl_hypot | 1266 | # define hypot rpl_hypot |
| 1251 | # endif | 1267 | # endif |
| 1252 | _GL_FUNCDECL_RPL (hypot, double, (double x, double y)); | 1268 | _GL_FUNCDECL_RPL (hypot, double, (double x, double y), ); |
| 1253 | _GL_CXXALIAS_RPL (hypot, double, (double x, double y)); | 1269 | _GL_CXXALIAS_RPL (hypot, double, (double x, double y)); |
| 1254 | # else | 1270 | # else |
| 1255 | _GL_CXXALIAS_SYS (hypot, double, (double x, double y)); | 1271 | _GL_CXXALIAS_SYS (hypot, double, (double x, double y)); |
| @@ -1272,11 +1288,11 @@ _GL_WARN_ON_USE (hypotf, "hypot has portability problems - " | |||
| 1272 | # undef hypotl | 1288 | # undef hypotl |
| 1273 | # define hypotl rpl_hypotl | 1289 | # define hypotl rpl_hypotl |
| 1274 | # endif | 1290 | # endif |
| 1275 | _GL_FUNCDECL_RPL (hypotl, long double, (long double x, long double y)); | 1291 | _GL_FUNCDECL_RPL (hypotl, long double, (long double x, long double y), ); |
| 1276 | _GL_CXXALIAS_RPL (hypotl, long double, (long double x, long double y)); | 1292 | _GL_CXXALIAS_RPL (hypotl, long double, (long double x, long double y)); |
| 1277 | # else | 1293 | # else |
| 1278 | # if !@HAVE_HYPOTL@ | 1294 | # if !@HAVE_HYPOTL@ |
| 1279 | _GL_FUNCDECL_SYS (hypotl, long double, (long double x, long double y)); | 1295 | _GL_FUNCDECL_SYS (hypotl, long double, (long double x, long double y), ); |
| 1280 | # endif | 1296 | # endif |
| 1281 | _GL_CXXALIAS_SYS (hypotl, long double, (long double x, long double y)); | 1297 | _GL_CXXALIAS_SYS (hypotl, long double, (long double x, long double y)); |
| 1282 | # endif | 1298 | # endif |
| @@ -1298,11 +1314,11 @@ _GL_WARN_ON_USE (hypotl, "hypotl is unportable - " | |||
| 1298 | # undef ilogbf | 1314 | # undef ilogbf |
| 1299 | # define ilogbf rpl_ilogbf | 1315 | # define ilogbf rpl_ilogbf |
| 1300 | # endif | 1316 | # endif |
| 1301 | _GL_FUNCDECL_RPL (ilogbf, int, (float x)); | 1317 | _GL_FUNCDECL_RPL (ilogbf, int, (float x), ); |
| 1302 | _GL_CXXALIAS_RPL (ilogbf, int, (float x)); | 1318 | _GL_CXXALIAS_RPL (ilogbf, int, (float x)); |
| 1303 | # else | 1319 | # else |
| 1304 | # if !@HAVE_ILOGBF@ | 1320 | # if !@HAVE_ILOGBF@ |
| 1305 | _GL_FUNCDECL_SYS (ilogbf, int, (float x)); | 1321 | _GL_FUNCDECL_SYS (ilogbf, int, (float x), ); |
| 1306 | # endif | 1322 | # endif |
| 1307 | _GL_CXXALIAS_SYS (ilogbf, int, (float x)); | 1323 | _GL_CXXALIAS_SYS (ilogbf, int, (float x)); |
| 1308 | # endif | 1324 | # endif |
| @@ -1321,11 +1337,11 @@ _GL_WARN_ON_USE (ilogbf, "ilogbf is unportable - " | |||
| 1321 | # undef ilogb | 1337 | # undef ilogb |
| 1322 | # define ilogb rpl_ilogb | 1338 | # define ilogb rpl_ilogb |
| 1323 | # endif | 1339 | # endif |
| 1324 | _GL_FUNCDECL_RPL (ilogb, int, (double x)); | 1340 | _GL_FUNCDECL_RPL (ilogb, int, (double x), ); |
| 1325 | _GL_CXXALIAS_RPL (ilogb, int, (double x)); | 1341 | _GL_CXXALIAS_RPL (ilogb, int, (double x)); |
| 1326 | # else | 1342 | # else |
| 1327 | # if !@HAVE_ILOGB@ | 1343 | # if !@HAVE_ILOGB@ |
| 1328 | _GL_FUNCDECL_SYS (ilogb, int, (double x)); | 1344 | _GL_FUNCDECL_SYS (ilogb, int, (double x), ); |
| 1329 | # endif | 1345 | # endif |
| 1330 | _GL_CXXALIAS_SYS (ilogb, int, (double x)); | 1346 | _GL_CXXALIAS_SYS (ilogb, int, (double x)); |
| 1331 | # endif | 1347 | # endif |
| @@ -1346,12 +1362,12 @@ _GL_WARN_ON_USE (ilogb, "ilogb is unportable - " | |||
| 1346 | # undef ilogbl | 1362 | # undef ilogbl |
| 1347 | # define ilogbl rpl_ilogbl | 1363 | # define ilogbl rpl_ilogbl |
| 1348 | # endif | 1364 | # endif |
| 1349 | _GL_FUNCDECL_RPL (ilogbl, int, (long double x)); | 1365 | _GL_FUNCDECL_RPL (ilogbl, int, (long double x), ); |
| 1350 | _GL_CXXALIAS_RPL (ilogbl, int, (long double x)); | 1366 | _GL_CXXALIAS_RPL (ilogbl, int, (long double x)); |
| 1351 | # else | 1367 | # else |
| 1352 | # if !@HAVE_ILOGBL@ | 1368 | # if !@HAVE_ILOGBL@ |
| 1353 | # undef ilogbl | 1369 | # undef ilogbl |
| 1354 | _GL_FUNCDECL_SYS (ilogbl, int, (long double x)); | 1370 | _GL_FUNCDECL_SYS (ilogbl, int, (long double x), ); |
| 1355 | # endif | 1371 | # endif |
| 1356 | _GL_CXXALIAS_SYS (ilogbl, int, (long double x)); | 1372 | _GL_CXXALIAS_SYS (ilogbl, int, (long double x)); |
| 1357 | # endif | 1373 | # endif |
| @@ -1420,7 +1436,7 @@ _GL_CXXALIASWARN (jn); | |||
| 1420 | #if @GNULIB_LDEXPF@ | 1436 | #if @GNULIB_LDEXPF@ |
| 1421 | # if !@HAVE_LDEXPF@ | 1437 | # if !@HAVE_LDEXPF@ |
| 1422 | # undef ldexpf | 1438 | # undef ldexpf |
| 1423 | _GL_FUNCDECL_SYS (ldexpf, float, (float x, int exp)); | 1439 | _GL_FUNCDECL_SYS (ldexpf, float, (float x, int exp), ); |
| 1424 | # endif | 1440 | # endif |
| 1425 | _GL_CXXALIAS_SYS (ldexpf, float, (float x, int exp)); | 1441 | _GL_CXXALIAS_SYS (ldexpf, float, (float x, int exp)); |
| 1426 | # if __GLIBC__ >= 2 | 1442 | # if __GLIBC__ >= 2 |
| @@ -1441,7 +1457,7 @@ _GL_WARN_ON_USE (ldexpf, "ldexpf is unportable - " | |||
| 1441 | # undef ldexp | 1457 | # undef ldexp |
| 1442 | # define ldexp rpl_ldexp | 1458 | # define ldexp rpl_ldexp |
| 1443 | # endif | 1459 | # endif |
| 1444 | _GL_FUNCDECL_RPL (ldexp, double, (double x, int exp)); | 1460 | _GL_FUNCDECL_RPL (ldexp, double, (double x, int exp), ); |
| 1445 | _GL_CXXALIAS_RPL (ldexp, double, (double x, int exp)); | 1461 | _GL_CXXALIAS_RPL (ldexp, double, (double x, int exp)); |
| 1446 | # else | 1462 | # else |
| 1447 | /* Assume ldexp is always declared. */ | 1463 | /* Assume ldexp is always declared. */ |
| @@ -1453,8 +1469,10 @@ _GL_CXXALIASWARN1 (ldexp, double, (double x, int exp)); | |||
| 1453 | #elif defined GNULIB_POSIXCHECK | 1469 | #elif defined GNULIB_POSIXCHECK |
| 1454 | # undef ldexp | 1470 | # undef ldexp |
| 1455 | /* Assume ldexp is always declared. */ | 1471 | /* Assume ldexp is always declared. */ |
| 1456 | _GL_WARN_ON_USE (ldexp, "ldexp is unportable - " | 1472 | _GL_WARN_ON_USE_CXX (ldexp, |
| 1457 | "use gnulib module ldexp for portability"); | 1473 | double, double, (double, int), |
| 1474 | "ldexp is unportable - " | ||
| 1475 | "use gnulib module ldexp for portability"); | ||
| 1458 | #endif | 1476 | #endif |
| 1459 | 1477 | ||
| 1460 | /* Return x * 2^exp. */ | 1478 | /* Return x * 2^exp. */ |
| @@ -1463,11 +1481,11 @@ _GL_WARN_ON_USE (ldexp, "ldexp is unportable - " | |||
| 1463 | # undef ldexpl | 1481 | # undef ldexpl |
| 1464 | # define ldexpl rpl_ldexpl | 1482 | # define ldexpl rpl_ldexpl |
| 1465 | # endif | 1483 | # endif |
| 1466 | _GL_FUNCDECL_RPL (ldexpl, long double, (long double x, int exp)); | 1484 | _GL_FUNCDECL_RPL (ldexpl, long double, (long double x, int exp), ); |
| 1467 | _GL_CXXALIAS_RPL (ldexpl, long double, (long double x, int exp)); | 1485 | _GL_CXXALIAS_RPL (ldexpl, long double, (long double x, int exp)); |
| 1468 | #else | 1486 | #else |
| 1469 | # if !@HAVE_DECL_LDEXPL@ | 1487 | # if !@HAVE_DECL_LDEXPL@ |
| 1470 | _GL_FUNCDECL_SYS (ldexpl, long double, (long double x, int exp)); | 1488 | _GL_FUNCDECL_SYS (ldexpl, long double, (long double x, int exp), ); |
| 1471 | # endif | 1489 | # endif |
| 1472 | # if @GNULIB_LDEXPL@ | 1490 | # if @GNULIB_LDEXPL@ |
| 1473 | _GL_CXXALIAS_SYS (ldexpl, long double, (long double x, int exp)); | 1491 | _GL_CXXALIAS_SYS (ldexpl, long double, (long double x, int exp)); |
| @@ -1493,12 +1511,12 @@ _GL_WARN_ON_USE (ldexpl, "ldexpl is unportable - " | |||
| 1493 | # undef logf | 1511 | # undef logf |
| 1494 | # define logf rpl_logf | 1512 | # define logf rpl_logf |
| 1495 | # endif | 1513 | # endif |
| 1496 | _GL_FUNCDECL_RPL (logf, float, (float x)); | 1514 | _GL_FUNCDECL_RPL (logf, float, (float x), ); |
| 1497 | _GL_CXXALIAS_RPL (logf, float, (float x)); | 1515 | _GL_CXXALIAS_RPL (logf, float, (float x)); |
| 1498 | # else | 1516 | # else |
| 1499 | # if !@HAVE_LOGF@ | 1517 | # if !@HAVE_LOGF@ |
| 1500 | # undef logf | 1518 | # undef logf |
| 1501 | _GL_FUNCDECL_SYS (logf, float, (float x)); | 1519 | _GL_FUNCDECL_SYS (logf, float, (float x), ); |
| 1502 | # endif | 1520 | # endif |
| 1503 | _GL_CXXALIAS_SYS (logf, float, (float x)); | 1521 | _GL_CXXALIAS_SYS (logf, float, (float x)); |
| 1504 | # endif | 1522 | # endif |
| @@ -1517,7 +1535,7 @@ _GL_WARN_ON_USE (logf, "logf is unportable - " | |||
| 1517 | # undef log | 1535 | # undef log |
| 1518 | # define log rpl_log | 1536 | # define log rpl_log |
| 1519 | # endif | 1537 | # endif |
| 1520 | _GL_FUNCDECL_RPL (log, double, (double x)); | 1538 | _GL_FUNCDECL_RPL (log, double, (double x), ); |
| 1521 | _GL_CXXALIAS_RPL (log, double, (double x)); | 1539 | _GL_CXXALIAS_RPL (log, double, (double x)); |
| 1522 | # else | 1540 | # else |
| 1523 | _GL_CXXALIAS_SYS (log, double, (double x)); | 1541 | _GL_CXXALIAS_SYS (log, double, (double x)); |
| @@ -1539,12 +1557,12 @@ _GL_WARN_ON_USE (log, "log has portability problems - " | |||
| 1539 | # undef logl | 1557 | # undef logl |
| 1540 | # define logl rpl_logl | 1558 | # define logl rpl_logl |
| 1541 | # endif | 1559 | # endif |
| 1542 | _GL_FUNCDECL_RPL (logl, long double, (long double x)); | 1560 | _GL_FUNCDECL_RPL (logl, long double, (long double x), ); |
| 1543 | _GL_CXXALIAS_RPL (logl, long double, (long double x)); | 1561 | _GL_CXXALIAS_RPL (logl, long double, (long double x)); |
| 1544 | # else | 1562 | # else |
| 1545 | # if !@HAVE_LOGL@ || !@HAVE_DECL_LOGL@ | 1563 | # if !@HAVE_LOGL@ || !@HAVE_DECL_LOGL@ |
| 1546 | # undef logl | 1564 | # undef logl |
| 1547 | _GL_FUNCDECL_SYS (logl, long double, (long double x)); | 1565 | _GL_FUNCDECL_SYS (logl, long double, (long double x), ); |
| 1548 | # endif | 1566 | # endif |
| 1549 | _GL_CXXALIAS_SYS (logl, long double, (long double x)); | 1567 | _GL_CXXALIAS_SYS (logl, long double, (long double x)); |
| 1550 | # endif | 1568 | # endif |
| @@ -1566,12 +1584,12 @@ _GL_WARN_ON_USE (logl, "logl is unportable - " | |||
| 1566 | # undef log10f | 1584 | # undef log10f |
| 1567 | # define log10f rpl_log10f | 1585 | # define log10f rpl_log10f |
| 1568 | # endif | 1586 | # endif |
| 1569 | _GL_FUNCDECL_RPL (log10f, float, (float x)); | 1587 | _GL_FUNCDECL_RPL (log10f, float, (float x), ); |
| 1570 | _GL_CXXALIAS_RPL (log10f, float, (float x)); | 1588 | _GL_CXXALIAS_RPL (log10f, float, (float x)); |
| 1571 | # else | 1589 | # else |
| 1572 | # if !@HAVE_LOG10F@ | 1590 | # if !@HAVE_LOG10F@ |
| 1573 | # undef log10f | 1591 | # undef log10f |
| 1574 | _GL_FUNCDECL_SYS (log10f, float, (float x)); | 1592 | _GL_FUNCDECL_SYS (log10f, float, (float x), ); |
| 1575 | # endif | 1593 | # endif |
| 1576 | _GL_CXXALIAS_SYS (log10f, float, (float x)); | 1594 | _GL_CXXALIAS_SYS (log10f, float, (float x)); |
| 1577 | # endif | 1595 | # endif |
| @@ -1590,7 +1608,7 @@ _GL_WARN_ON_USE (log10f, "log10f is unportable - " | |||
| 1590 | # undef log10 | 1608 | # undef log10 |
| 1591 | # define log10 rpl_log10 | 1609 | # define log10 rpl_log10 |
| 1592 | # endif | 1610 | # endif |
| 1593 | _GL_FUNCDECL_RPL (log10, double, (double x)); | 1611 | _GL_FUNCDECL_RPL (log10, double, (double x), ); |
| 1594 | _GL_CXXALIAS_RPL (log10, double, (double x)); | 1612 | _GL_CXXALIAS_RPL (log10, double, (double x)); |
| 1595 | # else | 1613 | # else |
| 1596 | _GL_CXXALIAS_SYS (log10, double, (double x)); | 1614 | _GL_CXXALIAS_SYS (log10, double, (double x)); |
| @@ -1612,12 +1630,12 @@ _GL_WARN_ON_USE (log10, "log10 has portability problems - " | |||
| 1612 | # undef log10l | 1630 | # undef log10l |
| 1613 | # define log10l rpl_log10l | 1631 | # define log10l rpl_log10l |
| 1614 | # endif | 1632 | # endif |
| 1615 | _GL_FUNCDECL_RPL (log10l, long double, (long double x)); | 1633 | _GL_FUNCDECL_RPL (log10l, long double, (long double x), ); |
| 1616 | _GL_CXXALIAS_RPL (log10l, long double, (long double x)); | 1634 | _GL_CXXALIAS_RPL (log10l, long double, (long double x)); |
| 1617 | # else | 1635 | # else |
| 1618 | # if !@HAVE_LOG10L@ || !@HAVE_DECL_LOG10L@ | 1636 | # if !@HAVE_LOG10L@ || !@HAVE_DECL_LOG10L@ |
| 1619 | # undef log10l | 1637 | # undef log10l |
| 1620 | _GL_FUNCDECL_SYS (log10l, long double, (long double x)); | 1638 | _GL_FUNCDECL_SYS (log10l, long double, (long double x), ); |
| 1621 | # endif | 1639 | # endif |
| 1622 | _GL_CXXALIAS_SYS (log10l, long double, (long double x)); | 1640 | _GL_CXXALIAS_SYS (log10l, long double, (long double x)); |
| 1623 | # endif | 1641 | # endif |
| @@ -1639,11 +1657,11 @@ _GL_WARN_ON_USE (log10l, "log10l is unportable - " | |||
| 1639 | # undef log1pf | 1657 | # undef log1pf |
| 1640 | # define log1pf rpl_log1pf | 1658 | # define log1pf rpl_log1pf |
| 1641 | # endif | 1659 | # endif |
| 1642 | _GL_FUNCDECL_RPL (log1pf, float, (float x)); | 1660 | _GL_FUNCDECL_RPL (log1pf, float, (float x), ); |
| 1643 | _GL_CXXALIAS_RPL (log1pf, float, (float x)); | 1661 | _GL_CXXALIAS_RPL (log1pf, float, (float x)); |
| 1644 | # else | 1662 | # else |
| 1645 | # if !@HAVE_LOG1PF@ | 1663 | # if !@HAVE_LOG1PF@ |
| 1646 | _GL_FUNCDECL_SYS (log1pf, float, (float x)); | 1664 | _GL_FUNCDECL_SYS (log1pf, float, (float x), ); |
| 1647 | # endif | 1665 | # endif |
| 1648 | _GL_CXXALIAS_SYS (log1pf, float, (float x)); | 1666 | _GL_CXXALIAS_SYS (log1pf, float, (float x)); |
| 1649 | # endif | 1667 | # endif |
| @@ -1662,11 +1680,11 @@ _GL_WARN_ON_USE (log1pf, "log1pf is unportable - " | |||
| 1662 | # undef log1p | 1680 | # undef log1p |
| 1663 | # define log1p rpl_log1p | 1681 | # define log1p rpl_log1p |
| 1664 | # endif | 1682 | # endif |
| 1665 | _GL_FUNCDECL_RPL (log1p, double, (double x)); | 1683 | _GL_FUNCDECL_RPL (log1p, double, (double x), ); |
| 1666 | _GL_CXXALIAS_RPL (log1p, double, (double x)); | 1684 | _GL_CXXALIAS_RPL (log1p, double, (double x)); |
| 1667 | # else | 1685 | # else |
| 1668 | # if !@HAVE_LOG1P@ | 1686 | # if !@HAVE_LOG1P@ |
| 1669 | _GL_FUNCDECL_SYS (log1p, double, (double x)); | 1687 | _GL_FUNCDECL_SYS (log1p, double, (double x), ); |
| 1670 | # endif | 1688 | # endif |
| 1671 | _GL_CXXALIAS_SYS (log1p, double, (double x)); | 1689 | _GL_CXXALIAS_SYS (log1p, double, (double x)); |
| 1672 | # endif | 1690 | # endif |
| @@ -1687,11 +1705,11 @@ _GL_WARN_ON_USE (log1p, "log1p has portability problems - " | |||
| 1687 | # undef log1pl | 1705 | # undef log1pl |
| 1688 | # define log1pl rpl_log1pl | 1706 | # define log1pl rpl_log1pl |
| 1689 | # endif | 1707 | # endif |
| 1690 | _GL_FUNCDECL_RPL (log1pl, long double, (long double x)); | 1708 | _GL_FUNCDECL_RPL (log1pl, long double, (long double x), ); |
| 1691 | _GL_CXXALIAS_RPL (log1pl, long double, (long double x)); | 1709 | _GL_CXXALIAS_RPL (log1pl, long double, (long double x)); |
| 1692 | # else | 1710 | # else |
| 1693 | # if !@HAVE_LOG1PL@ | 1711 | # if !@HAVE_LOG1PL@ |
| 1694 | _GL_FUNCDECL_SYS (log1pl, long double, (long double x)); | 1712 | _GL_FUNCDECL_SYS (log1pl, long double, (long double x), ); |
| 1695 | # endif | 1713 | # endif |
| 1696 | _GL_CXXALIAS_SYS (log1pl, long double, (long double x)); | 1714 | _GL_CXXALIAS_SYS (log1pl, long double, (long double x)); |
| 1697 | # endif | 1715 | # endif |
| @@ -1713,12 +1731,12 @@ _GL_WARN_ON_USE (log1pl, "log1pl has portability problems - " | |||
| 1713 | # undef log2f | 1731 | # undef log2f |
| 1714 | # define log2f rpl_log2f | 1732 | # define log2f rpl_log2f |
| 1715 | # endif | 1733 | # endif |
| 1716 | _GL_FUNCDECL_RPL (log2f, float, (float x)); | 1734 | _GL_FUNCDECL_RPL (log2f, float, (float x), ); |
| 1717 | _GL_CXXALIAS_RPL (log2f, float, (float x)); | 1735 | _GL_CXXALIAS_RPL (log2f, float, (float x)); |
| 1718 | # else | 1736 | # else |
| 1719 | # if !@HAVE_DECL_LOG2F@ | 1737 | # if !@HAVE_DECL_LOG2F@ |
| 1720 | # undef log2f | 1738 | # undef log2f |
| 1721 | _GL_FUNCDECL_SYS (log2f, float, (float x)); | 1739 | _GL_FUNCDECL_SYS (log2f, float, (float x), ); |
| 1722 | # endif | 1740 | # endif |
| 1723 | _GL_CXXALIAS_SYS (log2f, float, (float x)); | 1741 | _GL_CXXALIAS_SYS (log2f, float, (float x)); |
| 1724 | # endif | 1742 | # endif |
| @@ -1739,12 +1757,12 @@ _GL_WARN_ON_USE (log2f, "log2f is unportable - " | |||
| 1739 | # undef log2 | 1757 | # undef log2 |
| 1740 | # define log2 rpl_log2 | 1758 | # define log2 rpl_log2 |
| 1741 | # endif | 1759 | # endif |
| 1742 | _GL_FUNCDECL_RPL (log2, double, (double x)); | 1760 | _GL_FUNCDECL_RPL (log2, double, (double x), ); |
| 1743 | _GL_CXXALIAS_RPL (log2, double, (double x)); | 1761 | _GL_CXXALIAS_RPL (log2, double, (double x)); |
| 1744 | # else | 1762 | # else |
| 1745 | # if !@HAVE_DECL_LOG2@ | 1763 | # if !@HAVE_DECL_LOG2@ |
| 1746 | # undef log2 | 1764 | # undef log2 |
| 1747 | _GL_FUNCDECL_SYS (log2, double, (double x)); | 1765 | _GL_FUNCDECL_SYS (log2, double, (double x), ); |
| 1748 | # endif | 1766 | # endif |
| 1749 | _GL_CXXALIAS_SYS (log2, double, (double x)); | 1767 | _GL_CXXALIAS_SYS (log2, double, (double x)); |
| 1750 | # endif | 1768 | # endif |
| @@ -1765,11 +1783,11 @@ _GL_WARN_ON_USE (log2, "log2 is unportable - " | |||
| 1765 | # undef log2l | 1783 | # undef log2l |
| 1766 | # define log2l rpl_log2l | 1784 | # define log2l rpl_log2l |
| 1767 | # endif | 1785 | # endif |
| 1768 | _GL_FUNCDECL_RPL (log2l, long double, (long double x)); | 1786 | _GL_FUNCDECL_RPL (log2l, long double, (long double x), ); |
| 1769 | _GL_CXXALIAS_RPL (log2l, long double, (long double x)); | 1787 | _GL_CXXALIAS_RPL (log2l, long double, (long double x)); |
| 1770 | # else | 1788 | # else |
| 1771 | # if !@HAVE_DECL_LOG2L@ | 1789 | # if !@HAVE_DECL_LOG2L@ |
| 1772 | _GL_FUNCDECL_SYS (log2l, long double, (long double x)); | 1790 | _GL_FUNCDECL_SYS (log2l, long double, (long double x), ); |
| 1773 | # endif | 1791 | # endif |
| 1774 | _GL_CXXALIAS_SYS (log2l, long double, (long double x)); | 1792 | _GL_CXXALIAS_SYS (log2l, long double, (long double x)); |
| 1775 | # endif | 1793 | # endif |
| @@ -1791,11 +1809,11 @@ _GL_WARN_ON_USE (log2l, "log2l is unportable - " | |||
| 1791 | # undef logbf | 1809 | # undef logbf |
| 1792 | # define logbf rpl_logbf | 1810 | # define logbf rpl_logbf |
| 1793 | # endif | 1811 | # endif |
| 1794 | _GL_FUNCDECL_RPL (logbf, float, (float x)); | 1812 | _GL_FUNCDECL_RPL (logbf, float, (float x), ); |
| 1795 | _GL_CXXALIAS_RPL (logbf, float, (float x)); | 1813 | _GL_CXXALIAS_RPL (logbf, float, (float x)); |
| 1796 | # else | 1814 | # else |
| 1797 | # if !@HAVE_LOGBF@ | 1815 | # if !@HAVE_LOGBF@ |
| 1798 | _GL_FUNCDECL_SYS (logbf, float, (float x)); | 1816 | _GL_FUNCDECL_SYS (logbf, float, (float x), ); |
| 1799 | # endif | 1817 | # endif |
| 1800 | _GL_CXXALIAS_SYS (logbf, float, (float x)); | 1818 | _GL_CXXALIAS_SYS (logbf, float, (float x)); |
| 1801 | # endif | 1819 | # endif |
| @@ -1814,11 +1832,11 @@ _GL_WARN_ON_USE (logbf, "logbf is unportable - " | |||
| 1814 | # undef logb | 1832 | # undef logb |
| 1815 | # define logb rpl_logb | 1833 | # define logb rpl_logb |
| 1816 | # endif | 1834 | # endif |
| 1817 | _GL_FUNCDECL_RPL (logb, double, (double x)); | 1835 | _GL_FUNCDECL_RPL (logb, double, (double x), ); |
| 1818 | _GL_CXXALIAS_RPL (logb, double, (double x)); | 1836 | _GL_CXXALIAS_RPL (logb, double, (double x)); |
| 1819 | # else | 1837 | # else |
| 1820 | # if !@HAVE_DECL_LOGB@ | 1838 | # if !@HAVE_DECL_LOGB@ |
| 1821 | _GL_FUNCDECL_SYS (logb, double, (double x)); | 1839 | _GL_FUNCDECL_SYS (logb, double, (double x), ); |
| 1822 | # endif | 1840 | # endif |
| 1823 | _GL_CXXALIAS_SYS (logb, double, (double x)); | 1841 | _GL_CXXALIAS_SYS (logb, double, (double x)); |
| 1824 | # endif | 1842 | # endif |
| @@ -1839,11 +1857,11 @@ _GL_WARN_ON_USE (logb, "logb is unportable - " | |||
| 1839 | # undef logbl | 1857 | # undef logbl |
| 1840 | # define logbl rpl_logbl | 1858 | # define logbl rpl_logbl |
| 1841 | # endif | 1859 | # endif |
| 1842 | _GL_FUNCDECL_RPL (logbl, long double, (long double x)); | 1860 | _GL_FUNCDECL_RPL (logbl, long double, (long double x), ); |
| 1843 | _GL_CXXALIAS_RPL (logbl, long double, (long double x)); | 1861 | _GL_CXXALIAS_RPL (logbl, long double, (long double x)); |
| 1844 | # else | 1862 | # else |
| 1845 | # if !@HAVE_LOGBL@ | 1863 | # if !@HAVE_LOGBL@ |
| 1846 | _GL_FUNCDECL_SYS (logbl, long double, (long double x)); | 1864 | _GL_FUNCDECL_SYS (logbl, long double, (long double x), ); |
| 1847 | # endif | 1865 | # endif |
| 1848 | _GL_CXXALIAS_SYS (logbl, long double, (long double x)); | 1866 | _GL_CXXALIAS_SYS (logbl, long double, (long double x)); |
| 1849 | # endif | 1867 | # endif |
| @@ -1859,18 +1877,67 @@ _GL_WARN_ON_USE (logbl, "logbl is unportable - " | |||
| 1859 | #endif | 1877 | #endif |
| 1860 | 1878 | ||
| 1861 | 1879 | ||
| 1880 | #if @GNULIB_LOGP1F@ | ||
| 1881 | # if !@HAVE_LOGP1F@ | ||
| 1882 | _GL_FUNCDECL_SYS (logp1f, float, (float x), ); | ||
| 1883 | # endif | ||
| 1884 | _GL_CXXALIAS_SYS (logp1f, float, (float x)); | ||
| 1885 | # if __GLIBC__ >= 2 | ||
| 1886 | _GL_CXXALIASWARN1 (logp1f, float, (float x)); | ||
| 1887 | # endif | ||
| 1888 | #elif defined GNULIB_POSIXCHECK | ||
| 1889 | # undef logp1f | ||
| 1890 | # if HAVE_RAW_DECL_LOGP1F | ||
| 1891 | _GL_WARN_ON_USE (logp1f, "logp1f is unportable - " | ||
| 1892 | "use gnulib module logp1f for portability"); | ||
| 1893 | # endif | ||
| 1894 | #endif | ||
| 1895 | |||
| 1896 | #if @GNULIB_LOGP1@ | ||
| 1897 | # if !@HAVE_LOGP1@ | ||
| 1898 | _GL_FUNCDECL_SYS (logp1, double, (double x), ); | ||
| 1899 | # endif | ||
| 1900 | _GL_CXXALIAS_SYS (logp1, double, (double x)); | ||
| 1901 | # if __GLIBC__ >= 2 | ||
| 1902 | _GL_CXXALIASWARN1 (logp1, double, (double x)); | ||
| 1903 | # endif | ||
| 1904 | #elif defined GNULIB_POSIXCHECK | ||
| 1905 | # undef logp1 | ||
| 1906 | # if HAVE_RAW_DECL_LOGP1 | ||
| 1907 | _GL_WARN_ON_USE (logp1, "logp1 is unportable - " | ||
| 1908 | "use gnulib module logp1 for portability"); | ||
| 1909 | # endif | ||
| 1910 | #endif | ||
| 1911 | |||
| 1912 | #if @GNULIB_LOGP1L@ | ||
| 1913 | # if !@HAVE_LOGP1L@ | ||
| 1914 | _GL_FUNCDECL_SYS (logp1l, long double, (long double x), ); | ||
| 1915 | # endif | ||
| 1916 | _GL_CXXALIAS_SYS (logp1l, long double, (long double x)); | ||
| 1917 | # if __GLIBC__ >= 2 | ||
| 1918 | _GL_CXXALIASWARN1 (logp1l, long double, (long double x)); | ||
| 1919 | # endif | ||
| 1920 | #elif defined GNULIB_POSIXCHECK | ||
| 1921 | # undef logp1l | ||
| 1922 | # if HAVE_RAW_DECL_LOGP1L | ||
| 1923 | _GL_WARN_ON_USE (logp1l, "logp1l is unportable - " | ||
| 1924 | "use gnulib module logp1l for portability"); | ||
| 1925 | # endif | ||
| 1926 | #endif | ||
| 1927 | |||
| 1928 | |||
| 1862 | #if @GNULIB_MODFF@ | 1929 | #if @GNULIB_MODFF@ |
| 1863 | # if @REPLACE_MODFF@ | 1930 | # if @REPLACE_MODFF@ |
| 1864 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1931 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1865 | # undef modff | 1932 | # undef modff |
| 1866 | # define modff rpl_modff | 1933 | # define modff rpl_modff |
| 1867 | # endif | 1934 | # endif |
| 1868 | _GL_FUNCDECL_RPL (modff, float, (float x, float *iptr) _GL_ARG_NONNULL ((2))); | 1935 | _GL_FUNCDECL_RPL (modff, float, (float x, float *iptr), _GL_ARG_NONNULL ((2))); |
| 1869 | _GL_CXXALIAS_RPL (modff, float, (float x, float *iptr)); | 1936 | _GL_CXXALIAS_RPL (modff, float, (float x, float *iptr)); |
| 1870 | # else | 1937 | # else |
| 1871 | # if !@HAVE_MODFF@ | 1938 | # if !@HAVE_MODFF@ |
| 1872 | # undef modff | 1939 | # undef modff |
| 1873 | _GL_FUNCDECL_SYS (modff, float, (float x, float *iptr) _GL_ARG_NONNULL ((2))); | 1940 | _GL_FUNCDECL_SYS (modff, float, (float x, float *iptr), _GL_ARG_NONNULL ((2))); |
| 1874 | # endif | 1941 | # endif |
| 1875 | _GL_CXXALIAS_SYS (modff, float, (float x, float *iptr)); | 1942 | _GL_CXXALIAS_SYS (modff, float, (float x, float *iptr)); |
| 1876 | # endif | 1943 | # endif |
| @@ -1889,7 +1956,8 @@ _GL_WARN_ON_USE (modff, "modff is unportable - " | |||
| 1889 | # undef modf | 1956 | # undef modf |
| 1890 | # define modf rpl_modf | 1957 | # define modf rpl_modf |
| 1891 | # endif | 1958 | # endif |
| 1892 | _GL_FUNCDECL_RPL (modf, double, (double x, double *iptr) _GL_ARG_NONNULL ((2))); | 1959 | _GL_FUNCDECL_RPL (modf, double, (double x, double *iptr), |
| 1960 | _GL_ARG_NONNULL ((2))); | ||
| 1893 | _GL_CXXALIAS_RPL (modf, double, (double x, double *iptr)); | 1961 | _GL_CXXALIAS_RPL (modf, double, (double x, double *iptr)); |
| 1894 | # else | 1962 | # else |
| 1895 | _GL_CXXALIAS_SYS (modf, double, (double x, double *iptr)); | 1963 | _GL_CXXALIAS_SYS (modf, double, (double x, double *iptr)); |
| @@ -1911,13 +1979,13 @@ _GL_WARN_ON_USE (modf, "modf has portability problems - " | |||
| 1911 | # undef modfl | 1979 | # undef modfl |
| 1912 | # define modfl rpl_modfl | 1980 | # define modfl rpl_modfl |
| 1913 | # endif | 1981 | # endif |
| 1914 | _GL_FUNCDECL_RPL (modfl, long double, (long double x, long double *iptr) | 1982 | _GL_FUNCDECL_RPL (modfl, long double, (long double x, long double *iptr), |
| 1915 | _GL_ARG_NONNULL ((2))); | 1983 | _GL_ARG_NONNULL ((2))); |
| 1916 | _GL_CXXALIAS_RPL (modfl, long double, (long double x, long double *iptr)); | 1984 | _GL_CXXALIAS_RPL (modfl, long double, (long double x, long double *iptr)); |
| 1917 | # else | 1985 | # else |
| 1918 | # if !@HAVE_MODFL@ | 1986 | # if !@HAVE_MODFL@ |
| 1919 | # undef modfl | 1987 | # undef modfl |
| 1920 | _GL_FUNCDECL_SYS (modfl, long double, (long double x, long double *iptr) | 1988 | _GL_FUNCDECL_SYS (modfl, long double, (long double x, long double *iptr), |
| 1921 | _GL_ARG_NONNULL ((2))); | 1989 | _GL_ARG_NONNULL ((2))); |
| 1922 | # endif | 1990 | # endif |
| 1923 | _GL_CXXALIAS_SYS (modfl, long double, (long double x, long double *iptr)); | 1991 | _GL_CXXALIAS_SYS (modfl, long double, (long double x, long double *iptr)); |
| @@ -1937,7 +2005,7 @@ _GL_WARN_ON_USE (modfl, "modfl is unportable - " | |||
| 1937 | #if @GNULIB_POWF@ | 2005 | #if @GNULIB_POWF@ |
| 1938 | # if !@HAVE_POWF@ | 2006 | # if !@HAVE_POWF@ |
| 1939 | # undef powf | 2007 | # undef powf |
| 1940 | _GL_FUNCDECL_SYS (powf, float, (float x, float y)); | 2008 | _GL_FUNCDECL_SYS (powf, float, (float x, float y), ); |
| 1941 | # endif | 2009 | # endif |
| 1942 | _GL_CXXALIAS_SYS (powf, float, (float x, float y)); | 2010 | _GL_CXXALIAS_SYS (powf, float, (float x, float y)); |
| 1943 | _GL_CXXALIASWARN (powf); | 2011 | _GL_CXXALIASWARN (powf); |
| @@ -1956,11 +2024,11 @@ _GL_WARN_ON_USE (powf, "powf is unportable - " | |||
| 1956 | # undef remainderf | 2024 | # undef remainderf |
| 1957 | # define remainderf rpl_remainderf | 2025 | # define remainderf rpl_remainderf |
| 1958 | # endif | 2026 | # endif |
| 1959 | _GL_FUNCDECL_RPL (remainderf, float, (float x, float y)); | 2027 | _GL_FUNCDECL_RPL (remainderf, float, (float x, float y), ); |
| 1960 | _GL_CXXALIAS_RPL (remainderf, float, (float x, float y)); | 2028 | _GL_CXXALIAS_RPL (remainderf, float, (float x, float y)); |
| 1961 | # else | 2029 | # else |
| 1962 | # if !@HAVE_REMAINDERF@ | 2030 | # if !@HAVE_REMAINDERF@ |
| 1963 | _GL_FUNCDECL_SYS (remainderf, float, (float x, float y)); | 2031 | _GL_FUNCDECL_SYS (remainderf, float, (float x, float y), ); |
| 1964 | # endif | 2032 | # endif |
| 1965 | _GL_CXXALIAS_SYS (remainderf, float, (float x, float y)); | 2033 | _GL_CXXALIAS_SYS (remainderf, float, (float x, float y)); |
| 1966 | # endif | 2034 | # endif |
| @@ -1979,11 +2047,11 @@ _GL_WARN_ON_USE (remainderf, "remainderf is unportable - " | |||
| 1979 | # undef remainder | 2047 | # undef remainder |
| 1980 | # define remainder rpl_remainder | 2048 | # define remainder rpl_remainder |
| 1981 | # endif | 2049 | # endif |
| 1982 | _GL_FUNCDECL_RPL (remainder, double, (double x, double y)); | 2050 | _GL_FUNCDECL_RPL (remainder, double, (double x, double y), ); |
| 1983 | _GL_CXXALIAS_RPL (remainder, double, (double x, double y)); | 2051 | _GL_CXXALIAS_RPL (remainder, double, (double x, double y)); |
| 1984 | # else | 2052 | # else |
| 1985 | # if !@HAVE_REMAINDER@ || !@HAVE_DECL_REMAINDER@ | 2053 | # if !@HAVE_REMAINDER@ || !@HAVE_DECL_REMAINDER@ |
| 1986 | _GL_FUNCDECL_SYS (remainder, double, (double x, double y)); | 2054 | _GL_FUNCDECL_SYS (remainder, double, (double x, double y), ); |
| 1987 | # endif | 2055 | # endif |
| 1988 | _GL_CXXALIAS_SYS (remainder, double, (double x, double y)); | 2056 | _GL_CXXALIAS_SYS (remainder, double, (double x, double y)); |
| 1989 | # endif | 2057 | # endif |
| @@ -2004,13 +2072,13 @@ _GL_WARN_ON_USE (remainder, "remainder is unportable - " | |||
| 2004 | # undef remainderl | 2072 | # undef remainderl |
| 2005 | # define remainderl rpl_remainderl | 2073 | # define remainderl rpl_remainderl |
| 2006 | # endif | 2074 | # endif |
| 2007 | _GL_FUNCDECL_RPL (remainderl, long double, (long double x, long double y)); | 2075 | _GL_FUNCDECL_RPL (remainderl, long double, (long double x, long double y), ); |
| 2008 | _GL_CXXALIAS_RPL (remainderl, long double, (long double x, long double y)); | 2076 | _GL_CXXALIAS_RPL (remainderl, long double, (long double x, long double y)); |
| 2009 | # else | 2077 | # else |
| 2010 | # if !@HAVE_DECL_REMAINDERL@ | 2078 | # if !@HAVE_DECL_REMAINDERL@ |
| 2011 | # undef remainderl | 2079 | # undef remainderl |
| 2012 | # if !(defined __cplusplus && defined _AIX) | 2080 | # if !(defined __cplusplus && defined _AIX) |
| 2013 | _GL_FUNCDECL_SYS (remainderl, long double, (long double x, long double y)); | 2081 | _GL_FUNCDECL_SYS (remainderl, long double, (long double x, long double y), ); |
| 2014 | # endif | 2082 | # endif |
| 2015 | # endif | 2083 | # endif |
| 2016 | _GL_CXXALIAS_SYS (remainderl, long double, (long double x, long double y)); | 2084 | _GL_CXXALIAS_SYS (remainderl, long double, (long double x, long double y)); |
| @@ -2029,7 +2097,7 @@ _GL_WARN_ON_USE (remainderl, "remainderl is unportable - " | |||
| 2029 | 2097 | ||
| 2030 | #if @GNULIB_RINTF@ | 2098 | #if @GNULIB_RINTF@ |
| 2031 | # if !@HAVE_DECL_RINTF@ | 2099 | # if !@HAVE_DECL_RINTF@ |
| 2032 | _GL_FUNCDECL_SYS (rintf, float, (float x)); | 2100 | _GL_FUNCDECL_SYS (rintf, float, (float x), ); |
| 2033 | # endif | 2101 | # endif |
| 2034 | _GL_CXXALIAS_SYS (rintf, float, (float x)); | 2102 | _GL_CXXALIAS_SYS (rintf, float, (float x)); |
| 2035 | _GL_CXXALIASWARN (rintf); | 2103 | _GL_CXXALIASWARN (rintf); |
| @@ -2043,7 +2111,7 @@ _GL_WARN_ON_USE (rintf, "rintf is unportable - " | |||
| 2043 | 2111 | ||
| 2044 | #if @GNULIB_RINT@ | 2112 | #if @GNULIB_RINT@ |
| 2045 | # if !@HAVE_RINT@ | 2113 | # if !@HAVE_RINT@ |
| 2046 | _GL_FUNCDECL_SYS (rint, double, (double x)); | 2114 | _GL_FUNCDECL_SYS (rint, double, (double x), ); |
| 2047 | # endif | 2115 | # endif |
| 2048 | _GL_CXXALIAS_SYS (rint, double, (double x)); | 2116 | _GL_CXXALIAS_SYS (rint, double, (double x)); |
| 2049 | # if __GLIBC__ >= 2 | 2117 | # if __GLIBC__ >= 2 |
| @@ -2063,11 +2131,11 @@ _GL_WARN_ON_USE (rint, "rint is unportable - " | |||
| 2063 | # undef rintl | 2131 | # undef rintl |
| 2064 | # define rintl rpl_rintl | 2132 | # define rintl rpl_rintl |
| 2065 | # endif | 2133 | # endif |
| 2066 | _GL_FUNCDECL_RPL (rintl, long double, (long double x)); | 2134 | _GL_FUNCDECL_RPL (rintl, long double, (long double x), ); |
| 2067 | _GL_CXXALIAS_RPL (rintl, long double, (long double x)); | 2135 | _GL_CXXALIAS_RPL (rintl, long double, (long double x)); |
| 2068 | # else | 2136 | # else |
| 2069 | # if !@HAVE_RINTL@ | 2137 | # if !@HAVE_RINTL@ |
| 2070 | _GL_FUNCDECL_SYS (rintl, long double, (long double x)); | 2138 | _GL_FUNCDECL_SYS (rintl, long double, (long double x), ); |
| 2071 | # endif | 2139 | # endif |
| 2072 | _GL_CXXALIAS_SYS (rintl, long double, (long double x)); | 2140 | _GL_CXXALIAS_SYS (rintl, long double, (long double x)); |
| 2073 | # endif | 2141 | # endif |
| @@ -2089,11 +2157,11 @@ _GL_WARN_ON_USE (rintl, "rintl is unportable - " | |||
| 2089 | # undef roundf | 2157 | # undef roundf |
| 2090 | # define roundf rpl_roundf | 2158 | # define roundf rpl_roundf |
| 2091 | # endif | 2159 | # endif |
| 2092 | _GL_FUNCDECL_RPL (roundf, float, (float x)); | 2160 | _GL_FUNCDECL_RPL (roundf, float, (float x), ); |
| 2093 | _GL_CXXALIAS_RPL (roundf, float, (float x)); | 2161 | _GL_CXXALIAS_RPL (roundf, float, (float x)); |
| 2094 | # else | 2162 | # else |
| 2095 | # if !@HAVE_DECL_ROUNDF@ | 2163 | # if !@HAVE_DECL_ROUNDF@ |
| 2096 | _GL_FUNCDECL_SYS (roundf, float, (float x)); | 2164 | _GL_FUNCDECL_SYS (roundf, float, (float x), ); |
| 2097 | # endif | 2165 | # endif |
| 2098 | _GL_CXXALIAS_SYS (roundf, float, (float x)); | 2166 | _GL_CXXALIAS_SYS (roundf, float, (float x)); |
| 2099 | # endif | 2167 | # endif |
| @@ -2112,11 +2180,11 @@ _GL_WARN_ON_USE (roundf, "roundf is unportable - " | |||
| 2112 | # undef round | 2180 | # undef round |
| 2113 | # define round rpl_round | 2181 | # define round rpl_round |
| 2114 | # endif | 2182 | # endif |
| 2115 | _GL_FUNCDECL_RPL (round, double, (double x)); | 2183 | _GL_FUNCDECL_RPL (round, double, (double x), ); |
| 2116 | _GL_CXXALIAS_RPL (round, double, (double x)); | 2184 | _GL_CXXALIAS_RPL (round, double, (double x)); |
| 2117 | # else | 2185 | # else |
| 2118 | # if !@HAVE_DECL_ROUND@ | 2186 | # if !@HAVE_DECL_ROUND@ |
| 2119 | _GL_FUNCDECL_SYS (round, double, (double x)); | 2187 | _GL_FUNCDECL_SYS (round, double, (double x), ); |
| 2120 | # endif | 2188 | # endif |
| 2121 | _GL_CXXALIAS_SYS (round, double, (double x)); | 2189 | _GL_CXXALIAS_SYS (round, double, (double x)); |
| 2122 | # endif | 2190 | # endif |
| @@ -2137,13 +2205,13 @@ _GL_WARN_ON_USE (round, "round is unportable - " | |||
| 2137 | # undef roundl | 2205 | # undef roundl |
| 2138 | # define roundl rpl_roundl | 2206 | # define roundl rpl_roundl |
| 2139 | # endif | 2207 | # endif |
| 2140 | _GL_FUNCDECL_RPL (roundl, long double, (long double x)); | 2208 | _GL_FUNCDECL_RPL (roundl, long double, (long double x), ); |
| 2141 | _GL_CXXALIAS_RPL (roundl, long double, (long double x)); | 2209 | _GL_CXXALIAS_RPL (roundl, long double, (long double x)); |
| 2142 | # else | 2210 | # else |
| 2143 | # if !@HAVE_DECL_ROUNDL@ | 2211 | # if !@HAVE_DECL_ROUNDL@ |
| 2144 | # undef roundl | 2212 | # undef roundl |
| 2145 | # if !(defined __cplusplus && defined _AIX) | 2213 | # if !(defined __cplusplus && defined _AIX) |
| 2146 | _GL_FUNCDECL_SYS (roundl, long double, (long double x)); | 2214 | _GL_FUNCDECL_SYS (roundl, long double, (long double x), ); |
| 2147 | # endif | 2215 | # endif |
| 2148 | # endif | 2216 | # endif |
| 2149 | _GL_CXXALIAS_SYS (roundl, long double, (long double x)); | 2217 | _GL_CXXALIAS_SYS (roundl, long double, (long double x)); |
| @@ -2166,12 +2234,12 @@ _GL_WARN_ON_USE (roundl, "roundl is unportable - " | |||
| 2166 | # undef sinf | 2234 | # undef sinf |
| 2167 | # define sinf rpl_sinf | 2235 | # define sinf rpl_sinf |
| 2168 | # endif | 2236 | # endif |
| 2169 | _GL_FUNCDECL_RPL (sinf, float, (float x)); | 2237 | _GL_FUNCDECL_RPL (sinf, float, (float x), ); |
| 2170 | _GL_CXXALIAS_RPL (sinf, float, (float x)); | 2238 | _GL_CXXALIAS_RPL (sinf, float, (float x)); |
| 2171 | # else | 2239 | # else |
| 2172 | # if !@HAVE_SINF@ | 2240 | # if !@HAVE_SINF@ |
| 2173 | # undef sinf | 2241 | # undef sinf |
| 2174 | _GL_FUNCDECL_SYS (sinf, float, (float x)); | 2242 | _GL_FUNCDECL_SYS (sinf, float, (float x), ); |
| 2175 | # endif | 2243 | # endif |
| 2176 | _GL_CXXALIAS_SYS (sinf, float, (float x)); | 2244 | _GL_CXXALIAS_SYS (sinf, float, (float x)); |
| 2177 | # endif | 2245 | # endif |
| @@ -2185,11 +2253,20 @@ _GL_WARN_ON_USE (sinf, "sinf is unportable - " | |||
| 2185 | #endif | 2253 | #endif |
| 2186 | 2254 | ||
| 2187 | #if @GNULIB_SINL@ | 2255 | #if @GNULIB_SINL@ |
| 2188 | # if !@HAVE_SINL@ || !@HAVE_DECL_SINL@ | 2256 | # if @REPLACE_SINL@ |
| 2189 | # undef sinl | 2257 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 2190 | _GL_FUNCDECL_SYS (sinl, long double, (long double x)); | 2258 | # undef sinl |
| 2191 | # endif | 2259 | # define sinl rpl_sinl |
| 2260 | # endif | ||
| 2261 | _GL_FUNCDECL_RPL (sinl, long double, (long double x), ); | ||
| 2262 | _GL_CXXALIAS_RPL (sinl, long double, (long double x)); | ||
| 2263 | # else | ||
| 2264 | # if !@HAVE_SINL@ || !@HAVE_DECL_SINL@ | ||
| 2265 | # undef sinl | ||
| 2266 | _GL_FUNCDECL_SYS (sinl, long double, (long double x), ); | ||
| 2267 | # endif | ||
| 2192 | _GL_CXXALIAS_SYS (sinl, long double, (long double x)); | 2268 | _GL_CXXALIAS_SYS (sinl, long double, (long double x)); |
| 2269 | # endif | ||
| 2193 | # if __GLIBC__ >= 2 | 2270 | # if __GLIBC__ >= 2 |
| 2194 | _GL_CXXALIASWARN (sinl); | 2271 | _GL_CXXALIASWARN (sinl); |
| 2195 | # endif | 2272 | # endif |
| @@ -2208,12 +2285,12 @@ _GL_WARN_ON_USE (sinl, "sinl is unportable - " | |||
| 2208 | # undef sinhf | 2285 | # undef sinhf |
| 2209 | # define sinhf rpl_sinhf | 2286 | # define sinhf rpl_sinhf |
| 2210 | # endif | 2287 | # endif |
| 2211 | _GL_FUNCDECL_RPL (sinhf, float, (float x)); | 2288 | _GL_FUNCDECL_RPL (sinhf, float, (float x), ); |
| 2212 | _GL_CXXALIAS_RPL (sinhf, float, (float x)); | 2289 | _GL_CXXALIAS_RPL (sinhf, float, (float x)); |
| 2213 | # else | 2290 | # else |
| 2214 | # if !@HAVE_SINHF@ | 2291 | # if !@HAVE_SINHF@ |
| 2215 | # undef sinhf | 2292 | # undef sinhf |
| 2216 | _GL_FUNCDECL_SYS (sinhf, float, (float x)); | 2293 | _GL_FUNCDECL_SYS (sinhf, float, (float x), ); |
| 2217 | # endif | 2294 | # endif |
| 2218 | _GL_CXXALIAS_SYS (sinhf, float, (float x)); | 2295 | _GL_CXXALIAS_SYS (sinhf, float, (float x)); |
| 2219 | # endif | 2296 | # endif |
| @@ -2233,12 +2310,12 @@ _GL_WARN_ON_USE (sinhf, "sinhf is unportable - " | |||
| 2233 | # undef sqrtf | 2310 | # undef sqrtf |
| 2234 | # define sqrtf rpl_sqrtf | 2311 | # define sqrtf rpl_sqrtf |
| 2235 | # endif | 2312 | # endif |
| 2236 | _GL_FUNCDECL_RPL (sqrtf, float, (float x)); | 2313 | _GL_FUNCDECL_RPL (sqrtf, float, (float x), ); |
| 2237 | _GL_CXXALIAS_RPL (sqrtf, float, (float x)); | 2314 | _GL_CXXALIAS_RPL (sqrtf, float, (float x)); |
| 2238 | # else | 2315 | # else |
| 2239 | # if !@HAVE_SQRTF@ | 2316 | # if !@HAVE_SQRTF@ |
| 2240 | # undef sqrtf | 2317 | # undef sqrtf |
| 2241 | _GL_FUNCDECL_SYS (sqrtf, float, (float x)); | 2318 | _GL_FUNCDECL_SYS (sqrtf, float, (float x), ); |
| 2242 | # endif | 2319 | # endif |
| 2243 | _GL_CXXALIAS_SYS (sqrtf, float, (float x)); | 2320 | _GL_CXXALIAS_SYS (sqrtf, float, (float x)); |
| 2244 | # endif | 2321 | # endif |
| @@ -2257,12 +2334,12 @@ _GL_WARN_ON_USE (sqrtf, "sqrtf is unportable - " | |||
| 2257 | # undef sqrtl | 2334 | # undef sqrtl |
| 2258 | # define sqrtl rpl_sqrtl | 2335 | # define sqrtl rpl_sqrtl |
| 2259 | # endif | 2336 | # endif |
| 2260 | _GL_FUNCDECL_RPL (sqrtl, long double, (long double x)); | 2337 | _GL_FUNCDECL_RPL (sqrtl, long double, (long double x), ); |
| 2261 | _GL_CXXALIAS_RPL (sqrtl, long double, (long double x)); | 2338 | _GL_CXXALIAS_RPL (sqrtl, long double, (long double x)); |
| 2262 | # else | 2339 | # else |
| 2263 | # if !@HAVE_SQRTL@ || !@HAVE_DECL_SQRTL@ | 2340 | # if !@HAVE_SQRTL@ || !@HAVE_DECL_SQRTL@ |
| 2264 | # undef sqrtl | 2341 | # undef sqrtl |
| 2265 | _GL_FUNCDECL_SYS (sqrtl, long double, (long double x)); | 2342 | _GL_FUNCDECL_SYS (sqrtl, long double, (long double x), ); |
| 2266 | # endif | 2343 | # endif |
| 2267 | _GL_CXXALIAS_SYS (sqrtl, long double, (long double x)); | 2344 | _GL_CXXALIAS_SYS (sqrtl, long double, (long double x)); |
| 2268 | # endif | 2345 | # endif |
| @@ -2284,12 +2361,12 @@ _GL_WARN_ON_USE (sqrtl, "sqrtl is unportable - " | |||
| 2284 | # undef tanf | 2361 | # undef tanf |
| 2285 | # define tanf rpl_tanf | 2362 | # define tanf rpl_tanf |
| 2286 | # endif | 2363 | # endif |
| 2287 | _GL_FUNCDECL_RPL (tanf, float, (float x)); | 2364 | _GL_FUNCDECL_RPL (tanf, float, (float x), ); |
| 2288 | _GL_CXXALIAS_RPL (tanf, float, (float x)); | 2365 | _GL_CXXALIAS_RPL (tanf, float, (float x)); |
| 2289 | # else | 2366 | # else |
| 2290 | # if !@HAVE_TANF@ | 2367 | # if !@HAVE_TANF@ |
| 2291 | # undef tanf | 2368 | # undef tanf |
| 2292 | _GL_FUNCDECL_SYS (tanf, float, (float x)); | 2369 | _GL_FUNCDECL_SYS (tanf, float, (float x), ); |
| 2293 | # endif | 2370 | # endif |
| 2294 | _GL_CXXALIAS_SYS (tanf, float, (float x)); | 2371 | _GL_CXXALIAS_SYS (tanf, float, (float x)); |
| 2295 | # endif | 2372 | # endif |
| @@ -2305,7 +2382,7 @@ _GL_WARN_ON_USE (tanf, "tanf is unportable - " | |||
| 2305 | #if @GNULIB_TANL@ | 2382 | #if @GNULIB_TANL@ |
| 2306 | # if !@HAVE_TANL@ || !@HAVE_DECL_TANL@ | 2383 | # if !@HAVE_TANL@ || !@HAVE_DECL_TANL@ |
| 2307 | # undef tanl | 2384 | # undef tanl |
| 2308 | _GL_FUNCDECL_SYS (tanl, long double, (long double x)); | 2385 | _GL_FUNCDECL_SYS (tanl, long double, (long double x), ); |
| 2309 | # endif | 2386 | # endif |
| 2310 | _GL_CXXALIAS_SYS (tanl, long double, (long double x)); | 2387 | _GL_CXXALIAS_SYS (tanl, long double, (long double x)); |
| 2311 | # if __GLIBC__ >= 2 | 2388 | # if __GLIBC__ >= 2 |
| @@ -2326,12 +2403,12 @@ _GL_WARN_ON_USE (tanl, "tanl is unportable - " | |||
| 2326 | # undef tanhf | 2403 | # undef tanhf |
| 2327 | # define tanhf rpl_tanhf | 2404 | # define tanhf rpl_tanhf |
| 2328 | # endif | 2405 | # endif |
| 2329 | _GL_FUNCDECL_RPL (tanhf, float, (float x)); | 2406 | _GL_FUNCDECL_RPL (tanhf, float, (float x), ); |
| 2330 | _GL_CXXALIAS_RPL (tanhf, float, (float x)); | 2407 | _GL_CXXALIAS_RPL (tanhf, float, (float x)); |
| 2331 | # else | 2408 | # else |
| 2332 | # if !@HAVE_TANHF@ | 2409 | # if !@HAVE_TANHF@ |
| 2333 | # undef tanhf | 2410 | # undef tanhf |
| 2334 | _GL_FUNCDECL_SYS (tanhf, float, (float x)); | 2411 | _GL_FUNCDECL_SYS (tanhf, float, (float x), ); |
| 2335 | # endif | 2412 | # endif |
| 2336 | _GL_CXXALIAS_SYS (tanhf, float, (float x)); | 2413 | _GL_CXXALIAS_SYS (tanhf, float, (float x)); |
| 2337 | # endif | 2414 | # endif |
| @@ -2351,11 +2428,11 @@ _GL_WARN_ON_USE (tanhf, "tanhf is unportable - " | |||
| 2351 | # undef truncf | 2428 | # undef truncf |
| 2352 | # define truncf rpl_truncf | 2429 | # define truncf rpl_truncf |
| 2353 | # endif | 2430 | # endif |
| 2354 | _GL_FUNCDECL_RPL (truncf, float, (float x)); | 2431 | _GL_FUNCDECL_RPL (truncf, float, (float x), ); |
| 2355 | _GL_CXXALIAS_RPL (truncf, float, (float x)); | 2432 | _GL_CXXALIAS_RPL (truncf, float, (float x)); |
| 2356 | # else | 2433 | # else |
| 2357 | # if !@HAVE_DECL_TRUNCF@ | 2434 | # if !@HAVE_DECL_TRUNCF@ |
| 2358 | _GL_FUNCDECL_SYS (truncf, float, (float x)); | 2435 | _GL_FUNCDECL_SYS (truncf, float, (float x), ); |
| 2359 | # endif | 2436 | # endif |
| 2360 | _GL_CXXALIAS_SYS (truncf, float, (float x)); | 2437 | _GL_CXXALIAS_SYS (truncf, float, (float x)); |
| 2361 | # endif | 2438 | # endif |
| @@ -2374,11 +2451,11 @@ _GL_WARN_ON_USE (truncf, "truncf is unportable - " | |||
| 2374 | # undef trunc | 2451 | # undef trunc |
| 2375 | # define trunc rpl_trunc | 2452 | # define trunc rpl_trunc |
| 2376 | # endif | 2453 | # endif |
| 2377 | _GL_FUNCDECL_RPL (trunc, double, (double x)); | 2454 | _GL_FUNCDECL_RPL (trunc, double, (double x), ); |
| 2378 | _GL_CXXALIAS_RPL (trunc, double, (double x)); | 2455 | _GL_CXXALIAS_RPL (trunc, double, (double x)); |
| 2379 | # else | 2456 | # else |
| 2380 | # if !@HAVE_DECL_TRUNC@ | 2457 | # if !@HAVE_DECL_TRUNC@ |
| 2381 | _GL_FUNCDECL_SYS (trunc, double, (double x)); | 2458 | _GL_FUNCDECL_SYS (trunc, double, (double x), ); |
| 2382 | # endif | 2459 | # endif |
| 2383 | _GL_CXXALIAS_SYS (trunc, double, (double x)); | 2460 | _GL_CXXALIAS_SYS (trunc, double, (double x)); |
| 2384 | # endif | 2461 | # endif |
| @@ -2399,11 +2476,11 @@ _GL_WARN_ON_USE (trunc, "trunc is unportable - " | |||
| 2399 | # undef truncl | 2476 | # undef truncl |
| 2400 | # define truncl rpl_truncl | 2477 | # define truncl rpl_truncl |
| 2401 | # endif | 2478 | # endif |
| 2402 | _GL_FUNCDECL_RPL (truncl, long double, (long double x)); | 2479 | _GL_FUNCDECL_RPL (truncl, long double, (long double x), ); |
| 2403 | _GL_CXXALIAS_RPL (truncl, long double, (long double x)); | 2480 | _GL_CXXALIAS_RPL (truncl, long double, (long double x)); |
| 2404 | # else | 2481 | # else |
| 2405 | # if !@HAVE_DECL_TRUNCL@ | 2482 | # if !@HAVE_DECL_TRUNCL@ |
| 2406 | _GL_FUNCDECL_SYS (truncl, long double, (long double x)); | 2483 | _GL_FUNCDECL_SYS (truncl, long double, (long double x), ); |
| 2407 | # endif | 2484 | # endif |
| 2408 | _GL_CXXALIAS_SYS (truncl, long double, (long double x)); | 2485 | _GL_CXXALIAS_SYS (truncl, long double, (long double x)); |
| 2409 | # endif | 2486 | # endif |
| @@ -2487,7 +2564,7 @@ _GL_EXTERN_C int gl_isfinitel (long double x); | |||
| 2487 | # if defined isfinite || defined GNULIB_NAMESPACE | 2564 | # if defined isfinite || defined GNULIB_NAMESPACE |
| 2488 | _GL_MATH_CXX_REAL_FLOATING_DECL_1 (isfinite) | 2565 | _GL_MATH_CXX_REAL_FLOATING_DECL_1 (isfinite) |
| 2489 | # undef isfinite | 2566 | # undef isfinite |
| 2490 | # if __GNUC__ >= 6 || (defined __clang__ && !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined _AIX || (defined _WIN32 && !defined __CYGWIN__))) | 2567 | # if __GNUC__ >= 6 || (defined __clang__ && (__clang_major__ >= 19 || !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined _AIX || (defined _WIN32 && !defined __CYGWIN__)))) |
| 2491 | /* This platform's <cmath> possibly defines isfinite through a set of inline | 2568 | /* This platform's <cmath> possibly defines isfinite through a set of inline |
| 2492 | functions. */ | 2569 | functions. */ |
| 2493 | _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite, rpl_isfinite, bool) | 2570 | _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite, rpl_isfinite, bool) |
| @@ -2557,7 +2634,7 @@ _GL_EXTERN_C int isnanf (float x); | |||
| 2557 | GCC >= 4.0 also provides __builtin_isnanf, but clang doesn't. */ | 2634 | GCC >= 4.0 also provides __builtin_isnanf, but clang doesn't. */ |
| 2558 | # undef isnanf | 2635 | # undef isnanf |
| 2559 | # define isnanf(x) __builtin_isnan ((float)(x)) | 2636 | # define isnanf(x) __builtin_isnan ((float)(x)) |
| 2560 | # elif defined isnan | 2637 | # elif defined isnan && !defined HAVE_ISNANF_NOLIBM |
| 2561 | # undef isnanf | 2638 | # undef isnanf |
| 2562 | # define isnanf(x) isnan ((float)(x)) | 2639 | # define isnanf(x) isnan ((float)(x)) |
| 2563 | # endif | 2640 | # endif |
| @@ -2586,7 +2663,7 @@ _GL_EXTERN_C int isnand (double x); | |||
| 2586 | /* GCC >= 4.0 and clang provide a type-generic built-in for isnan. */ | 2663 | /* GCC >= 4.0 and clang provide a type-generic built-in for isnan. */ |
| 2587 | # undef isnand | 2664 | # undef isnand |
| 2588 | # define isnand(x) __builtin_isnan ((double)(x)) | 2665 | # define isnand(x) __builtin_isnan ((double)(x)) |
| 2589 | # else | 2666 | # elif !defined HAVE_ISNAND_NOLIBM |
| 2590 | # undef isnand | 2667 | # undef isnand |
| 2591 | # define isnand(x) isnan ((double)(x)) | 2668 | # define isnand(x) isnan ((double)(x)) |
| 2592 | # endif | 2669 | # endif |
| @@ -2609,7 +2686,7 @@ _GL_EXTERN_C int isnand (double x); | |||
| 2609 | GCC >= 4.0 also provides __builtin_isnanl, but clang doesn't. */ | 2686 | GCC >= 4.0 also provides __builtin_isnanl, but clang doesn't. */ |
| 2610 | # undef isnanl | 2687 | # undef isnanl |
| 2611 | # define isnanl(x) __builtin_isnan ((long double)(x)) | 2688 | # define isnanl(x) __builtin_isnan ((long double)(x)) |
| 2612 | # elif defined isnan | 2689 | # elif defined isnan && !defined HAVE_ISNANL_NOLIBM |
| 2613 | # undef isnanl | 2690 | # undef isnanl |
| 2614 | # define isnanl(x) isnan ((long double)(x)) | 2691 | # define isnanl(x) isnan ((long double)(x)) |
| 2615 | # endif | 2692 | # endif |
| @@ -2754,7 +2831,7 @@ _GL_EXTERN_C int gl_signbitl (long double arg); | |||
| 2754 | # if defined signbit || defined GNULIB_NAMESPACE | 2831 | # if defined signbit || defined GNULIB_NAMESPACE |
| 2755 | _GL_MATH_CXX_REAL_FLOATING_DECL_1 (signbit) | 2832 | _GL_MATH_CXX_REAL_FLOATING_DECL_1 (signbit) |
| 2756 | # undef signbit | 2833 | # undef signbit |
| 2757 | # if __GNUC__ >= 6 || (defined __clang__ && !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined _AIX || (defined _WIN32 && !defined __CYGWIN__))) | 2834 | # if __cplusplus >= 201103L || __GNUC__ >= 6 || (defined __clang__ && !((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined _AIX || (defined _WIN32 && !defined __CYGWIN__))) |
| 2758 | /* This platform's <cmath> possibly defines signbit through a set of inline | 2835 | /* This platform's <cmath> possibly defines signbit through a set of inline |
| 2759 | functions. */ | 2836 | functions. */ |
| 2760 | _GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit, rpl_signbit, bool) | 2837 | _GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit, rpl_signbit, bool) |
| @@ -2780,11 +2857,11 @@ _GL_WARN_REAL_FLOATING_DECL (signbit); | |||
| 2780 | # undef getpayloadf | 2857 | # undef getpayloadf |
| 2781 | # define getpayloadf rpl_getpayloadf | 2858 | # define getpayloadf rpl_getpayloadf |
| 2782 | # endif | 2859 | # endif |
| 2783 | _GL_FUNCDECL_RPL (getpayloadf, float, (const float *)); | 2860 | _GL_FUNCDECL_RPL (getpayloadf, float, (const float *), ); |
| 2784 | _GL_CXXALIAS_RPL (getpayloadf, float, (const float *)); | 2861 | _GL_CXXALIAS_RPL (getpayloadf, float, (const float *)); |
| 2785 | # else | 2862 | # else |
| 2786 | # if !@HAVE_GETPAYLOADF@ | 2863 | # if !@HAVE_GETPAYLOADF@ |
| 2787 | _GL_FUNCDECL_SYS (getpayloadf, float, (const float *)); | 2864 | _GL_FUNCDECL_SYS (getpayloadf, float, (const float *), ); |
| 2788 | # endif | 2865 | # endif |
| 2789 | _GL_CXXALIAS_SYS (getpayloadf, float, (const float *)); | 2866 | _GL_CXXALIAS_SYS (getpayloadf, float, (const float *)); |
| 2790 | # endif | 2867 | # endif |
| @@ -2803,11 +2880,11 @@ _GL_WARN_ON_USE (getpayloadf, "getpayloadf is unportable - " | |||
| 2803 | # undef getpayload | 2880 | # undef getpayload |
| 2804 | # define getpayload rpl_getpayload | 2881 | # define getpayload rpl_getpayload |
| 2805 | # endif | 2882 | # endif |
| 2806 | _GL_FUNCDECL_RPL (getpayload, double, (const double *)); | 2883 | _GL_FUNCDECL_RPL (getpayload, double, (const double *), ); |
| 2807 | _GL_CXXALIAS_RPL (getpayload, double, (const double *)); | 2884 | _GL_CXXALIAS_RPL (getpayload, double, (const double *)); |
| 2808 | # else | 2885 | # else |
| 2809 | # if !@HAVE_GETPAYLOAD@ | 2886 | # if !@HAVE_GETPAYLOAD@ |
| 2810 | _GL_FUNCDECL_SYS (getpayload, double, (const double *)); | 2887 | _GL_FUNCDECL_SYS (getpayload, double, (const double *), ); |
| 2811 | # endif | 2888 | # endif |
| 2812 | _GL_CXXALIAS_SYS (getpayload, double, (const double *)); | 2889 | _GL_CXXALIAS_SYS (getpayload, double, (const double *)); |
| 2813 | # endif | 2890 | # endif |
| @@ -2826,11 +2903,11 @@ _GL_WARN_ON_USE (getpayload, "getpayload is unportable - " | |||
| 2826 | # undef getpayloadl | 2903 | # undef getpayloadl |
| 2827 | # define getpayloadl rpl_getpayloadl | 2904 | # define getpayloadl rpl_getpayloadl |
| 2828 | # endif | 2905 | # endif |
| 2829 | _GL_FUNCDECL_RPL (getpayloadl, long double, (const long double *)); | 2906 | _GL_FUNCDECL_RPL (getpayloadl, long double, (const long double *), ); |
| 2830 | _GL_CXXALIAS_RPL (getpayloadl, long double, (const long double *)); | 2907 | _GL_CXXALIAS_RPL (getpayloadl, long double, (const long double *)); |
| 2831 | # else | 2908 | # else |
| 2832 | # if !@HAVE_GETPAYLOADL@ | 2909 | # if !@HAVE_GETPAYLOADL@ |
| 2833 | _GL_FUNCDECL_SYS (getpayloadl, long double, (const long double *)); | 2910 | _GL_FUNCDECL_SYS (getpayloadl, long double, (const long double *), ); |
| 2834 | # endif | 2911 | # endif |
| 2835 | _GL_CXXALIAS_SYS (getpayloadl, long double, (const long double *)); | 2912 | _GL_CXXALIAS_SYS (getpayloadl, long double, (const long double *)); |
| 2836 | # endif | 2913 | # endif |
| @@ -2846,7 +2923,7 @@ _GL_WARN_ON_USE (getpayloadl, "getpayloadl is unportable - " | |||
| 2846 | 2923 | ||
| 2847 | #if @GNULIB_SETPAYLOADF@ | 2924 | #if @GNULIB_SETPAYLOADF@ |
| 2848 | # if !@HAVE_SETPAYLOADF@ | 2925 | # if !@HAVE_SETPAYLOADF@ |
| 2849 | _GL_FUNCDECL_SYS (setpayloadf, int, (float *, float)); | 2926 | _GL_FUNCDECL_SYS (setpayloadf, int, (float *, float), ); |
| 2850 | # endif | 2927 | # endif |
| 2851 | _GL_CXXALIAS_SYS (setpayloadf, int, (float *, float)); | 2928 | _GL_CXXALIAS_SYS (setpayloadf, int, (float *, float)); |
| 2852 | _GL_CXXALIASWARN (setpayloadf); | 2929 | _GL_CXXALIASWARN (setpayloadf); |
| @@ -2860,7 +2937,7 @@ _GL_WARN_ON_USE (setpayloadf, "setpayloadf is unportable - " | |||
| 2860 | 2937 | ||
| 2861 | #if @GNULIB_SETPAYLOAD@ | 2938 | #if @GNULIB_SETPAYLOAD@ |
| 2862 | # if !@HAVE_SETPAYLOAD@ | 2939 | # if !@HAVE_SETPAYLOAD@ |
| 2863 | _GL_FUNCDECL_SYS (setpayload, int, (double *, double)); | 2940 | _GL_FUNCDECL_SYS (setpayload, int, (double *, double), ); |
| 2864 | # endif | 2941 | # endif |
| 2865 | _GL_CXXALIAS_SYS (setpayload, int, (double *, double)); | 2942 | _GL_CXXALIAS_SYS (setpayload, int, (double *, double)); |
| 2866 | _GL_CXXALIASWARN (setpayload); | 2943 | _GL_CXXALIASWARN (setpayload); |
| @@ -2874,7 +2951,7 @@ _GL_WARN_ON_USE (setpayload, "setpayload is unportable - " | |||
| 2874 | 2951 | ||
| 2875 | #if @GNULIB_SETPAYLOADL@ | 2952 | #if @GNULIB_SETPAYLOADL@ |
| 2876 | # if !@HAVE_SETPAYLOADL@ | 2953 | # if !@HAVE_SETPAYLOADL@ |
| 2877 | _GL_FUNCDECL_SYS (setpayloadl, int, (long double *, long double)); | 2954 | _GL_FUNCDECL_SYS (setpayloadl, int, (long double *, long double), ); |
| 2878 | # endif | 2955 | # endif |
| 2879 | _GL_CXXALIAS_SYS (setpayloadl, int, (long double *, long double)); | 2956 | _GL_CXXALIAS_SYS (setpayloadl, int, (long double *, long double)); |
| 2880 | _GL_CXXALIASWARN (setpayloadl); | 2957 | _GL_CXXALIASWARN (setpayloadl); |
| @@ -2889,7 +2966,7 @@ _GL_WARN_ON_USE (setpayloadl, "setpayloadl is unportable - " | |||
| 2889 | 2966 | ||
| 2890 | #if @GNULIB_SETPAYLOADSIGF@ | 2967 | #if @GNULIB_SETPAYLOADSIGF@ |
| 2891 | # if !@HAVE_SETPAYLOADSIGF@ | 2968 | # if !@HAVE_SETPAYLOADSIGF@ |
| 2892 | _GL_FUNCDECL_SYS (setpayloadsigf, int, (float *, float)); | 2969 | _GL_FUNCDECL_SYS (setpayloadsigf, int, (float *, float), ); |
| 2893 | # endif | 2970 | # endif |
| 2894 | _GL_CXXALIAS_SYS (setpayloadsigf, int, (float *, float)); | 2971 | _GL_CXXALIAS_SYS (setpayloadsigf, int, (float *, float)); |
| 2895 | _GL_CXXALIASWARN (setpayloadsigf); | 2972 | _GL_CXXALIASWARN (setpayloadsigf); |
| @@ -2903,7 +2980,7 @@ _GL_WARN_ON_USE (setpayloadsigf, "setpayloadsigf is unportable - " | |||
| 2903 | 2980 | ||
| 2904 | #if @GNULIB_SETPAYLOADSIG@ | 2981 | #if @GNULIB_SETPAYLOADSIG@ |
| 2905 | # if !@HAVE_SETPAYLOADSIG@ | 2982 | # if !@HAVE_SETPAYLOADSIG@ |
| 2906 | _GL_FUNCDECL_SYS (setpayloadsig, int, (double *, double)); | 2983 | _GL_FUNCDECL_SYS (setpayloadsig, int, (double *, double), ); |
| 2907 | # endif | 2984 | # endif |
| 2908 | _GL_CXXALIAS_SYS (setpayloadsig, int, (double *, double)); | 2985 | _GL_CXXALIAS_SYS (setpayloadsig, int, (double *, double)); |
| 2909 | _GL_CXXALIASWARN (setpayloadsig); | 2986 | _GL_CXXALIASWARN (setpayloadsig); |
| @@ -2917,7 +2994,7 @@ _GL_WARN_ON_USE (setpayloadsig, "setpayloadsig is unportable - " | |||
| 2917 | 2994 | ||
| 2918 | #if @GNULIB_SETPAYLOADSIGL@ | 2995 | #if @GNULIB_SETPAYLOADSIGL@ |
| 2919 | # if !@HAVE_SETPAYLOADSIGL@ | 2996 | # if !@HAVE_SETPAYLOADSIGL@ |
| 2920 | _GL_FUNCDECL_SYS (setpayloadsigl, int, (long double *, long double)); | 2997 | _GL_FUNCDECL_SYS (setpayloadsigl, int, (long double *, long double), ); |
| 2921 | # endif | 2998 | # endif |
| 2922 | _GL_CXXALIAS_SYS (setpayloadsigl, int, (long double *, long double)); | 2999 | _GL_CXXALIAS_SYS (setpayloadsigl, int, (long double *, long double)); |
| 2923 | _GL_CXXALIASWARN (setpayloadsigl); | 3000 | _GL_CXXALIASWARN (setpayloadsigl); |
| @@ -2936,11 +3013,11 @@ _GL_WARN_ON_USE (setpayloadsigl, "setpayloadsigl is unportable - " | |||
| 2936 | # undef totalorderf | 3013 | # undef totalorderf |
| 2937 | # define totalorderf rpl_totalorderf | 3014 | # define totalorderf rpl_totalorderf |
| 2938 | # endif | 3015 | # endif |
| 2939 | _GL_FUNCDECL_RPL (totalorderf, int, (float const *, float const *)); | 3016 | _GL_FUNCDECL_RPL (totalorderf, int, (float const *, float const *), ); |
| 2940 | _GL_CXXALIAS_RPL (totalorderf, int, (float const *, float const *)); | 3017 | _GL_CXXALIAS_RPL (totalorderf, int, (float const *, float const *)); |
| 2941 | # else | 3018 | # else |
| 2942 | # if !@HAVE_TOTALORDERF@ | 3019 | # if !@HAVE_TOTALORDERF@ |
| 2943 | _GL_FUNCDECL_SYS (totalorderf, int, (float const *, float const *)); | 3020 | _GL_FUNCDECL_SYS (totalorderf, int, (float const *, float const *), ); |
| 2944 | # endif | 3021 | # endif |
| 2945 | _GL_CXXALIAS_SYS (totalorderf, int, (float const *, float const *)); | 3022 | _GL_CXXALIAS_SYS (totalorderf, int, (float const *, float const *)); |
| 2946 | # endif | 3023 | # endif |
| @@ -2959,11 +3036,11 @@ _GL_WARN_ON_USE (totalorderf, "totalorderf is unportable - " | |||
| 2959 | # undef totalorder | 3036 | # undef totalorder |
| 2960 | # define totalorder rpl_totalorder | 3037 | # define totalorder rpl_totalorder |
| 2961 | # endif | 3038 | # endif |
| 2962 | _GL_FUNCDECL_RPL (totalorder, int, (double const *, double const *)); | 3039 | _GL_FUNCDECL_RPL (totalorder, int, (double const *, double const *), ); |
| 2963 | _GL_CXXALIAS_RPL (totalorder, int, (double const *, double const *)); | 3040 | _GL_CXXALIAS_RPL (totalorder, int, (double const *, double const *)); |
| 2964 | # else | 3041 | # else |
| 2965 | # if !@HAVE_TOTALORDER@ | 3042 | # if !@HAVE_TOTALORDER@ |
| 2966 | _GL_FUNCDECL_SYS (totalorder, int, (double const *, double const *)); | 3043 | _GL_FUNCDECL_SYS (totalorder, int, (double const *, double const *), ); |
| 2967 | # endif | 3044 | # endif |
| 2968 | _GL_CXXALIAS_SYS (totalorder, int, (double const *, double const *)); | 3045 | _GL_CXXALIAS_SYS (totalorder, int, (double const *, double const *)); |
| 2969 | # endif | 3046 | # endif |
| @@ -2985,13 +3062,13 @@ _GL_WARN_ON_USE (totalorder, "totalorder is unportable - " | |||
| 2985 | # define totalorderl rpl_totalorderl | 3062 | # define totalorderl rpl_totalorderl |
| 2986 | # endif | 3063 | # endif |
| 2987 | _GL_FUNCDECL_RPL (totalorderl, int, | 3064 | _GL_FUNCDECL_RPL (totalorderl, int, |
| 2988 | (long double const *, long double const *)); | 3065 | (long double const *, long double const *), ); |
| 2989 | _GL_CXXALIAS_RPL (totalorderl, int, | 3066 | _GL_CXXALIAS_RPL (totalorderl, int, |
| 2990 | (long double const *, long double const *)); | 3067 | (long double const *, long double const *)); |
| 2991 | # else | 3068 | # else |
| 2992 | # if !@HAVE_TOTALORDERL@ | 3069 | # if !@HAVE_TOTALORDERL@ |
| 2993 | _GL_FUNCDECL_SYS (totalorderl, int, | 3070 | _GL_FUNCDECL_SYS (totalorderl, int, |
| 2994 | (long double const *, long double const *)); | 3071 | (long double const *, long double const *), ); |
| 2995 | # endif | 3072 | # endif |
| 2996 | _GL_CXXALIAS_SYS (totalorderl, int, | 3073 | _GL_CXXALIAS_SYS (totalorderl, int, |
| 2997 | (long double const *, long double const *)); | 3074 | (long double const *, long double const *)); |
| @@ -3012,11 +3089,11 @@ _GL_WARN_ON_USE (totalorderl, "totalorderl is unportable - " | |||
| 3012 | # undef totalordermagf | 3089 | # undef totalordermagf |
| 3013 | # define totalordermagf rpl_totalordermagf | 3090 | # define totalordermagf rpl_totalordermagf |
| 3014 | # endif | 3091 | # endif |
| 3015 | _GL_FUNCDECL_RPL (totalordermagf, int, (float const *, float const *)); | 3092 | _GL_FUNCDECL_RPL (totalordermagf, int, (float const *, float const *), ); |
| 3016 | _GL_CXXALIAS_RPL (totalordermagf, int, (float const *, float const *)); | 3093 | _GL_CXXALIAS_RPL (totalordermagf, int, (float const *, float const *)); |
| 3017 | # else | 3094 | # else |
| 3018 | # if !@HAVE_TOTALORDERMAGF@ | 3095 | # if !@HAVE_TOTALORDERMAGF@ |
| 3019 | _GL_FUNCDECL_SYS (totalordermagf, int, (float const *, float const *)); | 3096 | _GL_FUNCDECL_SYS (totalordermagf, int, (float const *, float const *), ); |
| 3020 | # endif | 3097 | # endif |
| 3021 | _GL_CXXALIAS_SYS (totalordermagf, int, (float const *, float const *)); | 3098 | _GL_CXXALIAS_SYS (totalordermagf, int, (float const *, float const *)); |
| 3022 | # endif | 3099 | # endif |
| @@ -3037,11 +3114,11 @@ _GL_WARN_ON_USE (totalordermagf, "totalordermagf is unportable - " | |||
| 3037 | # undef totalordermag | 3114 | # undef totalordermag |
| 3038 | # define totalordermag rpl_totalordermag | 3115 | # define totalordermag rpl_totalordermag |
| 3039 | # endif | 3116 | # endif |
| 3040 | _GL_FUNCDECL_RPL (totalordermag, int, (double const *, double const *)); | 3117 | _GL_FUNCDECL_RPL (totalordermag, int, (double const *, double const *), ); |
| 3041 | _GL_CXXALIAS_RPL (totalordermag, int, (double const *, double const *)); | 3118 | _GL_CXXALIAS_RPL (totalordermag, int, (double const *, double const *)); |
| 3042 | # else | 3119 | # else |
| 3043 | # if !@HAVE_TOTALORDERMAG@ | 3120 | # if !@HAVE_TOTALORDERMAG@ |
| 3044 | _GL_FUNCDECL_SYS (totalordermag, int, (double const *, double const *)); | 3121 | _GL_FUNCDECL_SYS (totalordermag, int, (double const *, double const *), ); |
| 3045 | # endif | 3122 | # endif |
| 3046 | _GL_CXXALIAS_SYS (totalordermag, int, (double const *, double const *)); | 3123 | _GL_CXXALIAS_SYS (totalordermag, int, (double const *, double const *)); |
| 3047 | # endif | 3124 | # endif |
| @@ -3063,13 +3140,13 @@ _GL_WARN_ON_USE (totalordermag, "totalordermag is unportable - " | |||
| 3063 | # define totalordermagl rpl_totalordermagl | 3140 | # define totalordermagl rpl_totalordermagl |
| 3064 | # endif | 3141 | # endif |
| 3065 | _GL_FUNCDECL_RPL (totalordermagl, int, | 3142 | _GL_FUNCDECL_RPL (totalordermagl, int, |
| 3066 | (long double const *, long double const *)); | 3143 | (long double const *, long double const *), ); |
| 3067 | _GL_CXXALIAS_RPL (totalordermagl, int, | 3144 | _GL_CXXALIAS_RPL (totalordermagl, int, |
| 3068 | (long double const *, long double const *)); | 3145 | (long double const *, long double const *)); |
| 3069 | # else | 3146 | # else |
| 3070 | # if !@HAVE_TOTALORDERMAGL@ | 3147 | # if !@HAVE_TOTALORDERMAGL@ |
| 3071 | _GL_FUNCDECL_SYS (totalordermagl, int, | 3148 | _GL_FUNCDECL_SYS (totalordermagl, int, |
| 3072 | (long double const *, long double const *)); | 3149 | (long double const *, long double const *), ); |
| 3073 | # endif | 3150 | # endif |
| 3074 | _GL_CXXALIAS_SYS (totalordermagl, int, | 3151 | _GL_CXXALIAS_SYS (totalordermagl, int, |
| 3075 | (long double const *, long double const *)); | 3152 | (long double const *, long double const *)); |
diff --git a/gl/mbchar.c b/gl/mbchar.c new file mode 100644 index 00000000..713c2f74 --- /dev/null +++ b/gl/mbchar.c | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* Copyright (C) 2001, 2006, 2009-2025 Free Software Foundation, Inc. | ||
| 2 | |||
| 3 | This file is free software: you can redistribute it and/or modify | ||
| 4 | it under the terms of the GNU Lesser General Public License as | ||
| 5 | published by the Free Software Foundation; either version 2.1 of the | ||
| 6 | License, or (at your option) any later version. | ||
| 7 | |||
| 8 | This file is distributed in the hope that it will be useful, | ||
| 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | GNU Lesser General Public License for more details. | ||
| 12 | |||
| 13 | You should have received a copy of the GNU Lesser General Public License | ||
| 14 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 15 | |||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | #define MBCHAR_INLINE _GL_EXTERN_INLINE | ||
| 20 | |||
| 21 | #include <limits.h> | ||
| 22 | |||
| 23 | #include "mbchar.h" | ||
diff --git a/gl/mbchar.h b/gl/mbchar.h new file mode 100644 index 00000000..d77168e7 --- /dev/null +++ b/gl/mbchar.h | |||
| @@ -0,0 +1,383 @@ | |||
| 1 | /* Multibyte character data type. | ||
| 2 | Copyright (C) 2001, 2005-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>. */ | ||
| 18 | |||
| 19 | /* A multibyte character is a short subsequence of a char* string, | ||
| 20 | representing a single 32-bit wide character. | ||
| 21 | |||
| 22 | We use multibyte characters instead of 32-bit wide characters because | ||
| 23 | of the following goals: | ||
| 24 | 1) correct multibyte handling, i.e. operate according to the LC_CTYPE | ||
| 25 | locale, | ||
| 26 | 2) ease of maintenance, i.e. the maintainer needs not know all details | ||
| 27 | of the ISO C 99 standard, | ||
| 28 | 3) don't fail grossly if the input is not in the encoding set by the | ||
| 29 | locale, because often different encodings are in use in the same | ||
| 30 | countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...), | ||
| 31 | 4) fast in the case of ASCII characters. | ||
| 32 | |||
| 33 | Multibyte characters are only accessed through the mb* macros. | ||
| 34 | |||
| 35 | mb_ptr (mbc) | ||
| 36 | return a pointer to the beginning of the multibyte sequence. | ||
| 37 | |||
| 38 | mb_len (mbc) | ||
| 39 | returns the number of bytes occupied by the multibyte sequence. | ||
| 40 | Always > 0. | ||
| 41 | |||
| 42 | mb_iseq (mbc, sc) | ||
| 43 | returns true if mbc is the standard ASCII character sc. | ||
| 44 | |||
| 45 | mb_isnul (mbc) | ||
| 46 | returns true if mbc is the nul character. | ||
| 47 | |||
| 48 | mb_cmp (mbc1, mbc2) | ||
| 49 | returns a positive, zero, or negative value depending on whether mbc1 | ||
| 50 | sorts after, same or before mbc2. | ||
| 51 | |||
| 52 | mb_casecmp (mbc1, mbc2) | ||
| 53 | returns a positive, zero, or negative value depending on whether mbc1 | ||
| 54 | sorts after, same or before mbc2, modulo upper/lowercase conversion. | ||
| 55 | |||
| 56 | mb_equal (mbc1, mbc2) | ||
| 57 | returns true if mbc1 and mbc2 are equal. | ||
| 58 | |||
| 59 | mb_caseequal (mbc1, mbc2) | ||
| 60 | returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion. | ||
| 61 | |||
| 62 | mb_isalnum (mbc) | ||
| 63 | returns true if mbc is alphanumeric. | ||
| 64 | |||
| 65 | mb_isalpha (mbc) | ||
| 66 | returns true if mbc is alphabetic. | ||
| 67 | |||
| 68 | mb_isascii(mbc) | ||
| 69 | returns true if mbc is plain ASCII. | ||
| 70 | |||
| 71 | mb_isblank (mbc) | ||
| 72 | returns true if mbc is a blank. | ||
| 73 | |||
| 74 | mb_iscntrl (mbc) | ||
| 75 | returns true if mbc is a control character. | ||
| 76 | |||
| 77 | mb_isdigit (mbc) | ||
| 78 | returns true if mbc is a decimal digit. | ||
| 79 | |||
| 80 | mb_isgraph (mbc) | ||
| 81 | returns true if mbc is a graphic character. | ||
| 82 | |||
| 83 | mb_islower (mbc) | ||
| 84 | returns true if mbc is lowercase. | ||
| 85 | |||
| 86 | mb_isprint (mbc) | ||
| 87 | returns true if mbc is a printable character. | ||
| 88 | |||
| 89 | mb_ispunct (mbc) | ||
| 90 | returns true if mbc is a punctuation character. | ||
| 91 | |||
| 92 | mb_isspace (mbc) | ||
| 93 | returns true if mbc is a space character. | ||
| 94 | |||
| 95 | mb_isupper (mbc) | ||
| 96 | returns true if mbc is uppercase. | ||
| 97 | |||
| 98 | mb_isxdigit (mbc) | ||
| 99 | returns true if mbc is a hexadecimal digit. | ||
| 100 | |||
| 101 | mb_width (mbc) | ||
| 102 | returns the number of columns on the output device occupied by mbc. | ||
| 103 | Always >= 0. | ||
| 104 | |||
| 105 | mb_putc (mbc, stream) | ||
| 106 | outputs mbc on stream, a byte oriented FILE stream opened for output. | ||
| 107 | |||
| 108 | mb_setascii (&mbc, sc) | ||
| 109 | assigns the standard ASCII character sc to mbc. | ||
| 110 | (Only available if the 'mbfile' module is in use.) | ||
| 111 | |||
| 112 | mb_copy (&destmbc, &srcmbc) | ||
| 113 | copies srcmbc to destmbc. | ||
| 114 | |||
| 115 | Here are the function prototypes of the macros. | ||
| 116 | |||
| 117 | extern const char * mb_ptr (const mbchar_t mbc); | ||
| 118 | extern size_t mb_len (const mbchar_t mbc); | ||
| 119 | extern bool mb_iseq (const mbchar_t mbc, char sc); | ||
| 120 | extern bool mb_isnul (const mbchar_t mbc); | ||
| 121 | extern int mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2); | ||
| 122 | extern int mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2); | ||
| 123 | extern bool mb_equal (const mbchar_t mbc1, const mbchar_t mbc2); | ||
| 124 | extern bool mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2); | ||
| 125 | extern bool mb_isalnum (const mbchar_t mbc); | ||
| 126 | extern bool mb_isalpha (const mbchar_t mbc); | ||
| 127 | extern bool mb_isascii (const mbchar_t mbc); | ||
| 128 | extern bool mb_isblank (const mbchar_t mbc); | ||
| 129 | extern bool mb_iscntrl (const mbchar_t mbc); | ||
| 130 | extern bool mb_isdigit (const mbchar_t mbc); | ||
| 131 | extern bool mb_isgraph (const mbchar_t mbc); | ||
| 132 | extern bool mb_islower (const mbchar_t mbc); | ||
| 133 | extern bool mb_isprint (const mbchar_t mbc); | ||
| 134 | extern bool mb_ispunct (const mbchar_t mbc); | ||
| 135 | extern bool mb_isspace (const mbchar_t mbc); | ||
| 136 | extern bool mb_isupper (const mbchar_t mbc); | ||
| 137 | extern bool mb_isxdigit (const mbchar_t mbc); | ||
| 138 | extern int mb_width (const mbchar_t mbc); | ||
| 139 | extern void mb_putc (const mbchar_t mbc, FILE *stream); | ||
| 140 | extern void mb_setascii (mbchar_t *new, char sc); | ||
| 141 | extern void mb_copy (mbchar_t *new, const mbchar_t *old); | ||
| 142 | */ | ||
| 143 | |||
| 144 | #ifndef _MBCHAR_H | ||
| 145 | #define _MBCHAR_H 1 | ||
| 146 | |||
| 147 | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ | ||
| 148 | #if !_GL_CONFIG_H_INCLUDED | ||
| 149 | #error "Please include config.h first." | ||
| 150 | #endif | ||
| 151 | |||
| 152 | #include <string.h> | ||
| 153 | #include <uchar.h> | ||
| 154 | |||
| 155 | _GL_INLINE_HEADER_BEGIN | ||
| 156 | #ifndef MBCHAR_INLINE | ||
| 157 | # define MBCHAR_INLINE _GL_INLINE | ||
| 158 | #endif | ||
| 159 | |||
| 160 | #ifdef __cplusplus | ||
| 161 | extern "C" { | ||
| 162 | #endif | ||
| 163 | |||
| 164 | |||
| 165 | /* The longest multibyte characters, nowadays, are 4 bytes long. | ||
| 166 | Regardless of the values of MB_CUR_MAX and MB_LEN_MAX. */ | ||
| 167 | #define MBCHAR_BUF_SIZE 4 | ||
| 168 | |||
| 169 | struct mbchar | ||
| 170 | { | ||
| 171 | const char *ptr; /* pointer to current character */ | ||
| 172 | size_t bytes; /* number of bytes of current character, > 0 */ | ||
| 173 | bool wc_valid; /* true if wc is a valid 32-bit wide character */ | ||
| 174 | char32_t wc; /* if wc_valid: the current character */ | ||
| 175 | #if defined GNULIB_MBFILE | ||
| 176 | char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */ | ||
| 177 | #endif | ||
| 178 | }; | ||
| 179 | |||
| 180 | /* EOF (not a real character) is represented with bytes = 0 and | ||
| 181 | wc_valid = false. */ | ||
| 182 | |||
| 183 | typedef struct mbchar mbchar_t; | ||
| 184 | |||
| 185 | /* Access the current character. */ | ||
| 186 | #define mb_ptr(mbc) ((mbc).ptr) | ||
| 187 | #define mb_len(mbc) ((mbc).bytes) | ||
| 188 | |||
| 189 | /* Comparison of characters. */ | ||
| 190 | #define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc)) | ||
| 191 | #define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0) | ||
| 192 | #define mb_cmp(mbc1, mbc2) \ | ||
| 193 | ((mbc1).wc_valid \ | ||
| 194 | ? ((mbc2).wc_valid \ | ||
| 195 | ? _GL_CMP ((mbc1).wc, (mbc2).wc) \ | ||
| 196 | : -1) \ | ||
| 197 | : ((mbc2).wc_valid \ | ||
| 198 | ? 1 \ | ||
| 199 | : (mbc1).bytes == (mbc2).bytes \ | ||
| 200 | ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ | ||
| 201 | : (mbc1).bytes < (mbc2).bytes \ | ||
| 202 | ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ | ||
| 203 | : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) | ||
| 204 | #define mb_casecmp(mbc1, mbc2) \ | ||
| 205 | ((mbc1).wc_valid \ | ||
| 206 | ? ((mbc2).wc_valid \ | ||
| 207 | ? _GL_CMP (c32tolower ((mbc1).wc), c32tolower ((mbc2).wc)) \ | ||
| 208 | : -1) \ | ||
| 209 | : ((mbc2).wc_valid \ | ||
| 210 | ? 1 \ | ||
| 211 | : (mbc1).bytes == (mbc2).bytes \ | ||
| 212 | ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ | ||
| 213 | : (mbc1).bytes < (mbc2).bytes \ | ||
| 214 | ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ | ||
| 215 | : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) | ||
| 216 | #define mb_equal(mbc1, mbc2) \ | ||
| 217 | ((mbc1).wc_valid && (mbc2).wc_valid \ | ||
| 218 | ? (mbc1).wc == (mbc2).wc \ | ||
| 219 | : (mbc1).bytes == (mbc2).bytes \ | ||
| 220 | && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) | ||
| 221 | #define mb_caseequal(mbc1, mbc2) \ | ||
| 222 | ((mbc1).wc_valid && (mbc2).wc_valid \ | ||
| 223 | ? c32tolower ((mbc1).wc) == c32tolower ((mbc2).wc) \ | ||
| 224 | : (mbc1).bytes == (mbc2).bytes \ | ||
| 225 | && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) | ||
| 226 | |||
| 227 | /* <ctype.h>, <wctype.h> classification. */ | ||
| 228 | #define mb_isascii(mbc) \ | ||
| 229 | ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127) | ||
| 230 | #define mb_isalnum(mbc) ((mbc).wc_valid && c32isalnum ((mbc).wc)) | ||
| 231 | #define mb_isalpha(mbc) ((mbc).wc_valid && c32isalpha ((mbc).wc)) | ||
| 232 | #define mb_isblank(mbc) ((mbc).wc_valid && c32isblank ((mbc).wc)) | ||
| 233 | #define mb_iscntrl(mbc) ((mbc).wc_valid && c32iscntrl ((mbc).wc)) | ||
| 234 | #define mb_isdigit(mbc) ((mbc).wc_valid && c32isdigit ((mbc).wc)) | ||
| 235 | #define mb_isgraph(mbc) ((mbc).wc_valid && c32isgraph ((mbc).wc)) | ||
| 236 | #define mb_islower(mbc) ((mbc).wc_valid && c32islower ((mbc).wc)) | ||
| 237 | #define mb_isprint(mbc) ((mbc).wc_valid && c32isprint ((mbc).wc)) | ||
| 238 | #define mb_ispunct(mbc) ((mbc).wc_valid && c32ispunct ((mbc).wc)) | ||
| 239 | #define mb_isspace(mbc) ((mbc).wc_valid && c32isspace ((mbc).wc)) | ||
| 240 | #define mb_isupper(mbc) ((mbc).wc_valid && c32isupper ((mbc).wc)) | ||
| 241 | #define mb_isxdigit(mbc) ((mbc).wc_valid && c32isxdigit ((mbc).wc)) | ||
| 242 | |||
| 243 | /* Extra <wchar.h> function. */ | ||
| 244 | |||
| 245 | /* Unprintable characters appear as a small box of width 1. */ | ||
| 246 | #define MB_UNPRINTABLE_WIDTH 1 | ||
| 247 | |||
| 248 | MBCHAR_INLINE int | ||
| 249 | mb_width_aux (char32_t wc) | ||
| 250 | { | ||
| 251 | int w = c32width (wc); | ||
| 252 | /* For unprintable characters, arbitrarily return 0 for control characters | ||
| 253 | and MB_UNPRINTABLE_WIDTH otherwise. */ | ||
| 254 | return (w >= 0 ? w : c32iscntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH); | ||
| 255 | } | ||
| 256 | |||
| 257 | #define mb_width(mbc) \ | ||
| 258 | ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH) | ||
| 259 | |||
| 260 | /* Output. */ | ||
| 261 | #define mb_putc(mbc, stream) fwrite ((mbc).ptr, 1, (mbc).bytes, (stream)) | ||
| 262 | |||
| 263 | #if defined GNULIB_MBFILE | ||
| 264 | /* Assignment. */ | ||
| 265 | # define mb_setascii(mbc, sc) \ | ||
| 266 | ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \ | ||
| 267 | (mbc)->wc = (mbc)->buf[0] = (sc)) | ||
| 268 | #endif | ||
| 269 | |||
| 270 | /* Copying a character. */ | ||
| 271 | MBCHAR_INLINE void | ||
| 272 | mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc) | ||
| 273 | { | ||
| 274 | #if defined GNULIB_MBFILE | ||
| 275 | if (old_mbc->ptr == &old_mbc->buf[0]) | ||
| 276 | { | ||
| 277 | memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes); | ||
| 278 | new_mbc->ptr = &new_mbc->buf[0]; | ||
| 279 | } | ||
| 280 | else | ||
| 281 | #endif | ||
| 282 | new_mbc->ptr = old_mbc->ptr; | ||
| 283 | new_mbc->bytes = old_mbc->bytes; | ||
| 284 | if ((new_mbc->wc_valid = old_mbc->wc_valid)) | ||
| 285 | new_mbc->wc = old_mbc->wc; | ||
| 286 | } | ||
| 287 | |||
| 288 | |||
| 289 | /* is_basic(c) tests whether the single-byte character c is | ||
| 290 | - in the ISO C "basic character set" or is one of '@', '$', and '`' | ||
| 291 | which ISO C 23 § 5.2.1.1.(1) guarantees to be single-byte and in | ||
| 292 | practice are safe to treat as basic in the execution character set, | ||
| 293 | or | ||
| 294 | - in the POSIX "portable character set", which | ||
| 295 | <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap06.html> | ||
| 296 | equally guarantees to be single-byte. | ||
| 297 | This is a convenience function, and is in this file only to share code | ||
| 298 | between mbiter.h, mbuiter.h, and mbfile.h. */ | ||
| 299 | #if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ | ||
| 300 | && ('$' == 36) && ('%' == 37) && ('&' == 38) && ('\'' == 39) \ | ||
| 301 | && ('(' == 40) && (')' == 41) && ('*' == 42) && ('+' == 43) \ | ||
| 302 | && (',' == 44) && ('-' == 45) && ('.' == 46) && ('/' == 47) \ | ||
| 303 | && ('0' == 48) && ('1' == 49) && ('2' == 50) && ('3' == 51) \ | ||
| 304 | && ('4' == 52) && ('5' == 53) && ('6' == 54) && ('7' == 55) \ | ||
| 305 | && ('8' == 56) && ('9' == 57) && (':' == 58) && (';' == 59) \ | ||
| 306 | && ('<' == 60) && ('=' == 61) && ('>' == 62) && ('?' == 63) \ | ||
| 307 | && ('@' == 64) && ('A' == 65) && ('B' == 66) && ('C' == 67) \ | ||
| 308 | && ('D' == 68) && ('E' == 69) && ('F' == 70) && ('G' == 71) \ | ||
| 309 | && ('H' == 72) && ('I' == 73) && ('J' == 74) && ('K' == 75) \ | ||
| 310 | && ('L' == 76) && ('M' == 77) && ('N' == 78) && ('O' == 79) \ | ||
| 311 | && ('P' == 80) && ('Q' == 81) && ('R' == 82) && ('S' == 83) \ | ||
| 312 | && ('T' == 84) && ('U' == 85) && ('V' == 86) && ('W' == 87) \ | ||
| 313 | && ('X' == 88) && ('Y' == 89) && ('Z' == 90) && ('[' == 91) \ | ||
| 314 | && ('\\' == 92) && (']' == 93) && ('^' == 94) && ('_' == 95) \ | ||
| 315 | && ('`' == 96) && ('a' == 97) && ('b' == 98) && ('c' == 99) \ | ||
| 316 | && ('d' == 100) && ('e' == 101) && ('f' == 102) && ('g' == 103) \ | ||
| 317 | && ('h' == 104) && ('i' == 105) && ('j' == 106) && ('k' == 107) \ | ||
| 318 | && ('l' == 108) && ('m' == 109) && ('n' == 110) && ('o' == 111) \ | ||
| 319 | && ('p' == 112) && ('q' == 113) && ('r' == 114) && ('s' == 115) \ | ||
| 320 | && ('t' == 116) && ('u' == 117) && ('v' == 118) && ('w' == 119) \ | ||
| 321 | && ('x' == 120) && ('y' == 121) && ('z' == 122) && ('{' == 123) \ | ||
| 322 | && ('|' == 124) && ('}' == 125) && ('~' == 126) | ||
| 323 | /* The character set is ISO-646, not EBCDIC. */ | ||
| 324 | # define IS_BASIC_ASCII 1 | ||
| 325 | |||
| 326 | /* All locale encodings (see localcharset.h) map the characters 0x00..0x7F | ||
| 327 | to U+0000..U+007F, like ASCII, except for | ||
| 328 | CP864 different mapping of '%' | ||
| 329 | SHIFT_JIS different mappings of 0x5C, 0x7E | ||
| 330 | JOHAB different mapping of 0x5C | ||
| 331 | However, these characters in the range 0x20..0x7E are in the ISO C | ||
| 332 | "basic character set" and in the POSIX "portable character set", which | ||
| 333 | ISO C and POSIX guarantee to be single-byte. Thus, locales with these | ||
| 334 | encodings are not POSIX compliant. And they are most likely not in use | ||
| 335 | any more (as of 2023). */ | ||
| 336 | # define is_basic(c) ((unsigned char) (c) < 0x80) | ||
| 337 | |||
| 338 | #else | ||
| 339 | |||
| 340 | MBCHAR_INLINE bool | ||
| 341 | is_basic (char c) | ||
| 342 | { | ||
| 343 | switch (c) | ||
| 344 | { | ||
| 345 | case '\0': | ||
| 346 | case '\007': case '\010': | ||
| 347 | case '\t': case '\n': case '\v': case '\f': case '\r': | ||
| 348 | case ' ': case '!': case '"': case '#': case '$': case '%': | ||
| 349 | case '&': case '\'': case '(': case ')': case '*': | ||
| 350 | case '+': case ',': case '-': case '.': case '/': | ||
| 351 | case '0': case '1': case '2': case '3': case '4': | ||
| 352 | case '5': case '6': case '7': case '8': case '9': | ||
| 353 | case ':': case ';': case '<': case '=': case '>': | ||
| 354 | case '?': case '@': | ||
| 355 | case 'A': case 'B': case 'C': case 'D': case 'E': | ||
| 356 | case 'F': case 'G': case 'H': case 'I': case 'J': | ||
| 357 | case 'K': case 'L': case 'M': case 'N': case 'O': | ||
| 358 | case 'P': case 'Q': case 'R': case 'S': case 'T': | ||
| 359 | case 'U': case 'V': case 'W': case 'X': case 'Y': | ||
| 360 | case 'Z': | ||
| 361 | case '[': case '\\': case ']': case '^': case '_': case '`': | ||
| 362 | case 'a': case 'b': case 'c': case 'd': case 'e': | ||
| 363 | case 'f': case 'g': case 'h': case 'i': case 'j': | ||
| 364 | case 'k': case 'l': case 'm': case 'n': case 'o': | ||
| 365 | case 'p': case 'q': case 'r': case 's': case 't': | ||
| 366 | case 'u': case 'v': case 'w': case 'x': case 'y': | ||
| 367 | case 'z': case '{': case '|': case '}': case '~': | ||
| 368 | return 1; | ||
| 369 | default: | ||
| 370 | return 0; | ||
| 371 | } | ||
| 372 | } | ||
| 373 | |||
| 374 | #endif | ||
| 375 | |||
| 376 | |||
| 377 | #ifdef __cplusplus | ||
| 378 | } | ||
| 379 | #endif | ||
| 380 | |||
| 381 | _GL_INLINE_HEADER_END | ||
| 382 | |||
| 383 | #endif /* _MBCHAR_H */ | ||
diff --git a/gl/mbiterf.c b/gl/mbiterf.c new file mode 100644 index 00000000..ad354c55 --- /dev/null +++ b/gl/mbiterf.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Iterating through multibyte strings: macros for multi-byte encodings. | ||
| 2 | |||
| 3 | Copyright (C) 2023-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | #define MBITERF_INLINE _GL_EXTERN_INLINE | ||
| 21 | #include "mbiterf.h" | ||
diff --git a/gl/mbiterf.h b/gl/mbiterf.h new file mode 100644 index 00000000..99d8d11d --- /dev/null +++ b/gl/mbiterf.h | |||
| @@ -0,0 +1,214 @@ | |||
| 1 | /* Iterating through multibyte strings, faster: macros for multi-byte encodings. | ||
| 2 | Copyright (C) 2001, 2005, 2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, | ||
| 18 | with insights from Paul Eggert. */ | ||
| 19 | |||
| 20 | /* The macros in this file implement forward iteration through a | ||
| 21 | multi-byte string. | ||
| 22 | |||
| 23 | With these macros, an iteration loop that looks like | ||
| 24 | |||
| 25 | char *iter; | ||
| 26 | for (iter = buf; iter < buf + buflen; iter++) | ||
| 27 | { | ||
| 28 | do_something (*iter); | ||
| 29 | } | ||
| 30 | |||
| 31 | becomes | ||
| 32 | |||
| 33 | const char *buf_end = buf + buflen; | ||
| 34 | mbif_state_t state; | ||
| 35 | [const] char *iter; | ||
| 36 | for (mbif_init (state), iter = buf; mbif_avail (state, iter, buf_end); ) | ||
| 37 | { | ||
| 38 | mbchar_t cur = mbif_next (state, iter, buf_end); | ||
| 39 | // Note: Here always mb_ptr (cur) == iter. | ||
| 40 | do_something (iter, mb_len (cur)); | ||
| 41 | iter += mb_len (cur); | ||
| 42 | } | ||
| 43 | |||
| 44 | The benefit of these macros over plain use of mbrtowc or mbrtoc32 is: | ||
| 45 | - Handling of invalid multibyte sequences is possible without | ||
| 46 | making the code more complicated, while still preserving the | ||
| 47 | invalid multibyte sequences. | ||
| 48 | |||
| 49 | The benefit of these macros over those from mbiter.h is that it | ||
| 50 | produces faster code with today's optimizing compilers (because mbif_next | ||
| 51 | returns its result by value). | ||
| 52 | |||
| 53 | mbif_state_t | ||
| 54 | is a type usable for variable declarations. | ||
| 55 | |||
| 56 | mbif_init (state) | ||
| 57 | initializes the state. | ||
| 58 | |||
| 59 | mbif_avail (state, iter, endptr) | ||
| 60 | returns true if another loop round is needed. | ||
| 61 | |||
| 62 | mbif_next (state, iter, endptr) | ||
| 63 | returns the next multibyte character. | ||
| 64 | It asssumes that the state is initialized and that iter < endptr. | ||
| 65 | |||
| 66 | Here are the function prototypes of the macros. | ||
| 67 | |||
| 68 | extern void mbif_init (mbif_state_t state); | ||
| 69 | extern bool mbif_avail (mbif_state_t state, const char *iter, const char *endptr); | ||
| 70 | extern mbchar_t mbif_next (mbif_state_t state, const char *iter, const char *endptr); | ||
| 71 | */ | ||
| 72 | |||
| 73 | #ifndef _MBITERF_H | ||
| 74 | #define _MBITERF_H 1 | ||
| 75 | |||
| 76 | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, | ||
| 77 | _GL_ATTRIBUTE_ALWAYS_INLINE. */ | ||
| 78 | #if !_GL_CONFIG_H_INCLUDED | ||
| 79 | #error "Please include config.h first." | ||
| 80 | #endif | ||
| 81 | |||
| 82 | #include <assert.h> | ||
| 83 | #include <stddef.h> | ||
| 84 | #include <string.h> | ||
| 85 | #include <uchar.h> | ||
| 86 | #include <wchar.h> | ||
| 87 | |||
| 88 | #include "mbchar.h" | ||
| 89 | |||
| 90 | _GL_INLINE_HEADER_BEGIN | ||
| 91 | #ifndef MBITERF_INLINE | ||
| 92 | # define MBITERF_INLINE _GL_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE | ||
| 93 | #endif | ||
| 94 | |||
| 95 | #ifdef __cplusplus | ||
| 96 | extern "C" { | ||
| 97 | #endif | ||
| 98 | |||
| 99 | |||
| 100 | struct mbif_state | ||
| 101 | { | ||
| 102 | #if !GNULIB_MBRTOC32_REGULAR | ||
| 103 | bool in_shift; /* true if next byte may not be interpreted as ASCII */ | ||
| 104 | /* If GNULIB_MBRTOC32_REGULAR, it is always false, | ||
| 105 | so optimize it away. */ | ||
| 106 | #endif | ||
| 107 | mbstate_t state; /* if in_shift: current shift state */ | ||
| 108 | /* If GNULIB_MBRTOC32_REGULAR, it is in an initial state | ||
| 109 | before and after every mbiterf_next invocation. | ||
| 110 | */ | ||
| 111 | }; | ||
| 112 | |||
| 113 | MBITERF_INLINE mbchar_t | ||
| 114 | mbiterf_next (struct mbif_state *ps, const char *iter, const char *endptr) | ||
| 115 | { | ||
| 116 | #if !GNULIB_MBRTOC32_REGULAR | ||
| 117 | if (ps->in_shift) | ||
| 118 | goto with_shift; | ||
| 119 | #endif | ||
| 120 | /* Handle most ASCII characters quickly, without calling mbrtowc(). */ | ||
| 121 | if (is_basic (*iter)) | ||
| 122 | { | ||
| 123 | /* These characters are part of the POSIX portable character set. | ||
| 124 | For most of them, namely those in the ISO C basic character set, | ||
| 125 | ISO C 99 guarantees that their wide character code is identical to | ||
| 126 | their char code. For the few other ones, this is the case as well, | ||
| 127 | in all locale encodings that are in use. The 32-bit wide character | ||
| 128 | code is the same as well. */ | ||
| 129 | return (mbchar_t) { .ptr = iter, .bytes = 1, .wc_valid = true, .wc = *iter }; | ||
| 130 | } | ||
| 131 | else | ||
| 132 | { | ||
| 133 | assert (mbsinit (&ps->state)); | ||
| 134 | #if !GNULIB_MBRTOC32_REGULAR | ||
| 135 | ps->in_shift = true; | ||
| 136 | with_shift:; | ||
| 137 | #endif | ||
| 138 | size_t bytes; | ||
| 139 | char32_t wc; | ||
| 140 | bytes = mbrtoc32 (&wc, iter, endptr - iter, &ps->state); | ||
| 141 | if (bytes == (size_t) -1) | ||
| 142 | { | ||
| 143 | /* An invalid multibyte sequence was encountered. */ | ||
| 144 | /* Allow the next invocation to continue from a sane state. */ | ||
| 145 | #if !GNULIB_MBRTOC32_REGULAR | ||
| 146 | ps->in_shift = false; | ||
| 147 | #endif | ||
| 148 | mbszero (&ps->state); | ||
| 149 | return (mbchar_t) { .ptr = iter, .bytes = 1, .wc_valid = false }; | ||
| 150 | } | ||
| 151 | else if (bytes == (size_t) -2) | ||
| 152 | { | ||
| 153 | /* An incomplete multibyte character at the end. */ | ||
| 154 | #if !GNULIB_MBRTOC32_REGULAR | ||
| 155 | ps->in_shift = false; | ||
| 156 | #endif | ||
| 157 | /* Whether to reset ps->state or not is not important; the string end | ||
| 158 | is reached anyway. */ | ||
| 159 | return (mbchar_t) { .ptr = iter, .bytes = endptr - iter, .wc_valid = false }; | ||
| 160 | } | ||
| 161 | else | ||
| 162 | { | ||
| 163 | if (bytes == 0) | ||
| 164 | { | ||
| 165 | /* A null wide character was encountered. */ | ||
| 166 | bytes = 1; | ||
| 167 | assert (*iter == '\0'); | ||
| 168 | assert (wc == 0); | ||
| 169 | } | ||
| 170 | #if !GNULIB_MBRTOC32_REGULAR | ||
| 171 | else if (bytes == (size_t) -3) | ||
| 172 | /* The previous multibyte sequence produced an additional 32-bit | ||
| 173 | wide character. */ | ||
| 174 | bytes = 0; | ||
| 175 | #endif | ||
| 176 | |||
| 177 | /* When in an initial state, we can go back treating ASCII | ||
| 178 | characters more quickly. */ | ||
| 179 | #if !GNULIB_MBRTOC32_REGULAR | ||
| 180 | if (mbsinit (&ps->state)) | ||
| 181 | ps->in_shift = false; | ||
| 182 | #endif | ||
| 183 | return (mbchar_t) { .ptr = iter, .bytes = bytes, .wc_valid = true, .wc = wc }; | ||
| 184 | } | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | /* Iteration macros. */ | ||
| 189 | typedef struct mbif_state mbif_state_t; | ||
| 190 | #if !GNULIB_MBRTOC32_REGULAR | ||
| 191 | #define mbif_init(st) \ | ||
| 192 | ((st).in_shift = false, mbszero (&(st).state)) | ||
| 193 | #else | ||
| 194 | /* Optimized: no in_shift. */ | ||
| 195 | #define mbif_init(st) \ | ||
| 196 | (mbszero (&(st).state)) | ||
| 197 | #endif | ||
| 198 | #if !GNULIB_MBRTOC32_REGULAR | ||
| 199 | #define mbif_avail(st, iter, endptr) ((st).in_shift || ((iter) < (endptr))) | ||
| 200 | #else | ||
| 201 | /* Optimized: no in_shift. */ | ||
| 202 | #define mbif_avail(st, iter, endptr) ((iter) < (endptr)) | ||
| 203 | #endif | ||
| 204 | #define mbif_next(st, iter, endptr) \ | ||
| 205 | mbiterf_next (&(st), (iter), (endptr)) | ||
| 206 | |||
| 207 | |||
| 208 | #ifdef __cplusplus | ||
| 209 | } | ||
| 210 | #endif | ||
| 211 | |||
| 212 | _GL_INLINE_HEADER_END | ||
| 213 | |||
| 214 | #endif /* _MBITERF_H */ | ||
diff --git a/gl/mbrtoc32.c b/gl/mbrtoc32.c new file mode 100644 index 00000000..c4625525 --- /dev/null +++ b/gl/mbrtoc32.c | |||
| @@ -0,0 +1,288 @@ | |||
| 1 | /* Convert multibyte character to 32-bit wide character. | ||
| 2 | Copyright (C) 2020-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, 2020. */ | ||
| 18 | |||
| 19 | #include <config.h> | ||
| 20 | |||
| 21 | /* Specification. */ | ||
| 22 | #include <uchar.h> | ||
| 23 | |||
| 24 | #include "attribute.h" | ||
| 25 | |||
| 26 | #include <errno.h> | ||
| 27 | #include <stdlib.h> | ||
| 28 | |||
| 29 | #if GL_CHAR32_T_IS_UNICODE | ||
| 30 | # include "lc-charset-unicode.h" | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #if GNULIB_defined_mbstate_t /* AIX, IRIX */ | ||
| 34 | /* Implement mbrtoc32() on top of mbtowc() for the non-UTF-8 locales | ||
| 35 | and directly for the UTF-8 locales. */ | ||
| 36 | |||
| 37 | /* Note: On AIX (64-bit) we can implement mbrtoc32 in two equivalent ways: | ||
| 38 | - in a way that parallels the override of mbrtowc; this is the code branch | ||
| 39 | here; | ||
| 40 | - in a way that invokes the overridden mbrtowc; this would be the #else | ||
| 41 | branch below. | ||
| 42 | They are equivalent. */ | ||
| 43 | |||
| 44 | # if AVOID_ANY_THREADS | ||
| 45 | |||
| 46 | /* The option '--disable-threads' explicitly requests no locking. */ | ||
| 47 | |||
| 48 | # elif defined _WIN32 && !defined __CYGWIN__ | ||
| 49 | |||
| 50 | # define WIN32_LEAN_AND_MEAN /* avoid including junk */ | ||
| 51 | # include <windows.h> | ||
| 52 | |||
| 53 | # elif HAVE_PTHREAD_API | ||
| 54 | |||
| 55 | # include <pthread.h> | ||
| 56 | # if HAVE_THREADS_H && HAVE_WEAK_SYMBOLS | ||
| 57 | # include <threads.h> | ||
| 58 | # pragma weak thrd_exit | ||
| 59 | # define c11_threads_in_use() (thrd_exit != NULL) | ||
| 60 | # else | ||
| 61 | # define c11_threads_in_use() 0 | ||
| 62 | # endif | ||
| 63 | |||
| 64 | # elif HAVE_THREADS_H | ||
| 65 | |||
| 66 | # include <threads.h> | ||
| 67 | |||
| 68 | # endif | ||
| 69 | |||
| 70 | # include "lc-charset-dispatch.h" | ||
| 71 | # include "mbtowc-lock.h" | ||
| 72 | |||
| 73 | static_assert (sizeof (mbstate_t) >= 4); | ||
| 74 | static char internal_state[4]; | ||
| 75 | |||
| 76 | size_t | ||
| 77 | mbrtoc32 (char32_t *pwc, const char *s, size_t n, mbstate_t *ps) | ||
| 78 | { | ||
| 79 | # define FITS_IN_CHAR_TYPE(wc) 1 | ||
| 80 | # include "mbrtowc-impl.h" | ||
| 81 | } | ||
| 82 | |||
| 83 | #else /* glibc, macOS, FreeBSD, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, mingw, MSVC, Minix, Android */ | ||
| 84 | |||
| 85 | /* Implement mbrtoc32() based on the original mbrtoc32() or on mbrtowc(). */ | ||
| 86 | |||
| 87 | # include <wchar.h> | ||
| 88 | |||
| 89 | # include "localcharset.h" | ||
| 90 | # include "streq.h" | ||
| 91 | |||
| 92 | # if MBRTOC32_IN_C_LOCALE_MAYBE_EILSEQ | ||
| 93 | # include "hard-locale.h" | ||
| 94 | # include <locale.h> | ||
| 95 | # endif | ||
| 96 | |||
| 97 | static mbstate_t internal_state; | ||
| 98 | |||
| 99 | size_t | ||
| 100 | mbrtoc32 (char32_t *pwc, const char *s, size_t n, mbstate_t *ps) | ||
| 101 | # undef mbrtoc32 | ||
| 102 | { | ||
| 103 | /* It's simpler to handle the case s == NULL upfront, than to worry about | ||
| 104 | this case later, before every test of pwc and n. */ | ||
| 105 | if (s == NULL) | ||
| 106 | { | ||
| 107 | pwc = NULL; | ||
| 108 | s = ""; | ||
| 109 | n = 1; | ||
| 110 | } | ||
| 111 | |||
| 112 | # if MBRTOC32_EMPTY_INPUT_BUG || _GL_SMALL_WCHAR_T | ||
| 113 | if (n == 0) | ||
| 114 | return (size_t) -2; | ||
| 115 | # endif | ||
| 116 | |||
| 117 | if (ps == NULL) | ||
| 118 | ps = &internal_state; | ||
| 119 | |||
| 120 | # if HAVE_WORKING_MBRTOC32 && HAVE_WORKING_C32RTOMB && !MBRTOC32_MULTIBYTE_LOCALE_BUG | ||
| 121 | /* mbrtoc32() may produce different values for wc than mbrtowc(). Therefore | ||
| 122 | use mbrtoc32(). */ | ||
| 123 | |||
| 124 | # if defined _WIN32 && !defined __CYGWIN__ | ||
| 125 | char32_t wc; | ||
| 126 | size_t ret = mbrtoc32 (&wc, s, n, ps); | ||
| 127 | if (ret < (size_t) -2 && pwc != NULL) | ||
| 128 | *pwc = wc; | ||
| 129 | # else | ||
| 130 | size_t ret = mbrtoc32 (pwc, s, n, ps); | ||
| 131 | # endif | ||
| 132 | |||
| 133 | # if GNULIB_MBRTOC32_REGULAR | ||
| 134 | /* Verify that mbrtoc32 is regular. */ | ||
| 135 | if (ret < (size_t) -3 && ! mbsinit (ps)) | ||
| 136 | /* This occurs on glibc 2.36. */ | ||
| 137 | mbszero (ps); | ||
| 138 | if (ret == (size_t) -3) | ||
| 139 | abort (); | ||
| 140 | # endif | ||
| 141 | |||
| 142 | # if MBRTOC32_IN_C_LOCALE_MAYBE_EILSEQ | ||
| 143 | if ((size_t) -2 <= ret && n != 0 && ! hard_locale (LC_CTYPE)) | ||
| 144 | { | ||
| 145 | if (pwc != NULL) | ||
| 146 | *pwc = (unsigned char) *s; | ||
| 147 | return 1; | ||
| 148 | } | ||
| 149 | # endif | ||
| 150 | |||
| 151 | return ret; | ||
| 152 | |||
| 153 | # elif _GL_SMALL_WCHAR_T | ||
| 154 | |||
| 155 | /* Special-case all encodings that may produce wide character values | ||
| 156 | > WCHAR_MAX. */ | ||
| 157 | const char *encoding = locale_charset (); | ||
| 158 | if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) | ||
| 159 | { | ||
| 160 | /* Special-case the UTF-8 encoding. Assume that the wide-character | ||
| 161 | encoding in a UTF-8 locale is UCS-2 or, equivalently, UTF-16. */ | ||
| 162 | /* Here n > 0. */ | ||
| 163 | char *pstate = (char *)ps; | ||
| 164 | size_t nstate = pstate[0]; | ||
| 165 | char buf[4]; | ||
| 166 | const char *p; | ||
| 167 | size_t m; | ||
| 168 | int res; | ||
| 169 | |||
| 170 | switch (nstate) | ||
| 171 | { | ||
| 172 | case 0: | ||
| 173 | p = s; | ||
| 174 | m = n; | ||
| 175 | break; | ||
| 176 | case 3: | ||
| 177 | buf[2] = pstate[3]; | ||
| 178 | FALLTHROUGH; | ||
| 179 | case 2: | ||
| 180 | buf[1] = pstate[2]; | ||
| 181 | FALLTHROUGH; | ||
| 182 | case 1: | ||
| 183 | buf[0] = pstate[1]; | ||
| 184 | p = buf; | ||
| 185 | m = nstate; | ||
| 186 | buf[m++] = s[0]; | ||
| 187 | if (n >= 2 && m < 4) | ||
| 188 | { | ||
| 189 | buf[m++] = s[1]; | ||
| 190 | if (n >= 3 && m < 4) | ||
| 191 | buf[m++] = s[2]; | ||
| 192 | } | ||
| 193 | break; | ||
| 194 | default: | ||
| 195 | errno = EINVAL; | ||
| 196 | return (size_t)(-1); | ||
| 197 | } | ||
| 198 | |||
| 199 | /* Here m > 0. */ | ||
| 200 | |||
| 201 | { | ||
| 202 | # define FITS_IN_CHAR_TYPE(wc) 1 | ||
| 203 | # include "mbrtowc-impl-utf8.h" | ||
| 204 | } | ||
| 205 | |||
| 206 | success: | ||
| 207 | if (nstate >= (res > 0 ? res : 1)) | ||
| 208 | abort (); | ||
| 209 | res -= nstate; | ||
| 210 | /* Set *ps to an initial state. */ | ||
| 211 | # if defined _WIN32 && !defined __CYGWIN__ | ||
| 212 | /* Native Windows. */ | ||
| 213 | /* MSVC defines 'mbstate_t' as an 8-byte struct; the first 4 bytes matter. | ||
| 214 | On mingw, 'mbstate_t' is sometimes defined as 'int', sometimes defined | ||
| 215 | as an 8-byte struct, of which the first 4 bytes matter. */ | ||
| 216 | *(unsigned int *)pstate = 0; | ||
| 217 | # elif defined __CYGWIN__ | ||
| 218 | /* Cygwin defines 'mbstate_t' as an 8-byte struct; the first 4 bytes | ||
| 219 | matter. */ | ||
| 220 | ps->__count = 0; | ||
| 221 | # else | ||
| 222 | pstate[0] = 0; | ||
| 223 | # endif | ||
| 224 | return res; | ||
| 225 | |||
| 226 | incomplete: | ||
| 227 | { | ||
| 228 | size_t k = nstate; | ||
| 229 | /* Here 0 <= k < m < 4. */ | ||
| 230 | pstate[++k] = s[0]; | ||
| 231 | if (k < m) | ||
| 232 | { | ||
| 233 | pstate[++k] = s[1]; | ||
| 234 | if (k < m) | ||
| 235 | pstate[++k] = s[2]; | ||
| 236 | } | ||
| 237 | if (k != m) | ||
| 238 | abort (); | ||
| 239 | } | ||
| 240 | pstate[0] = m; | ||
| 241 | return (size_t)(-2); | ||
| 242 | |||
| 243 | invalid: | ||
| 244 | errno = EILSEQ; | ||
| 245 | /* The conversion state is undefined, says POSIX. */ | ||
| 246 | return (size_t)(-1); | ||
| 247 | } | ||
| 248 | else | ||
| 249 | { | ||
| 250 | wchar_t wc; | ||
| 251 | size_t ret = mbrtowc (&wc, s, n, ps); | ||
| 252 | if (ret < (size_t) -2 && pwc != NULL) | ||
| 253 | *pwc = wc; | ||
| 254 | return ret; | ||
| 255 | } | ||
| 256 | |||
| 257 | # else | ||
| 258 | |||
| 259 | /* char32_t and wchar_t are equivalent. Use mbrtowc(). */ | ||
| 260 | wchar_t wc; | ||
| 261 | size_t ret = mbrtowc (&wc, s, n, ps); | ||
| 262 | |||
| 263 | # if GNULIB_MBRTOC32_REGULAR | ||
| 264 | /* Ensure that mbrtoc32 is regular. */ | ||
| 265 | if (ret < (size_t) -2 && ! mbsinit (ps)) | ||
| 266 | /* This occurs on glibc 2.12. */ | ||
| 267 | mbszero (ps); | ||
| 268 | # endif | ||
| 269 | |||
| 270 | # if GL_CHAR32_T_IS_UNICODE && GL_CHAR32_T_VS_WCHAR_T_NEEDS_CONVERSION | ||
| 271 | if (ret < (size_t) -2 && wc != 0) | ||
| 272 | { | ||
| 273 | wc = locale_encoding_to_unicode (wc); | ||
| 274 | if (wc == 0) | ||
| 275 | { | ||
| 276 | ret = (size_t) -1; | ||
| 277 | errno = EILSEQ; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | # endif | ||
| 281 | if (ret < (size_t) -2 && pwc != NULL) | ||
| 282 | *pwc = wc; | ||
| 283 | return ret; | ||
| 284 | |||
| 285 | # endif | ||
| 286 | } | ||
| 287 | |||
| 288 | #endif | ||
diff --git a/gl/mbrtowc-impl-utf8.h b/gl/mbrtowc-impl-utf8.h index 3a3ba13c..98858e22 100644 --- a/gl/mbrtowc-impl-utf8.h +++ b/gl/mbrtowc-impl-utf8.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Convert multibyte character to wide character. | 1 | /* Convert multibyte character to wide character. |
| 2 | Copyright (C) 1999-2002, 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1999-2002, 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/mbrtowc-impl.h b/gl/mbrtowc-impl.h index 963631ca..61be6599 100644 --- a/gl/mbrtowc-impl.h +++ b/gl/mbrtowc-impl.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Convert multibyte character to wide character. | 1 | /* Convert multibyte character to wide character. |
| 2 | Copyright (C) 1999-2002, 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1999-2002, 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/mbrtowc.c b/gl/mbrtowc.c index 8a1646d2..6f0aa129 100644 --- a/gl/mbrtowc.c +++ b/gl/mbrtowc.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Convert multibyte character to wide character. | 1 | /* Convert multibyte character to wide character. |
| 2 | Copyright (C) 1999-2002, 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1999-2002, 2005-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/mbsinit.c b/gl/mbsinit.c index d1b8475c..2df30b32 100644 --- a/gl/mbsinit.c +++ b/gl/mbsinit.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Test for initial conversion state. | 1 | /* Test for initial conversion state. |
| 2 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/mbsnlen.c b/gl/mbsnlen.c new file mode 100644 index 00000000..9c25465a --- /dev/null +++ b/gl/mbsnlen.c | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* Counting the multibyte characters in a string. | ||
| 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2007. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include <string.h> | ||
| 22 | |||
| 23 | #include <stdlib.h> | ||
| 24 | |||
| 25 | #if GNULIB_MCEL_PREFER | ||
| 26 | # include "mcel.h" | ||
| 27 | #else | ||
| 28 | # include "mbiterf.h" | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* Return the number of multibyte characters in the character string starting | ||
| 32 | at STRING and ending at STRING + LEN. */ | ||
| 33 | size_t | ||
| 34 | mbsnlen (const char *string, size_t len) | ||
| 35 | { | ||
| 36 | if (MB_CUR_MAX > 1) | ||
| 37 | { | ||
| 38 | size_t count = 0; | ||
| 39 | |||
| 40 | const char *string_end = string + len; | ||
| 41 | |||
| 42 | #if GNULIB_MCEL_PREFER | ||
| 43 | for (; string < string_end; string += mcel_scan (string, string_end).len) | ||
| 44 | count++; | ||
| 45 | #else | ||
| 46 | mbif_state_t state; | ||
| 47 | const char *iter; | ||
| 48 | for (mbif_init (state), iter = string; mbif_avail (state, iter, string_end); ) | ||
| 49 | { | ||
| 50 | mbchar_t cur = mbif_next (state, iter, string_end); | ||
| 51 | count++; | ||
| 52 | iter += mb_len (cur); | ||
| 53 | } | ||
| 54 | #endif | ||
| 55 | |||
| 56 | return count; | ||
| 57 | } | ||
| 58 | else | ||
| 59 | return len; | ||
| 60 | } | ||
diff --git a/gl/mbszero.c b/gl/mbszero.c index 25af2848..36fc9200 100644 --- a/gl/mbszero.c +++ b/gl/mbszero.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Put an mbstate_t into an initial conversion state. | 1 | /* Put an mbstate_t into an initial conversion state. |
| 2 | Copyright (C) 2023-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2023-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/mbtowc-impl.h b/gl/mbtowc-impl.h index 92efb4a7..3366c9da 100644 --- a/gl/mbtowc-impl.h +++ b/gl/mbtowc-impl.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Convert multibyte character to wide character. | 1 | /* Convert multibyte character to wide character. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/mbtowc-lock.c b/gl/mbtowc-lock.c index 9001c5af..e350608b 100644 --- a/gl/mbtowc-lock.c +++ b/gl/mbtowc-lock.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Return the internal lock used by mbrtowc and mbrtoc32. | 1 | /* Return the internal lock used by mbrtowc and mbrtoc32. |
| 2 | Copyright (C) 2019-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/mbtowc-lock.h b/gl/mbtowc-lock.h index 10f7dc7c..500f74cc 100644 --- a/gl/mbtowc-lock.h +++ b/gl/mbtowc-lock.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Use the internal lock used by mbrtowc and mbrtoc32. | 1 | /* Use the internal lock used by mbrtowc and mbrtoc32. |
| 2 | Copyright (C) 2019-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/mbtowc.c b/gl/mbtowc.c index 31a2d635..27ff35c6 100644 --- a/gl/mbtowc.c +++ b/gl/mbtowc.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Convert multibyte character to wide character. | 1 | /* Convert multibyte character to wide character. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/memchr.c b/gl/memchr.c index 67687a8f..ef0d15f7 100644 --- a/gl/memchr.c +++ b/gl/memchr.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2024 | 1 | /* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2025 |
| 2 | Free Software Foundation, Inc. | 2 | Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | Based on strlen implementation by Torbjorn Granlund (tege@sics.se), | 4 | Based on strlen implementation by Torbjorn Granlund (tege@sics.se), |
diff --git a/gl/memchr.valgrind b/gl/memchr.valgrind index 0295d7e6..8e55c207 100644 --- a/gl/memchr.valgrind +++ b/gl/memchr.valgrind | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | # Suppress a valgrind message about use of uninitialized memory in memchr(). | 1 | # Suppress a valgrind message about use of uninitialized memory in memchr(). |
| 2 | 2 | ||
| 3 | # Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | # Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | # | 4 | # |
| 5 | # This file is free software: you can redistribute it and/or modify | 5 | # This file is free software: you can redistribute it and/or modify |
| 6 | # it under the terms of the GNU Lesser General Public License as | 6 | # it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/minmax.h b/gl/minmax.h index f3df58b0..355de4b1 100644 --- a/gl/minmax.h +++ b/gl/minmax.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* MIN, MAX macros. | 1 | /* MIN, MAX macros. |
| 2 | Copyright (C) 1995, 1998, 2001, 2003, 2005, 2009-2024 Free Software | 2 | Copyright (C) 1995, 1998, 2001, 2003, 2005, 2009-2025 Free Software |
| 3 | Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/mktime-internal.h b/gl/mktime-internal.h index 0693aaf1..215be914 100644 --- a/gl/mktime-internal.h +++ b/gl/mktime-internal.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Internals of mktime and related functions | 1 | /* Internals of mktime and related functions |
| 2 | Copyright 2016-2024 Free Software Foundation, Inc. | 2 | Copyright 2016-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Contributed by Paul Eggert <eggert@cs.ucla.edu>. | 4 | Contributed by Paul Eggert <eggert@cs.ucla.edu>. |
| 5 | 5 | ||
| @@ -19,6 +19,9 @@ | |||
| 19 | 19 | ||
| 20 | #ifndef _LIBC | 20 | #ifndef _LIBC |
| 21 | # include <time.h> | 21 | # include <time.h> |
| 22 | # define __libc_lock_lock(lock) ((void) 0) | ||
| 23 | # define __libc_lock_unlock(lock) ((void) 0) | ||
| 24 | # define __tzset_unlocked() tzset () | ||
| 22 | #endif | 25 | #endif |
| 23 | 26 | ||
| 24 | /* mktime_offset_t is a signed type wide enough to hold a UTC offset | 27 | /* mktime_offset_t is a signed type wide enough to hold a UTC offset |
| @@ -71,9 +74,10 @@ typedef int mktime_offset_t; | |||
| 71 | #endif | 74 | #endif |
| 72 | 75 | ||
| 73 | /* Subroutine of mktime. Return the time_t representation of TP and | 76 | /* Subroutine of mktime. Return the time_t representation of TP and |
| 74 | normalize TP, given that a struct tm * maps to a time_t as performed | 77 | normalize TP, given that a struct tm * maps to a time_t. If |
| 75 | by FUNC. Record next guess for localtime-gmtime offset in *OFFSET. */ | 78 | LOCAL, the mapping is performed by localtime_r, otherwise by gmtime_r. |
| 76 | extern __time64_t __mktime_internal (struct tm *tp, | 79 | Record next guess for localtime-gmtime offset in *OFFSET. |
| 77 | struct tm *(*func) (__time64_t const *, | 80 | |
| 78 | struct tm *), | 81 | If _LIBC, the caller must lock __tzset_lock. */ |
| 82 | extern __time64_t __mktime_internal (struct tm *tp, bool local, | ||
| 79 | mktime_offset_t *offset) attribute_hidden; | 83 | mktime_offset_t *offset) attribute_hidden; |
diff --git a/gl/mktime.c b/gl/mktime.c index c704f415..4218fca6 100644 --- a/gl/mktime.c +++ b/gl/mktime.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Convert a 'struct tm' to a time_t value. | 1 | /* Convert a 'struct tm' to a time_t value. |
| 2 | Copyright (C) 1993-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1993-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Contributed by Paul Eggert <eggert@twinsun.com>. | 4 | Contributed by Paul Eggert <eggert@twinsun.com>. |
| 5 | 5 | ||
| @@ -51,7 +51,6 @@ | |||
| 51 | #include <string.h> | 51 | #include <string.h> |
| 52 | 52 | ||
| 53 | #include <intprops.h> | 53 | #include <intprops.h> |
| 54 | #include <verify.h> | ||
| 55 | 54 | ||
| 56 | #ifndef NEED_MKTIME_INTERNAL | 55 | #ifndef NEED_MKTIME_INTERNAL |
| 57 | # define NEED_MKTIME_INTERNAL 0 | 56 | # define NEED_MKTIME_INTERNAL 0 |
| @@ -63,6 +62,9 @@ | |||
| 63 | # define NEED_MKTIME_WORKING 0 | 62 | # define NEED_MKTIME_WORKING 0 |
| 64 | #endif | 63 | #endif |
| 65 | 64 | ||
| 65 | #ifdef _LIBC | ||
| 66 | # include <tzset.h> | ||
| 67 | #endif | ||
| 66 | #include "mktime-internal.h" | 68 | #include "mktime-internal.h" |
| 67 | 69 | ||
| 68 | #if !defined _LIBC && (NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS) | 70 | #if !defined _LIBC && (NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS) |
| @@ -99,8 +101,8 @@ my_tzset (void) | |||
| 99 | tzset (); | 101 | tzset (); |
| 100 | # endif | 102 | # endif |
| 101 | } | 103 | } |
| 102 | # undef __tzset | 104 | # undef tzset |
| 103 | # define __tzset() my_tzset () | 105 | # define tzset() my_tzset () |
| 104 | #endif | 106 | #endif |
| 105 | 107 | ||
| 106 | #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL | 108 | #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL |
| @@ -119,12 +121,12 @@ my_tzset (void) | |||
| 119 | __time64_t values that mktime can generate even on platforms where | 121 | __time64_t values that mktime can generate even on platforms where |
| 120 | __time64_t is wider than the int components of struct tm. */ | 122 | __time64_t is wider than the int components of struct tm. */ |
| 121 | 123 | ||
| 122 | #if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60 | 124 | # if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60 |
| 123 | typedef long int long_int; | 125 | typedef long int long_int; |
| 124 | #else | 126 | # else |
| 125 | typedef long long int long_int; | 127 | typedef long long int long_int; |
| 126 | #endif | 128 | # endif |
| 127 | verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 4 / 366 / 24 / 60 / 60); | 129 | static_assert (INT_MAX <= TYPE_MAXIMUM (long_int) / 4 / 366 / 24 / 60 / 60); |
| 128 | 130 | ||
| 129 | /* Shift A right by B bits portably, by dividing A by 2**B and | 131 | /* Shift A right by B bits portably, by dividing A by 2**B and |
| 130 | truncating towards minus infinity. B should be in the range 0 <= B | 132 | truncating towards minus infinity. B should be in the range 0 <= B |
| @@ -155,9 +157,9 @@ static long_int const mktime_max | |||
| 155 | = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t) | 157 | = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t) |
| 156 | ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t)); | 158 | ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t)); |
| 157 | 159 | ||
| 158 | #define EPOCH_YEAR 1970 | 160 | # define EPOCH_YEAR 1970 |
| 159 | #define TM_YEAR_BASE 1900 | 161 | # define TM_YEAR_BASE 1900 |
| 160 | verify (TM_YEAR_BASE % 100 == 0); | 162 | static_assert (TM_YEAR_BASE % 100 == 0); |
| 161 | 163 | ||
| 162 | /* Is YEAR + TM_YEAR_BASE a leap year? */ | 164 | /* Is YEAR + TM_YEAR_BASE a leap year? */ |
| 163 | static bool | 165 | static bool |
| @@ -172,9 +174,9 @@ leapyear (long_int year) | |||
| 172 | } | 174 | } |
| 173 | 175 | ||
| 174 | /* How many days come before each month (0-12). */ | 176 | /* How many days come before each month (0-12). */ |
| 175 | #ifndef _LIBC | 177 | # ifndef _LIBC |
| 176 | static | 178 | static |
| 177 | #endif | 179 | # endif |
| 178 | const unsigned short int __mon_yday[2][13] = | 180 | const unsigned short int __mon_yday[2][13] = |
| 179 | { | 181 | { |
| 180 | /* Normal years. */ | 182 | /* Normal years. */ |
| @@ -206,7 +208,7 @@ static long_int | |||
| 206 | ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, | 208 | ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, |
| 207 | int year0, int yday0, int hour0, int min0, int sec0) | 209 | int year0, int yday0, int hour0, int min0, int sec0) |
| 208 | { | 210 | { |
| 209 | verify (-1 / 2 == 0); | 211 | static_assert (-1 / 2 == 0); |
| 210 | 212 | ||
| 211 | /* Compute intervening leap days correctly even if year is negative. | 213 | /* Compute intervening leap days correctly even if year is negative. |
| 212 | Take care to avoid integer overflow here. */ | 214 | Take care to avoid integer overflow here. */ |
| @@ -251,29 +253,34 @@ tm_diff (long_int year, long_int yday, int hour, int min, int sec, | |||
| 251 | tp->tm_hour, tp->tm_min, tp->tm_sec); | 253 | tp->tm_hour, tp->tm_min, tp->tm_sec); |
| 252 | } | 254 | } |
| 253 | 255 | ||
| 254 | /* Use CONVERT to convert T to a struct tm value in *TM. T must be in | 256 | #ifndef _LIBC |
| 255 | range for __time64_t. Return TM if successful, NULL (setting errno) on | 257 | /* Convert T to a struct tm value in *TM. Use localtime64_r if LOCAL, |
| 256 | failure. */ | 258 | otherwise gmtime64_r. T must be in range for __time64_t. Return |
| 259 | TM if successful, NULL (setting errno) on failure. */ | ||
| 257 | static struct tm * | 260 | static struct tm * |
| 258 | convert_time (struct tm *(*convert) (const __time64_t *, struct tm *), | 261 | convert_time (long_int t, bool local, struct tm *tm) |
| 259 | long_int t, struct tm *tm) | ||
| 260 | { | 262 | { |
| 261 | __time64_t x = t; | 263 | __time64_t x = t; |
| 262 | return convert (&x, tm); | 264 | if (local) |
| 265 | return __localtime64_r (&x, tm); | ||
| 266 | else | ||
| 267 | return __gmtime64_r (&x, tm); | ||
| 263 | } | 268 | } |
| 269 | # define __tz_convert convert_time | ||
| 270 | #endif | ||
| 264 | 271 | ||
| 265 | /* Use CONVERT to convert *T to a broken down time in *TP. | 272 | /* Convert *T to a broken down time in *TP (as if by localtime if |
| 266 | If *T is out of range for conversion, adjust it so that | 273 | LOCAL, otherwise as if by gmtime). If *T is out of range for |
| 267 | it is the nearest in-range value and then convert that. | 274 | conversion, adjust it so that it is the nearest in-range value and |
| 268 | A value is in range if it fits in both __time64_t and long_int. | 275 | then convert that. A value is in range if it fits in both |
| 269 | Return TP on success, NULL (setting errno) on failure. */ | 276 | __time64_t and long_int. Return TP on success, NULL (setting |
| 277 | errno) on failure. */ | ||
| 270 | static struct tm * | 278 | static struct tm * |
| 271 | ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *), | 279 | ranged_convert (bool local, long_int *t, struct tm *tp) |
| 272 | long_int *t, struct tm *tp) | ||
| 273 | { | 280 | { |
| 274 | long_int t1 = (*t < mktime_min ? mktime_min | 281 | long_int t1 = (*t < mktime_min ? mktime_min |
| 275 | : *t <= mktime_max ? *t : mktime_max); | 282 | : *t <= mktime_max ? *t : mktime_max); |
| 276 | struct tm *r = convert_time (convert, t1, tp); | 283 | struct tm *r = __tz_convert (t1, local, tp); |
| 277 | if (r) | 284 | if (r) |
| 278 | { | 285 | { |
| 279 | *t = t1; | 286 | *t = t1; |
| @@ -294,7 +301,7 @@ ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *), | |||
| 294 | long_int mid = long_int_avg (ok, bad); | 301 | long_int mid = long_int_avg (ok, bad); |
| 295 | if (mid == ok || mid == bad) | 302 | if (mid == ok || mid == bad) |
| 296 | break; | 303 | break; |
| 297 | if (convert_time (convert, mid, tp)) | 304 | if (__tz_convert (mid, local, tp)) |
| 298 | ok = mid, oktm = *tp; | 305 | ok = mid, oktm = *tp; |
| 299 | else if (errno != EOVERFLOW) | 306 | else if (errno != EOVERFLOW) |
| 300 | return NULL; | 307 | return NULL; |
| @@ -310,29 +317,38 @@ ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *), | |||
| 310 | } | 317 | } |
| 311 | 318 | ||
| 312 | 319 | ||
| 313 | /* Convert *TP to a __time64_t value, inverting | 320 | /* Convert *TP to a __time64_t value. If LOCAL, the reverse mapping |
| 314 | the monotonic and mostly-unit-linear conversion function CONVERT. | 321 | is performed as if localtime, otherwise as if by gmtime. Use |
| 315 | Use *OFFSET to keep track of a guess at the offset of the result, | 322 | *OFFSET to keep track of a guess at the offset of the result, |
| 316 | compared to what the result would be for UTC without leap seconds. | 323 | compared to what the result would be for UTC without leap seconds. |
| 317 | If *OFFSET's guess is correct, only one CONVERT call is needed. | 324 | If *OFFSET's guess is correct, only one reverse mapping call is |
| 318 | If successful, set *TP to the canonicalized struct tm; | 325 | needed. If successful, set *TP to the canonicalized struct tm; |
| 319 | otherwise leave *TP alone, return ((time_t) -1) and set errno. | 326 | otherwise leave *TP alone, return ((time_t) -1) and set errno. |
| 320 | This function is external because it is used also by timegm.c. */ | 327 | This function is external because it is used also by timegm.c. |
| 328 | |||
| 329 | If _LIBC, the caller must lock __tzset_lock. */ | ||
| 321 | __time64_t | 330 | __time64_t |
| 322 | __mktime_internal (struct tm *tp, | 331 | __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset) |
| 323 | struct tm *(*convert) (const __time64_t *, struct tm *), | ||
| 324 | mktime_offset_t *offset) | ||
| 325 | { | 332 | { |
| 326 | struct tm tm; | 333 | struct tm tm; |
| 327 | 334 | ||
| 328 | /* The maximum number of probes (calls to CONVERT) should be enough | 335 | /* The maximum number of probes should be enough to handle any |
| 329 | to handle any combinations of time zone rule changes, solar time, | 336 | combinations of time zone rule changes, solar time, leap seconds, |
| 330 | leap seconds, and oscillations around a spring-forward gap. | 337 | and oscillations around a spring-forward gap. POSIX.1 prohibits |
| 331 | POSIX.1 prohibits leap seconds, but some hosts have them anyway. */ | 338 | leap seconds, but some hosts have them anyway. */ |
| 332 | int remaining_probes = 6; | 339 | int remaining_probes = 6; |
| 333 | 340 | ||
| 334 | /* Time requested. Copy it in case CONVERT modifies *TP; this can | 341 | #ifndef _LIBC |
| 335 | occur if TP is localtime's returned value and CONVERT is localtime. */ | 342 | /* Gnulib mktime doesn't lock the tz state, so it may need to probe |
| 343 | more often if some other thread changes local time while | ||
| 344 | __mktime_internal is probing. Double the number of probes; this | ||
| 345 | should suffice for practical cases that are at all likely. */ | ||
| 346 | remaining_probes *= 2; | ||
| 347 | #endif | ||
| 348 | |||
| 349 | /* Time requested. Copy it in case gmtime/localtime modify *TP; | ||
| 350 | this can occur if TP is localtime's returned value and CONVERT is | ||
| 351 | localtime. */ | ||
| 336 | int sec = tp->tm_sec; | 352 | int sec = tp->tm_sec; |
| 337 | int min = tp->tm_min; | 353 | int min = tp->tm_min; |
| 338 | int hour = tp->tm_hour; | 354 | int hour = tp->tm_hour; |
| @@ -341,8 +357,8 @@ __mktime_internal (struct tm *tp, | |||
| 341 | int year_requested = tp->tm_year; | 357 | int year_requested = tp->tm_year; |
| 342 | int isdst = tp->tm_isdst; | 358 | int isdst = tp->tm_isdst; |
| 343 | 359 | ||
| 344 | /* 1 if the previous probe was DST. */ | 360 | /* True if the previous probe was DST. */ |
| 345 | int dst2 = 0; | 361 | bool dst2 = false; |
| 346 | 362 | ||
| 347 | /* Ensure that mon is in range, and set year accordingly. */ | 363 | /* Ensure that mon is in range, and set year accordingly. */ |
| 348 | int mon_remainder = mon % 12; | 364 | int mon_remainder = mon % 12; |
| @@ -390,7 +406,7 @@ __mktime_internal (struct tm *tp, | |||
| 390 | 406 | ||
| 391 | while (true) | 407 | while (true) |
| 392 | { | 408 | { |
| 393 | if (! ranged_convert (convert, &t, &tm)) | 409 | if (! ranged_convert (local, &t, &tm)) |
| 394 | return -1; | 410 | return -1; |
| 395 | long_int dt = tm_diff (year, yday, hour, min, sec, &tm); | 411 | long_int dt = tm_diff (year, yday, hour, min, sec, &tm); |
| 396 | if (dt == 0) | 412 | if (dt == 0) |
| @@ -431,13 +447,10 @@ __mktime_internal (struct tm *tp, | |||
| 431 | 447 | ||
| 432 | Heuristic: probe the adjacent timestamps in both directions, | 448 | Heuristic: probe the adjacent timestamps in both directions, |
| 433 | looking for the desired isdst. If none is found within a | 449 | looking for the desired isdst. If none is found within a |
| 434 | reasonable duration bound, assume a one-hour DST difference. | 450 | reasonable duration bound, ignore the disagreement. |
| 435 | This should work for all real time zone histories in the tz | 451 | This should work for all real time zone histories in the tz |
| 436 | database. */ | 452 | database. */ |
| 437 | 453 | ||
| 438 | /* +1 if we wanted standard time but got DST, -1 if the reverse. */ | ||
| 439 | int dst_difference = (isdst == 0) - (tm.tm_isdst == 0); | ||
| 440 | |||
| 441 | /* Distance between probes when looking for a DST boundary. In | 454 | /* Distance between probes when looking for a DST boundary. In |
| 442 | tzdata2003a, the shortest period of DST is 601200 seconds | 455 | tzdata2003a, the shortest period of DST is 601200 seconds |
| 443 | (e.g., America/Recife starting 2000-10-08 01:00), and the | 456 | (e.g., America/Recife starting 2000-10-08 01:00), and the |
| @@ -447,21 +460,17 @@ __mktime_internal (struct tm *tp, | |||
| 447 | periods when probing. */ | 460 | periods when probing. */ |
| 448 | int stride = 601200; | 461 | int stride = 601200; |
| 449 | 462 | ||
| 450 | /* In TZDB 2021e, the longest period of DST (or of non-DST), in | 463 | /* Do not probe too far away from the requested time, |
| 451 | which the DST (or adjacent DST) difference is not one hour, | 464 | by striding until at least a year has passed, but then giving up. |
| 452 | is 457243209 seconds: e.g., America/Cambridge_Bay with leap | 465 | This helps avoid unexpected results in (for example) Asia/Kolkata, |
| 453 | seconds, starting 1965-10-31 00:00 in a switch from | 466 | for which today's users expect to see no DST even though it |
| 454 | double-daylight time (-05) to standard time (-07), and | 467 | did observe DST long ago. */ |
| 455 | continuing to 1980-04-27 02:00 in a switch from standard time | 468 | int year_seconds_bound = 366 * 24 * 60 * 60 + 1; |
| 456 | (-07) to daylight time (-06). */ | 469 | int delta_bound = year_seconds_bound + stride; |
| 457 | int duration_max = 457243209; | ||
| 458 | |||
| 459 | /* Search in both directions, so the maximum distance is half | ||
| 460 | the duration; add the stride to avoid off-by-1 problems. */ | ||
| 461 | int delta_bound = duration_max / 2 + stride; | ||
| 462 | 470 | ||
| 463 | int delta, direction; | 471 | int delta, direction; |
| 464 | 472 | ||
| 473 | /* Search in both directions, closest first. */ | ||
| 465 | for (delta = stride; delta < delta_bound; delta += stride) | 474 | for (delta = stride; delta < delta_bound; delta += stride) |
| 466 | for (direction = -1; direction <= 1; direction += 2) | 475 | for (direction = -1; direction <= 1; direction += 2) |
| 467 | { | 476 | { |
| @@ -469,7 +478,7 @@ __mktime_internal (struct tm *tp, | |||
| 469 | if (! ckd_add (&ot, t, delta * direction)) | 478 | if (! ckd_add (&ot, t, delta * direction)) |
| 470 | { | 479 | { |
| 471 | struct tm otm; | 480 | struct tm otm; |
| 472 | if (! ranged_convert (convert, &ot, &otm)) | 481 | if (! ranged_convert (local, &ot, &otm)) |
| 473 | return -1; | 482 | return -1; |
| 474 | if (! isdst_differ (isdst, otm.tm_isdst)) | 483 | if (! isdst_differ (isdst, otm.tm_isdst)) |
| 475 | { | 484 | { |
| @@ -479,7 +488,7 @@ __mktime_internal (struct tm *tp, | |||
| 479 | &otm); | 488 | &otm); |
| 480 | if (mktime_min <= gt && gt <= mktime_max) | 489 | if (mktime_min <= gt && gt <= mktime_max) |
| 481 | { | 490 | { |
| 482 | if (convert_time (convert, gt, &tm)) | 491 | if (__tz_convert (gt, local, &tm)) |
| 483 | { | 492 | { |
| 484 | t = gt; | 493 | t = gt; |
| 485 | goto offset_found; | 494 | goto offset_found; |
| @@ -491,13 +500,8 @@ __mktime_internal (struct tm *tp, | |||
| 491 | } | 500 | } |
| 492 | } | 501 | } |
| 493 | 502 | ||
| 494 | /* No unusual DST offset was found nearby. Assume one-hour DST. */ | 503 | /* No probe with the requested tm_isdst was found nearby. |
| 495 | t += 60 * 60 * dst_difference; | 504 | Ignore the requested tm_isdst. */ |
| 496 | if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm)) | ||
| 497 | goto offset_found; | ||
| 498 | |||
| 499 | __set_errno (EOVERFLOW); | ||
| 500 | return -1; | ||
| 501 | } | 505 | } |
| 502 | 506 | ||
| 503 | offset_found: | 507 | offset_found: |
| @@ -520,7 +524,7 @@ __mktime_internal (struct tm *tp, | |||
| 520 | __set_errno (EOVERFLOW); | 524 | __set_errno (EOVERFLOW); |
| 521 | return -1; | 525 | return -1; |
| 522 | } | 526 | } |
| 523 | if (! convert_time (convert, t, &tm)) | 527 | if (! __tz_convert (t, local, &tm)) |
| 524 | return -1; | 528 | return -1; |
| 525 | } | 529 | } |
| 526 | 530 | ||
| @@ -536,18 +540,19 @@ __mktime_internal (struct tm *tp, | |||
| 536 | __time64_t | 540 | __time64_t |
| 537 | __mktime64 (struct tm *tp) | 541 | __mktime64 (struct tm *tp) |
| 538 | { | 542 | { |
| 539 | /* POSIX.1 8.1.1 requires that whenever mktime() is called, the | 543 | __libc_lock_lock (__tzset_lock); |
| 540 | time zone names contained in the external variable 'tzname' shall | 544 | __tzset_unlocked (); |
| 541 | be set as if the tzset() function had been called. */ | ||
| 542 | __tzset (); | ||
| 543 | 545 | ||
| 544 | # if defined _LIBC || NEED_MKTIME_WORKING | 546 | # if defined _LIBC || NEED_MKTIME_WORKING |
| 545 | static mktime_offset_t localtime_offset; | 547 | static mktime_offset_t localtime_offset; |
| 546 | return __mktime_internal (tp, __localtime64_r, &localtime_offset); | 548 | __time64_t result = __mktime_internal (tp, true, &localtime_offset); |
| 547 | # else | 549 | # else |
| 548 | # undef mktime | 550 | # undef mktime |
| 549 | return mktime (tp); | 551 | __time64_t result = mktime (tp); |
| 550 | # endif | 552 | # endif |
| 553 | |||
| 554 | __libc_lock_unlock (__tzset_lock); | ||
| 555 | return result; | ||
| 551 | } | 556 | } |
| 552 | #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */ | 557 | #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */ |
| 553 | 558 | ||
diff --git a/gl/mountlist.c b/gl/mountlist.c index 06300d6b..dcff6f83 100644 --- a/gl/mountlist.c +++ b/gl/mountlist.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* mountlist.c -- return a list of mounted file systems | 1 | /* mountlist.c -- return a list of mounted file systems |
| 2 | 2 | ||
| 3 | Copyright (C) 1991-1992, 1997-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1991-1992, 1997-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software: you can redistribute it and/or modify | 5 | This program is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
| @@ -19,20 +19,18 @@ | |||
| 19 | 19 | ||
| 20 | #include "mountlist.h" | 20 | #include "mountlist.h" |
| 21 | 21 | ||
| 22 | #include <errno.h> | ||
| 23 | #include <fcntl.h> | ||
| 22 | #include <limits.h> | 24 | #include <limits.h> |
| 23 | #include <stdio.h> | 25 | #include <stdio.h> |
| 24 | #include <stdlib.h> | 26 | #include <stdlib.h> |
| 25 | #include <string.h> | 27 | #include <string.h> |
| 26 | #include <stdint.h> | 28 | #include <stdint.h> |
| 29 | #include <unistd.h> | ||
| 27 | 30 | ||
| 31 | #include "c-ctype.h" | ||
| 28 | #include "xalloc.h" | 32 | #include "xalloc.h" |
| 29 | 33 | ||
| 30 | #include <errno.h> | ||
| 31 | |||
| 32 | #include <fcntl.h> | ||
| 33 | |||
| 34 | #include <unistd.h> | ||
| 35 | |||
| 36 | #if HAVE_SYS_PARAM_H | 34 | #if HAVE_SYS_PARAM_H |
| 37 | # include <sys/param.h> | 35 | # include <sys/param.h> |
| 38 | #endif | 36 | #endif |
| @@ -132,6 +130,10 @@ | |||
| 132 | # endif | 130 | # endif |
| 133 | #endif | 131 | #endif |
| 134 | 132 | ||
| 133 | #if defined _WIN32 && !defined __CYGWIN__ | ||
| 134 | # include <windows.h> | ||
| 135 | #endif | ||
| 136 | |||
| 135 | #ifndef HAVE_HASMNTOPT | 137 | #ifndef HAVE_HASMNTOPT |
| 136 | # define hasmntopt(mnt, opt) ((char *) 0) | 138 | # define hasmntopt(mnt, opt) ((char *) 0) |
| 137 | #endif | 139 | #endif |
| @@ -396,15 +398,18 @@ dev_from_mount_options (char const *mount_options) | |||
| 396 | if (devopt) | 398 | if (devopt) |
| 397 | { | 399 | { |
| 398 | char const *optval = devopt + sizeof dev_pattern - 1; | 400 | char const *optval = devopt + sizeof dev_pattern - 1; |
| 399 | char *optvalend; | 401 | if (c_isxdigit (*optval)) |
| 400 | unsigned long int dev; | 402 | { |
| 401 | errno = 0; | 403 | char *optvalend; |
| 402 | dev = strtoul (optval, &optvalend, 16); | 404 | unsigned long int dev; |
| 403 | if (optval != optvalend | 405 | errno = 0; |
| 404 | && (*optvalend == '\0' || *optvalend == ',') | 406 | dev = strtoul (optval, &optvalend, 16); |
| 405 | && ! (dev == ULONG_MAX && errno == ERANGE) | 407 | if (optval != optvalend |
| 406 | && dev == (dev_t) dev) | 408 | && (*optvalend == '\0' || *optvalend == ',') |
| 407 | return dev; | 409 | && ! (dev == ULONG_MAX && errno == ERANGE) |
| 410 | && dev == (dev_t) dev) | ||
| 411 | return dev; | ||
| 412 | } | ||
| 408 | } | 413 | } |
| 409 | 414 | ||
| 410 | # endif | 415 | # endif |
| @@ -452,12 +457,8 @@ terminate_at_blank (char *str) | |||
| 452 | *s = '\0'; | 457 | *s = '\0'; |
| 453 | return s; | 458 | return s; |
| 454 | } | 459 | } |
| 455 | #endif | ||
| 456 | 460 | ||
| 457 | /* Return a list of the currently mounted file systems, or NULL on error. | 461 | #endif |
| 458 | Add each entry to the tail of the list so that they stay in order. | ||
| 459 | If NEED_FS_TYPE is true, ensure that the file system type fields in | ||
| 460 | the returned list are valid. Otherwise, they might not be. */ | ||
| 461 | 462 | ||
| 462 | struct mount_entry * | 463 | struct mount_entry * |
| 463 | read_file_system_list (bool need_fs_type) | 464 | read_file_system_list (bool need_fs_type) |
| @@ -567,7 +568,7 @@ read_file_system_list (bool need_fs_type) | |||
| 567 | goto free_then_fail; | 568 | goto free_then_fail; |
| 568 | } | 569 | } |
| 569 | else /* fallback to /proc/self/mounts (/etc/mtab). */ | 570 | else /* fallback to /proc/self/mounts (/etc/mtab). */ |
| 570 | # endif /* __linux __ || __ANDROID__ */ | 571 | # endif /* __linux__ || __ANDROID__ */ |
| 571 | { | 572 | { |
| 572 | struct mntent *mnt; | 573 | struct mntent *mnt; |
| 573 | char const *table = MOUNTED; | 574 | char const *table = MOUNTED; |
| @@ -883,7 +884,9 @@ read_file_system_list (bool need_fs_type) | |||
| 883 | me->me_mntroot = NULL; | 884 | me->me_mntroot = NULL; |
| 884 | me->me_type = xstrdup (mnt.mnt_fstype); | 885 | me->me_type = xstrdup (mnt.mnt_fstype); |
| 885 | me->me_type_malloced = 1; | 886 | me->me_type_malloced = 1; |
| 886 | me->me_dummy = MNT_IGNORE (&mnt) != 0; | 887 | /* The cast from 'struct extmnttab *' to 'struct mnttab *' is OK |
| 888 | because 'struct extmnttab' extends 'struct mnttab'. */ | ||
| 889 | me->me_dummy = MNT_IGNORE ((struct mnttab *) &mnt) != 0; | ||
| 887 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); | 890 | me->me_remote = ME_REMOTE (me->me_devname, me->me_type); |
| 888 | me->me_dev = makedev (mnt.mnt_major, mnt.mnt_minor); | 891 | me->me_dev = makedev (mnt.mnt_major, mnt.mnt_minor); |
| 889 | 892 | ||
| @@ -1092,6 +1095,201 @@ read_file_system_list (bool need_fs_type) | |||
| 1092 | } | 1095 | } |
| 1093 | #endif /* MOUNTED_INTERIX_STATVFS */ | 1096 | #endif /* MOUNTED_INTERIX_STATVFS */ |
| 1094 | 1097 | ||
| 1098 | #if defined _WIN32 && !defined __CYGWIN__ /* native Windows */ | ||
| 1099 | /* Don't assume that UNICODE is not defined. */ | ||
| 1100 | # undef GetDriveType | ||
| 1101 | # define GetDriveType GetDriveTypeA | ||
| 1102 | # undef GetVolumeInformation | ||
| 1103 | # define GetVolumeInformation GetVolumeInformationA | ||
| 1104 | { | ||
| 1105 | /* Windows has drive prefixes which are similar to mount points. | ||
| 1106 | GetLogicalDrives returns a bitmask where the i-th bit is set | ||
| 1107 | if ASCII 'A' + i is an available drive. See: | ||
| 1108 | <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getlogicaldrives>. */ | ||
| 1109 | DWORD value = GetLogicalDrives (); | ||
| 1110 | unsigned int i; | ||
| 1111 | |||
| 1112 | for (i = 0; i < 26; ++i) | ||
| 1113 | { | ||
| 1114 | if (value & (1U << i)) | ||
| 1115 | { | ||
| 1116 | char mountdir[4]; | ||
| 1117 | char fs_name[MAX_PATH + 1]; | ||
| 1118 | mountdir[0] = 'A' + i; | ||
| 1119 | mountdir[1] = ':'; | ||
| 1120 | mountdir[2] = '\\'; | ||
| 1121 | mountdir[3] = '\0'; | ||
| 1122 | /* Test whether the drive actually exists, and | ||
| 1123 | get the name of the file system. See: | ||
| 1124 | <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa>. */ | ||
| 1125 | if (GetVolumeInformation (mountdir, NULL, 0, NULL, NULL, NULL, | ||
| 1126 | fs_name, sizeof fs_name)) | ||
| 1127 | { | ||
| 1128 | me = xmalloc (sizeof *me); | ||
| 1129 | me->me_mountdir = xstrdup (mountdir); | ||
| 1130 | /* Check if drive is remote. See: | ||
| 1131 | <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdrivetypea>. */ | ||
| 1132 | me->me_remote = GetDriveType (mountdir) == DRIVE_REMOTE; | ||
| 1133 | /* Here we could use | ||
| 1134 | QueryDosDeviceW -> returns something like '\Device\HarddiskVolume2' | ||
| 1135 | GetVolumeNameForVolumeMountPointW -> return something like '\\?\Volume{...}' | ||
| 1136 | */ | ||
| 1137 | me->me_devname = NULL; | ||
| 1138 | { | ||
| 1139 | /* Find the SUBST or NET USE mapping of the given drive. | ||
| 1140 | <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-querydosdevicew> | ||
| 1141 | For testing of SUBST: <https://ss64.com/nt/subst.html> | ||
| 1142 | For testing of NET USE: <https://ss64.com/nt/net-use.html> */ | ||
| 1143 | wchar_t drive[3]; | ||
| 1144 | wchar_t mapping[MAX_PATH + 1]; | ||
| 1145 | drive[0] = L'A' + i; | ||
| 1146 | drive[1] = L':'; | ||
| 1147 | drive[2] = L'\0'; | ||
| 1148 | DWORD mapping_len = QueryDosDeviceW (drive, mapping, sizeof (mapping) / sizeof (mapping[0])); | ||
| 1149 | if (mapping_len > 4 && wcsncmp (mapping, L"\\??\\", 4) == 0) | ||
| 1150 | { | ||
| 1151 | /* It's a SUBSTed drive. */ | ||
| 1152 | char subst_dir[MAX_PATH + 1]; | ||
| 1153 | size_t subst_dir_len = wcstombs (subst_dir, mapping + 4, sizeof (subst_dir)); | ||
| 1154 | if (subst_dir_len > 0 && subst_dir_len <= MAX_PATH) | ||
| 1155 | me->me_mntroot = xstrdup (subst_dir); | ||
| 1156 | else | ||
| 1157 | /* mapping is too long or not convertible to the | ||
| 1158 | locale encoding. */ | ||
| 1159 | me->me_mntroot = NULL; | ||
| 1160 | } | ||
| 1161 | else if (mapping_len > 26 | ||
| 1162 | && wcsncmp (mapping, L"\\Device\\LanmanRedirector\\;", 26) == 0) | ||
| 1163 | { | ||
| 1164 | wchar_t *next_backslash = wcschr (mapping + 26, L'\\'); | ||
| 1165 | if (next_backslash != NULL) | ||
| 1166 | { | ||
| 1167 | *--next_backslash = L'\\'; | ||
| 1168 | char share_dir[MAX_PATH + 1]; | ||
| 1169 | size_t share_dir_len = wcstombs (share_dir, next_backslash, sizeof (share_dir)); | ||
| 1170 | if (share_dir_len > 0 && share_dir_len <= MAX_PATH) | ||
| 1171 | me->me_mntroot = xstrdup (share_dir); | ||
| 1172 | else | ||
| 1173 | /* mapping is too long or not convertible to the | ||
| 1174 | locale encoding. */ | ||
| 1175 | me->me_mntroot = NULL; | ||
| 1176 | } | ||
| 1177 | else | ||
| 1178 | /* mapping does not have the expected form. */ | ||
| 1179 | me->me_mntroot = NULL; | ||
| 1180 | } | ||
| 1181 | else | ||
| 1182 | /* It's neither a SUBSTed nor a NET USEd drive. */ | ||
| 1183 | me->me_mntroot = NULL; | ||
| 1184 | } | ||
| 1185 | me->me_dev = (dev_t) -1; | ||
| 1186 | me->me_dummy = 0; | ||
| 1187 | me->me_type = xstrdup (fs_name); | ||
| 1188 | me->me_type_malloced = 1; | ||
| 1189 | |||
| 1190 | /* Add to the linked list. */ | ||
| 1191 | *mtail = me; | ||
| 1192 | mtail = &me->me_next; | ||
| 1193 | } | ||
| 1194 | } | ||
| 1195 | } | ||
| 1196 | } | ||
| 1197 | { | ||
| 1198 | /* Windows also has true mount points, called "mounted folders". See | ||
| 1199 | <https://learn.microsoft.com/en-us/windows/win32/fileio/volume-mount-points> | ||
| 1200 | For testing: <https://learn.microsoft.com/en-us/windows-server/storage/disk-management/assign-a-mount-point-folder-path-to-a-drive> */ | ||
| 1201 | /* Enumerate the volumes. See | ||
| 1202 | <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstvolumew> | ||
| 1203 | <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findnextvolumew> | ||
| 1204 | <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findvolumeclose> */ | ||
| 1205 | wchar_t vol_name[MAX_PATH + 1]; | ||
| 1206 | HANDLE h = FindFirstVolumeW (vol_name, sizeof (vol_name) / sizeof (vol_name[0])); | ||
| 1207 | if (h != INVALID_HANDLE_VALUE) | ||
| 1208 | { | ||
| 1209 | do | ||
| 1210 | { | ||
| 1211 | /* Look where the volume vol_name is mounted. | ||
| 1212 | There are two APIs for doing this: | ||
| 1213 | - FindFirstVolumeMountPointW, FindNextVolumeMountPointW, | ||
| 1214 | FindVolumeMountPointClose. This API always fails with | ||
| 1215 | error code ERROR_ACCESS_DENIED. | ||
| 1216 | - GetVolumePathNamesForVolumeNameW. This API works but | ||
| 1217 | may require a significantly larger buffer. | ||
| 1218 | <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumepathnamesforvolumenamew> */ | ||
| 1219 | wchar_t stack_buf[MAX_PATH + 2]; | ||
| 1220 | wchar_t *malloced_buf = NULL; | ||
| 1221 | wchar_t *buf = stack_buf; | ||
| 1222 | DWORD bufsize = sizeof (stack_buf) / sizeof (wchar_t); | ||
| 1223 | BOOL success; | ||
| 1224 | for (;;) | ||
| 1225 | { | ||
| 1226 | success = GetVolumePathNamesForVolumeNameW (vol_name, buf, bufsize, &bufsize); | ||
| 1227 | if (!success && GetLastError () == ERROR_MORE_DATA) | ||
| 1228 | { | ||
| 1229 | free (malloced_buf); | ||
| 1230 | malloced_buf = (wchar_t *) xmalloc (bufsize * sizeof (wchar_t)); | ||
| 1231 | buf = malloced_buf; | ||
| 1232 | } | ||
| 1233 | else | ||
| 1234 | break; | ||
| 1235 | } | ||
| 1236 | if (success) | ||
| 1237 | { | ||
| 1238 | wchar_t *mount_dir = buf; | ||
| 1239 | while (*mount_dir != L'\0') | ||
| 1240 | { | ||
| 1241 | /* Drive mounts are already handled above. */ | ||
| 1242 | if (!(mount_dir[0] >= L'A' && mount_dir[0] <= L'Z' | ||
| 1243 | && mount_dir[1] == L':' && mount_dir[2] == L'\\' | ||
| 1244 | && mount_dir[3] == L'\0')) | ||
| 1245 | { | ||
| 1246 | char mountdir[MAX_PATH + 1]; | ||
| 1247 | size_t mountdir_len = wcstombs (mountdir, mount_dir, sizeof (mountdir)); | ||
| 1248 | if (mountdir_len > 0 && mountdir_len <= MAX_PATH) | ||
| 1249 | { | ||
| 1250 | char fs_name[MAX_PATH + 1]; | ||
| 1251 | /* Get the name of the file system. See: | ||
| 1252 | <https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa>. */ | ||
| 1253 | if (GetVolumeInformation (mountdir, NULL, 0, NULL, NULL, NULL, | ||
| 1254 | fs_name, sizeof fs_name)) | ||
| 1255 | { | ||
| 1256 | me = xmalloc (sizeof *me); | ||
| 1257 | me->me_mountdir = xstrdup (mountdir); | ||
| 1258 | me->me_remote = false; | ||
| 1259 | /* Here we could use vol_name, something like '\\?\Volume{...}'. */ | ||
| 1260 | me->me_devname = NULL; | ||
| 1261 | me->me_mntroot = NULL; | ||
| 1262 | me->me_dev = (dev_t) -1; | ||
| 1263 | me->me_dummy = 0; | ||
| 1264 | me->me_type = xstrdup (fs_name); | ||
| 1265 | me->me_type_malloced = 1; | ||
| 1266 | |||
| 1267 | /* Add to the linked list. */ | ||
| 1268 | *mtail = me; | ||
| 1269 | mtail = &me->me_next; | ||
| 1270 | } | ||
| 1271 | } | ||
| 1272 | else | ||
| 1273 | { | ||
| 1274 | /* mount_dir is too long or not convertible to the | ||
| 1275 | locale encoding. */ | ||
| 1276 | } | ||
| 1277 | } | ||
| 1278 | mount_dir += wcslen (mount_dir) + 1; | ||
| 1279 | } | ||
| 1280 | } | ||
| 1281 | free (malloced_buf); | ||
| 1282 | } | ||
| 1283 | while (FindNextVolumeW (h, vol_name, sizeof (vol_name) / sizeof (vol_name[0]))); | ||
| 1284 | FindVolumeClose (h); | ||
| 1285 | } | ||
| 1286 | } | ||
| 1287 | #endif | ||
| 1288 | |||
| 1289 | #if MOUNTED_NOT_PORTED | ||
| 1290 | # error "Please port gnulib mountlist.c to your platform!" | ||
| 1291 | #endif | ||
| 1292 | |||
| 1095 | *mtail = NULL; | 1293 | *mtail = NULL; |
| 1096 | return mount_list; | 1294 | return mount_list; |
| 1097 | 1295 | ||
diff --git a/gl/mountlist.h b/gl/mountlist.h index 9728e38b..e8ba1d96 100644 --- a/gl/mountlist.h +++ b/gl/mountlist.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* mountlist.h -- declarations for list of mounted file systems | 1 | /* mountlist.h -- declarations for list of mounted file systems |
| 2 | 2 | ||
| 3 | Copyright (C) 1991-1992, 1998, 2000-2005, 2009-2024 Free Software | 3 | Copyright (C) 1991-1992, 1998, 2000-2005, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This program is free software: you can redistribute it and/or modify | 6 | This program is free software: you can redistribute it and/or modify |
| @@ -46,8 +46,13 @@ struct mount_entry | |||
| 46 | struct mount_entry *me_next; | 46 | struct mount_entry *me_next; |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | /* Return a list of the currently mounted file systems, or NULL on error. | ||
| 50 | Add each entry to the tail of the list so that they stay in order. | ||
| 51 | If NEED_FS_TYPE is true, ensure that the file system type fields in | ||
| 52 | the returned list are valid. Otherwise, they might not be. */ | ||
| 49 | struct mount_entry *read_file_system_list (bool need_fs_type) | 53 | struct mount_entry *read_file_system_list (bool need_fs_type) |
| 50 | _GL_ATTRIBUTE_MALLOC; | 54 | _GL_ATTRIBUTE_MALLOC; |
| 55 | |||
| 51 | void free_mount_entry (struct mount_entry *entry); | 56 | void free_mount_entry (struct mount_entry *entry); |
| 52 | 57 | ||
| 53 | 58 | ||
diff --git a/gl/msvc-inval.c b/gl/msvc-inval.c index da3fc86a..1b51b1b0 100644 --- a/gl/msvc-inval.c +++ b/gl/msvc-inval.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Invalid parameter handler for MSVC runtime libraries. | 1 | /* Invalid parameter handler for MSVC runtime libraries. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/msvc-inval.h b/gl/msvc-inval.h index 7aee6e5d..9bb8a156 100644 --- a/gl/msvc-inval.h +++ b/gl/msvc-inval.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Invalid parameter handler for MSVC runtime libraries. | 1 | /* Invalid parameter handler for MSVC runtime libraries. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/msvc-nothrow.c b/gl/msvc-nothrow.c index 06b35a61..7cf7517e 100644 --- a/gl/msvc-nothrow.c +++ b/gl/msvc-nothrow.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Wrappers that don't throw invalid parameter notifications | 1 | /* Wrappers that don't throw invalid parameter notifications |
| 2 | with MSVC runtime libraries. | 2 | with MSVC runtime libraries. |
| 3 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/msvc-nothrow.h b/gl/msvc-nothrow.h index 121773d1..b02f36c4 100644 --- a/gl/msvc-nothrow.h +++ b/gl/msvc-nothrow.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Wrappers that don't throw invalid parameter notifications | 1 | /* Wrappers that don't throw invalid parameter notifications |
| 2 | with MSVC runtime libraries. | 2 | with MSVC runtime libraries. |
| 3 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/netdb.in.h b/gl/netdb.in.h index 43409b2f..22059ea0 100644 --- a/gl/netdb.in.h +++ b/gl/netdb.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Provide a netdb.h header file for systems lacking it (read: MinGW). | 1 | /* Provide a netdb.h header file for systems lacking it (read: MinGW). |
| 2 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 3 | Written by Simon Josefsson. | 3 | Written by Simon Josefsson. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -54,6 +54,14 @@ | |||
| 54 | /* Declarations for a platform that lacks <netdb.h>, or where it is | 54 | /* Declarations for a platform that lacks <netdb.h>, or where it is |
| 55 | incomplete. */ | 55 | incomplete. */ |
| 56 | 56 | ||
| 57 | /* Maximum length of a fully-qualified domain name. */ | ||
| 58 | #undef NI_MAXHOST | ||
| 59 | #define NI_MAXHOST 1025 | ||
| 60 | |||
| 61 | /* Maximum length of a service. */ | ||
| 62 | #undef NI_MAXSERV | ||
| 63 | #define NI_MAXSERV 32 | ||
| 64 | |||
| 57 | #if @GNULIB_GETADDRINFO@ | 65 | #if @GNULIB_GETADDRINFO@ |
| 58 | 66 | ||
| 59 | # if !@HAVE_STRUCT_ADDRINFO@ | 67 | # if !@HAVE_STRUCT_ADDRINFO@ |
| @@ -91,12 +99,11 @@ struct addrinfo | |||
| 91 | # ifndef AI_CANONNAME | 99 | # ifndef AI_CANONNAME |
| 92 | # define AI_CANONNAME 0x0002 /* Request for canonical name. */ | 100 | # define AI_CANONNAME 0x0002 /* Request for canonical name. */ |
| 93 | # endif | 101 | # endif |
| 94 | # ifndef AI_NUMERICSERV | 102 | # ifndef AI_NUMERICHOST |
| 95 | # define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */ | 103 | # define AI_NUMERICHOST 0x0004 /* Return numeric host address as name. */ |
| 96 | # endif | 104 | # endif |
| 97 | 105 | # ifndef AI_NUMERICSERV | |
| 98 | # if 0 | 106 | # define AI_NUMERICSERV 0x0400 /* Return service number as service name. */ |
| 99 | # define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */ | ||
| 100 | # endif | 107 | # endif |
| 101 | 108 | ||
| 102 | /* These symbolic constants are required to be present by POSIX, but | 109 | /* These symbolic constants are required to be present by POSIX, but |
| @@ -176,7 +183,7 @@ _GL_FUNCDECL_RPL (getaddrinfo, int, | |||
| 176 | (const char *restrict nodename, | 183 | (const char *restrict nodename, |
| 177 | const char *restrict servname, | 184 | const char *restrict servname, |
| 178 | const struct addrinfo *restrict hints, | 185 | const struct addrinfo *restrict hints, |
| 179 | struct addrinfo **restrict res) | 186 | struct addrinfo **restrict res), |
| 180 | _GL_ARG_NONNULL ((4))); | 187 | _GL_ARG_NONNULL ((4))); |
| 181 | _GL_CXXALIAS_RPL (getaddrinfo, int, | 188 | _GL_CXXALIAS_RPL (getaddrinfo, int, |
| 182 | (const char *restrict nodename, | 189 | (const char *restrict nodename, |
| @@ -189,7 +196,7 @@ _GL_FUNCDECL_SYS (getaddrinfo, int, | |||
| 189 | (const char *restrict nodename, | 196 | (const char *restrict nodename, |
| 190 | const char *restrict servname, | 197 | const char *restrict servname, |
| 191 | const struct addrinfo *restrict hints, | 198 | const struct addrinfo *restrict hints, |
| 192 | struct addrinfo **restrict res) | 199 | struct addrinfo **restrict res), |
| 193 | _GL_ARG_NONNULL ((4))); | 200 | _GL_ARG_NONNULL ((4))); |
| 194 | # endif | 201 | # endif |
| 195 | _GL_CXXALIAS_SYS (getaddrinfo, int, | 202 | _GL_CXXALIAS_SYS (getaddrinfo, int, |
| @@ -208,12 +215,12 @@ _GL_CXXALIASWARN (getaddrinfo); | |||
| 208 | # undef freeaddrinfo | 215 | # undef freeaddrinfo |
| 209 | # define freeaddrinfo rpl_freeaddrinfo | 216 | # define freeaddrinfo rpl_freeaddrinfo |
| 210 | # endif | 217 | # endif |
| 211 | _GL_FUNCDECL_RPL (freeaddrinfo, void, (struct addrinfo *ai) | 218 | _GL_FUNCDECL_RPL (freeaddrinfo, void, (struct addrinfo *ai), |
| 212 | _GL_ARG_NONNULL ((1))); | 219 | _GL_ARG_NONNULL ((1))); |
| 213 | _GL_CXXALIAS_RPL (freeaddrinfo, void, (struct addrinfo *ai)); | 220 | _GL_CXXALIAS_RPL (freeaddrinfo, void, (struct addrinfo *ai)); |
| 214 | # else | 221 | # else |
| 215 | # if !@HAVE_DECL_FREEADDRINFO@ | 222 | # if !@HAVE_DECL_FREEADDRINFO@ |
| 216 | _GL_FUNCDECL_SYS (freeaddrinfo, void, (struct addrinfo *ai) | 223 | _GL_FUNCDECL_SYS (freeaddrinfo, void, (struct addrinfo *ai), |
| 217 | _GL_ARG_NONNULL ((1))); | 224 | _GL_ARG_NONNULL ((1))); |
| 218 | # endif | 225 | # endif |
| 219 | _GL_CXXALIAS_SYS (freeaddrinfo, void, (struct addrinfo *ai)); | 226 | _GL_CXXALIAS_SYS (freeaddrinfo, void, (struct addrinfo *ai)); |
| @@ -225,14 +232,14 @@ _GL_CXXALIASWARN (freeaddrinfo); | |||
| 225 | # undef gai_strerror | 232 | # undef gai_strerror |
| 226 | # define gai_strerror rpl_gai_strerror | 233 | # define gai_strerror rpl_gai_strerror |
| 227 | # endif | 234 | # endif |
| 228 | _GL_FUNCDECL_RPL (gai_strerror, const char *, (int ecode)); | 235 | _GL_FUNCDECL_RPL (gai_strerror, const char *, (int ecode), ); |
| 229 | _GL_CXXALIAS_RPL (gai_strerror, const char *, (int ecode)); | 236 | _GL_CXXALIAS_RPL (gai_strerror, const char *, (int ecode)); |
| 230 | # else | 237 | # else |
| 231 | # if !@HAVE_DECL_GAI_STRERROR@ | 238 | # if !@HAVE_DECL_GAI_STRERROR@ |
| 232 | /* Convert error return from getaddrinfo() to a string. | 239 | /* Convert error return from getaddrinfo() to a string. |
| 233 | For more details, see the POSIX:2008 specification | 240 | For more details, see the POSIX:2008 specification |
| 234 | <https://pubs.opengroup.org/onlinepubs/9699919799/functions/gai_strerror.html>. */ | 241 | <https://pubs.opengroup.org/onlinepubs/9699919799/functions/gai_strerror.html>. */ |
| 235 | _GL_FUNCDECL_SYS (gai_strerror, const char *, (int ecode)); | 242 | _GL_FUNCDECL_SYS (gai_strerror, const char *, (int ecode), ); |
| 236 | # endif | 243 | # endif |
| 237 | _GL_CXXALIAS_SYS (gai_strerror, const char *, (int ecode)); | 244 | _GL_CXXALIAS_SYS (gai_strerror, const char *, (int ecode)); |
| 238 | # endif | 245 | # endif |
| @@ -248,7 +255,7 @@ _GL_FUNCDECL_SYS (getnameinfo, int, | |||
| 248 | (const struct sockaddr *restrict sa, socklen_t salen, | 255 | (const struct sockaddr *restrict sa, socklen_t salen, |
| 249 | char *restrict node, socklen_t nodelen, | 256 | char *restrict node, socklen_t nodelen, |
| 250 | char *restrict service, socklen_t servicelen, | 257 | char *restrict service, socklen_t servicelen, |
| 251 | int flags) | 258 | int flags), |
| 252 | _GL_ARG_NONNULL ((1))); | 259 | _GL_ARG_NONNULL ((1))); |
| 253 | # endif | 260 | # endif |
| 254 | /* Need to cast, because on glibc systems, the seventh parameter is | 261 | /* Need to cast, because on glibc systems, the seventh parameter is |
diff --git a/gl/netinet_in.in.h b/gl/netinet_in.in.h index 4e9f6f2d..402d01a9 100644 --- a/gl/netinet_in.in.h +++ b/gl/netinet_in.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Substitute for <netinet/in.h>. | 1 | /* Substitute for <netinet/in.h>. |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/nl_langinfo-lock.c b/gl/nl_langinfo-lock.c index 5a248ed8..1ac25515 100644 --- a/gl/nl_langinfo-lock.c +++ b/gl/nl_langinfo-lock.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Return the internal lock used by nl_langinfo. | 1 | /* Return the internal lock used by nl_langinfo. |
| 2 | Copyright (C) 2019-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/nl_langinfo.c b/gl/nl_langinfo.c index 64ff93b0..0180c26a 100644 --- a/gl/nl_langinfo.c +++ b/gl/nl_langinfo.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* nl_langinfo() replacement: query locale dependent information. | 1 | /* nl_langinfo() replacement: query locale dependent information. |
| 2 | 2 | ||
| 3 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -154,11 +154,15 @@ ctype_codeset (void) | |||
| 154 | "thread5 disturbed by threadN!", even when threadN invokes only | 154 | "thread5 disturbed by threadN!", even when threadN invokes only |
| 155 | nl_langinfo (CODESET); | 155 | nl_langinfo (CODESET); |
| 156 | nl_langinfo (CRNCYSTR); | 156 | nl_langinfo (CRNCYSTR); |
| 157 | Similarly on Solaris 10. */ | 157 | Similarly on Solaris 10 and macOS 26. */ |
| 158 | 158 | ||
| 159 | # if !NL_LANGINFO_MTSAFE /* Solaris */ | 159 | # if !NL_LANGINFO_MTSAFE /* macOS, Solaris */ |
| 160 | 160 | ||
| 161 | # define ITEMS (MAXSTRMSG + 1) | 161 | # ifdef __sun /* Solaris */ |
| 162 | # define ITEMS (MAXSTRMSG + 1) | ||
| 163 | # else /* macOS */ | ||
| 164 | # define ITEMS (CRNCYSTR + 20) | ||
| 165 | # endif | ||
| 162 | # define MAX_RESULT_LEN 80 | 166 | # define MAX_RESULT_LEN 80 |
| 163 | 167 | ||
| 164 | static char * | 168 | static char * |
| @@ -317,6 +321,24 @@ rpl_nl_langinfo (nl_item item) | |||
| 317 | item = item - ALTMON_1 + MON_1; | 321 | item = item - ALTMON_1 + MON_1; |
| 318 | break; | 322 | break; |
| 319 | # endif | 323 | # endif |
| 324 | # if GNULIB_defined_ABALTMON | ||
| 325 | case ABALTMON_1: | ||
| 326 | case ABALTMON_2: | ||
| 327 | case ABALTMON_3: | ||
| 328 | case ABALTMON_4: | ||
| 329 | case ABALTMON_5: | ||
| 330 | case ABALTMON_6: | ||
| 331 | case ABALTMON_7: | ||
| 332 | case ABALTMON_8: | ||
| 333 | case ABALTMON_9: | ||
| 334 | case ABALTMON_10: | ||
| 335 | case ABALTMON_11: | ||
| 336 | case ABALTMON_12: | ||
| 337 | /* We don't ship the appropriate localizations with gnulib. Therefore, | ||
| 338 | treat ABALTMON_i like ABMON_i. */ | ||
| 339 | item = item - ABALTMON_1 + ABMON_1; | ||
| 340 | break; | ||
| 341 | # endif | ||
| 320 | # if GNULIB_defined_ERA | 342 | # if GNULIB_defined_ERA |
| 321 | case ERA: | 343 | case ERA: |
| 322 | /* The format is not standardized. In glibc it is a sequence of strings | 344 | /* The format is not standardized. In glibc it is a sequence of strings |
| @@ -510,30 +532,57 @@ nl_langinfo (nl_item item) | |||
| 510 | return result[item - ALTMON_1]; | 532 | return result[item - ALTMON_1]; |
| 511 | } | 533 | } |
| 512 | } | 534 | } |
| 513 | case ABMON_1: | 535 | { |
| 514 | case ABMON_2: | 536 | static char const abmonths[][sizeof "Jan"] = { |
| 515 | case ABMON_3: | 537 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", |
| 516 | case ABMON_4: | 538 | "Aug", "Sep", "Oct", "Nov", "Dec" |
| 517 | case ABMON_5: | 539 | }; |
| 518 | case ABMON_6: | 540 | case ABMON_1: |
| 519 | case ABMON_7: | 541 | case ABMON_2: |
| 520 | case ABMON_8: | 542 | case ABMON_3: |
| 521 | case ABMON_9: | 543 | case ABMON_4: |
| 522 | case ABMON_10: | 544 | case ABMON_5: |
| 523 | case ABMON_11: | 545 | case ABMON_6: |
| 524 | case ABMON_12: | 546 | case ABMON_7: |
| 525 | { | 547 | case ABMON_8: |
| 526 | static char result[12][30]; | 548 | case ABMON_9: |
| 527 | static char const abmonths[][sizeof "Jan"] = { | 549 | case ABMON_10: |
| 528 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", | 550 | case ABMON_11: |
| 529 | "Aug", "Sep", "Oct", "Nov", "Dec" | 551 | case ABMON_12: |
| 530 | }; | 552 | { |
| 531 | tmm.tm_mon = item - ABMON_1; | 553 | static char result[12][30]; |
| 532 | if (!strftime (buf, sizeof result[0], "%b", &tmm)) | 554 | tmm.tm_mon = item - ABMON_1; |
| 533 | return (char *) abmonths[item - ABMON_1]; | 555 | if (!strftime (buf, sizeof result[0], "%b", &tmm)) |
| 534 | strcpy (result[item - ABMON_1], buf); | 556 | return (char *) abmonths[item - ABMON_1]; |
| 535 | return result[item - ABMON_1]; | 557 | strcpy (result[item - ABMON_1], buf); |
| 536 | } | 558 | return result[item - ABMON_1]; |
| 559 | } | ||
| 560 | case ABALTMON_1: | ||
| 561 | case ABALTMON_2: | ||
| 562 | case ABALTMON_3: | ||
| 563 | case ABALTMON_4: | ||
| 564 | case ABALTMON_5: | ||
| 565 | case ABALTMON_6: | ||
| 566 | case ABALTMON_7: | ||
| 567 | case ABALTMON_8: | ||
| 568 | case ABALTMON_9: | ||
| 569 | case ABALTMON_10: | ||
| 570 | case ABALTMON_11: | ||
| 571 | case ABALTMON_12: | ||
| 572 | { | ||
| 573 | static char result[12][50]; | ||
| 574 | tmm.tm_mon = item - ABALTMON_1; | ||
| 575 | /* The platforms without nl_langinfo() don't support strftime with | ||
| 576 | %Ob. We don't even need to try. */ | ||
| 577 | #if 0 | ||
| 578 | if (!strftime (buf, sizeof result[0], "%Ob", &tmm)) | ||
| 579 | #endif | ||
| 580 | if (!strftime (buf, sizeof result[0], "%b", &tmm)) | ||
| 581 | return (char *) abmonths[item - ABALTMON_1]; | ||
| 582 | strcpy (result[item - ABALTMON_1], buf); | ||
| 583 | return result[item - ABALTMON_1]; | ||
| 584 | } | ||
| 585 | } | ||
| 537 | case ERA: | 586 | case ERA: |
| 538 | return (char *) ""; | 587 | return (char *) ""; |
| 539 | case ALT_DIGITS: | 588 | case ALT_DIGITS: |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Open a descriptor to a file. | 1 | /* Open a descriptor to a file. |
| 2 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -55,24 +55,29 @@ orig_open (const char *filename, int flags, mode_t mode) | |||
| 55 | #include <sys/stat.h> | 55 | #include <sys/stat.h> |
| 56 | #include <unistd.h> | 56 | #include <unistd.h> |
| 57 | 57 | ||
| 58 | #ifndef HAVE_WORKING_O_DIRECTORY | ||
| 59 | # define HAVE_WORKING_O_DIRECTORY false | ||
| 60 | #endif | ||
| 61 | |||
| 62 | #ifndef OPEN_TRAILING_SLASH_BUG | ||
| 63 | # define OPEN_TRAILING_SLASH_BUG false | ||
| 64 | #endif | ||
| 65 | |||
| 58 | #ifndef REPLACE_OPEN_DIRECTORY | 66 | #ifndef REPLACE_OPEN_DIRECTORY |
| 59 | # define REPLACE_OPEN_DIRECTORY 0 | 67 | # define REPLACE_OPEN_DIRECTORY false |
| 60 | #endif | 68 | #endif |
| 61 | 69 | ||
| 70 | static int | ||
| 71 | lstatif (char const *filename, struct stat *st, int flags) | ||
| 72 | { | ||
| 73 | return flags & O_NOFOLLOW ? lstat (filename, st) : stat (filename, st); | ||
| 74 | } | ||
| 75 | |||
| 62 | int | 76 | int |
| 63 | open (const char *filename, int flags, ...) | 77 | open (const char *filename, int flags, ...) |
| 64 | { | 78 | { |
| 65 | /* 0 = unknown, 1 = yes, -1 = no. */ | 79 | mode_t mode = 0; |
| 66 | #if GNULIB_defined_O_CLOEXEC | ||
| 67 | int have_cloexec = -1; | ||
| 68 | #else | ||
| 69 | static int have_cloexec; | ||
| 70 | #endif | ||
| 71 | |||
| 72 | mode_t mode; | ||
| 73 | int fd; | ||
| 74 | 80 | ||
| 75 | mode = 0; | ||
| 76 | if (flags & O_CREAT) | 81 | if (flags & O_CREAT) |
| 77 | { | 82 | { |
| 78 | va_list arg; | 83 | va_list arg; |
| @@ -99,7 +104,6 @@ open (const char *filename, int flags, ...) | |||
| 99 | filename = "NUL"; | 104 | filename = "NUL"; |
| 100 | #endif | 105 | #endif |
| 101 | 106 | ||
| 102 | #if OPEN_TRAILING_SLASH_BUG | ||
| 103 | /* Fail if one of O_CREAT, O_WRONLY, O_RDWR is specified and the filename | 107 | /* Fail if one of O_CREAT, O_WRONLY, O_RDWR is specified and the filename |
| 104 | ends in a slash, as POSIX says such a filename must name a directory | 108 | ends in a slash, as POSIX says such a filename must name a directory |
| 105 | <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>: | 109 | <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>: |
| @@ -118,21 +122,55 @@ open (const char *filename, int flags, ...) | |||
| 118 | directories, | 122 | directories, |
| 119 | - if O_WRONLY or O_RDWR is specified, open() must fail because the | 123 | - if O_WRONLY or O_RDWR is specified, open() must fail because the |
| 120 | file does not contain a '.' directory. */ | 124 | file does not contain a '.' directory. */ |
| 121 | if ((flags & O_CREAT) | 125 | bool check_for_slash_bug; |
| 122 | || (flags & O_ACCMODE) == O_RDWR | 126 | if (OPEN_TRAILING_SLASH_BUG) |
| 123 | || (flags & O_ACCMODE) == O_WRONLY) | ||
| 124 | { | 127 | { |
| 125 | size_t len = strlen (filename); | 128 | size_t len = strlen (filename); |
| 126 | if (len > 0 && filename[len - 1] == '/') | 129 | check_for_slash_bug = len && filename[len - 1] == '/'; |
| 130 | } | ||
| 131 | else | ||
| 132 | check_for_slash_bug = false; | ||
| 133 | |||
| 134 | if (check_for_slash_bug | ||
| 135 | && (flags & O_CREAT | ||
| 136 | || (flags & O_ACCMODE) == O_RDWR | ||
| 137 | || (flags & O_ACCMODE) == O_WRONLY)) | ||
| 138 | { | ||
| 139 | errno = EISDIR; | ||
| 140 | return -1; | ||
| 141 | } | ||
| 142 | |||
| 143 | /* With the trailing slash bug or without working O_DIRECTORY, check with | ||
| 144 | stat first lest we hang trying to open a fifo. Although there is | ||
| 145 | a race between this and opening the file, we can do no better. | ||
| 146 | After opening the file we will check again with fstat. */ | ||
| 147 | bool check_directory = | ||
| 148 | (check_for_slash_bug | ||
| 149 | || (!HAVE_WORKING_O_DIRECTORY && flags & O_DIRECTORY)); | ||
| 150 | if (check_directory) | ||
| 151 | { | ||
| 152 | struct stat statbuf; | ||
| 153 | if (lstatif (filename, &statbuf, flags) < 0) | ||
| 154 | { | ||
| 155 | if (! (flags & O_CREAT && errno == ENOENT)) | ||
| 156 | return -1; | ||
| 157 | } | ||
| 158 | else if (!S_ISDIR (statbuf.st_mode)) | ||
| 127 | { | 159 | { |
| 128 | errno = EISDIR; | 160 | errno = ENOTDIR; |
| 129 | return -1; | 161 | return -1; |
| 130 | } | 162 | } |
| 131 | } | 163 | } |
| 164 | |||
| 165 | /* 0 = unknown, 1 = yes, -1 = no. */ | ||
| 166 | #if GNULIB_defined_O_CLOEXEC | ||
| 167 | int have_cloexec = -1; | ||
| 168 | #else | ||
| 169 | static int have_cloexec; | ||
| 132 | #endif | 170 | #endif |
| 133 | 171 | ||
| 134 | fd = orig_open (filename, | 172 | int fd = orig_open (filename, |
| 135 | flags & ~(have_cloexec < 0 ? O_CLOEXEC : 0), mode); | 173 | flags & ~(have_cloexec < 0 ? O_CLOEXEC : 0), mode); |
| 136 | 174 | ||
| 137 | if (flags & O_CLOEXEC) | 175 | if (flags & O_CLOEXEC) |
| 138 | { | 176 | { |
| @@ -154,19 +192,21 @@ open (const char *filename, int flags, ...) | |||
| 154 | #if REPLACE_FCHDIR | 192 | #if REPLACE_FCHDIR |
| 155 | /* Implementing fchdir and fdopendir requires the ability to open a | 193 | /* Implementing fchdir and fdopendir requires the ability to open a |
| 156 | directory file descriptor. If open doesn't support that (as on | 194 | directory file descriptor. If open doesn't support that (as on |
| 157 | mingw), we use a dummy file that behaves the same as directories | 195 | mingw), use a dummy file that behaves the same as directories |
| 158 | on Linux (ie. always reports EOF on attempts to read()), and | 196 | on Linux (ie. always reports EOF on attempts to read()), and |
| 159 | override fstat() in fchdir.c to hide the fact that we have a | 197 | override fstat in fchdir.c to hide the dummy. */ |
| 160 | dummy. */ | ||
| 161 | if (REPLACE_OPEN_DIRECTORY && fd < 0 && errno == EACCES | 198 | if (REPLACE_OPEN_DIRECTORY && fd < 0 && errno == EACCES |
| 162 | && ((flags & O_ACCMODE) == O_RDONLY | 199 | && ((flags & (O_ACCMODE | O_CREAT)) == O_RDONLY |
| 163 | || (O_SEARCH != O_RDONLY && (flags & O_ACCMODE) == O_SEARCH))) | 200 | || (O_SEARCH != O_RDONLY |
| 201 | && (flags & (O_ACCMODE | O_CREAT)) == O_SEARCH))) | ||
| 164 | { | 202 | { |
| 165 | struct stat statbuf; | 203 | struct stat statbuf; |
| 166 | if (stat (filename, &statbuf) == 0 && S_ISDIR (statbuf.st_mode)) | 204 | if (check_directory |
| 205 | || (lstatif (filename, &statbuf, flags) == 0 | ||
| 206 | && S_ISDIR (statbuf.st_mode))) | ||
| 167 | { | 207 | { |
| 168 | /* Maximum recursion depth of 1. */ | 208 | /* Maximum recursion depth of 1. */ |
| 169 | fd = open ("/dev/null", flags, mode); | 209 | fd = open ("/dev/null", flags & ~O_DIRECTORY, mode); |
| 170 | if (0 <= fd) | 210 | if (0 <= fd) |
| 171 | fd = _gl_register_fd (fd, filename); | 211 | fd = _gl_register_fd (fd, filename); |
| 172 | } | 212 | } |
| @@ -175,10 +215,8 @@ open (const char *filename, int flags, ...) | |||
| 175 | } | 215 | } |
| 176 | #endif | 216 | #endif |
| 177 | 217 | ||
| 178 | #if OPEN_TRAILING_SLASH_BUG | 218 | /* If checking for directories, fail if fd does not refer to a directory. |
| 179 | /* If the filename ends in a slash and fd does not refer to a directory, | 219 | Rationale: A filename ending in slash cannot name a non-directory |
| 180 | then fail. | ||
| 181 | Rationale: POSIX says such a filename must name a directory | ||
| 182 | <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>: | 220 | <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>: |
| 183 | "A pathname that contains at least one non-<slash> character and that | 221 | "A pathname that contains at least one non-<slash> character and that |
| 184 | ends with one or more trailing <slash> characters shall not be resolved | 222 | ends with one or more trailing <slash> characters shall not be resolved |
| @@ -186,23 +224,18 @@ open (const char *filename, int flags, ...) | |||
| 186 | <slash> characters names an existing directory" | 224 | <slash> characters names an existing directory" |
| 187 | If the named file without the slash is not a directory, open() must fail | 225 | If the named file without the slash is not a directory, open() must fail |
| 188 | with ENOTDIR. */ | 226 | with ENOTDIR. */ |
| 189 | if (fd >= 0) | 227 | if (check_directory && 0 <= fd) |
| 190 | { | 228 | { |
| 191 | /* We know len is positive, since open did not fail with ENOENT. */ | 229 | struct stat statbuf; |
| 192 | size_t len = strlen (filename); | 230 | int r = fstat (fd, &statbuf); |
| 193 | if (filename[len - 1] == '/') | 231 | if (r < 0 || !S_ISDIR (statbuf.st_mode)) |
| 194 | { | 232 | { |
| 195 | struct stat statbuf; | 233 | int err = r < 0 ? errno : ENOTDIR; |
| 196 | 234 | close (fd); | |
| 197 | if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode)) | 235 | errno = err; |
| 198 | { | 236 | return -1; |
| 199 | close (fd); | ||
| 200 | errno = ENOTDIR; | ||
| 201 | return -1; | ||
| 202 | } | ||
| 203 | } | 237 | } |
| 204 | } | 238 | } |
| 205 | #endif | ||
| 206 | 239 | ||
| 207 | #if REPLACE_FCHDIR | 240 | #if REPLACE_FCHDIR |
| 208 | if (!REPLACE_OPEN_DIRECTORY && 0 <= fd) | 241 | if (!REPLACE_OPEN_DIRECTORY && 0 <= fd) |
diff --git a/gl/pathmax.h b/gl/pathmax.h index d6512c6f..5f535517 100644 --- a/gl/pathmax.h +++ b/gl/pathmax.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Define PATH_MAX somehow. Requires sys/types.h. | 1 | /* Define PATH_MAX somehow. Requires sys/types.h. |
| 2 | Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009-2024 Free Software | 2 | Copyright (C) 1992, 1999, 2001, 2003, 2005, 2009-2025 Free Software |
| 3 | Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/printf-args.c b/gl/printf-args.c index eb0d2cdc..b83ec1e8 100644 --- a/gl/printf-args.c +++ b/gl/printf-args.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Decomposed printf argument list. | 1 | /* Decomposed printf argument list. |
| 2 | Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2024 Free Software | 2 | Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2025 Free Software |
| 3 | Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -32,6 +32,9 @@ | |||
| 32 | /* Get INT_WIDTH. */ | 32 | /* Get INT_WIDTH. */ |
| 33 | #include <limits.h> | 33 | #include <limits.h> |
| 34 | 34 | ||
| 35 | /* Get abort(). */ | ||
| 36 | #include <stdlib.h> | ||
| 37 | |||
| 35 | #ifdef STATIC | 38 | #ifdef STATIC |
| 36 | STATIC | 39 | STATIC |
| 37 | #endif | 40 | #endif |
| @@ -198,7 +201,6 @@ PRINTF_FETCHARGS (va_list args, arguments *a) | |||
| 198 | if (ap->a.a_string == NULL) | 201 | if (ap->a.a_string == NULL) |
| 199 | ap->a.a_string = "(NULL)"; | 202 | ap->a.a_string = "(NULL)"; |
| 200 | break; | 203 | break; |
| 201 | #if HAVE_WCHAR_T | ||
| 202 | case TYPE_WIDE_STRING: | 204 | case TYPE_WIDE_STRING: |
| 203 | ap->a.a_wide_string = va_arg (args, const wchar_t *); | 205 | ap->a.a_wide_string = va_arg (args, const wchar_t *); |
| 204 | /* A null pointer is an invalid argument for "%ls", but in practice | 206 | /* A null pointer is an invalid argument for "%ls", but in practice |
| @@ -216,7 +218,6 @@ PRINTF_FETCHARGS (va_list args, arguments *a) | |||
| 216 | ap->a.a_wide_string = wide_null_string; | 218 | ap->a.a_wide_string = wide_null_string; |
| 217 | } | 219 | } |
| 218 | break; | 220 | break; |
| 219 | #endif | ||
| 220 | case TYPE_POINTER: | 221 | case TYPE_POINTER: |
| 221 | ap->a.a_pointer = va_arg (args, void *); | 222 | ap->a.a_pointer = va_arg (args, void *); |
| 222 | break; | 223 | break; |
| @@ -298,9 +299,19 @@ PRINTF_FETCHARGS (va_list args, arguments *a) | |||
| 298 | } | 299 | } |
| 299 | break; | 300 | break; |
| 300 | #endif | 301 | #endif |
| 301 | default: | 302 | case TYPE_NONE: |
| 302 | /* Unknown type. */ | 303 | /* Argument i is not used by any directive, but some argument with |
| 304 | number > i is used by a format directive. POSIX says that this | ||
| 305 | is invalid: | ||
| 306 | "When numbered argument specifications are used, specifying the | ||
| 307 | Nth argument requires that all the leading arguments, from the | ||
| 308 | first to the (N-1)th, are specified in the format string." | ||
| 309 | The reason is that we cannot know how many bytes to skip in the | ||
| 310 | va_arg sequence. */ | ||
| 303 | return -1; | 311 | return -1; |
| 312 | default: | ||
| 313 | /* Unknown type. Should not happen. */ | ||
| 314 | abort (); | ||
| 304 | } | 315 | } |
| 305 | return 0; | 316 | return 0; |
| 306 | } | 317 | } |
diff --git a/gl/printf-args.h b/gl/printf-args.h index 9b80bb39..6edc570c 100644 --- a/gl/printf-args.h +++ b/gl/printf-args.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Decomposed printf argument list. | 1 | /* Decomposed printf argument list. |
| 2 | Copyright (C) 1999, 2002-2003, 2006-2007, 2011-2024 Free Software | 2 | Copyright (C) 1999, 2002-2003, 2006-2007, 2011-2025 Free Software |
| 3 | Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -28,14 +28,9 @@ | |||
| 28 | # define PRINTF_FETCHARGS printf_fetchargs | 28 | # define PRINTF_FETCHARGS printf_fetchargs |
| 29 | #endif | 29 | #endif |
| 30 | 30 | ||
| 31 | /* Get size_t. */ | 31 | /* Get size_t, wchar_t. */ |
| 32 | #include <stddef.h> | 32 | #include <stddef.h> |
| 33 | 33 | ||
| 34 | /* Get wchar_t. */ | ||
| 35 | #if HAVE_WCHAR_T | ||
| 36 | # include <stddef.h> | ||
| 37 | #endif | ||
| 38 | |||
| 39 | /* Get wint_t. */ | 34 | /* Get wint_t. */ |
| 40 | #if HAVE_WINT_T | 35 | #if HAVE_WINT_T |
| 41 | # include <wchar.h> | 36 | # include <wchar.h> |
| @@ -89,9 +84,7 @@ typedef enum | |||
| 89 | TYPE_WIDE_CHAR, | 84 | TYPE_WIDE_CHAR, |
| 90 | #endif | 85 | #endif |
| 91 | TYPE_STRING, | 86 | TYPE_STRING, |
| 92 | #if HAVE_WCHAR_T | ||
| 93 | TYPE_WIDE_STRING, | 87 | TYPE_WIDE_STRING, |
| 94 | #endif | ||
| 95 | TYPE_POINTER, | 88 | TYPE_POINTER, |
| 96 | TYPE_COUNT_SCHAR_POINTER, | 89 | TYPE_COUNT_SCHAR_POINTER, |
| 97 | TYPE_COUNT_SHORT_POINTER, | 90 | TYPE_COUNT_SHORT_POINTER, |
| @@ -154,9 +147,7 @@ typedef struct | |||
| 154 | wint_t a_wide_char; | 147 | wint_t a_wide_char; |
| 155 | #endif | 148 | #endif |
| 156 | const char* a_string; | 149 | const char* a_string; |
| 157 | #if HAVE_WCHAR_T | ||
| 158 | const wchar_t* a_wide_string; | 150 | const wchar_t* a_wide_string; |
| 159 | #endif | ||
| 160 | void* a_pointer; | 151 | void* a_pointer; |
| 161 | signed char * a_count_schar_pointer; | 152 | signed char * a_count_schar_pointer; |
| 162 | short * a_count_short_pointer; | 153 | short * a_count_short_pointer; |
diff --git a/gl/printf-parse.c b/gl/printf-parse.c index a33e27a0..79b35034 100644 --- a/gl/printf-parse.c +++ b/gl/printf-parse.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Formatted output to strings. | 1 | /* Formatted output to strings. |
| 2 | Copyright (C) 1999-2000, 2002-2003, 2006-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1999-2000, 2002-2003, 2006-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -600,20 +600,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) | |||
| 600 | if (signed_type == TYPE_LONGINT | 600 | if (signed_type == TYPE_LONGINT |
| 601 | /* For backward compatibility only. */ | 601 | /* For backward compatibility only. */ |
| 602 | || signed_type == TYPE_LONGLONGINT) | 602 | || signed_type == TYPE_LONGLONGINT) |
| 603 | #if HAVE_WCHAR_T | ||
| 604 | type = TYPE_WIDE_STRING; | 603 | type = TYPE_WIDE_STRING; |
| 605 | #else | ||
| 606 | goto error; | ||
| 607 | #endif | ||
| 608 | else | 604 | else |
| 609 | type = TYPE_STRING; | 605 | type = TYPE_STRING; |
| 610 | break; | 606 | break; |
| 611 | #if HAVE_WCHAR_T | ||
| 612 | case 'S': | 607 | case 'S': |
| 613 | type = TYPE_WIDE_STRING; | 608 | type = TYPE_WIDE_STRING; |
| 614 | c = 's'; | 609 | c = 's'; |
| 615 | break; | 610 | break; |
| 616 | #endif | ||
| 617 | case 'p': | 611 | case 'p': |
| 618 | type = TYPE_POINTER; | 612 | type = TYPE_POINTER; |
| 619 | break; | 613 | break; |
diff --git a/gl/printf-parse.h b/gl/printf-parse.h index 949b8754..673053b8 100644 --- a/gl/printf-parse.h +++ b/gl/printf-parse.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Parse printf format string. | 1 | /* Parse printf format string. |
| 2 | Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2024 Free Software | 2 | Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2025 Free Software |
| 3 | Foundation, Inc. | 3 | Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/pthread-once.c b/gl/pthread-once.c new file mode 100644 index 00000000..b19dae50 --- /dev/null +++ b/gl/pthread-once.c | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | /* POSIX once-only control. | ||
| 2 | Copyright (C) 2019-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, 2019. */ | ||
| 18 | |||
| 19 | #include <config.h> | ||
| 20 | |||
| 21 | /* Specification. */ | ||
| 22 | #include <pthread.h> | ||
| 23 | |||
| 24 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 25 | # include "windows-once.h" | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 29 | /* Use Windows threads. */ | ||
| 30 | |||
| 31 | int | ||
| 32 | pthread_once (pthread_once_t *once_control, void (*initfunction) (void)) | ||
| 33 | { | ||
| 34 | glwthread_once (once_control, initfunction); | ||
| 35 | return 0; | ||
| 36 | } | ||
| 37 | |||
| 38 | #elif HAVE_PTHREAD_H | ||
| 39 | /* Provide workarounds for POSIX threads. */ | ||
| 40 | |||
| 41 | # if defined __CYGWIN__ | ||
| 42 | |||
| 43 | # include <stdlib.h> | ||
| 44 | |||
| 45 | int | ||
| 46 | pthread_once (pthread_once_t *once_control, void (*initfunction) (void)) | ||
| 47 | { | ||
| 48 | /* In this implementation, we reuse the type | ||
| 49 | typedef struct { pthread_mutex_t mutex; int state; } pthread_once_t; | ||
| 50 | #define PTHREAD_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, 0 } | ||
| 51 | while assigning the following meaning to the state: | ||
| 52 | state = (<number of waiting threads> << 16) + <1 if done> | ||
| 53 | In other words: | ||
| 54 | state = { unsigned int num_threads : 16; unsigned int done : 16; } | ||
| 55 | */ | ||
| 56 | struct actual_state | ||
| 57 | { | ||
| 58 | _Atomic unsigned short num_threads; | ||
| 59 | /* done == 0: initial state | ||
| 60 | done == 1: initfunction executed, lock still active | ||
| 61 | done == 2: initfunction executed, lock no longer usable */ | ||
| 62 | _Atomic unsigned short done; | ||
| 63 | }; | ||
| 64 | struct actual_state *state_p = (struct actual_state *) &once_control->state; | ||
| 65 | /* This test is not necessary. It's only an optimization, to establish | ||
| 66 | a fast path for the common case that the 'done' word is already > 0. */ | ||
| 67 | if (state_p->done == 0) | ||
| 68 | { | ||
| 69 | /* Increment num_threads (atomically), to indicate that this thread will | ||
| 70 | possibly take the lock. */ | ||
| 71 | state_p->num_threads += 1; | ||
| 72 | /* Test the 'done' word. */ | ||
| 73 | if (state_p->done == 0) | ||
| 74 | { | ||
| 75 | /* The 'done' word is still zero. Now take the lock. */ | ||
| 76 | pthread_mutex_lock (&once_control->mutex); | ||
| 77 | /* Test the 'done' word again. */ | ||
| 78 | if (state_p->done == 0) | ||
| 79 | { | ||
| 80 | /* Execute the initfunction. */ | ||
| 81 | (*initfunction) (); | ||
| 82 | /* Set the 'done' word to 1 (atomically). */ | ||
| 83 | state_p->done = 1; | ||
| 84 | } | ||
| 85 | /* Now the 'done' word is 1. Release the lock. */ | ||
| 86 | pthread_mutex_unlock (&once_control->mutex); | ||
| 87 | } | ||
| 88 | /* Here, done is > 0. */ | ||
| 89 | /* Decrement num_threads (atomically). */ | ||
| 90 | if ((state_p->num_threads -= 1) == 0) | ||
| 91 | { | ||
| 92 | /* num_threads is now zero, and done is > 0. | ||
| 93 | No other thread will need to use the lock. | ||
| 94 | We can therefore destroy the lock, to free resources. */ | ||
| 95 | if (__sync_bool_compare_and_swap (&state_p->done, 1, 2)) | ||
| 96 | pthread_mutex_destroy (&once_control->mutex); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | /* Proof of correctness: | ||
| 100 | * num_threads is incremented and then decremented by some threads. | ||
| 101 | Therefore, num_threads always stays >= 0, and is == 0 at the end. | ||
| 102 | * The 'done' word, once > 0, stays > 0 (since it is never assigned 0). | ||
| 103 | * The 'done' word is changed from == 0 to > 0 only while the lock | ||
| 104 | is taken. Therefore, only the first thread that succeeds in taking | ||
| 105 | the lock executes the initfunction and sets the 'done' word to a | ||
| 106 | value > 0; the other threads that take the lock do no side effects | ||
| 107 | between taking and releasing the lock. | ||
| 108 | * The 'done' word does not change any more once it is 2. | ||
| 109 | Therefore, it can be changed from 1 to 2 only once. | ||
| 110 | * pthread_mutex_destroy gets invoked right after 'done' has been changed | ||
| 111 | from 1 to 2. Therefore, pthread_mutex_destroy gets invoked only once. | ||
| 112 | * After a moment where num_threads was 0 and done was > 0, no thread can | ||
| 113 | reach the pthread_mutex_lock invocation. Proof: | ||
| 114 | - At such a moment, no thread is in the code range between | ||
| 115 | state_p->num_threads += 1 | ||
| 116 | and | ||
| 117 | state_p->num_threads -= 1 | ||
| 118 | - After such a moment, some thread can increment num_threads, but from | ||
| 119 | there they cannot reach the pthread_mutex_lock invocation, because the | ||
| 120 | if (state_p->done == 0) | ||
| 121 | test prevents that. | ||
| 122 | * From this it follows that: | ||
| 123 | - pthread_mutex_destroy cannot be executed while the lock is taken | ||
| 124 | (because pthread_mutex_destroy is only executed after a moment where | ||
| 125 | num_threads was 0 and done was > 0). | ||
| 126 | - Once pthread_mutex_destroy has been executed, the lock is not used any | ||
| 127 | more. | ||
| 128 | */ | ||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | # endif | ||
| 133 | |||
| 134 | #else | ||
| 135 | /* Provide a dummy implementation for single-threaded applications. */ | ||
| 136 | |||
| 137 | int | ||
| 138 | pthread_once (pthread_once_t *once_control, void (*initfunction) (void)) | ||
| 139 | { | ||
| 140 | if (*once_control == 0) | ||
| 141 | { | ||
| 142 | *once_control = ~ 0; | ||
| 143 | initfunction (); | ||
| 144 | } | ||
| 145 | return 0; | ||
| 146 | } | ||
| 147 | |||
| 148 | #endif | ||
diff --git a/gl/pthread.h b/gl/pthread.h new file mode 100644 index 00000000..599f1633 --- /dev/null +++ b/gl/pthread.h | |||
| @@ -0,0 +1,2571 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* Implement the most essential subset of POSIX pthread.h. | ||
| 3 | |||
| 4 | Copyright (C) 2009-2025 Free Software Foundation, Inc. | ||
| 5 | |||
| 6 | This file is free software: you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU Lesser General Public License as | ||
| 8 | published by the Free Software Foundation; either version 2.1 of the | ||
| 9 | License, or (at your option) any later version. | ||
| 10 | |||
| 11 | This file is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU Lesser General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU Lesser General Public License | ||
| 17 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | /* Written by Paul Eggert, Glen Lenker, and Bruno Haible. */ | ||
| 20 | |||
| 21 | #if __GNUC__ >= 3 | ||
| 22 | #pragma GCC system_header | ||
| 23 | #endif | ||
| 24 | |||
| 25 | |||
| 26 | #if defined _GL_ALREADY_INCLUDING_PTHREAD_H | ||
| 27 | /* Special invocation convention: | ||
| 28 | On Android, we have a sequence of nested includes | ||
| 29 | <pthread.h> -> <time.h> -> <sys/time.h> -> <sys/select.h> -> | ||
| 30 | <signal.h> -> <pthread.h>. | ||
| 31 | In this situation, PTHREAD_COND_INITIALIZER is not yet defined, | ||
| 32 | therefore we should not attempt to define PTHREAD_MUTEX_NORMAL etc. */ | ||
| 33 | |||
| 34 | #include_next <pthread.h> | ||
| 35 | |||
| 36 | #else | ||
| 37 | /* Normal invocation convention. */ | ||
| 38 | |||
| 39 | #ifndef _GL_PTHREAD_H_ | ||
| 40 | |||
| 41 | #if 1 | ||
| 42 | |||
| 43 | # define _GL_ALREADY_INCLUDING_PTHREAD_H | ||
| 44 | |||
| 45 | /* The include_next requires a split double-inclusion guard. */ | ||
| 46 | # include_next <pthread.h> | ||
| 47 | |||
| 48 | # undef _GL_ALREADY_INCLUDING_PTHREAD_H | ||
| 49 | |||
| 50 | #endif | ||
| 51 | |||
| 52 | #ifndef _GL_PTHREAD_H_ | ||
| 53 | #define _GL_PTHREAD_H_ | ||
| 54 | |||
| 55 | /* This file uses _Noreturn, _GL_ATTRIBUTE_PURE, GNULIB_POSIXCHECK, | ||
| 56 | HAVE_RAW_DECL_*. */ | ||
| 57 | #if !_GL_CONFIG_H_INCLUDED | ||
| 58 | #error "Please include config.h first." | ||
| 59 | #endif | ||
| 60 | |||
| 61 | #define __need_system_stdlib_h | ||
| 62 | #include <stdlib.h> | ||
| 63 | #undef __need_system_stdlib_h | ||
| 64 | |||
| 65 | |||
| 66 | /* The pthreads-win32 <pthread.h> defines a couple of broken macros. */ | ||
| 67 | #undef asctime_r | ||
| 68 | #undef ctime_r | ||
| 69 | #undef gmtime_r | ||
| 70 | #undef localtime_r | ||
| 71 | #undef rand_r | ||
| 72 | #undef strtok_r | ||
| 73 | |||
| 74 | #include <errno.h> | ||
| 75 | #include <sched.h> | ||
| 76 | #include <sys/types.h> | ||
| 77 | #include <time.h> | ||
| 78 | |||
| 79 | /* The __attribute__ feature is available in gcc versions 2.5 and later. | ||
| 80 | The attribute __pure__ was added in gcc 2.96. */ | ||
| 81 | #ifndef _GL_ATTRIBUTE_PURE | ||
| 82 | # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ | ||
| 83 | # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) | ||
| 84 | # else | ||
| 85 | # define _GL_ATTRIBUTE_PURE /* empty */ | ||
| 86 | # endif | ||
| 87 | #endif | ||
| 88 | |||
| 89 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | ||
| 90 | /* C++ compatible function declaration macros. | ||
| 91 | Copyright (C) 2010-2025 Free Software Foundation, Inc. | ||
| 92 | |||
| 93 | This program is free software: you can redistribute it and/or modify it | ||
| 94 | under the terms of the GNU Lesser General Public License as published | ||
| 95 | by the Free Software Foundation; either version 2 of the License, or | ||
| 96 | (at your option) any later version. | ||
| 97 | |||
| 98 | This program is distributed in the hope that it will be useful, | ||
| 99 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 100 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 101 | Lesser General Public License for more details. | ||
| 102 | |||
| 103 | You should have received a copy of the GNU Lesser General Public License | ||
| 104 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 105 | |||
| 106 | #ifndef _GL_CXXDEFS_H | ||
| 107 | #define _GL_CXXDEFS_H | ||
| 108 | |||
| 109 | /* Begin/end the GNULIB_NAMESPACE namespace. */ | ||
| 110 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 111 | # define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE { | ||
| 112 | # define _GL_END_NAMESPACE } | ||
| 113 | #else | ||
| 114 | # define _GL_BEGIN_NAMESPACE | ||
| 115 | # define _GL_END_NAMESPACE | ||
| 116 | #endif | ||
| 117 | |||
| 118 | /* The three most frequent use cases of these macros are: | ||
| 119 | |||
| 120 | * For providing a substitute for a function that is missing on some | ||
| 121 | platforms, but is declared and works fine on the platforms on which | ||
| 122 | it exists: | ||
| 123 | |||
| 124 | #if @GNULIB_FOO@ | ||
| 125 | # if !@HAVE_FOO@ | ||
| 126 | _GL_FUNCDECL_SYS (foo, ...); | ||
| 127 | # endif | ||
| 128 | _GL_CXXALIAS_SYS (foo, ...); | ||
| 129 | _GL_CXXALIASWARN (foo); | ||
| 130 | #elif defined GNULIB_POSIXCHECK | ||
| 131 | ... | ||
| 132 | #endif | ||
| 133 | |||
| 134 | * For providing a replacement for a function that exists on all platforms, | ||
| 135 | but is broken/insufficient and needs to be replaced on some platforms: | ||
| 136 | |||
| 137 | #if @GNULIB_FOO@ | ||
| 138 | # if @REPLACE_FOO@ | ||
| 139 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 140 | # undef foo | ||
| 141 | # define foo rpl_foo | ||
| 142 | # endif | ||
| 143 | _GL_FUNCDECL_RPL (foo, ...); | ||
| 144 | _GL_CXXALIAS_RPL (foo, ...); | ||
| 145 | # else | ||
| 146 | _GL_CXXALIAS_SYS (foo, ...); | ||
| 147 | # endif | ||
| 148 | _GL_CXXALIASWARN (foo); | ||
| 149 | #elif defined GNULIB_POSIXCHECK | ||
| 150 | ... | ||
| 151 | #endif | ||
| 152 | |||
| 153 | * For providing a replacement for a function that exists on some platforms | ||
| 154 | but is broken/insufficient and needs to be replaced on some of them and | ||
| 155 | is additionally either missing or undeclared on some other platforms: | ||
| 156 | |||
| 157 | #if @GNULIB_FOO@ | ||
| 158 | # if @REPLACE_FOO@ | ||
| 159 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 160 | # undef foo | ||
| 161 | # define foo rpl_foo | ||
| 162 | # endif | ||
| 163 | _GL_FUNCDECL_RPL (foo, ...); | ||
| 164 | _GL_CXXALIAS_RPL (foo, ...); | ||
| 165 | # else | ||
| 166 | # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ | ||
| 167 | _GL_FUNCDECL_SYS (foo, ...); | ||
| 168 | # endif | ||
| 169 | _GL_CXXALIAS_SYS (foo, ...); | ||
| 170 | # endif | ||
| 171 | _GL_CXXALIASWARN (foo); | ||
| 172 | #elif defined GNULIB_POSIXCHECK | ||
| 173 | ... | ||
| 174 | #endif | ||
| 175 | */ | ||
| 176 | |||
| 177 | /* _GL_EXTERN_C declaration; | ||
| 178 | performs the declaration with C linkage. */ | ||
| 179 | #if defined __cplusplus | ||
| 180 | # define _GL_EXTERN_C extern "C" | ||
| 181 | #else | ||
| 182 | # define _GL_EXTERN_C extern | ||
| 183 | #endif | ||
| 184 | |||
| 185 | /* _GL_EXTERN_C_FUNC declaration; | ||
| 186 | performs the declaration of a function with C linkage. */ | ||
| 187 | #if defined __cplusplus | ||
| 188 | # define _GL_EXTERN_C_FUNC extern "C" | ||
| 189 | #else | ||
| 190 | /* In C mode, omit the 'extern' keyword, because attributes in bracket syntax | ||
| 191 | are not allowed between 'extern' and the return type (see gnulib-common.m4). | ||
| 192 | */ | ||
| 193 | # define _GL_EXTERN_C_FUNC | ||
| 194 | #endif | ||
| 195 | |||
| 196 | /* _GL_FUNCDECL_RPL (func, rettype, parameters, [attributes]); | ||
| 197 | declares a replacement function, named rpl_func, with the given prototype, | ||
| 198 | consisting of return type, parameters, and attributes. | ||
| 199 | Although attributes are optional, the comma before them is required | ||
| 200 | for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW, | ||
| 201 | if needed, must be placed after the _GL_FUNCDECL_RPL invocation, | ||
| 202 | at the end of the declaration. | ||
| 203 | Examples: | ||
| 204 | _GL_FUNCDECL_RPL (free, void, (void *ptr), ) _GL_ATTRIBUTE_NOTHROW; | ||
| 205 | _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...), | ||
| 206 | _GL_ARG_NONNULL ((1))); | ||
| 207 | |||
| 208 | Note: Attributes, such as _GL_ATTRIBUTE_DEPRECATED, are supported in front | ||
| 209 | of a _GL_FUNCDECL_RPL invocation only in C mode, not in C++ mode. (That's | ||
| 210 | because | ||
| 211 | [[...]] extern "C" <declaration>; | ||
| 212 | is invalid syntax in C++.) | ||
| 213 | */ | ||
| 214 | #define _GL_FUNCDECL_RPL(func,rettype,parameters,...) \ | ||
| 215 | _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters, __VA_ARGS__) | ||
| 216 | #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \ | ||
| 217 | _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters | ||
| 218 | |||
| 219 | /* _GL_FUNCDECL_SYS_NAME (func) expands to plain func if C++, and to | ||
| 220 | parenthesized func otherwise. Parenthesization is needed in C23 if | ||
| 221 | the function is like strchr and so is a qualifier-generic macro | ||
| 222 | that expands to something more complicated. */ | ||
| 223 | #ifdef __cplusplus | ||
| 224 | # define _GL_FUNCDECL_SYS_NAME(func) func | ||
| 225 | #else | ||
| 226 | # define _GL_FUNCDECL_SYS_NAME(func) (func) | ||
| 227 | #endif | ||
| 228 | |||
| 229 | /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]); | ||
| 230 | declares the system function, named func, with the given prototype, | ||
| 231 | consisting of return type, parameters, and attributes. | ||
| 232 | Although attributes are optional, the comma before them is required | ||
| 233 | for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW, | ||
| 234 | if needed, must be placed after the _GL_FUNCDECL_RPL invocation, | ||
| 235 | at the end of the declaration. | ||
| 236 | Examples: | ||
| 237 | _GL_FUNCDECL_SYS (getumask, mode_t, (void), ) _GL_ATTRIBUTE_NOTHROW; | ||
| 238 | _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD); | ||
| 239 | */ | ||
| 240 | #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \ | ||
| 241 | _GL_EXTERN_C_FUNC __VA_ARGS__ rettype _GL_FUNCDECL_SYS_NAME (func) parameters | ||
| 242 | |||
| 243 | /* _GL_CXXALIAS_RPL (func, rettype, parameters); | ||
| 244 | declares a C++ alias called GNULIB_NAMESPACE::func | ||
| 245 | that redirects to rpl_func, if GNULIB_NAMESPACE is defined. | ||
| 246 | Example: | ||
| 247 | _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); | ||
| 248 | |||
| 249 | Wrapping rpl_func in an object with an inline conversion operator | ||
| 250 | avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is | ||
| 251 | actually used in the program. */ | ||
| 252 | #define _GL_CXXALIAS_RPL(func,rettype,parameters) \ | ||
| 253 | _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) | ||
| 254 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 255 | # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ | ||
| 256 | namespace GNULIB_NAMESPACE \ | ||
| 257 | { \ | ||
| 258 | static const struct _gl_ ## func ## _wrapper \ | ||
| 259 | { \ | ||
| 260 | typedef rettype (*type) parameters; \ | ||
| 261 | \ | ||
| 262 | inline operator type () const \ | ||
| 263 | { \ | ||
| 264 | return ::rpl_func; \ | ||
| 265 | } \ | ||
| 266 | } func = {}; \ | ||
| 267 | } \ | ||
| 268 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 269 | #else | ||
| 270 | # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ | ||
| 271 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 272 | #endif | ||
| 273 | |||
| 274 | /* _GL_CXXALIAS_MDA (func, rettype, parameters); | ||
| 275 | is to be used when func is a Microsoft deprecated alias, on native Windows. | ||
| 276 | It declares a C++ alias called GNULIB_NAMESPACE::func | ||
| 277 | that redirects to _func, if GNULIB_NAMESPACE is defined. | ||
| 278 | Example: | ||
| 279 | _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...)); | ||
| 280 | */ | ||
| 281 | #define _GL_CXXALIAS_MDA(func,rettype,parameters) \ | ||
| 282 | _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters) | ||
| 283 | |||
| 284 | /* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); | ||
| 285 | is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); | ||
| 286 | except that the C function rpl_func may have a slightly different | ||
| 287 | declaration. A cast is used to silence the "invalid conversion" error | ||
| 288 | that would otherwise occur. */ | ||
| 289 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 290 | # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ | ||
| 291 | namespace GNULIB_NAMESPACE \ | ||
| 292 | { \ | ||
| 293 | static const struct _gl_ ## func ## _wrapper \ | ||
| 294 | { \ | ||
| 295 | typedef rettype (*type) parameters; \ | ||
| 296 | \ | ||
| 297 | inline operator type () const \ | ||
| 298 | { \ | ||
| 299 | return reinterpret_cast<type>(::rpl_func); \ | ||
| 300 | } \ | ||
| 301 | } func = {}; \ | ||
| 302 | } \ | ||
| 303 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 304 | #else | ||
| 305 | # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ | ||
| 306 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 307 | #endif | ||
| 308 | |||
| 309 | /* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters); | ||
| 310 | is like _GL_CXXALIAS_MDA (func, rettype, parameters); | ||
| 311 | except that the C function func may have a slightly different declaration. | ||
| 312 | A cast is used to silence the "invalid conversion" error that would | ||
| 313 | otherwise occur. */ | ||
| 314 | #define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \ | ||
| 315 | _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters) | ||
| 316 | |||
| 317 | /* _GL_CXXALIAS_SYS (func, rettype, parameters); | ||
| 318 | declares a C++ alias called GNULIB_NAMESPACE::func | ||
| 319 | that redirects to the system provided function func, if GNULIB_NAMESPACE | ||
| 320 | is defined. | ||
| 321 | Example: | ||
| 322 | _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); | ||
| 323 | |||
| 324 | Wrapping func in an object with an inline conversion operator | ||
| 325 | avoids a reference to func unless GNULIB_NAMESPACE::func is | ||
| 326 | actually used in the program. */ | ||
| 327 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 328 | # define _GL_CXXALIAS_SYS(func,rettype,parameters) \ | ||
| 329 | namespace GNULIB_NAMESPACE \ | ||
| 330 | { \ | ||
| 331 | static const struct _gl_ ## func ## _wrapper \ | ||
| 332 | { \ | ||
| 333 | typedef rettype (*type) parameters; \ | ||
| 334 | \ | ||
| 335 | inline operator type () const \ | ||
| 336 | { \ | ||
| 337 | return ::func; \ | ||
| 338 | } \ | ||
| 339 | } func = {}; \ | ||
| 340 | } \ | ||
| 341 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 342 | #else | ||
| 343 | # define _GL_CXXALIAS_SYS(func,rettype,parameters) \ | ||
| 344 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 345 | #endif | ||
| 346 | |||
| 347 | /* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); | ||
| 348 | is like _GL_CXXALIAS_SYS (func, rettype, parameters); | ||
| 349 | except that the C function func may have a slightly different declaration. | ||
| 350 | A cast is used to silence the "invalid conversion" error that would | ||
| 351 | otherwise occur. */ | ||
| 352 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 353 | # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ | ||
| 354 | namespace GNULIB_NAMESPACE \ | ||
| 355 | { \ | ||
| 356 | static const struct _gl_ ## func ## _wrapper \ | ||
| 357 | { \ | ||
| 358 | typedef rettype (*type) parameters; \ | ||
| 359 | \ | ||
| 360 | inline operator type () const \ | ||
| 361 | { \ | ||
| 362 | return reinterpret_cast<type>(::func); \ | ||
| 363 | } \ | ||
| 364 | } func = {}; \ | ||
| 365 | } \ | ||
| 366 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 367 | #else | ||
| 368 | # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ | ||
| 369 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 370 | #endif | ||
| 371 | |||
| 372 | /* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); | ||
| 373 | is like _GL_CXXALIAS_SYS (func, rettype, parameters); | ||
| 374 | except that the C function is picked among a set of overloaded functions, | ||
| 375 | namely the one with rettype2 and parameters2. Two consecutive casts | ||
| 376 | are used to silence the "cannot find a match" and "invalid conversion" | ||
| 377 | errors that would otherwise occur. */ | ||
| 378 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 379 | /* The outer cast must be a reinterpret_cast. | ||
| 380 | The inner cast: When the function is defined as a set of overloaded | ||
| 381 | functions, it works as a static_cast<>, choosing the designated variant. | ||
| 382 | When the function is defined as a single variant, it works as a | ||
| 383 | reinterpret_cast<>. The parenthesized cast syntax works both ways. */ | ||
| 384 | # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ | ||
| 385 | namespace GNULIB_NAMESPACE \ | ||
| 386 | { \ | ||
| 387 | static const struct _gl_ ## func ## _wrapper \ | ||
| 388 | { \ | ||
| 389 | typedef rettype (*type) parameters; \ | ||
| 390 | \ | ||
| 391 | inline operator type () const \ | ||
| 392 | { \ | ||
| 393 | return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \ | ||
| 394 | } \ | ||
| 395 | } func = {}; \ | ||
| 396 | } \ | ||
| 397 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 398 | #else | ||
| 399 | # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ | ||
| 400 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 401 | #endif | ||
| 402 | |||
| 403 | /* _GL_CXXALIASWARN (func); | ||
| 404 | causes a warning to be emitted when ::func is used but not when | ||
| 405 | GNULIB_NAMESPACE::func is used. func must be defined without overloaded | ||
| 406 | variants. */ | ||
| 407 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 408 | # define _GL_CXXALIASWARN(func) \ | ||
| 409 | _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) | ||
| 410 | # define _GL_CXXALIASWARN_1(func,namespace) \ | ||
| 411 | _GL_CXXALIASWARN_2 (func, namespace) | ||
| 412 | /* To work around GCC bug <https://gcc.gnu.org/PR43881>, | ||
| 413 | we enable the warning only when not optimizing. */ | ||
| 414 | # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) | ||
| 415 | # define _GL_CXXALIASWARN_2(func,namespace) \ | ||
| 416 | _GL_WARN_ON_USE (func, \ | ||
| 417 | "The symbol ::" #func " refers to the system function. " \ | ||
| 418 | "Use " #namespace "::" #func " instead.") | ||
| 419 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING | ||
| 420 | # define _GL_CXXALIASWARN_2(func,namespace) \ | ||
| 421 | extern __typeof__ (func) func | ||
| 422 | # else | ||
| 423 | # define _GL_CXXALIASWARN_2(func,namespace) \ | ||
| 424 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 425 | # endif | ||
| 426 | #else | ||
| 427 | # define _GL_CXXALIASWARN(func) \ | ||
| 428 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 429 | #endif | ||
| 430 | |||
| 431 | /* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); | ||
| 432 | causes a warning to be emitted when the given overloaded variant of ::func | ||
| 433 | is used but not when GNULIB_NAMESPACE::func is used. */ | ||
| 434 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 435 | # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ | ||
| 436 | _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ | ||
| 437 | GNULIB_NAMESPACE) | ||
| 438 | # define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ | ||
| 439 | _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) | ||
| 440 | /* To work around GCC bug <https://gcc.gnu.org/PR43881>, | ||
| 441 | we enable the warning only when not optimizing. */ | ||
| 442 | # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) | ||
| 443 | # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ | ||
| 444 | _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \ | ||
| 445 | "The symbol ::" #func " refers to the system function. " \ | ||
| 446 | "Use " #namespace "::" #func " instead.") | ||
| 447 | # else | ||
| 448 | # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ | ||
| 449 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 450 | # endif | ||
| 451 | #else | ||
| 452 | # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ | ||
| 453 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 454 | #endif | ||
| 455 | |||
| 456 | #endif /* _GL_CXXDEFS_H */ | ||
| 457 | |||
| 458 | /* The definition of _Noreturn is copied here. */ | ||
| 459 | /* A C macro for declaring that a function does not return. | ||
| 460 | Copyright (C) 2011-2025 Free Software Foundation, Inc. | ||
| 461 | |||
| 462 | This program is free software: you can redistribute it and/or modify it | ||
| 463 | under the terms of the GNU Lesser General Public License as published | ||
| 464 | by the Free Software Foundation; either version 2 of the License, or | ||
| 465 | (at your option) any later version. | ||
| 466 | |||
| 467 | This program is distributed in the hope that it will be useful, | ||
| 468 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 469 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 470 | Lesser General Public License for more details. | ||
| 471 | |||
| 472 | You should have received a copy of the GNU Lesser General Public License | ||
| 473 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 474 | |||
| 475 | /* The _Noreturn keyword of C11. | ||
| 476 | Do not use [[noreturn]], because with it the syntax | ||
| 477 | extern _Noreturn void func (...); | ||
| 478 | would not be valid; such a declaration would be valid only with 'extern' | ||
| 479 | and '_Noreturn' swapped, or without the 'extern' keyword. However, some | ||
| 480 | AIX system header files and several gnulib header files use precisely | ||
| 481 | this syntax with 'extern'. So even though C23 deprecates _Noreturn, | ||
| 482 | it is currently more portable to prefer it to [[noreturn]]. | ||
| 483 | |||
| 484 | Also, do not try to work around LLVM bug 59792 (clang 15 or earlier). | ||
| 485 | This rare bug can be worked around by compiling with 'clang -D_Noreturn=', | ||
| 486 | though the workaround may generate many false-alarm warnings. */ | ||
| 487 | #ifndef _Noreturn | ||
| 488 | # if ((!defined __cplusplus || defined __clang__) \ | ||
| 489 | && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0))) | ||
| 490 | /* _Noreturn works as-is. */ | ||
| 491 | # elif (2 < __GNUC__ + (8 <= __GNUC_MINOR__) || defined __clang__ \ | ||
| 492 | || 0x5110 <= __SUNPRO_C) | ||
| 493 | /* Prefer __attribute__ ((__noreturn__)) to plain _Noreturn even if the | ||
| 494 | latter works, as 'gcc -std=gnu99 -Wpedantic' warns about _Noreturn. */ | ||
| 495 | # define _Noreturn __attribute__ ((__noreturn__)) | ||
| 496 | # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) | ||
| 497 | # define _Noreturn __declspec (noreturn) | ||
| 498 | # else | ||
| 499 | # define _Noreturn | ||
| 500 | # endif | ||
| 501 | #endif | ||
| 502 | |||
| 503 | /* The definition of _GL_ARG_NONNULL is copied here. */ | ||
| 504 | /* A C macro for declaring that specific arguments must not be NULL. | ||
| 505 | Copyright (C) 2009-2025 Free Software Foundation, Inc. | ||
| 506 | |||
| 507 | This program is free software: you can redistribute it and/or modify it | ||
| 508 | under the terms of the GNU Lesser General Public License as published | ||
| 509 | by the Free Software Foundation; either version 2 of the License, or | ||
| 510 | (at your option) any later version. | ||
| 511 | |||
| 512 | This program is distributed in the hope that it will be useful, | ||
| 513 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 514 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 515 | Lesser General Public License for more details. | ||
| 516 | |||
| 517 | You should have received a copy of the GNU Lesser General Public License | ||
| 518 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 519 | |||
| 520 | /* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools | ||
| 521 | that the values passed as arguments n, ..., m must be non-NULL pointers. | ||
| 522 | n = 1 stands for the first argument, n = 2 for the second argument etc. */ | ||
| 523 | #ifndef _GL_ARG_NONNULL | ||
| 524 | # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__ | ||
| 525 | # define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) | ||
| 526 | # else | ||
| 527 | # define _GL_ARG_NONNULL(params) | ||
| 528 | # endif | ||
| 529 | #endif | ||
| 530 | |||
| 531 | /* The definition of _GL_WARN_ON_USE is copied here. */ | ||
| 532 | /* A C macro for emitting warnings if a function is used. | ||
| 533 | Copyright (C) 2010-2025 Free Software Foundation, Inc. | ||
| 534 | |||
| 535 | This program is free software: you can redistribute it and/or modify it | ||
| 536 | under the terms of the GNU Lesser General Public License as published | ||
| 537 | by the Free Software Foundation; either version 2 of the License, or | ||
| 538 | (at your option) any later version. | ||
| 539 | |||
| 540 | This program is distributed in the hope that it will be useful, | ||
| 541 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 542 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 543 | Lesser General Public License for more details. | ||
| 544 | |||
| 545 | You should have received a copy of the GNU Lesser General Public License | ||
| 546 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 547 | |||
| 548 | /* _GL_WARN_ON_USE (function, "literal string") issues a declaration | ||
| 549 | for FUNCTION which will then trigger a compiler warning containing | ||
| 550 | the text of "literal string" anywhere that function is called, if | ||
| 551 | supported by the compiler. If the compiler does not support this | ||
| 552 | feature, the macro expands to an unused extern declaration. | ||
| 553 | |||
| 554 | _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the | ||
| 555 | attribute used in _GL_WARN_ON_USE. If the compiler does not support | ||
| 556 | this feature, it expands to empty. | ||
| 557 | |||
| 558 | These macros are useful for marking a function as a potential | ||
| 559 | portability trap, with the intent that "literal string" include | ||
| 560 | instructions on the replacement function that should be used | ||
| 561 | instead. | ||
| 562 | _GL_WARN_ON_USE is for functions with 'extern' linkage. | ||
| 563 | _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline' | ||
| 564 | linkage. | ||
| 565 | |||
| 566 | _GL_WARN_ON_USE should not be used more than once for a given function | ||
| 567 | in a given compilation unit (because this may generate a warning even | ||
| 568 | if the function is never called). | ||
| 569 | |||
| 570 | However, one of the reasons that a function is a portability trap is | ||
| 571 | if it has the wrong signature. Declaring FUNCTION with a different | ||
| 572 | signature in C is a compilation error, so this macro must use the | ||
| 573 | same type as any existing declaration so that programs that avoid | ||
| 574 | the problematic FUNCTION do not fail to compile merely because they | ||
| 575 | included a header that poisoned the function. But this implies that | ||
| 576 | _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already | ||
| 577 | have a declaration. Use of this macro implies that there must not | ||
| 578 | be any other macro hiding the declaration of FUNCTION; but | ||
| 579 | undefining FUNCTION first is part of the poisoning process anyway | ||
| 580 | (although for symbols that are provided only via a macro, the result | ||
| 581 | is a compilation error rather than a warning containing | ||
| 582 | "literal string"). Also note that in C++, it is only safe to use if | ||
| 583 | FUNCTION has no overloads. | ||
| 584 | |||
| 585 | For an example, it is possible to poison 'getline' by: | ||
| 586 | - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]], | ||
| 587 | [getline]) in configure.ac, which potentially defines | ||
| 588 | HAVE_RAW_DECL_GETLINE | ||
| 589 | - adding this code to a header that wraps the system <stdio.h>: | ||
| 590 | #undef getline | ||
| 591 | #if HAVE_RAW_DECL_GETLINE | ||
| 592 | _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but" | ||
| 593 | "not universally present; use the gnulib module getline"); | ||
| 594 | #endif | ||
| 595 | |||
| 596 | It is not possible to directly poison global variables. But it is | ||
| 597 | possible to write a wrapper accessor function, and poison that | ||
| 598 | (less common usage, like &environ, will cause a compilation error | ||
| 599 | rather than issue the nice warning, but the end result of informing | ||
| 600 | the developer about their portability problem is still achieved): | ||
| 601 | #if HAVE_RAW_DECL_ENVIRON | ||
| 602 | static char *** | ||
| 603 | rpl_environ (void) { return &environ; } | ||
| 604 | _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared"); | ||
| 605 | # undef environ | ||
| 606 | # define environ (*rpl_environ ()) | ||
| 607 | #endif | ||
| 608 | or better (avoiding contradictory use of 'static' and 'extern'): | ||
| 609 | #if HAVE_RAW_DECL_ENVIRON | ||
| 610 | static char *** | ||
| 611 | _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared") | ||
| 612 | rpl_environ (void) { return &environ; } | ||
| 613 | # undef environ | ||
| 614 | # define environ (*rpl_environ ()) | ||
| 615 | #endif | ||
| 616 | */ | ||
| 617 | #ifndef _GL_WARN_ON_USE | ||
| 618 | |||
| 619 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ | ||
| 620 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ | ||
| 621 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 622 | _GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message))) | ||
| 623 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) \ | ||
| 624 | __attribute__ ((__warning__ (message))) | ||
| 625 | # elif __clang_major__ >= 4 | ||
| 626 | /* Another compiler attribute is available in clang. */ | ||
| 627 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 628 | _GL_WARN_EXTERN_C __typeof__ (function) function \ | ||
| 629 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) | ||
| 630 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) \ | ||
| 631 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) | ||
| 632 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING | ||
| 633 | /* Verify the existence of the function. */ | ||
| 634 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 635 | _GL_WARN_EXTERN_C __typeof__ (function) function | ||
| 636 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) | ||
| 637 | # else /* Unsupported. */ | ||
| 638 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 639 | _GL_WARN_EXTERN_C int _gl_warn_on_use | ||
| 640 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) | ||
| 641 | # endif | ||
| 642 | #endif | ||
| 643 | |||
| 644 | /* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message") | ||
| 645 | is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode the | ||
| 646 | function is declared with the given prototype, consisting of return type, | ||
| 647 | parameters, and attributes. | ||
| 648 | This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does | ||
| 649 | not work in this case. */ | ||
| 650 | #ifndef _GL_WARN_ON_USE_CXX | ||
| 651 | # if !defined __cplusplus | ||
| 652 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 653 | _GL_WARN_ON_USE (function, msg) | ||
| 654 | # else | ||
| 655 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ | ||
| 656 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ | ||
| 657 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 658 | extern rettype_gcc function parameters_and_attributes \ | ||
| 659 | __attribute__ ((__warning__ (msg))) | ||
| 660 | # elif __clang_major__ >= 4 | ||
| 661 | /* Another compiler attribute is available in clang. */ | ||
| 662 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 663 | extern rettype_clang function parameters_and_attributes \ | ||
| 664 | __attribute__ ((__diagnose_if__ (1, msg, "warning"))) | ||
| 665 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING | ||
| 666 | /* Verify the existence of the function. */ | ||
| 667 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 668 | extern rettype_gcc function parameters_and_attributes | ||
| 669 | # else /* Unsupported. */ | ||
| 670 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 671 | _GL_WARN_EXTERN_C int _gl_warn_on_use | ||
| 672 | # endif | ||
| 673 | # endif | ||
| 674 | #endif | ||
| 675 | |||
| 676 | /* _GL_WARN_EXTERN_C declaration; | ||
| 677 | performs the declaration with C linkage. */ | ||
| 678 | #ifndef _GL_WARN_EXTERN_C | ||
| 679 | # if defined __cplusplus | ||
| 680 | # define _GL_WARN_EXTERN_C extern "C" | ||
| 681 | # else | ||
| 682 | # define _GL_WARN_EXTERN_C extern | ||
| 683 | # endif | ||
| 684 | #endif | ||
| 685 | |||
| 686 | /* =========== Thread types and macros =========== */ | ||
| 687 | |||
| 688 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 689 | # if 0 | ||
| 690 | # include "windows-thread.h" | ||
| 691 | # if 1 | ||
| 692 | # define pthread_t rpl_pthread_t | ||
| 693 | # define pthread_attr_t rpl_pthread_attr_t | ||
| 694 | # endif | ||
| 695 | # if !GNULIB_defined_pthread_thread_types | ||
| 696 | typedef glwthread_thread_t pthread_t; | ||
| 697 | typedef unsigned int pthread_attr_t; | ||
| 698 | # define GNULIB_defined_pthread_thread_types 1 | ||
| 699 | # endif | ||
| 700 | # else | ||
| 701 | # if 1 | ||
| 702 | # define pthread_t rpl_pthread_t | ||
| 703 | # define pthread_attr_t rpl_pthread_attr_t | ||
| 704 | # endif | ||
| 705 | # if !GNULIB_defined_pthread_thread_types | ||
| 706 | typedef int pthread_t; | ||
| 707 | typedef unsigned int pthread_attr_t; | ||
| 708 | # define GNULIB_defined_pthread_thread_types 1 | ||
| 709 | # endif | ||
| 710 | # endif | ||
| 711 | # undef PTHREAD_CREATE_JOINABLE | ||
| 712 | # undef PTHREAD_CREATE_DETACHED | ||
| 713 | # define PTHREAD_CREATE_JOINABLE 0 | ||
| 714 | # define PTHREAD_CREATE_DETACHED 1 | ||
| 715 | #else | ||
| 716 | # if !1 | ||
| 717 | # if !GNULIB_defined_pthread_thread_types | ||
| 718 | typedef int pthread_t; | ||
| 719 | typedef unsigned int pthread_attr_t; | ||
| 720 | # define GNULIB_defined_pthread_thread_types 1 | ||
| 721 | # endif | ||
| 722 | # endif | ||
| 723 | # if !1 | ||
| 724 | # define PTHREAD_CREATE_JOINABLE 0 | ||
| 725 | # define PTHREAD_CREATE_DETACHED 1 | ||
| 726 | # endif | ||
| 727 | #endif | ||
| 728 | |||
| 729 | /* =========== Once-only control (initialization) types and macros ========== */ | ||
| 730 | |||
| 731 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 732 | # if 1 | ||
| 733 | # include "windows-once.h" | ||
| 734 | # if 1 | ||
| 735 | # define pthread_once_t rpl_pthread_once_t | ||
| 736 | # endif | ||
| 737 | # if !GNULIB_defined_pthread_once_types | ||
| 738 | typedef glwthread_once_t pthread_once_t; | ||
| 739 | # define GNULIB_defined_pthread_once_types 1 | ||
| 740 | # endif | ||
| 741 | # undef PTHREAD_ONCE_INIT | ||
| 742 | # define PTHREAD_ONCE_INIT GLWTHREAD_ONCE_INIT | ||
| 743 | # else | ||
| 744 | # if 1 | ||
| 745 | # define pthread_once_t rpl_pthread_once_t | ||
| 746 | # endif | ||
| 747 | # if !GNULIB_defined_pthread_once_types | ||
| 748 | typedef int pthread_once_t; | ||
| 749 | # define GNULIB_defined_pthread_once_types 1 | ||
| 750 | # endif | ||
| 751 | # undef PTHREAD_ONCE_INIT | ||
| 752 | # define PTHREAD_ONCE_INIT { 0 } | ||
| 753 | # endif | ||
| 754 | #else | ||
| 755 | # if !1 | ||
| 756 | # if !GNULIB_defined_pthread_once_types | ||
| 757 | typedef int pthread_once_t; | ||
| 758 | # define GNULIB_defined_pthread_once_types 1 | ||
| 759 | # endif | ||
| 760 | # undef PTHREAD_ONCE_INIT | ||
| 761 | # define PTHREAD_ONCE_INIT { 0 } | ||
| 762 | # endif | ||
| 763 | #endif | ||
| 764 | |||
| 765 | /* =========== Mutex types and macros =========== */ | ||
| 766 | |||
| 767 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 768 | # if 0 | ||
| 769 | # include "windows-timedmutex.h" | ||
| 770 | # include "windows-timedrecmutex.h" | ||
| 771 | # if 1 | ||
| 772 | # define pthread_mutex_t rpl_pthread_mutex_t | ||
| 773 | # define pthread_mutexattr_t rpl_pthread_mutexattr_t | ||
| 774 | # endif | ||
| 775 | # if !GNULIB_defined_pthread_mutex_types | ||
| 776 | typedef struct | ||
| 777 | { | ||
| 778 | int type; | ||
| 779 | union | ||
| 780 | { | ||
| 781 | glwthread_timedmutex_t u_timedmutex; | ||
| 782 | glwthread_timedrecmutex_t u_timedrecmutex; | ||
| 783 | } | ||
| 784 | u; | ||
| 785 | } | ||
| 786 | pthread_mutex_t; | ||
| 787 | typedef unsigned int pthread_mutexattr_t; | ||
| 788 | # define GNULIB_defined_pthread_mutex_types 1 | ||
| 789 | # endif | ||
| 790 | # undef PTHREAD_MUTEX_INITIALIZER | ||
| 791 | # define PTHREAD_MUTEX_INITIALIZER { 1, { GLWTHREAD_TIMEDMUTEX_INIT } } | ||
| 792 | # else | ||
| 793 | # if 1 | ||
| 794 | # define pthread_mutex_t rpl_pthread_mutex_t | ||
| 795 | # define pthread_mutexattr_t rpl_pthread_mutexattr_t | ||
| 796 | # endif | ||
| 797 | # if !GNULIB_defined_pthread_mutex_types | ||
| 798 | typedef int pthread_mutex_t; | ||
| 799 | typedef unsigned int pthread_mutexattr_t; | ||
| 800 | # define GNULIB_defined_pthread_mutex_types 1 | ||
| 801 | # endif | ||
| 802 | # undef PTHREAD_MUTEX_INITIALIZER | ||
| 803 | # define PTHREAD_MUTEX_INITIALIZER { 0 } | ||
| 804 | # endif | ||
| 805 | # undef PTHREAD_MUTEX_DEFAULT | ||
| 806 | # undef PTHREAD_MUTEX_NORMAL | ||
| 807 | # undef PTHREAD_MUTEX_ERRORCHECK | ||
| 808 | # undef PTHREAD_MUTEX_RECURSIVE | ||
| 809 | # define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL | ||
| 810 | # define PTHREAD_MUTEX_NORMAL 0 | ||
| 811 | # define PTHREAD_MUTEX_ERRORCHECK 1 | ||
| 812 | # define PTHREAD_MUTEX_RECURSIVE 2 | ||
| 813 | # undef PTHREAD_MUTEX_STALLED | ||
| 814 | # undef PTHREAD_MUTEX_ROBUST | ||
| 815 | # define PTHREAD_MUTEX_STALLED 0 | ||
| 816 | # define PTHREAD_MUTEX_ROBUST 1 | ||
| 817 | #else | ||
| 818 | # if !1 | ||
| 819 | # if !GNULIB_defined_pthread_mutex_types | ||
| 820 | typedef int pthread_mutex_t; | ||
| 821 | typedef unsigned int pthread_mutexattr_t; | ||
| 822 | # define GNULIB_defined_pthread_mutex_types 1 | ||
| 823 | # endif | ||
| 824 | # undef PTHREAD_MUTEX_INITIALIZER | ||
| 825 | # define PTHREAD_MUTEX_INITIALIZER { 0 } | ||
| 826 | # endif | ||
| 827 | # if !1 | ||
| 828 | # define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL | ||
| 829 | # define PTHREAD_MUTEX_NORMAL 0 | ||
| 830 | # define PTHREAD_MUTEX_ERRORCHECK 1 | ||
| 831 | # define PTHREAD_MUTEX_RECURSIVE 2 | ||
| 832 | # endif | ||
| 833 | # if !1 | ||
| 834 | # define PTHREAD_MUTEX_STALLED 0 | ||
| 835 | # define PTHREAD_MUTEX_ROBUST 1 | ||
| 836 | # endif | ||
| 837 | #endif | ||
| 838 | |||
| 839 | /* =========== Read-write lock types and macros =========== */ | ||
| 840 | |||
| 841 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 842 | # if 0 | ||
| 843 | # include "windows-timedrwlock.h" | ||
| 844 | # if 1 | ||
| 845 | # define pthread_rwlock_t rpl_pthread_rwlock_t | ||
| 846 | # define pthread_rwlockattr_t rpl_pthread_rwlockattr_t | ||
| 847 | # endif | ||
| 848 | # if !GNULIB_defined_pthread_rwlock_types | ||
| 849 | typedef glwthread_timedrwlock_t pthread_rwlock_t; | ||
| 850 | typedef unsigned int pthread_rwlockattr_t; | ||
| 851 | # define GNULIB_defined_pthread_rwlock_types 1 | ||
| 852 | # endif | ||
| 853 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 854 | # define PTHREAD_RWLOCK_INITIALIZER GLWTHREAD_TIMEDRWLOCK_INIT | ||
| 855 | # else | ||
| 856 | # if 1 | ||
| 857 | # define pthread_rwlock_t rpl_pthread_rwlock_t | ||
| 858 | # define pthread_rwlockattr_t rpl_pthread_rwlockattr_t | ||
| 859 | # endif | ||
| 860 | # if !GNULIB_defined_pthread_rwlock_types | ||
| 861 | typedef int pthread_rwlock_t; | ||
| 862 | typedef unsigned int pthread_rwlockattr_t; | ||
| 863 | # define GNULIB_defined_pthread_rwlock_types 1 | ||
| 864 | # endif | ||
| 865 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 866 | # define PTHREAD_RWLOCK_INITIALIZER { 0 } | ||
| 867 | # endif | ||
| 868 | #elif 0 && 0 /* i.e. PTHREAD_RWLOCK_UNIMPLEMENTED */ | ||
| 869 | # if 1 | ||
| 870 | # define pthread_rwlock_t rpl_pthread_rwlock_t | ||
| 871 | # define pthread_rwlockattr_t rpl_pthread_rwlockattr_t | ||
| 872 | # endif | ||
| 873 | # if !GNULIB_defined_pthread_rwlock_types | ||
| 874 | typedef struct | ||
| 875 | { | ||
| 876 | pthread_mutex_t lock; /* protects the remaining fields */ | ||
| 877 | pthread_cond_t waiting_readers; /* waiting readers */ | ||
| 878 | pthread_cond_t waiting_writers; /* waiting writers */ | ||
| 879 | unsigned int waiting_writers_count; /* number of waiting writers */ | ||
| 880 | int runcount; /* number of readers running, or -1 when a writer runs */ | ||
| 881 | } | ||
| 882 | pthread_rwlock_t; | ||
| 883 | typedef unsigned int pthread_rwlockattr_t; | ||
| 884 | # define GNULIB_defined_pthread_rwlock_types 1 | ||
| 885 | # endif | ||
| 886 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 887 | # define PTHREAD_RWLOCK_INITIALIZER \ | ||
| 888 | { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 } | ||
| 889 | #elif 0 && 0 /* i.e. PTHREAD_RWLOCK_BAD_WAITQUEUE */ | ||
| 890 | /* Use rwlocks of kind PREFER_WRITER or PREFER_WRITER_NONRECURSIVE instead of | ||
| 891 | the DEFAULT. */ | ||
| 892 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 893 | # define PTHREAD_RWLOCK_INITIALIZER PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP | ||
| 894 | #else | ||
| 895 | # if 1 | ||
| 896 | # if !defined PTHREAD_RWLOCK_INITIALIZER && defined PTHREAD_RWLOCK_INITIALIZER_NP /* z/OS */ | ||
| 897 | # define PTHREAD_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER_NP | ||
| 898 | # endif | ||
| 899 | # else | ||
| 900 | # if !GNULIB_defined_pthread_rwlock_types | ||
| 901 | typedef int pthread_rwlock_t; | ||
| 902 | typedef unsigned int pthread_rwlockattr_t; | ||
| 903 | # define GNULIB_defined_pthread_rwlock_types 1 | ||
| 904 | # endif | ||
| 905 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 906 | # define PTHREAD_RWLOCK_INITIALIZER { 0 } | ||
| 907 | # endif | ||
| 908 | #endif | ||
| 909 | |||
| 910 | /* =========== Condition variable types and macros =========== */ | ||
| 911 | |||
| 912 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 913 | # if 0 | ||
| 914 | # include "windows-cond.h" | ||
| 915 | # if 1 | ||
| 916 | # define pthread_cond_t rpl_pthread_cond_t | ||
| 917 | # define pthread_condattr_t rpl_pthread_condattr_t | ||
| 918 | # endif | ||
| 919 | # if !GNULIB_defined_pthread_cond_types | ||
| 920 | typedef glwthread_cond_t pthread_cond_t; | ||
| 921 | typedef unsigned int pthread_condattr_t; | ||
| 922 | # define GNULIB_defined_pthread_cond_types 1 | ||
| 923 | # endif | ||
| 924 | # undef PTHREAD_COND_INITIALIZER | ||
| 925 | # define PTHREAD_COND_INITIALIZER GLWTHREAD_COND_INIT | ||
| 926 | # else | ||
| 927 | # if 1 | ||
| 928 | # define pthread_cond_t rpl_pthread_cond_t | ||
| 929 | # define pthread_condattr_t rpl_pthread_condattr_t | ||
| 930 | # endif | ||
| 931 | # if !GNULIB_defined_pthread_cond_types | ||
| 932 | typedef int pthread_cond_t; | ||
| 933 | typedef unsigned int pthread_condattr_t; | ||
| 934 | # define GNULIB_defined_pthread_cond_types 1 | ||
| 935 | # endif | ||
| 936 | # undef PTHREAD_COND_INITIALIZER | ||
| 937 | # define PTHREAD_COND_INITIALIZER { 0 } | ||
| 938 | # endif | ||
| 939 | #else | ||
| 940 | # if !1 | ||
| 941 | # if !GNULIB_defined_pthread_cond_types | ||
| 942 | typedef int pthread_cond_t; | ||
| 943 | typedef unsigned int pthread_condattr_t; | ||
| 944 | # define GNULIB_defined_pthread_cond_types 1 | ||
| 945 | # endif | ||
| 946 | # undef PTHREAD_COND_INITIALIZER | ||
| 947 | # define PTHREAD_COND_INITIALIZER { 0 } | ||
| 948 | # endif | ||
| 949 | #endif | ||
| 950 | |||
| 951 | /* =========== Thread-specific storage types and macros =========== */ | ||
| 952 | |||
| 953 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 954 | # if 0 | ||
| 955 | # include "windows-tls.h" | ||
| 956 | # if 1 | ||
| 957 | # define pthread_key_t rpl_pthread_key_t | ||
| 958 | # endif | ||
| 959 | # if !GNULIB_defined_pthread_tss_types | ||
| 960 | typedef glwthread_tls_key_t pthread_key_t; | ||
| 961 | # define GNULIB_defined_pthread_tss_types 1 | ||
| 962 | # endif | ||
| 963 | # undef PTHREAD_DESTRUCTOR_ITERATIONS | ||
| 964 | # define PTHREAD_DESTRUCTOR_ITERATIONS GLWTHREAD_DESTRUCTOR_ITERATIONS | ||
| 965 | # else | ||
| 966 | # if 1 | ||
| 967 | # define pthread_key_t rpl_pthread_key_t | ||
| 968 | # endif | ||
| 969 | # if !GNULIB_defined_pthread_tss_types | ||
| 970 | typedef void ** pthread_key_t; | ||
| 971 | # define GNULIB_defined_pthread_tss_types 1 | ||
| 972 | # endif | ||
| 973 | # undef PTHREAD_DESTRUCTOR_ITERATIONS | ||
| 974 | # define PTHREAD_DESTRUCTOR_ITERATIONS 0 | ||
| 975 | # endif | ||
| 976 | #else | ||
| 977 | # if !1 | ||
| 978 | # if !GNULIB_defined_pthread_tss_types | ||
| 979 | typedef void ** pthread_key_t; | ||
| 980 | # define GNULIB_defined_pthread_tss_types 1 | ||
| 981 | # endif | ||
| 982 | # undef PTHREAD_DESTRUCTOR_ITERATIONS | ||
| 983 | # define PTHREAD_DESTRUCTOR_ITERATIONS 0 | ||
| 984 | # endif | ||
| 985 | #endif | ||
| 986 | |||
| 987 | /* =========== Spinlock types and macros =========== */ | ||
| 988 | |||
| 989 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 990 | # if 0 | ||
| 991 | # include "windows-spin.h" | ||
| 992 | # if 1 | ||
| 993 | # define pthread_spinlock_t rpl_pthread_spinlock_t | ||
| 994 | # endif | ||
| 995 | # if !GNULIB_defined_pthread_spin_types | ||
| 996 | typedef glwthread_spinlock_t pthread_spinlock_t; | ||
| 997 | # define GNULIB_defined_pthread_spin_types 1 | ||
| 998 | # endif | ||
| 999 | # else | ||
| 1000 | # if 1 | ||
| 1001 | # define pthread_spinlock_t rpl_pthread_spinlock_t | ||
| 1002 | # endif | ||
| 1003 | # if !GNULIB_defined_pthread_spin_types | ||
| 1004 | typedef pthread_mutex_t pthread_spinlock_t; | ||
| 1005 | # define GNULIB_defined_pthread_spin_types 1 | ||
| 1006 | # endif | ||
| 1007 | # endif | ||
| 1008 | # undef PTHREAD_PROCESS_PRIVATE | ||
| 1009 | # undef PTHREAD_PROCESS_SHARED | ||
| 1010 | # define PTHREAD_PROCESS_PRIVATE 0 | ||
| 1011 | # define PTHREAD_PROCESS_SHARED 1 | ||
| 1012 | #else | ||
| 1013 | # if 1 | ||
| 1014 | /* <pthread.h> exists and defines pthread_spinlock_t. */ | ||
| 1015 | # if !1 || 0 | ||
| 1016 | /* If the 'pthread-spin' module is in use, it defines all the pthread_spin* | ||
| 1017 | functions. Prepare for it by overriding pthread_spinlock_t if that might | ||
| 1018 | be needed. */ | ||
| 1019 | # if !(((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) \ | ||
| 1020 | || __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 1)) \ | ||
| 1021 | || (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \ | ||
| 1022 | && !defined __ANDROID__) \ | ||
| 1023 | || __clang_major__ >= 3)) \ | ||
| 1024 | && !defined __ibmxl__) | ||
| 1025 | /* We can't use GCC built-ins. Approximate spinlocks with mutexes. */ | ||
| 1026 | # if !GNULIB_defined_pthread_spin_types | ||
| 1027 | # define pthread_spinlock_t pthread_mutex_t | ||
| 1028 | # define GNULIB_defined_pthread_spin_types 1 | ||
| 1029 | # endif | ||
| 1030 | # endif | ||
| 1031 | # endif | ||
| 1032 | # else | ||
| 1033 | /* Approximate spinlocks with mutexes. */ | ||
| 1034 | # if !GNULIB_defined_pthread_spin_types | ||
| 1035 | typedef pthread_mutex_t pthread_spinlock_t; | ||
| 1036 | # define GNULIB_defined_pthread_spin_types 1 | ||
| 1037 | # endif | ||
| 1038 | # endif | ||
| 1039 | # if !1 | ||
| 1040 | # define PTHREAD_PROCESS_PRIVATE 0 | ||
| 1041 | # define PTHREAD_PROCESS_SHARED 1 | ||
| 1042 | # endif | ||
| 1043 | #endif | ||
| 1044 | |||
| 1045 | /* =========== Other types and macros =========== */ | ||
| 1046 | |||
| 1047 | #if !1 | ||
| 1048 | # if !GNULIB_defined_other_pthread_types | ||
| 1049 | typedef int pthread_barrier_t; | ||
| 1050 | typedef unsigned int pthread_barrierattr_t; | ||
| 1051 | # define GNULIB_defined_other_pthread_types 1 | ||
| 1052 | # endif | ||
| 1053 | #endif | ||
| 1054 | |||
| 1055 | #if !defined PTHREAD_CANCELED | ||
| 1056 | |||
| 1057 | # define PTHREAD_BARRIER_SERIAL_THREAD (-1) | ||
| 1058 | |||
| 1059 | # define PTHREAD_CANCEL_DEFERRED 0 | ||
| 1060 | # define PTHREAD_CANCEL_ASYNCHRONOUS 1 | ||
| 1061 | |||
| 1062 | # define PTHREAD_CANCEL_ENABLE 0 | ||
| 1063 | # define PTHREAD_CANCEL_DISABLE 1 | ||
| 1064 | |||
| 1065 | # define PTHREAD_CANCELED ((void *) -1) | ||
| 1066 | |||
| 1067 | # define PTHREAD_INHERIT_SCHED 0 | ||
| 1068 | # define PTHREAD_EXPLICIT_SCHED 1 | ||
| 1069 | |||
| 1070 | # define PTHREAD_PRIO_NONE 0 | ||
| 1071 | # define PTHREAD_PRIO_INHERIT 1 | ||
| 1072 | # define PTHREAD_PRIO_PROTECT 2 | ||
| 1073 | |||
| 1074 | # define PTHREAD_SCOPE_SYSTEM 0 | ||
| 1075 | # define PTHREAD_SCOPE_PROCESS 1 | ||
| 1076 | |||
| 1077 | #endif | ||
| 1078 | |||
| 1079 | /* =========== Thread functions =========== */ | ||
| 1080 | |||
| 1081 | #if 0 | ||
| 1082 | /* The 'restrict' qualifier on ARG is nonsense, but POSIX specifies it this way. | ||
| 1083 | Sigh. */ | ||
| 1084 | # if 0 | ||
| 1085 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1086 | # undef pthread_create | ||
| 1087 | # define pthread_create rpl_pthread_create | ||
| 1088 | # endif | ||
| 1089 | _GL_FUNCDECL_RPL (pthread_create, int, | ||
| 1090 | (pthread_t *restrict threadp, | ||
| 1091 | const pthread_attr_t *restrict attr, | ||
| 1092 | void * (*mainfunc) (void *), void *restrict arg), | ||
| 1093 | _GL_ARG_NONNULL ((1, 3))); | ||
| 1094 | _GL_CXXALIAS_RPL (pthread_create, int, | ||
| 1095 | (pthread_t *restrict threadp, | ||
| 1096 | const pthread_attr_t *restrict attr, | ||
| 1097 | void * (*mainfunc) (void *), void *restrict arg)); | ||
| 1098 | # else | ||
| 1099 | # if !1 | ||
| 1100 | _GL_FUNCDECL_SYS (pthread_create, int, | ||
| 1101 | (pthread_t *restrict threadp, | ||
| 1102 | const pthread_attr_t *restrict attr, | ||
| 1103 | void * (*mainfunc) (void *), void *restrict arg), | ||
| 1104 | _GL_ARG_NONNULL ((1, 3))); | ||
| 1105 | # endif | ||
| 1106 | _GL_CXXALIAS_SYS_CAST (pthread_create, int, | ||
| 1107 | (pthread_t *restrict threadp, | ||
| 1108 | const pthread_attr_t *restrict attr, | ||
| 1109 | void * (*mainfunc) (void *), void *restrict arg)); | ||
| 1110 | # endif | ||
| 1111 | # if __GLIBC__ >= 2 | ||
| 1112 | _GL_CXXALIASWARN (pthread_create); | ||
| 1113 | # endif | ||
| 1114 | #elif defined GNULIB_POSIXCHECK | ||
| 1115 | # if HAVE_RAW_DECL_PTHREAD_CREATE | ||
| 1116 | _GL_WARN_ON_USE (pthread_create, "pthread_create is not portable - " | ||
| 1117 | "use gnulib module pthread-thread for portability"); | ||
| 1118 | # endif | ||
| 1119 | #endif | ||
| 1120 | |||
| 1121 | #if 0 | ||
| 1122 | # if 0 | ||
| 1123 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1124 | # undef pthread_attr_init | ||
| 1125 | # define pthread_attr_init rpl_pthread_attr_init | ||
| 1126 | # endif | ||
| 1127 | _GL_FUNCDECL_RPL (pthread_attr_init, int, (pthread_attr_t *attr), | ||
| 1128 | _GL_ARG_NONNULL ((1))); | ||
| 1129 | _GL_CXXALIAS_RPL (pthread_attr_init, int, (pthread_attr_t *attr)); | ||
| 1130 | # else | ||
| 1131 | # if !1 | ||
| 1132 | _GL_FUNCDECL_SYS (pthread_attr_init, int, (pthread_attr_t *attr), | ||
| 1133 | _GL_ARG_NONNULL ((1))); | ||
| 1134 | # endif | ||
| 1135 | _GL_CXXALIAS_SYS (pthread_attr_init, int, (pthread_attr_t *attr)); | ||
| 1136 | # endif | ||
| 1137 | # if __GLIBC__ >= 2 | ||
| 1138 | _GL_CXXALIASWARN (pthread_attr_init); | ||
| 1139 | # endif | ||
| 1140 | #elif defined GNULIB_POSIXCHECK | ||
| 1141 | # if HAVE_RAW_DECL_PTHREAD_ATTR_INIT | ||
| 1142 | _GL_WARN_ON_USE (pthread_attr_init, "pthread_attr_init is not portable - " | ||
| 1143 | "use gnulib module pthread-thread for portability"); | ||
| 1144 | # endif | ||
| 1145 | #endif | ||
| 1146 | |||
| 1147 | #if 0 | ||
| 1148 | # if 0 | ||
| 1149 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1150 | # undef pthread_attr_getdetachstate | ||
| 1151 | # define pthread_attr_getdetachstate rpl_pthread_attr_getdetachstate | ||
| 1152 | # endif | ||
| 1153 | _GL_FUNCDECL_RPL (pthread_attr_getdetachstate, int, | ||
| 1154 | (const pthread_attr_t *attr, int *detachstatep), | ||
| 1155 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1156 | _GL_CXXALIAS_RPL (pthread_attr_getdetachstate, int, | ||
| 1157 | (const pthread_attr_t *attr, int *detachstatep)); | ||
| 1158 | # else | ||
| 1159 | # if !1 | ||
| 1160 | _GL_FUNCDECL_SYS (pthread_attr_getdetachstate, int, | ||
| 1161 | (const pthread_attr_t *attr, int *detachstatep), | ||
| 1162 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1163 | # endif | ||
| 1164 | _GL_CXXALIAS_SYS (pthread_attr_getdetachstate, int, | ||
| 1165 | (const pthread_attr_t *attr, int *detachstatep)); | ||
| 1166 | # endif | ||
| 1167 | # if __GLIBC__ >= 2 | ||
| 1168 | _GL_CXXALIASWARN (pthread_attr_getdetachstate); | ||
| 1169 | # endif | ||
| 1170 | #elif defined GNULIB_POSIXCHECK | ||
| 1171 | # if HAVE_RAW_DECL_PTHREAD_ATTR_GETDETACHSTATE | ||
| 1172 | _GL_WARN_ON_USE (pthread_attr_getdetachstate, "pthread_attr_getdetachstate is not portable - " | ||
| 1173 | "use gnulib module pthread-thread for portability"); | ||
| 1174 | # endif | ||
| 1175 | #endif | ||
| 1176 | |||
| 1177 | #if 0 | ||
| 1178 | # if 0 | ||
| 1179 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1180 | # undef pthread_attr_setdetachstate | ||
| 1181 | # define pthread_attr_setdetachstate rpl_pthread_attr_setdetachstate | ||
| 1182 | # endif | ||
| 1183 | _GL_FUNCDECL_RPL (pthread_attr_setdetachstate, int, | ||
| 1184 | (pthread_attr_t *attr, int detachstate), | ||
| 1185 | _GL_ARG_NONNULL ((1))); | ||
| 1186 | _GL_CXXALIAS_RPL (pthread_attr_setdetachstate, int, | ||
| 1187 | (pthread_attr_t *attr, int detachstate)); | ||
| 1188 | # else | ||
| 1189 | # if !1 | ||
| 1190 | _GL_FUNCDECL_SYS (pthread_attr_setdetachstate, int, | ||
| 1191 | (pthread_attr_t *attr, int detachstate), | ||
| 1192 | _GL_ARG_NONNULL ((1))); | ||
| 1193 | # endif | ||
| 1194 | _GL_CXXALIAS_SYS (pthread_attr_setdetachstate, int, | ||
| 1195 | (pthread_attr_t *attr, int detachstate)); | ||
| 1196 | # endif | ||
| 1197 | # if __GLIBC__ >= 2 | ||
| 1198 | _GL_CXXALIASWARN (pthread_attr_setdetachstate); | ||
| 1199 | # endif | ||
| 1200 | #elif defined GNULIB_POSIXCHECK | ||
| 1201 | # if HAVE_RAW_DECL_PTHREAD_ATTR_SETDETACHSTATE | ||
| 1202 | _GL_WARN_ON_USE (pthread_attr_setdetachstate, "pthread_attr_setdetachstate is not portable - " | ||
| 1203 | "use gnulib module pthread-thread for portability"); | ||
| 1204 | # endif | ||
| 1205 | #endif | ||
| 1206 | |||
| 1207 | #if 0 | ||
| 1208 | # if 0 | ||
| 1209 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1210 | # undef pthread_attr_destroy | ||
| 1211 | # define pthread_attr_destroy rpl_pthread_attr_destroy | ||
| 1212 | # endif | ||
| 1213 | _GL_FUNCDECL_RPL (pthread_attr_destroy, int, (pthread_attr_t *attr), | ||
| 1214 | _GL_ARG_NONNULL ((1))); | ||
| 1215 | _GL_CXXALIAS_RPL (pthread_attr_destroy, int, (pthread_attr_t *attr)); | ||
| 1216 | # else | ||
| 1217 | # if !1 | ||
| 1218 | _GL_FUNCDECL_SYS (pthread_attr_destroy, int, (pthread_attr_t *attr), | ||
| 1219 | _GL_ARG_NONNULL ((1))); | ||
| 1220 | # endif | ||
| 1221 | _GL_CXXALIAS_SYS (pthread_attr_destroy, int, (pthread_attr_t *attr)); | ||
| 1222 | # endif | ||
| 1223 | # if __GLIBC__ >= 2 | ||
| 1224 | _GL_CXXALIASWARN (pthread_attr_destroy); | ||
| 1225 | # endif | ||
| 1226 | #elif defined GNULIB_POSIXCHECK | ||
| 1227 | # if HAVE_RAW_DECL_PTHREAD_ATTR_DESTROY | ||
| 1228 | _GL_WARN_ON_USE (pthread_attr_destroy, "pthread_attr_destroy is not portable - " | ||
| 1229 | "use gnulib module pthread-thread for portability"); | ||
| 1230 | # endif | ||
| 1231 | #endif | ||
| 1232 | |||
| 1233 | #if 0 | ||
| 1234 | # if 0 | ||
| 1235 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1236 | # undef pthread_self | ||
| 1237 | # define pthread_self rpl_pthread_self | ||
| 1238 | # endif | ||
| 1239 | _GL_FUNCDECL_RPL (pthread_self, pthread_t, (void), _GL_ATTRIBUTE_PURE); | ||
| 1240 | _GL_CXXALIAS_RPL (pthread_self, pthread_t, (void)); | ||
| 1241 | # else | ||
| 1242 | # if !1 | ||
| 1243 | _GL_FUNCDECL_SYS (pthread_self, pthread_t, (void), _GL_ATTRIBUTE_PURE); | ||
| 1244 | # endif | ||
| 1245 | _GL_CXXALIAS_SYS (pthread_self, pthread_t, (void)); | ||
| 1246 | # endif | ||
| 1247 | # if __GLIBC__ >= 2 | ||
| 1248 | _GL_CXXALIASWARN (pthread_self); | ||
| 1249 | # endif | ||
| 1250 | #elif defined GNULIB_POSIXCHECK | ||
| 1251 | # if HAVE_RAW_DECL_PTHREAD_SELF | ||
| 1252 | _GL_WARN_ON_USE (pthread_self, "pthread_self is not portable - " | ||
| 1253 | "use gnulib module pthread-thread for portability"); | ||
| 1254 | # endif | ||
| 1255 | #endif | ||
| 1256 | |||
| 1257 | #if 0 | ||
| 1258 | # if 0 | ||
| 1259 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1260 | # undef pthread_equal | ||
| 1261 | # define pthread_equal rpl_pthread_equal | ||
| 1262 | # endif | ||
| 1263 | _GL_FUNCDECL_RPL (pthread_equal, int, (pthread_t thread1, pthread_t thread2), ); | ||
| 1264 | _GL_CXXALIAS_RPL (pthread_equal, int, (pthread_t thread1, pthread_t thread2)); | ||
| 1265 | # else | ||
| 1266 | # if !1 | ||
| 1267 | _GL_FUNCDECL_SYS (pthread_equal, int, (pthread_t thread1, pthread_t thread2), ); | ||
| 1268 | # endif | ||
| 1269 | _GL_CXXALIAS_SYS (pthread_equal, int, (pthread_t thread1, pthread_t thread2)); | ||
| 1270 | # endif | ||
| 1271 | # if __GLIBC__ >= 2 | ||
| 1272 | _GL_CXXALIASWARN (pthread_equal); | ||
| 1273 | # endif | ||
| 1274 | #elif defined GNULIB_POSIXCHECK | ||
| 1275 | # if HAVE_RAW_DECL_PTHREAD_EQUAL | ||
| 1276 | _GL_WARN_ON_USE (pthread_equal, "pthread_equal is not portable - " | ||
| 1277 | "use gnulib module pthread-thread for portability"); | ||
| 1278 | # endif | ||
| 1279 | #endif | ||
| 1280 | |||
| 1281 | #if 0 | ||
| 1282 | # if 0 | ||
| 1283 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1284 | # undef pthread_detach | ||
| 1285 | # define pthread_detach rpl_pthread_detach | ||
| 1286 | # endif | ||
| 1287 | _GL_FUNCDECL_RPL (pthread_detach, int, (pthread_t thread), ); | ||
| 1288 | _GL_CXXALIAS_RPL (pthread_detach, int, (pthread_t thread)); | ||
| 1289 | # else | ||
| 1290 | # if !1 | ||
| 1291 | _GL_FUNCDECL_SYS (pthread_detach, int, (pthread_t thread), ); | ||
| 1292 | # endif | ||
| 1293 | _GL_CXXALIAS_SYS (pthread_detach, int, (pthread_t thread)); | ||
| 1294 | # endif | ||
| 1295 | # if __GLIBC__ >= 2 | ||
| 1296 | _GL_CXXALIASWARN (pthread_detach); | ||
| 1297 | # endif | ||
| 1298 | #elif defined GNULIB_POSIXCHECK | ||
| 1299 | # if HAVE_RAW_DECL_PTHREAD_DETACH | ||
| 1300 | _GL_WARN_ON_USE (pthread_detach, "pthread_detach is not portable - " | ||
| 1301 | "use gnulib module pthread-thread for portability"); | ||
| 1302 | # endif | ||
| 1303 | #endif | ||
| 1304 | |||
| 1305 | #if 0 | ||
| 1306 | # if 0 | ||
| 1307 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1308 | # undef pthread_join | ||
| 1309 | # define pthread_join rpl_pthread_join | ||
| 1310 | # endif | ||
| 1311 | _GL_FUNCDECL_RPL (pthread_join, int, (pthread_t thread, void **valuep), ); | ||
| 1312 | _GL_CXXALIAS_RPL (pthread_join, int, (pthread_t thread, void **valuep)); | ||
| 1313 | # else | ||
| 1314 | # if !1 | ||
| 1315 | _GL_FUNCDECL_SYS (pthread_join, int, (pthread_t thread, void **valuep), ); | ||
| 1316 | # endif | ||
| 1317 | _GL_CXXALIAS_SYS (pthread_join, int, (pthread_t thread, void **valuep)); | ||
| 1318 | # endif | ||
| 1319 | # if __GLIBC__ >= 2 | ||
| 1320 | _GL_CXXALIASWARN (pthread_join); | ||
| 1321 | # endif | ||
| 1322 | #elif defined GNULIB_POSIXCHECK | ||
| 1323 | # if HAVE_RAW_DECL_PTHREAD_JOIN | ||
| 1324 | _GL_WARN_ON_USE (pthread_join, "pthread_join is not portable - " | ||
| 1325 | "use gnulib module pthread-thread for portability"); | ||
| 1326 | # endif | ||
| 1327 | #endif | ||
| 1328 | |||
| 1329 | #if 0 | ||
| 1330 | # if 0 | ||
| 1331 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1332 | # undef pthread_exit | ||
| 1333 | # define pthread_exit rpl_pthread_exit | ||
| 1334 | # endif | ||
| 1335 | _GL_FUNCDECL_RPL (pthread_exit, _Noreturn void, (void *value), ); | ||
| 1336 | _GL_CXXALIAS_RPL (pthread_exit, void, (void *value)); | ||
| 1337 | # else | ||
| 1338 | # if !1 | ||
| 1339 | _GL_FUNCDECL_SYS (pthread_exit, _Noreturn void, (void *value), ); | ||
| 1340 | # endif | ||
| 1341 | /* Need to cast because of AIX with xlclang++. */ | ||
| 1342 | _GL_CXXALIAS_SYS_CAST (pthread_exit, void, (void *value)); | ||
| 1343 | # endif | ||
| 1344 | # if __GLIBC__ >= 2 | ||
| 1345 | _GL_CXXALIASWARN (pthread_exit); | ||
| 1346 | # endif | ||
| 1347 | #elif defined GNULIB_POSIXCHECK | ||
| 1348 | # if HAVE_RAW_DECL_PTHREAD_EXIT | ||
| 1349 | _GL_WARN_ON_USE (pthread_exit, "pthread_exit is not portable - " | ||
| 1350 | "use gnulib module pthread-thread for portability"); | ||
| 1351 | # endif | ||
| 1352 | #endif | ||
| 1353 | |||
| 1354 | /* =========== Once-only control (initialization) functions =========== */ | ||
| 1355 | |||
| 1356 | #if 1 | ||
| 1357 | # if 0 | ||
| 1358 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1359 | # undef pthread_once | ||
| 1360 | # define pthread_once rpl_pthread_once | ||
| 1361 | # endif | ||
| 1362 | _GL_FUNCDECL_RPL (pthread_once, int, | ||
| 1363 | (pthread_once_t *once_control, void (*initfunction) (void)), | ||
| 1364 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1365 | _GL_CXXALIAS_RPL (pthread_once, int, | ||
| 1366 | (pthread_once_t *once_control, void (*initfunction) (void))); | ||
| 1367 | # else | ||
| 1368 | # if !1 | ||
| 1369 | _GL_FUNCDECL_SYS (pthread_once, int, | ||
| 1370 | (pthread_once_t *once_control, void (*initfunction) (void)), | ||
| 1371 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1372 | # endif | ||
| 1373 | _GL_CXXALIAS_SYS_CAST (pthread_once, int, | ||
| 1374 | (pthread_once_t *once_control, | ||
| 1375 | void (*initfunction) (void))); | ||
| 1376 | # endif | ||
| 1377 | # if __GLIBC__ >= 2 | ||
| 1378 | _GL_CXXALIASWARN (pthread_once); | ||
| 1379 | # endif | ||
| 1380 | #elif defined GNULIB_POSIXCHECK | ||
| 1381 | # if HAVE_RAW_DECL_PTHREAD_ONCE | ||
| 1382 | _GL_WARN_ON_USE (pthread_once, "pthread_once is not portable - " | ||
| 1383 | "use gnulib module pthread-once for portability"); | ||
| 1384 | # endif | ||
| 1385 | #endif | ||
| 1386 | |||
| 1387 | /* =========== Mutex functions =========== */ | ||
| 1388 | |||
| 1389 | #if 0 | ||
| 1390 | # if 0 | ||
| 1391 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1392 | # undef pthread_mutex_init | ||
| 1393 | # define pthread_mutex_init rpl_pthread_mutex_init | ||
| 1394 | # endif | ||
| 1395 | _GL_FUNCDECL_RPL (pthread_mutex_init, int, | ||
| 1396 | (pthread_mutex_t *restrict mutex, | ||
| 1397 | const pthread_mutexattr_t *restrict attr), | ||
| 1398 | _GL_ARG_NONNULL ((1))); | ||
| 1399 | _GL_CXXALIAS_RPL (pthread_mutex_init, int, | ||
| 1400 | (pthread_mutex_t *restrict mutex, | ||
| 1401 | const pthread_mutexattr_t *restrict attr)); | ||
| 1402 | # else | ||
| 1403 | # if !1 | ||
| 1404 | _GL_FUNCDECL_SYS (pthread_mutex_init, int, | ||
| 1405 | (pthread_mutex_t *restrict mutex, | ||
| 1406 | const pthread_mutexattr_t *restrict attr), | ||
| 1407 | _GL_ARG_NONNULL ((1))); | ||
| 1408 | # endif | ||
| 1409 | _GL_CXXALIAS_SYS (pthread_mutex_init, int, | ||
| 1410 | (pthread_mutex_t *restrict mutex, | ||
| 1411 | const pthread_mutexattr_t *restrict attr)); | ||
| 1412 | # endif | ||
| 1413 | # if __GLIBC__ >= 2 | ||
| 1414 | _GL_CXXALIASWARN (pthread_mutex_init); | ||
| 1415 | # endif | ||
| 1416 | #elif defined GNULIB_POSIXCHECK | ||
| 1417 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_INIT | ||
| 1418 | _GL_WARN_ON_USE (pthread_mutex_init, "pthread_mutex_init is not portable - " | ||
| 1419 | "use gnulib module pthread-mutex for portability"); | ||
| 1420 | # endif | ||
| 1421 | #endif | ||
| 1422 | |||
| 1423 | #if 0 | ||
| 1424 | # if 0 | ||
| 1425 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1426 | # undef pthread_mutexattr_init | ||
| 1427 | # define pthread_mutexattr_init rpl_pthread_mutexattr_init | ||
| 1428 | # endif | ||
| 1429 | _GL_FUNCDECL_RPL (pthread_mutexattr_init, int, (pthread_mutexattr_t *attr), | ||
| 1430 | _GL_ARG_NONNULL ((1))); | ||
| 1431 | _GL_CXXALIAS_RPL (pthread_mutexattr_init, int, (pthread_mutexattr_t *attr)); | ||
| 1432 | # else | ||
| 1433 | # if !1 | ||
| 1434 | _GL_FUNCDECL_SYS (pthread_mutexattr_init, int, (pthread_mutexattr_t *attr), | ||
| 1435 | _GL_ARG_NONNULL ((1))); | ||
| 1436 | # endif | ||
| 1437 | _GL_CXXALIAS_SYS (pthread_mutexattr_init, int, (pthread_mutexattr_t *attr)); | ||
| 1438 | # endif | ||
| 1439 | # if __GLIBC__ >= 2 | ||
| 1440 | _GL_CXXALIASWARN (pthread_mutexattr_init); | ||
| 1441 | # endif | ||
| 1442 | #elif defined GNULIB_POSIXCHECK | ||
| 1443 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_INIT | ||
| 1444 | _GL_WARN_ON_USE (pthread_mutexattr_init, "pthread_mutexattr_init is not portable - " | ||
| 1445 | "use gnulib module pthread-mutex for portability"); | ||
| 1446 | # endif | ||
| 1447 | #endif | ||
| 1448 | |||
| 1449 | #if 0 | ||
| 1450 | # if 0 | ||
| 1451 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1452 | # undef pthread_mutexattr_gettype | ||
| 1453 | # define pthread_mutexattr_gettype rpl_pthread_mutexattr_gettype | ||
| 1454 | # endif | ||
| 1455 | _GL_FUNCDECL_RPL (pthread_mutexattr_gettype, int, | ||
| 1456 | (const pthread_mutexattr_t *restrict attr, | ||
| 1457 | int *restrict typep), | ||
| 1458 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1459 | _GL_CXXALIAS_RPL (pthread_mutexattr_gettype, int, | ||
| 1460 | (const pthread_mutexattr_t *restrict attr, | ||
| 1461 | int *restrict typep)); | ||
| 1462 | # else | ||
| 1463 | # if !1 | ||
| 1464 | _GL_FUNCDECL_SYS (pthread_mutexattr_gettype, int, | ||
| 1465 | (const pthread_mutexattr_t *restrict attr, | ||
| 1466 | int *restrict typep), | ||
| 1467 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1468 | # endif | ||
| 1469 | /* Need to cast, because on FreeBSD the first parameter is | ||
| 1470 | pthread_mutexattr_t *attr. */ | ||
| 1471 | _GL_CXXALIAS_SYS_CAST (pthread_mutexattr_gettype, int, | ||
| 1472 | (const pthread_mutexattr_t *restrict attr, | ||
| 1473 | int *restrict typep)); | ||
| 1474 | # endif | ||
| 1475 | # if __GLIBC__ >= 2 | ||
| 1476 | _GL_CXXALIASWARN (pthread_mutexattr_gettype); | ||
| 1477 | # endif | ||
| 1478 | #elif defined GNULIB_POSIXCHECK | ||
| 1479 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_GETTYPE | ||
| 1480 | _GL_WARN_ON_USE (pthread_mutexattr_gettype, "pthread_mutexattr_gettype is not portable - " | ||
| 1481 | "use gnulib module pthread-mutex for portability"); | ||
| 1482 | # endif | ||
| 1483 | #endif | ||
| 1484 | |||
| 1485 | #if 0 | ||
| 1486 | # if 0 | ||
| 1487 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1488 | # undef pthread_mutexattr_settype | ||
| 1489 | # define pthread_mutexattr_settype rpl_pthread_mutexattr_settype | ||
| 1490 | # endif | ||
| 1491 | _GL_FUNCDECL_RPL (pthread_mutexattr_settype, int, | ||
| 1492 | (pthread_mutexattr_t *attr, int type), _GL_ARG_NONNULL ((1))); | ||
| 1493 | _GL_CXXALIAS_RPL (pthread_mutexattr_settype, int, | ||
| 1494 | (pthread_mutexattr_t *attr, int type)); | ||
| 1495 | # else | ||
| 1496 | # if !1 | ||
| 1497 | _GL_FUNCDECL_SYS (pthread_mutexattr_settype, int, | ||
| 1498 | (pthread_mutexattr_t *attr, int type), _GL_ARG_NONNULL ((1))); | ||
| 1499 | # endif | ||
| 1500 | _GL_CXXALIAS_SYS (pthread_mutexattr_settype, int, | ||
| 1501 | (pthread_mutexattr_t *attr, int type)); | ||
| 1502 | # endif | ||
| 1503 | # if __GLIBC__ >= 2 | ||
| 1504 | _GL_CXXALIASWARN (pthread_mutexattr_settype); | ||
| 1505 | # endif | ||
| 1506 | #elif defined GNULIB_POSIXCHECK | ||
| 1507 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_SETTYPE | ||
| 1508 | _GL_WARN_ON_USE (pthread_mutexattr_settype, "pthread_mutexattr_settype is not portable - " | ||
| 1509 | "use gnulib module pthread-mutex for portability"); | ||
| 1510 | # endif | ||
| 1511 | #endif | ||
| 1512 | |||
| 1513 | #if 0 | ||
| 1514 | # if 0 | ||
| 1515 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1516 | # undef pthread_mutexattr_getrobust | ||
| 1517 | # define pthread_mutexattr_getrobust rpl_pthread_mutexattr_getrobust | ||
| 1518 | # endif | ||
| 1519 | _GL_FUNCDECL_RPL (pthread_mutexattr_getrobust, int, | ||
| 1520 | (const pthread_mutexattr_t *restrict attr, | ||
| 1521 | int *restrict robustp), | ||
| 1522 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1523 | _GL_CXXALIAS_RPL (pthread_mutexattr_getrobust, int, | ||
| 1524 | (const pthread_mutexattr_t *restrict attr, | ||
| 1525 | int *restrict robustp)); | ||
| 1526 | # else | ||
| 1527 | # if !1 | ||
| 1528 | _GL_FUNCDECL_SYS (pthread_mutexattr_getrobust, int, | ||
| 1529 | (const pthread_mutexattr_t *restrict attr, | ||
| 1530 | int *restrict robustp), | ||
| 1531 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1532 | # endif | ||
| 1533 | /* Need to cast, because on FreeBSD the first parameter is | ||
| 1534 | pthread_mutexattr_t *attr. */ | ||
| 1535 | _GL_CXXALIAS_SYS_CAST (pthread_mutexattr_getrobust, int, | ||
| 1536 | (const pthread_mutexattr_t *restrict attr, | ||
| 1537 | int *restrict robustp)); | ||
| 1538 | # endif | ||
| 1539 | # if __GLIBC__ >= 2 | ||
| 1540 | _GL_CXXALIASWARN (pthread_mutexattr_getrobust); | ||
| 1541 | # endif | ||
| 1542 | #elif defined GNULIB_POSIXCHECK | ||
| 1543 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_GETROBUST | ||
| 1544 | _GL_WARN_ON_USE (pthread_mutexattr_getrobust, "pthread_mutexattr_getrobust is not portable - " | ||
| 1545 | "use gnulib module pthread-mutex for portability"); | ||
| 1546 | # endif | ||
| 1547 | #endif | ||
| 1548 | |||
| 1549 | #if 0 | ||
| 1550 | # if 0 | ||
| 1551 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1552 | # undef pthread_mutexattr_setrobust | ||
| 1553 | # define pthread_mutexattr_setrobust rpl_pthread_mutexattr_setrobust | ||
| 1554 | # endif | ||
| 1555 | _GL_FUNCDECL_RPL (pthread_mutexattr_setrobust, int, | ||
| 1556 | (pthread_mutexattr_t *attr, int robust), | ||
| 1557 | _GL_ARG_NONNULL ((1))); | ||
| 1558 | _GL_CXXALIAS_RPL (pthread_mutexattr_setrobust, int, | ||
| 1559 | (pthread_mutexattr_t *attr, int robust)); | ||
| 1560 | # else | ||
| 1561 | # if !1 | ||
| 1562 | _GL_FUNCDECL_SYS (pthread_mutexattr_setrobust, int, | ||
| 1563 | (pthread_mutexattr_t *attr, int robust), | ||
| 1564 | _GL_ARG_NONNULL ((1))); | ||
| 1565 | # endif | ||
| 1566 | _GL_CXXALIAS_SYS (pthread_mutexattr_setrobust, int, | ||
| 1567 | (pthread_mutexattr_t *attr, int robust)); | ||
| 1568 | # endif | ||
| 1569 | # if __GLIBC__ >= 2 | ||
| 1570 | _GL_CXXALIASWARN (pthread_mutexattr_setrobust); | ||
| 1571 | # endif | ||
| 1572 | #elif defined GNULIB_POSIXCHECK | ||
| 1573 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_SETROBUST | ||
| 1574 | _GL_WARN_ON_USE (pthread_mutexattr_setrobust, "pthread_mutexattr_setrobust is not portable - " | ||
| 1575 | "use gnulib module pthread-mutex for portability"); | ||
| 1576 | # endif | ||
| 1577 | #endif | ||
| 1578 | |||
| 1579 | #if 0 | ||
| 1580 | # if 0 | ||
| 1581 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1582 | # undef pthread_mutexattr_destroy | ||
| 1583 | # define pthread_mutexattr_destroy rpl_pthread_mutexattr_destroy | ||
| 1584 | # endif | ||
| 1585 | _GL_FUNCDECL_RPL (pthread_mutexattr_destroy, int, (pthread_mutexattr_t *attr), | ||
| 1586 | _GL_ARG_NONNULL ((1))); | ||
| 1587 | _GL_CXXALIAS_RPL (pthread_mutexattr_destroy, int, (pthread_mutexattr_t *attr)); | ||
| 1588 | # else | ||
| 1589 | # if !1 | ||
| 1590 | _GL_FUNCDECL_SYS (pthread_mutexattr_destroy, int, (pthread_mutexattr_t *attr), | ||
| 1591 | _GL_ARG_NONNULL ((1))); | ||
| 1592 | # endif | ||
| 1593 | _GL_CXXALIAS_SYS (pthread_mutexattr_destroy, int, (pthread_mutexattr_t *attr)); | ||
| 1594 | # endif | ||
| 1595 | # if __GLIBC__ >= 2 | ||
| 1596 | _GL_CXXALIASWARN (pthread_mutexattr_destroy); | ||
| 1597 | # endif | ||
| 1598 | #elif defined GNULIB_POSIXCHECK | ||
| 1599 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_DESTROY | ||
| 1600 | _GL_WARN_ON_USE (pthread_mutexattr_destroy, "pthread_mutexattr_destroy is not portable - " | ||
| 1601 | "use gnulib module pthread-mutex for portability"); | ||
| 1602 | # endif | ||
| 1603 | #endif | ||
| 1604 | |||
| 1605 | #if 0 | ||
| 1606 | # if 0 | ||
| 1607 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1608 | # undef pthread_mutex_lock | ||
| 1609 | # define pthread_mutex_lock rpl_pthread_mutex_lock | ||
| 1610 | # endif | ||
| 1611 | _GL_FUNCDECL_RPL (pthread_mutex_lock, int, (pthread_mutex_t *mutex), | ||
| 1612 | _GL_ARG_NONNULL ((1))); | ||
| 1613 | _GL_CXXALIAS_RPL (pthread_mutex_lock, int, (pthread_mutex_t *mutex)); | ||
| 1614 | # else | ||
| 1615 | # if !1 | ||
| 1616 | _GL_FUNCDECL_SYS (pthread_mutex_lock, int, (pthread_mutex_t *mutex), | ||
| 1617 | _GL_ARG_NONNULL ((1))); | ||
| 1618 | # endif | ||
| 1619 | _GL_CXXALIAS_SYS (pthread_mutex_lock, int, (pthread_mutex_t *mutex)); | ||
| 1620 | # endif | ||
| 1621 | # if __GLIBC__ >= 2 | ||
| 1622 | _GL_CXXALIASWARN (pthread_mutex_lock); | ||
| 1623 | # endif | ||
| 1624 | #elif defined GNULIB_POSIXCHECK | ||
| 1625 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_LOCK | ||
| 1626 | _GL_WARN_ON_USE (pthread_mutex_lock, "pthread_mutex_lock is not portable - " | ||
| 1627 | "use gnulib module pthread-mutex for portability"); | ||
| 1628 | # endif | ||
| 1629 | #endif | ||
| 1630 | |||
| 1631 | #if 0 | ||
| 1632 | # if 0 | ||
| 1633 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1634 | # undef pthread_mutex_trylock | ||
| 1635 | # define pthread_mutex_trylock rpl_pthread_mutex_trylock | ||
| 1636 | # endif | ||
| 1637 | _GL_FUNCDECL_RPL (pthread_mutex_trylock, int, (pthread_mutex_t *mutex), | ||
| 1638 | _GL_ARG_NONNULL ((1))); | ||
| 1639 | _GL_CXXALIAS_RPL (pthread_mutex_trylock, int, (pthread_mutex_t *mutex)); | ||
| 1640 | # else | ||
| 1641 | # if !1 | ||
| 1642 | _GL_FUNCDECL_SYS (pthread_mutex_trylock, int, (pthread_mutex_t *mutex), | ||
| 1643 | _GL_ARG_NONNULL ((1))); | ||
| 1644 | # endif | ||
| 1645 | _GL_CXXALIAS_SYS (pthread_mutex_trylock, int, (pthread_mutex_t *mutex)); | ||
| 1646 | # endif | ||
| 1647 | # if __GLIBC__ >= 2 | ||
| 1648 | _GL_CXXALIASWARN (pthread_mutex_trylock); | ||
| 1649 | # endif | ||
| 1650 | #elif defined GNULIB_POSIXCHECK | ||
| 1651 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_TRYLOCK | ||
| 1652 | _GL_WARN_ON_USE (pthread_mutex_trylock, "pthread_mutex_trylock is not portable - " | ||
| 1653 | "use gnulib module pthread-mutex for portability"); | ||
| 1654 | # endif | ||
| 1655 | #endif | ||
| 1656 | |||
| 1657 | #if 0 | ||
| 1658 | # if 0 | ||
| 1659 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1660 | # undef pthread_mutex_timedlock | ||
| 1661 | # define pthread_mutex_timedlock rpl_pthread_mutex_timedlock | ||
| 1662 | # endif | ||
| 1663 | _GL_FUNCDECL_RPL (pthread_mutex_timedlock, int, | ||
| 1664 | (pthread_mutex_t *restrict mutex, | ||
| 1665 | const struct timespec *restrict abstime), | ||
| 1666 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1667 | _GL_CXXALIAS_RPL (pthread_mutex_timedlock, int, | ||
| 1668 | (pthread_mutex_t *restrict mutex, | ||
| 1669 | const struct timespec *restrict abstime)); | ||
| 1670 | # else | ||
| 1671 | # if !1 | ||
| 1672 | _GL_FUNCDECL_SYS (pthread_mutex_timedlock, int, | ||
| 1673 | (pthread_mutex_t *restrict mutex, | ||
| 1674 | const struct timespec *restrict abstime), | ||
| 1675 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1676 | # endif | ||
| 1677 | _GL_CXXALIAS_SYS (pthread_mutex_timedlock, int, | ||
| 1678 | (pthread_mutex_t *restrict mutex, | ||
| 1679 | const struct timespec *restrict abstime)); | ||
| 1680 | # endif | ||
| 1681 | # if __GLIBC__ >= 2 | ||
| 1682 | _GL_CXXALIASWARN (pthread_mutex_timedlock); | ||
| 1683 | # endif | ||
| 1684 | #elif defined GNULIB_POSIXCHECK | ||
| 1685 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_TIMEDLOCK | ||
| 1686 | _GL_WARN_ON_USE (pthread_mutex_timedlock, "pthread_mutex_timedlock is not portable - " | ||
| 1687 | "use gnulib module pthread_mutex_timedlock for portability"); | ||
| 1688 | # endif | ||
| 1689 | #endif | ||
| 1690 | |||
| 1691 | #if 0 | ||
| 1692 | # if 0 | ||
| 1693 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1694 | # undef pthread_mutex_unlock | ||
| 1695 | # define pthread_mutex_unlock rpl_pthread_mutex_unlock | ||
| 1696 | # endif | ||
| 1697 | _GL_FUNCDECL_RPL (pthread_mutex_unlock, int, (pthread_mutex_t *mutex), | ||
| 1698 | _GL_ARG_NONNULL ((1))); | ||
| 1699 | _GL_CXXALIAS_RPL (pthread_mutex_unlock, int, (pthread_mutex_t *mutex)); | ||
| 1700 | # else | ||
| 1701 | # if !1 | ||
| 1702 | _GL_FUNCDECL_SYS (pthread_mutex_unlock, int, (pthread_mutex_t *mutex), | ||
| 1703 | _GL_ARG_NONNULL ((1))); | ||
| 1704 | # endif | ||
| 1705 | _GL_CXXALIAS_SYS (pthread_mutex_unlock, int, (pthread_mutex_t *mutex)); | ||
| 1706 | # endif | ||
| 1707 | # if __GLIBC__ >= 2 | ||
| 1708 | _GL_CXXALIASWARN (pthread_mutex_unlock); | ||
| 1709 | # endif | ||
| 1710 | #elif defined GNULIB_POSIXCHECK | ||
| 1711 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_UNLOCK | ||
| 1712 | _GL_WARN_ON_USE (pthread_mutex_unlock, "pthread_mutex_unlock is not portable - " | ||
| 1713 | "use gnulib module pthread-mutex for portability"); | ||
| 1714 | # endif | ||
| 1715 | #endif | ||
| 1716 | |||
| 1717 | #if 0 | ||
| 1718 | # if 0 | ||
| 1719 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1720 | # undef pthread_mutex_destroy | ||
| 1721 | # define pthread_mutex_destroy rpl_pthread_mutex_destroy | ||
| 1722 | # endif | ||
| 1723 | _GL_FUNCDECL_RPL (pthread_mutex_destroy, int, (pthread_mutex_t *mutex), | ||
| 1724 | _GL_ARG_NONNULL ((1))); | ||
| 1725 | _GL_CXXALIAS_RPL (pthread_mutex_destroy, int, (pthread_mutex_t *mutex)); | ||
| 1726 | # else | ||
| 1727 | # if !1 | ||
| 1728 | _GL_FUNCDECL_SYS (pthread_mutex_destroy, int, (pthread_mutex_t *mutex), | ||
| 1729 | _GL_ARG_NONNULL ((1))); | ||
| 1730 | # endif | ||
| 1731 | _GL_CXXALIAS_SYS (pthread_mutex_destroy, int, (pthread_mutex_t *mutex)); | ||
| 1732 | # endif | ||
| 1733 | # if __GLIBC__ >= 2 | ||
| 1734 | _GL_CXXALIASWARN (pthread_mutex_destroy); | ||
| 1735 | # endif | ||
| 1736 | #elif defined GNULIB_POSIXCHECK | ||
| 1737 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_DESTROY | ||
| 1738 | _GL_WARN_ON_USE (pthread_mutex_destroy, "pthread_mutex_destroy is not portable - " | ||
| 1739 | "use gnulib module pthread-mutex for portability"); | ||
| 1740 | # endif | ||
| 1741 | #endif | ||
| 1742 | |||
| 1743 | /* =========== Read-write lock functions =========== */ | ||
| 1744 | |||
| 1745 | #if 0 | ||
| 1746 | # if 0 | ||
| 1747 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1748 | # undef pthread_rwlock_init | ||
| 1749 | # define pthread_rwlock_init rpl_pthread_rwlock_init | ||
| 1750 | # endif | ||
| 1751 | _GL_FUNCDECL_RPL (pthread_rwlock_init, int, | ||
| 1752 | (pthread_rwlock_t *restrict lock, | ||
| 1753 | const pthread_rwlockattr_t *restrict attr), | ||
| 1754 | _GL_ARG_NONNULL ((1))); | ||
| 1755 | _GL_CXXALIAS_RPL (pthread_rwlock_init, int, | ||
| 1756 | (pthread_rwlock_t *restrict lock, | ||
| 1757 | const pthread_rwlockattr_t *restrict attr)); | ||
| 1758 | # else | ||
| 1759 | # if !1 | ||
| 1760 | _GL_FUNCDECL_SYS (pthread_rwlock_init, int, | ||
| 1761 | (pthread_rwlock_t *restrict lock, | ||
| 1762 | const pthread_rwlockattr_t *restrict attr), | ||
| 1763 | _GL_ARG_NONNULL ((1))); | ||
| 1764 | # endif | ||
| 1765 | _GL_CXXALIAS_SYS (pthread_rwlock_init, int, | ||
| 1766 | (pthread_rwlock_t *restrict lock, | ||
| 1767 | const pthread_rwlockattr_t *restrict attr)); | ||
| 1768 | # endif | ||
| 1769 | # if __GLIBC__ >= 2 | ||
| 1770 | _GL_CXXALIASWARN (pthread_rwlock_init); | ||
| 1771 | # endif | ||
| 1772 | #elif defined GNULIB_POSIXCHECK | ||
| 1773 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_INIT | ||
| 1774 | _GL_WARN_ON_USE (pthread_rwlock_init, "pthread_rwlock_init is not portable - " | ||
| 1775 | "use gnulib module pthread-rwlock for portability"); | ||
| 1776 | # endif | ||
| 1777 | #endif | ||
| 1778 | |||
| 1779 | #if 0 | ||
| 1780 | # if 0 | ||
| 1781 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1782 | # undef pthread_rwlockattr_init | ||
| 1783 | # define pthread_rwlockattr_init rpl_pthread_rwlockattr_init | ||
| 1784 | # endif | ||
| 1785 | _GL_FUNCDECL_RPL (pthread_rwlockattr_init, int, (pthread_rwlockattr_t *attr), | ||
| 1786 | _GL_ARG_NONNULL ((1))); | ||
| 1787 | _GL_CXXALIAS_RPL (pthread_rwlockattr_init, int, (pthread_rwlockattr_t *attr)); | ||
| 1788 | # else | ||
| 1789 | # if !1 | ||
| 1790 | _GL_FUNCDECL_SYS (pthread_rwlockattr_init, int, (pthread_rwlockattr_t *attr), | ||
| 1791 | _GL_ARG_NONNULL ((1))); | ||
| 1792 | # endif | ||
| 1793 | _GL_CXXALIAS_SYS (pthread_rwlockattr_init, int, (pthread_rwlockattr_t *attr)); | ||
| 1794 | # endif | ||
| 1795 | # if __GLIBC__ >= 2 | ||
| 1796 | _GL_CXXALIASWARN (pthread_rwlockattr_init); | ||
| 1797 | # endif | ||
| 1798 | #elif defined GNULIB_POSIXCHECK | ||
| 1799 | # if HAVE_RAW_DECL_PTHREAD_RWLOCKATTR_INIT | ||
| 1800 | _GL_WARN_ON_USE (pthread_rwlockattr_init, "pthread_rwlockattr_init is not portable - " | ||
| 1801 | "use gnulib module pthread-rwlock for portability"); | ||
| 1802 | # endif | ||
| 1803 | #endif | ||
| 1804 | |||
| 1805 | #if 0 | ||
| 1806 | # if 0 | ||
| 1807 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1808 | # undef pthread_rwlockattr_destroy | ||
| 1809 | # define pthread_rwlockattr_destroy rpl_pthread_rwlockattr_destroy | ||
| 1810 | # endif | ||
| 1811 | _GL_FUNCDECL_RPL (pthread_rwlockattr_destroy, int, | ||
| 1812 | (pthread_rwlockattr_t *attr), _GL_ARG_NONNULL ((1))); | ||
| 1813 | _GL_CXXALIAS_RPL (pthread_rwlockattr_destroy, int, | ||
| 1814 | (pthread_rwlockattr_t *attr)); | ||
| 1815 | # else | ||
| 1816 | # if !1 | ||
| 1817 | _GL_FUNCDECL_SYS (pthread_rwlockattr_destroy, int, | ||
| 1818 | (pthread_rwlockattr_t *attr), _GL_ARG_NONNULL ((1))); | ||
| 1819 | # endif | ||
| 1820 | _GL_CXXALIAS_SYS (pthread_rwlockattr_destroy, int, | ||
| 1821 | (pthread_rwlockattr_t *attr)); | ||
| 1822 | # endif | ||
| 1823 | # if __GLIBC__ >= 2 | ||
| 1824 | _GL_CXXALIASWARN (pthread_rwlockattr_destroy); | ||
| 1825 | # endif | ||
| 1826 | #elif defined GNULIB_POSIXCHECK | ||
| 1827 | # if HAVE_RAW_DECL_PTHREAD_RWLOCKATTR_DESTROY | ||
| 1828 | _GL_WARN_ON_USE (pthread_rwlockattr_destroy, "pthread_rwlockattr_destroy is not portable - " | ||
| 1829 | "use gnulib module pthread-rwlock for portability"); | ||
| 1830 | # endif | ||
| 1831 | #endif | ||
| 1832 | |||
| 1833 | #if 0 | ||
| 1834 | # if 0 | ||
| 1835 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1836 | # undef pthread_rwlock_rdlock | ||
| 1837 | # define pthread_rwlock_rdlock rpl_pthread_rwlock_rdlock | ||
| 1838 | # endif | ||
| 1839 | _GL_FUNCDECL_RPL (pthread_rwlock_rdlock, int, (pthread_rwlock_t *lock), | ||
| 1840 | _GL_ARG_NONNULL ((1))); | ||
| 1841 | _GL_CXXALIAS_RPL (pthread_rwlock_rdlock, int, (pthread_rwlock_t *lock)); | ||
| 1842 | # else | ||
| 1843 | # if !1 | ||
| 1844 | _GL_FUNCDECL_SYS (pthread_rwlock_rdlock, int, (pthread_rwlock_t *lock), | ||
| 1845 | _GL_ARG_NONNULL ((1))); | ||
| 1846 | # endif | ||
| 1847 | _GL_CXXALIAS_SYS (pthread_rwlock_rdlock, int, (pthread_rwlock_t *lock)); | ||
| 1848 | # endif | ||
| 1849 | # if __GLIBC__ >= 2 | ||
| 1850 | _GL_CXXALIASWARN (pthread_rwlock_rdlock); | ||
| 1851 | # endif | ||
| 1852 | #elif defined GNULIB_POSIXCHECK | ||
| 1853 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_RDLOCK | ||
| 1854 | _GL_WARN_ON_USE (pthread_rwlock_rdlock, "pthread_rwlock_rdlock is not portable - " | ||
| 1855 | "use gnulib module pthread-rwlock for portability"); | ||
| 1856 | # endif | ||
| 1857 | #endif | ||
| 1858 | |||
| 1859 | #if 0 | ||
| 1860 | # if 0 | ||
| 1861 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1862 | # undef pthread_rwlock_wrlock | ||
| 1863 | # define pthread_rwlock_wrlock rpl_pthread_rwlock_wrlock | ||
| 1864 | # endif | ||
| 1865 | _GL_FUNCDECL_RPL (pthread_rwlock_wrlock, int, (pthread_rwlock_t *lock), | ||
| 1866 | _GL_ARG_NONNULL ((1))); | ||
| 1867 | _GL_CXXALIAS_RPL (pthread_rwlock_wrlock, int, (pthread_rwlock_t *lock)); | ||
| 1868 | # else | ||
| 1869 | # if !1 | ||
| 1870 | _GL_FUNCDECL_SYS (pthread_rwlock_wrlock, int, (pthread_rwlock_t *lock), | ||
| 1871 | _GL_ARG_NONNULL ((1))); | ||
| 1872 | # endif | ||
| 1873 | _GL_CXXALIAS_SYS (pthread_rwlock_wrlock, int, (pthread_rwlock_t *lock)); | ||
| 1874 | # endif | ||
| 1875 | # if __GLIBC__ >= 2 | ||
| 1876 | _GL_CXXALIASWARN (pthread_rwlock_wrlock); | ||
| 1877 | # endif | ||
| 1878 | #elif defined GNULIB_POSIXCHECK | ||
| 1879 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_WRLOCK | ||
| 1880 | _GL_WARN_ON_USE (pthread_rwlock_wrlock, "pthread_rwlock_wrlock is not portable - " | ||
| 1881 | "use gnulib module pthread-rwlock for portability"); | ||
| 1882 | # endif | ||
| 1883 | #endif | ||
| 1884 | |||
| 1885 | #if 0 | ||
| 1886 | # if 0 | ||
| 1887 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1888 | # undef pthread_rwlock_tryrdlock | ||
| 1889 | # define pthread_rwlock_tryrdlock rpl_pthread_rwlock_tryrdlock | ||
| 1890 | # endif | ||
| 1891 | _GL_FUNCDECL_RPL (pthread_rwlock_tryrdlock, int, (pthread_rwlock_t *lock), | ||
| 1892 | _GL_ARG_NONNULL ((1))); | ||
| 1893 | _GL_CXXALIAS_RPL (pthread_rwlock_tryrdlock, int, (pthread_rwlock_t *lock)); | ||
| 1894 | # else | ||
| 1895 | # if !1 | ||
| 1896 | _GL_FUNCDECL_SYS (pthread_rwlock_tryrdlock, int, (pthread_rwlock_t *lock), | ||
| 1897 | _GL_ARG_NONNULL ((1))); | ||
| 1898 | # endif | ||
| 1899 | _GL_CXXALIAS_SYS (pthread_rwlock_tryrdlock, int, (pthread_rwlock_t *lock)); | ||
| 1900 | # endif | ||
| 1901 | # if __GLIBC__ >= 2 | ||
| 1902 | _GL_CXXALIASWARN (pthread_rwlock_tryrdlock); | ||
| 1903 | # endif | ||
| 1904 | #elif defined GNULIB_POSIXCHECK | ||
| 1905 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_TRYRDLOCK | ||
| 1906 | _GL_WARN_ON_USE (pthread_rwlock_tryrdlock, "pthread_rwlock_tryrdlock is not portable - " | ||
| 1907 | "use gnulib module pthread-rwlock for portability"); | ||
| 1908 | # endif | ||
| 1909 | #endif | ||
| 1910 | |||
| 1911 | #if 0 | ||
| 1912 | # if 0 | ||
| 1913 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1914 | # undef pthread_rwlock_trywrlock | ||
| 1915 | # define pthread_rwlock_trywrlock rpl_pthread_rwlock_trywrlock | ||
| 1916 | # endif | ||
| 1917 | _GL_FUNCDECL_RPL (pthread_rwlock_trywrlock, int, (pthread_rwlock_t *lock), | ||
| 1918 | _GL_ARG_NONNULL ((1))); | ||
| 1919 | _GL_CXXALIAS_RPL (pthread_rwlock_trywrlock, int, (pthread_rwlock_t *lock)); | ||
| 1920 | # else | ||
| 1921 | # if !1 | ||
| 1922 | _GL_FUNCDECL_SYS (pthread_rwlock_trywrlock, int, (pthread_rwlock_t *lock), | ||
| 1923 | _GL_ARG_NONNULL ((1))); | ||
| 1924 | # endif | ||
| 1925 | _GL_CXXALIAS_SYS (pthread_rwlock_trywrlock, int, (pthread_rwlock_t *lock)); | ||
| 1926 | # endif | ||
| 1927 | # if __GLIBC__ >= 2 | ||
| 1928 | _GL_CXXALIASWARN (pthread_rwlock_trywrlock); | ||
| 1929 | # endif | ||
| 1930 | #elif defined GNULIB_POSIXCHECK | ||
| 1931 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_TRYWRLOCK | ||
| 1932 | _GL_WARN_ON_USE (pthread_rwlock_trywrlock, "pthread_rwlock_trywrlock is not portable - " | ||
| 1933 | "use gnulib module pthread-rwlock for portability"); | ||
| 1934 | # endif | ||
| 1935 | #endif | ||
| 1936 | |||
| 1937 | #if 0 | ||
| 1938 | # if 0 | ||
| 1939 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1940 | # undef pthread_rwlock_timedrdlock | ||
| 1941 | # define pthread_rwlock_timedrdlock rpl_pthread_rwlock_timedrdlock | ||
| 1942 | # endif | ||
| 1943 | _GL_FUNCDECL_RPL (pthread_rwlock_timedrdlock, int, | ||
| 1944 | (pthread_rwlock_t *restrict lock, | ||
| 1945 | const struct timespec *restrict abstime), | ||
| 1946 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1947 | _GL_CXXALIAS_RPL (pthread_rwlock_timedrdlock, int, | ||
| 1948 | (pthread_rwlock_t *restrict lock, | ||
| 1949 | const struct timespec *restrict abstime)); | ||
| 1950 | # else | ||
| 1951 | # if !1 | ||
| 1952 | _GL_FUNCDECL_SYS (pthread_rwlock_timedrdlock, int, | ||
| 1953 | (pthread_rwlock_t *restrict lock, | ||
| 1954 | const struct timespec *restrict abstime), | ||
| 1955 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1956 | # endif | ||
| 1957 | _GL_CXXALIAS_SYS (pthread_rwlock_timedrdlock, int, | ||
| 1958 | (pthread_rwlock_t *restrict lock, | ||
| 1959 | const struct timespec *restrict abstime)); | ||
| 1960 | # endif | ||
| 1961 | # if __GLIBC__ >= 2 | ||
| 1962 | _GL_CXXALIASWARN (pthread_rwlock_timedrdlock); | ||
| 1963 | # endif | ||
| 1964 | #elif defined GNULIB_POSIXCHECK | ||
| 1965 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_TIMEDRDLOCK | ||
| 1966 | _GL_WARN_ON_USE (pthread_rwlock_timedrdlock, "pthread_rwlock_timedrdlock is not portable - " | ||
| 1967 | "use gnulib module pthread-rwlock for portability"); | ||
| 1968 | # endif | ||
| 1969 | #endif | ||
| 1970 | |||
| 1971 | #if 0 | ||
| 1972 | # if 0 | ||
| 1973 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1974 | # undef pthread_rwlock_timedwrlock | ||
| 1975 | # define pthread_rwlock_timedwrlock rpl_pthread_rwlock_timedwrlock | ||
| 1976 | # endif | ||
| 1977 | _GL_FUNCDECL_RPL (pthread_rwlock_timedwrlock, int, | ||
| 1978 | (pthread_rwlock_t *restrict lock, | ||
| 1979 | const struct timespec *restrict abstime), | ||
| 1980 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1981 | _GL_CXXALIAS_RPL (pthread_rwlock_timedwrlock, int, | ||
| 1982 | (pthread_rwlock_t *restrict lock, | ||
| 1983 | const struct timespec *restrict abstime)); | ||
| 1984 | # else | ||
| 1985 | # if !1 | ||
| 1986 | _GL_FUNCDECL_SYS (pthread_rwlock_timedwrlock, int, | ||
| 1987 | (pthread_rwlock_t *restrict lock, | ||
| 1988 | const struct timespec *restrict abstime), | ||
| 1989 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1990 | # endif | ||
| 1991 | _GL_CXXALIAS_SYS (pthread_rwlock_timedwrlock, int, | ||
| 1992 | (pthread_rwlock_t *restrict lock, | ||
| 1993 | const struct timespec *restrict abstime)); | ||
| 1994 | # endif | ||
| 1995 | # if __GLIBC__ >= 2 | ||
| 1996 | _GL_CXXALIASWARN (pthread_rwlock_timedwrlock); | ||
| 1997 | # endif | ||
| 1998 | #elif defined GNULIB_POSIXCHECK | ||
| 1999 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_TIMEDWRLOCK | ||
| 2000 | _GL_WARN_ON_USE (pthread_rwlock_timedwrlock, "pthread_rwlock_timedwrlock is not portable - " | ||
| 2001 | "use gnulib module pthread-rwlock for portability"); | ||
| 2002 | # endif | ||
| 2003 | #endif | ||
| 2004 | |||
| 2005 | #if 0 | ||
| 2006 | # if 0 | ||
| 2007 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2008 | # undef pthread_rwlock_unlock | ||
| 2009 | # define pthread_rwlock_unlock rpl_pthread_rwlock_unlock | ||
| 2010 | # endif | ||
| 2011 | _GL_FUNCDECL_RPL (pthread_rwlock_unlock, int, (pthread_rwlock_t *lock), | ||
| 2012 | _GL_ARG_NONNULL ((1))); | ||
| 2013 | _GL_CXXALIAS_RPL (pthread_rwlock_unlock, int, (pthread_rwlock_t *lock)); | ||
| 2014 | # else | ||
| 2015 | # if !1 | ||
| 2016 | _GL_FUNCDECL_SYS (pthread_rwlock_unlock, int, (pthread_rwlock_t *lock), | ||
| 2017 | _GL_ARG_NONNULL ((1))); | ||
| 2018 | # endif | ||
| 2019 | _GL_CXXALIAS_SYS (pthread_rwlock_unlock, int, (pthread_rwlock_t *lock)); | ||
| 2020 | # endif | ||
| 2021 | # if __GLIBC__ >= 2 | ||
| 2022 | _GL_CXXALIASWARN (pthread_rwlock_unlock); | ||
| 2023 | # endif | ||
| 2024 | #elif defined GNULIB_POSIXCHECK | ||
| 2025 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_UNLOCK | ||
| 2026 | _GL_WARN_ON_USE (pthread_rwlock_unlock, "pthread_rwlock_unlock is not portable - " | ||
| 2027 | "use gnulib module pthread-rwlock for portability"); | ||
| 2028 | # endif | ||
| 2029 | #endif | ||
| 2030 | |||
| 2031 | #if 0 | ||
| 2032 | # if 0 | ||
| 2033 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2034 | # undef pthread_rwlock_destroy | ||
| 2035 | # define pthread_rwlock_destroy rpl_pthread_rwlock_destroy | ||
| 2036 | # endif | ||
| 2037 | _GL_FUNCDECL_RPL (pthread_rwlock_destroy, int, (pthread_rwlock_t *lock), | ||
| 2038 | _GL_ARG_NONNULL ((1))); | ||
| 2039 | _GL_CXXALIAS_RPL (pthread_rwlock_destroy, int, (pthread_rwlock_t *lock)); | ||
| 2040 | # else | ||
| 2041 | # if !1 | ||
| 2042 | _GL_FUNCDECL_SYS (pthread_rwlock_destroy, int, (pthread_rwlock_t *lock), | ||
| 2043 | _GL_ARG_NONNULL ((1))); | ||
| 2044 | # endif | ||
| 2045 | _GL_CXXALIAS_SYS (pthread_rwlock_destroy, int, (pthread_rwlock_t *lock)); | ||
| 2046 | # endif | ||
| 2047 | # if __GLIBC__ >= 2 | ||
| 2048 | _GL_CXXALIASWARN (pthread_rwlock_destroy); | ||
| 2049 | # endif | ||
| 2050 | #elif defined GNULIB_POSIXCHECK | ||
| 2051 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_DESTROY | ||
| 2052 | _GL_WARN_ON_USE (pthread_rwlock_destroy, "pthread_rwlock_destroy is not portable - " | ||
| 2053 | "use gnulib module pthread-rwlock for portability"); | ||
| 2054 | # endif | ||
| 2055 | #endif | ||
| 2056 | |||
| 2057 | /* =========== Condition variable functions =========== */ | ||
| 2058 | |||
| 2059 | #if 0 | ||
| 2060 | # if 0 | ||
| 2061 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2062 | # undef pthread_cond_init | ||
| 2063 | # define pthread_cond_init rpl_pthread_cond_init | ||
| 2064 | # endif | ||
| 2065 | _GL_FUNCDECL_RPL (pthread_cond_init, int, | ||
| 2066 | (pthread_cond_t *restrict cond, | ||
| 2067 | const pthread_condattr_t *restrict attr), | ||
| 2068 | _GL_ARG_NONNULL ((1))); | ||
| 2069 | _GL_CXXALIAS_RPL (pthread_cond_init, int, | ||
| 2070 | (pthread_cond_t *restrict cond, | ||
| 2071 | const pthread_condattr_t *restrict attr)); | ||
| 2072 | # else | ||
| 2073 | # if !1 | ||
| 2074 | _GL_FUNCDECL_SYS (pthread_cond_init, int, | ||
| 2075 | (pthread_cond_t *restrict cond, | ||
| 2076 | const pthread_condattr_t *restrict attr), | ||
| 2077 | _GL_ARG_NONNULL ((1))); | ||
| 2078 | # endif | ||
| 2079 | _GL_CXXALIAS_SYS (pthread_cond_init, int, | ||
| 2080 | (pthread_cond_t *restrict cond, | ||
| 2081 | const pthread_condattr_t *restrict attr)); | ||
| 2082 | # endif | ||
| 2083 | # if __GLIBC__ >= 2 | ||
| 2084 | _GL_CXXALIASWARN (pthread_cond_init); | ||
| 2085 | # endif | ||
| 2086 | #elif defined GNULIB_POSIXCHECK | ||
| 2087 | # if HAVE_RAW_DECL_PTHREAD_COND_INIT | ||
| 2088 | _GL_WARN_ON_USE (pthread_cond_init, "pthread_cond_init is not portable - " | ||
| 2089 | "use gnulib module pthread-cond for portability"); | ||
| 2090 | # endif | ||
| 2091 | #endif | ||
| 2092 | |||
| 2093 | #if 0 | ||
| 2094 | # if 0 | ||
| 2095 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2096 | # undef pthread_condattr_init | ||
| 2097 | # define pthread_condattr_init rpl_pthread_condattr_init | ||
| 2098 | # endif | ||
| 2099 | _GL_FUNCDECL_RPL (pthread_condattr_init, int, (pthread_condattr_t *attr), | ||
| 2100 | _GL_ARG_NONNULL ((1))); | ||
| 2101 | _GL_CXXALIAS_RPL (pthread_condattr_init, int, (pthread_condattr_t *attr)); | ||
| 2102 | # else | ||
| 2103 | # if !1 | ||
| 2104 | _GL_FUNCDECL_SYS (pthread_condattr_init, int, (pthread_condattr_t *attr), | ||
| 2105 | _GL_ARG_NONNULL ((1))); | ||
| 2106 | # endif | ||
| 2107 | _GL_CXXALIAS_SYS (pthread_condattr_init, int, (pthread_condattr_t *attr)); | ||
| 2108 | # endif | ||
| 2109 | # if __GLIBC__ >= 2 | ||
| 2110 | _GL_CXXALIASWARN (pthread_condattr_init); | ||
| 2111 | # endif | ||
| 2112 | #elif defined GNULIB_POSIXCHECK | ||
| 2113 | # if HAVE_RAW_DECL_PTHREAD_CONDATTR_INIT | ||
| 2114 | _GL_WARN_ON_USE (pthread_condattr_init, "pthread_condattr_init is not portable - " | ||
| 2115 | "use gnulib module pthread-cond for portability"); | ||
| 2116 | # endif | ||
| 2117 | #endif | ||
| 2118 | |||
| 2119 | #if 0 | ||
| 2120 | # if 0 | ||
| 2121 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2122 | # undef pthread_condattr_destroy | ||
| 2123 | # define pthread_condattr_destroy rpl_pthread_condattr_destroy | ||
| 2124 | # endif | ||
| 2125 | _GL_FUNCDECL_RPL (pthread_condattr_destroy, int, (pthread_condattr_t *attr), | ||
| 2126 | _GL_ARG_NONNULL ((1))); | ||
| 2127 | _GL_CXXALIAS_RPL (pthread_condattr_destroy, int, (pthread_condattr_t *attr)); | ||
| 2128 | # else | ||
| 2129 | # if !1 | ||
| 2130 | _GL_FUNCDECL_SYS (pthread_condattr_destroy, int, (pthread_condattr_t *attr), | ||
| 2131 | _GL_ARG_NONNULL ((1))); | ||
| 2132 | # endif | ||
| 2133 | _GL_CXXALIAS_SYS (pthread_condattr_destroy, int, (pthread_condattr_t *attr)); | ||
| 2134 | # endif | ||
| 2135 | # if __GLIBC__ >= 2 | ||
| 2136 | _GL_CXXALIASWARN (pthread_condattr_destroy); | ||
| 2137 | # endif | ||
| 2138 | #elif defined GNULIB_POSIXCHECK | ||
| 2139 | # if HAVE_RAW_DECL_PTHREAD_CONDATTR_DESTROY | ||
| 2140 | _GL_WARN_ON_USE (pthread_condattr_destroy, "pthread_condattr_destroy is not portable - " | ||
| 2141 | "use gnulib module pthread-cond for portability"); | ||
| 2142 | # endif | ||
| 2143 | #endif | ||
| 2144 | |||
| 2145 | #if 0 | ||
| 2146 | # if 0 | ||
| 2147 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2148 | # undef pthread_cond_wait | ||
| 2149 | # define pthread_cond_wait rpl_pthread_cond_wait | ||
| 2150 | # endif | ||
| 2151 | _GL_FUNCDECL_RPL (pthread_cond_wait, int, | ||
| 2152 | (pthread_cond_t *restrict cond, | ||
| 2153 | pthread_mutex_t *restrict mutex), | ||
| 2154 | _GL_ARG_NONNULL ((1, 2))); | ||
| 2155 | _GL_CXXALIAS_RPL (pthread_cond_wait, int, | ||
| 2156 | (pthread_cond_t *restrict cond, | ||
| 2157 | pthread_mutex_t *restrict mutex)); | ||
| 2158 | # else | ||
| 2159 | # if !1 | ||
| 2160 | _GL_FUNCDECL_SYS (pthread_cond_wait, int, | ||
| 2161 | (pthread_cond_t *restrict cond, | ||
| 2162 | pthread_mutex_t *restrict mutex), | ||
| 2163 | _GL_ARG_NONNULL ((1, 2))); | ||
| 2164 | # endif | ||
| 2165 | _GL_CXXALIAS_SYS (pthread_cond_wait, int, | ||
| 2166 | (pthread_cond_t *restrict cond, | ||
| 2167 | pthread_mutex_t *restrict mutex)); | ||
| 2168 | # endif | ||
| 2169 | # if __GLIBC__ >= 2 | ||
| 2170 | _GL_CXXALIASWARN (pthread_cond_wait); | ||
| 2171 | # endif | ||
| 2172 | #elif defined GNULIB_POSIXCHECK | ||
| 2173 | # if HAVE_RAW_DECL_PTHREAD_COND_WAIT | ||
| 2174 | _GL_WARN_ON_USE (pthread_cond_wait, "pthread_cond_wait is not portable - " | ||
| 2175 | "use gnulib module pthread-cond for portability"); | ||
| 2176 | # endif | ||
| 2177 | #endif | ||
| 2178 | |||
| 2179 | #if 0 | ||
| 2180 | # if 0 | ||
| 2181 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2182 | # undef pthread_cond_timedwait | ||
| 2183 | # define pthread_cond_timedwait rpl_pthread_cond_timedwait | ||
| 2184 | # endif | ||
| 2185 | _GL_FUNCDECL_RPL (pthread_cond_timedwait, int, | ||
| 2186 | (pthread_cond_t *restrict cond, | ||
| 2187 | pthread_mutex_t *restrict mutex, | ||
| 2188 | const struct timespec *restrict abstime), | ||
| 2189 | _GL_ARG_NONNULL ((1, 2, 3))); | ||
| 2190 | _GL_CXXALIAS_RPL (pthread_cond_timedwait, int, | ||
| 2191 | (pthread_cond_t *restrict cond, | ||
| 2192 | pthread_mutex_t *restrict mutex, | ||
| 2193 | const struct timespec *restrict abstime)); | ||
| 2194 | # else | ||
| 2195 | # if !1 | ||
| 2196 | _GL_FUNCDECL_SYS (pthread_cond_timedwait, int, | ||
| 2197 | (pthread_cond_t *restrict cond, | ||
| 2198 | pthread_mutex_t *restrict mutex, | ||
| 2199 | const struct timespec *restrict abstime), | ||
| 2200 | _GL_ARG_NONNULL ((1, 2, 3))); | ||
| 2201 | # endif | ||
| 2202 | _GL_CXXALIAS_SYS (pthread_cond_timedwait, int, | ||
| 2203 | (pthread_cond_t *restrict cond, | ||
| 2204 | pthread_mutex_t *restrict mutex, | ||
| 2205 | const struct timespec *restrict abstime)); | ||
| 2206 | # endif | ||
| 2207 | # if __GLIBC__ >= 2 | ||
| 2208 | _GL_CXXALIASWARN (pthread_cond_timedwait); | ||
| 2209 | # endif | ||
| 2210 | #elif defined GNULIB_POSIXCHECK | ||
| 2211 | # if HAVE_RAW_DECL_PTHREAD_COND_TIMEDWAIT | ||
| 2212 | _GL_WARN_ON_USE (pthread_cond_timedwait, "pthread_cond_timedwait is not portable - " | ||
| 2213 | "use gnulib module pthread-cond for portability"); | ||
| 2214 | # endif | ||
| 2215 | #endif | ||
| 2216 | |||
| 2217 | #if 0 | ||
| 2218 | # if 0 | ||
| 2219 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2220 | # undef pthread_cond_signal | ||
| 2221 | # define pthread_cond_signal rpl_pthread_cond_signal | ||
| 2222 | # endif | ||
| 2223 | _GL_FUNCDECL_RPL (pthread_cond_signal, int, (pthread_cond_t *cond), | ||
| 2224 | _GL_ARG_NONNULL ((1))); | ||
| 2225 | _GL_CXXALIAS_RPL (pthread_cond_signal, int, (pthread_cond_t *cond)); | ||
| 2226 | # else | ||
| 2227 | # if !1 | ||
| 2228 | _GL_FUNCDECL_SYS (pthread_cond_signal, int, (pthread_cond_t *cond), | ||
| 2229 | _GL_ARG_NONNULL ((1))); | ||
| 2230 | # endif | ||
| 2231 | _GL_CXXALIAS_SYS (pthread_cond_signal, int, (pthread_cond_t *cond)); | ||
| 2232 | # endif | ||
| 2233 | # if __GLIBC__ >= 2 | ||
| 2234 | _GL_CXXALIASWARN (pthread_cond_signal); | ||
| 2235 | # endif | ||
| 2236 | #elif defined GNULIB_POSIXCHECK | ||
| 2237 | # if HAVE_RAW_DECL_PTHREAD_COND_SIGNAL | ||
| 2238 | _GL_WARN_ON_USE (pthread_cond_signal, "pthread_cond_signal is not portable - " | ||
| 2239 | "use gnulib module pthread-cond for portability"); | ||
| 2240 | # endif | ||
| 2241 | #endif | ||
| 2242 | |||
| 2243 | #if 0 | ||
| 2244 | # if 0 | ||
| 2245 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2246 | # undef pthread_cond_broadcast | ||
| 2247 | # define pthread_cond_broadcast rpl_pthread_cond_broadcast | ||
| 2248 | # endif | ||
| 2249 | _GL_FUNCDECL_RPL (pthread_cond_broadcast, int, (pthread_cond_t *cond), | ||
| 2250 | _GL_ARG_NONNULL ((1))); | ||
| 2251 | _GL_CXXALIAS_RPL (pthread_cond_broadcast, int, (pthread_cond_t *cond)); | ||
| 2252 | # else | ||
| 2253 | # if !1 | ||
| 2254 | _GL_FUNCDECL_SYS (pthread_cond_broadcast, int, (pthread_cond_t *cond), | ||
| 2255 | _GL_ARG_NONNULL ((1))); | ||
| 2256 | # endif | ||
| 2257 | _GL_CXXALIAS_SYS (pthread_cond_broadcast, int, (pthread_cond_t *cond)); | ||
| 2258 | # endif | ||
| 2259 | # if __GLIBC__ >= 2 | ||
| 2260 | _GL_CXXALIASWARN (pthread_cond_broadcast); | ||
| 2261 | # endif | ||
| 2262 | #elif defined GNULIB_POSIXCHECK | ||
| 2263 | # if HAVE_RAW_DECL_PTHREAD_COND_BROADCAST | ||
| 2264 | _GL_WARN_ON_USE (pthread_cond_broadcast, "pthread_cond_broadcast is not portable - " | ||
| 2265 | "use gnulib module pthread-cond for portability"); | ||
| 2266 | # endif | ||
| 2267 | #endif | ||
| 2268 | |||
| 2269 | #if 0 | ||
| 2270 | # if 0 | ||
| 2271 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2272 | # undef pthread_cond_destroy | ||
| 2273 | # define pthread_cond_destroy rpl_pthread_cond_destroy | ||
| 2274 | # endif | ||
| 2275 | _GL_FUNCDECL_RPL (pthread_cond_destroy, int, (pthread_cond_t *cond), | ||
| 2276 | _GL_ARG_NONNULL ((1))); | ||
| 2277 | _GL_CXXALIAS_RPL (pthread_cond_destroy, int, (pthread_cond_t *cond)); | ||
| 2278 | # else | ||
| 2279 | # if !1 | ||
| 2280 | _GL_FUNCDECL_SYS (pthread_cond_destroy, int, (pthread_cond_t *cond), | ||
| 2281 | _GL_ARG_NONNULL ((1))); | ||
| 2282 | # endif | ||
| 2283 | _GL_CXXALIAS_SYS (pthread_cond_destroy, int, (pthread_cond_t *cond)); | ||
| 2284 | # endif | ||
| 2285 | # if __GLIBC__ >= 2 | ||
| 2286 | _GL_CXXALIASWARN (pthread_cond_destroy); | ||
| 2287 | # endif | ||
| 2288 | #elif defined GNULIB_POSIXCHECK | ||
| 2289 | # if HAVE_RAW_DECL_PTHREAD_COND_DESTROY | ||
| 2290 | _GL_WARN_ON_USE (pthread_cond_destroy, "pthread_cond_destroy is not portable - " | ||
| 2291 | "use gnulib module pthread-cond for portability"); | ||
| 2292 | # endif | ||
| 2293 | #endif | ||
| 2294 | |||
| 2295 | /* =========== Thread-specific storage functions =========== */ | ||
| 2296 | |||
| 2297 | #if 0 | ||
| 2298 | # if 0 | ||
| 2299 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2300 | # undef pthread_key_create | ||
| 2301 | # define pthread_key_create rpl_pthread_key_create | ||
| 2302 | # endif | ||
| 2303 | _GL_FUNCDECL_RPL (pthread_key_create, int, | ||
| 2304 | (pthread_key_t *keyp, void (*destructor) (void *)), | ||
| 2305 | _GL_ARG_NONNULL ((1))); | ||
| 2306 | _GL_CXXALIAS_RPL (pthread_key_create, int, | ||
| 2307 | (pthread_key_t *keyp, void (*destructor) (void *))); | ||
| 2308 | # else | ||
| 2309 | # if !1 | ||
| 2310 | _GL_FUNCDECL_SYS (pthread_key_create, int, | ||
| 2311 | (pthread_key_t *keyp, void (*destructor) (void *)), | ||
| 2312 | _GL_ARG_NONNULL ((1))); | ||
| 2313 | # endif | ||
| 2314 | _GL_CXXALIAS_SYS_CAST (pthread_key_create, int, | ||
| 2315 | (pthread_key_t *keyp, void (*destructor) (void *))); | ||
| 2316 | # endif | ||
| 2317 | # if __GLIBC__ >= 2 | ||
| 2318 | _GL_CXXALIASWARN (pthread_key_create); | ||
| 2319 | # endif | ||
| 2320 | #elif defined GNULIB_POSIXCHECK | ||
| 2321 | # if HAVE_RAW_DECL_PTHREAD_KEY_CREATE | ||
| 2322 | _GL_WARN_ON_USE (pthread_key_create, "pthread_key_create is not portable - " | ||
| 2323 | "use gnulib module pthread-tss for portability"); | ||
| 2324 | # endif | ||
| 2325 | #endif | ||
| 2326 | |||
| 2327 | #if 0 | ||
| 2328 | # if 0 | ||
| 2329 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2330 | # undef pthread_setspecific | ||
| 2331 | # define pthread_setspecific rpl_pthread_setspecific | ||
| 2332 | # endif | ||
| 2333 | _GL_FUNCDECL_RPL (pthread_setspecific, int, | ||
| 2334 | (pthread_key_t key, const void *value), ); | ||
| 2335 | _GL_CXXALIAS_RPL (pthread_setspecific, int, | ||
| 2336 | (pthread_key_t key, const void *value)); | ||
| 2337 | # else | ||
| 2338 | # if !1 | ||
| 2339 | _GL_FUNCDECL_SYS (pthread_setspecific, int, | ||
| 2340 | (pthread_key_t key, const void *value), ); | ||
| 2341 | # endif | ||
| 2342 | _GL_CXXALIAS_SYS (pthread_setspecific, int, | ||
| 2343 | (pthread_key_t key, const void *value)); | ||
| 2344 | # endif | ||
| 2345 | # if __GLIBC__ >= 2 | ||
| 2346 | _GL_CXXALIASWARN (pthread_setspecific); | ||
| 2347 | # endif | ||
| 2348 | #elif defined GNULIB_POSIXCHECK | ||
| 2349 | # if HAVE_RAW_DECL_PTHREAD_SETSPECIFIC | ||
| 2350 | _GL_WARN_ON_USE (pthread_setspecific, "pthread_setspecific is not portable - " | ||
| 2351 | "use gnulib module pthread-tss for portability"); | ||
| 2352 | # endif | ||
| 2353 | #endif | ||
| 2354 | |||
| 2355 | #if 0 | ||
| 2356 | # if 0 | ||
| 2357 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2358 | # undef pthread_getspecific | ||
| 2359 | # define pthread_getspecific rpl_pthread_getspecific | ||
| 2360 | # endif | ||
| 2361 | _GL_FUNCDECL_RPL (pthread_getspecific, void *, (pthread_key_t key), ); | ||
| 2362 | _GL_CXXALIAS_RPL (pthread_getspecific, void *, (pthread_key_t key)); | ||
| 2363 | # else | ||
| 2364 | # if !1 | ||
| 2365 | _GL_FUNCDECL_SYS (pthread_getspecific, void *, (pthread_key_t key), ); | ||
| 2366 | # endif | ||
| 2367 | _GL_CXXALIAS_SYS (pthread_getspecific, void *, (pthread_key_t key)); | ||
| 2368 | # endif | ||
| 2369 | # if __GLIBC__ >= 2 | ||
| 2370 | _GL_CXXALIASWARN (pthread_getspecific); | ||
| 2371 | # endif | ||
| 2372 | #elif defined GNULIB_POSIXCHECK | ||
| 2373 | # if HAVE_RAW_DECL_PTHREAD_GETSPECIFIC | ||
| 2374 | _GL_WARN_ON_USE (pthread_getspecific, "pthread_getspecific is not portable - " | ||
| 2375 | "use gnulib module pthread-tss for portability"); | ||
| 2376 | # endif | ||
| 2377 | #endif | ||
| 2378 | |||
| 2379 | #if 0 | ||
| 2380 | # if 0 | ||
| 2381 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2382 | # undef pthread_key_delete | ||
| 2383 | # define pthread_key_delete rpl_pthread_key_delete | ||
| 2384 | # endif | ||
| 2385 | _GL_FUNCDECL_RPL (pthread_key_delete, int, (pthread_key_t key), ); | ||
| 2386 | _GL_CXXALIAS_RPL (pthread_key_delete, int, (pthread_key_t key)); | ||
| 2387 | # else | ||
| 2388 | # if !1 | ||
| 2389 | _GL_FUNCDECL_SYS (pthread_key_delete, int, (pthread_key_t key), ); | ||
| 2390 | # endif | ||
| 2391 | _GL_CXXALIAS_SYS (pthread_key_delete, int, (pthread_key_t key)); | ||
| 2392 | # endif | ||
| 2393 | # if __GLIBC__ >= 2 | ||
| 2394 | _GL_CXXALIASWARN (pthread_key_delete); | ||
| 2395 | # endif | ||
| 2396 | #elif defined GNULIB_POSIXCHECK | ||
| 2397 | # if HAVE_RAW_DECL_PTHREAD_KEY_DELETE | ||
| 2398 | _GL_WARN_ON_USE (pthread_key_delete, "pthread_key_delete is not portable - " | ||
| 2399 | "use gnulib module pthread-tss for portability"); | ||
| 2400 | # endif | ||
| 2401 | #endif | ||
| 2402 | |||
| 2403 | /* =========== Spinlock functions =========== */ | ||
| 2404 | |||
| 2405 | #if 0 | ||
| 2406 | # if 0 | ||
| 2407 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2408 | # undef pthread_spin_init | ||
| 2409 | # define pthread_spin_init rpl_pthread_spin_init | ||
| 2410 | # endif | ||
| 2411 | _GL_FUNCDECL_RPL (pthread_spin_init, int, | ||
| 2412 | (pthread_spinlock_t *lock, int shared_across_processes), | ||
| 2413 | _GL_ARG_NONNULL ((1))); | ||
| 2414 | _GL_CXXALIAS_RPL (pthread_spin_init, int, | ||
| 2415 | (pthread_spinlock_t *lock, int shared_across_processes)); | ||
| 2416 | # else | ||
| 2417 | # if !1 | ||
| 2418 | _GL_FUNCDECL_SYS (pthread_spin_init, int, | ||
| 2419 | (pthread_spinlock_t *lock, int shared_across_processes), | ||
| 2420 | _GL_ARG_NONNULL ((1))); | ||
| 2421 | # endif | ||
| 2422 | _GL_CXXALIAS_SYS (pthread_spin_init, int, | ||
| 2423 | (pthread_spinlock_t *lock, int shared_across_processes)); | ||
| 2424 | # endif | ||
| 2425 | # if __GLIBC__ >= 2 | ||
| 2426 | _GL_CXXALIASWARN (pthread_spin_init); | ||
| 2427 | # endif | ||
| 2428 | #elif defined GNULIB_POSIXCHECK | ||
| 2429 | # if HAVE_RAW_DECL_PTHREAD_SPIN_INIT | ||
| 2430 | _GL_WARN_ON_USE (pthread_spin_init, "pthread_spin_init is not portable - " | ||
| 2431 | "use gnulib module pthread-spin for portability"); | ||
| 2432 | # endif | ||
| 2433 | #endif | ||
| 2434 | |||
| 2435 | #if 0 | ||
| 2436 | # if 0 | ||
| 2437 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2438 | # undef pthread_spin_lock | ||
| 2439 | # define pthread_spin_lock rpl_pthread_spin_lock | ||
| 2440 | # endif | ||
| 2441 | _GL_FUNCDECL_RPL (pthread_spin_lock, int, (pthread_spinlock_t *lock), | ||
| 2442 | _GL_ARG_NONNULL ((1))); | ||
| 2443 | _GL_CXXALIAS_RPL (pthread_spin_lock, int, (pthread_spinlock_t *lock)); | ||
| 2444 | # else | ||
| 2445 | # if !1 | ||
| 2446 | _GL_FUNCDECL_SYS (pthread_spin_lock, int, (pthread_spinlock_t *lock), | ||
| 2447 | _GL_ARG_NONNULL ((1))); | ||
| 2448 | # endif | ||
| 2449 | _GL_CXXALIAS_SYS (pthread_spin_lock, int, (pthread_spinlock_t *lock)); | ||
| 2450 | # endif | ||
| 2451 | # if __GLIBC__ >= 2 | ||
| 2452 | _GL_CXXALIASWARN (pthread_spin_lock); | ||
| 2453 | # endif | ||
| 2454 | #elif defined GNULIB_POSIXCHECK | ||
| 2455 | # if HAVE_RAW_DECL_PTHREAD_SPIN_LOCK | ||
| 2456 | _GL_WARN_ON_USE (pthread_spin_lock, "pthread_spin_lock is not portable - " | ||
| 2457 | "use gnulib module pthread-spin for portability"); | ||
| 2458 | # endif | ||
| 2459 | #endif | ||
| 2460 | |||
| 2461 | #if 0 | ||
| 2462 | # if 0 | ||
| 2463 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2464 | # undef pthread_spin_trylock | ||
| 2465 | # define pthread_spin_trylock rpl_pthread_spin_trylock | ||
| 2466 | # endif | ||
| 2467 | _GL_FUNCDECL_RPL (pthread_spin_trylock, int, (pthread_spinlock_t *lock), | ||
| 2468 | _GL_ARG_NONNULL ((1))); | ||
| 2469 | _GL_CXXALIAS_RPL (pthread_spin_trylock, int, (pthread_spinlock_t *lock)); | ||
| 2470 | # else | ||
| 2471 | # if !1 | ||
| 2472 | _GL_FUNCDECL_SYS (pthread_spin_trylock, int, (pthread_spinlock_t *lock), | ||
| 2473 | _GL_ARG_NONNULL ((1))); | ||
| 2474 | # endif | ||
| 2475 | _GL_CXXALIAS_SYS (pthread_spin_trylock, int, (pthread_spinlock_t *lock)); | ||
| 2476 | # endif | ||
| 2477 | # if __GLIBC__ >= 2 | ||
| 2478 | _GL_CXXALIASWARN (pthread_spin_trylock); | ||
| 2479 | # endif | ||
| 2480 | #elif defined GNULIB_POSIXCHECK | ||
| 2481 | # if HAVE_RAW_DECL_PTHREAD_SPIN_TRYLOCK | ||
| 2482 | _GL_WARN_ON_USE (pthread_spin_trylock, "pthread_spin_trylock is not portable - " | ||
| 2483 | "use gnulib module pthread-spin for portability"); | ||
| 2484 | # endif | ||
| 2485 | #endif | ||
| 2486 | |||
| 2487 | #if 0 | ||
| 2488 | # if 0 | ||
| 2489 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2490 | # undef pthread_spin_unlock | ||
| 2491 | # define pthread_spin_unlock rpl_pthread_spin_unlock | ||
| 2492 | # endif | ||
| 2493 | _GL_FUNCDECL_RPL (pthread_spin_unlock, int, (pthread_spinlock_t *lock), | ||
| 2494 | _GL_ARG_NONNULL ((1))); | ||
| 2495 | _GL_CXXALIAS_RPL (pthread_spin_unlock, int, (pthread_spinlock_t *lock)); | ||
| 2496 | # else | ||
| 2497 | # if !1 | ||
| 2498 | _GL_FUNCDECL_SYS (pthread_spin_unlock, int, (pthread_spinlock_t *lock), | ||
| 2499 | _GL_ARG_NONNULL ((1))); | ||
| 2500 | # endif | ||
| 2501 | _GL_CXXALIAS_SYS (pthread_spin_unlock, int, (pthread_spinlock_t *lock)); | ||
| 2502 | # endif | ||
| 2503 | # if __GLIBC__ >= 2 | ||
| 2504 | _GL_CXXALIASWARN (pthread_spin_unlock); | ||
| 2505 | # endif | ||
| 2506 | #elif defined GNULIB_POSIXCHECK | ||
| 2507 | # if HAVE_RAW_DECL_PTHREAD_SPIN_UNLOCK | ||
| 2508 | _GL_WARN_ON_USE (pthread_spin_unlock, "pthread_spin_unlock is not portable - " | ||
| 2509 | "use gnulib module pthread-spin for portability"); | ||
| 2510 | # endif | ||
| 2511 | #endif | ||
| 2512 | |||
| 2513 | #if 0 | ||
| 2514 | # if 0 | ||
| 2515 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2516 | # undef pthread_spin_destroy | ||
| 2517 | # define pthread_spin_destroy rpl_pthread_spin_destroy | ||
| 2518 | # endif | ||
| 2519 | _GL_FUNCDECL_RPL (pthread_spin_destroy, int, (pthread_spinlock_t *lock), | ||
| 2520 | _GL_ARG_NONNULL ((1))); | ||
| 2521 | _GL_CXXALIAS_RPL (pthread_spin_destroy, int, (pthread_spinlock_t *lock)); | ||
| 2522 | # else | ||
| 2523 | # if !1 | ||
| 2524 | _GL_FUNCDECL_SYS (pthread_spin_destroy, int, (pthread_spinlock_t *lock), | ||
| 2525 | _GL_ARG_NONNULL ((1))); | ||
| 2526 | # endif | ||
| 2527 | _GL_CXXALIAS_SYS (pthread_spin_destroy, int, (pthread_spinlock_t *lock)); | ||
| 2528 | # endif | ||
| 2529 | # if __GLIBC__ >= 2 | ||
| 2530 | _GL_CXXALIASWARN (pthread_spin_destroy); | ||
| 2531 | # endif | ||
| 2532 | #elif defined GNULIB_POSIXCHECK | ||
| 2533 | # if HAVE_RAW_DECL_PTHREAD_SPIN_DESTROY | ||
| 2534 | _GL_WARN_ON_USE (pthread_spin_destroy, "pthread_spin_destroy is not portable - " | ||
| 2535 | "use gnulib module pthread-spin for portability"); | ||
| 2536 | # endif | ||
| 2537 | #endif | ||
| 2538 | |||
| 2539 | |||
| 2540 | #if defined __cplusplus && defined GNULIB_NAMESPACE && !1 && defined __MINGW32__ | ||
| 2541 | /* Provide the symbols required by mingw's <bits/gthr-default.h>. */ | ||
| 2542 | using GNULIB_NAMESPACE::pthread_create; | ||
| 2543 | using GNULIB_NAMESPACE::pthread_self; | ||
| 2544 | using GNULIB_NAMESPACE::pthread_equal; | ||
| 2545 | using GNULIB_NAMESPACE::pthread_detach; | ||
| 2546 | using GNULIB_NAMESPACE::pthread_join; | ||
| 2547 | using GNULIB_NAMESPACE::pthread_once; | ||
| 2548 | using GNULIB_NAMESPACE::pthread_mutex_init; | ||
| 2549 | using GNULIB_NAMESPACE::pthread_mutexattr_init; | ||
| 2550 | using GNULIB_NAMESPACE::pthread_mutexattr_settype; | ||
| 2551 | using GNULIB_NAMESPACE::pthread_mutexattr_destroy; | ||
| 2552 | using GNULIB_NAMESPACE::pthread_mutex_lock; | ||
| 2553 | using GNULIB_NAMESPACE::pthread_mutex_trylock; | ||
| 2554 | using GNULIB_NAMESPACE::pthread_mutex_timedlock; | ||
| 2555 | using GNULIB_NAMESPACE::pthread_mutex_unlock; | ||
| 2556 | using GNULIB_NAMESPACE::pthread_mutex_destroy; | ||
| 2557 | using GNULIB_NAMESPACE::pthread_cond_wait; | ||
| 2558 | using GNULIB_NAMESPACE::pthread_cond_timedwait; | ||
| 2559 | using GNULIB_NAMESPACE::pthread_cond_signal; | ||
| 2560 | using GNULIB_NAMESPACE::pthread_cond_broadcast; | ||
| 2561 | using GNULIB_NAMESPACE::pthread_cond_destroy; | ||
| 2562 | using GNULIB_NAMESPACE::pthread_key_create; | ||
| 2563 | using GNULIB_NAMESPACE::pthread_setspecific; | ||
| 2564 | using GNULIB_NAMESPACE::pthread_getspecific; | ||
| 2565 | using GNULIB_NAMESPACE::pthread_key_delete; | ||
| 2566 | #endif | ||
| 2567 | |||
| 2568 | |||
| 2569 | #endif /* _GL_PTHREAD_H_ */ | ||
| 2570 | #endif /* _GL_PTHREAD_H_ */ | ||
| 2571 | #endif | ||
diff --git a/gl/pthread.in.h b/gl/pthread.in.h new file mode 100644 index 00000000..28592cfc --- /dev/null +++ b/gl/pthread.in.h | |||
| @@ -0,0 +1,2032 @@ | |||
| 1 | /* Implement the most essential subset of POSIX pthread.h. | ||
| 2 | |||
| 3 | Copyright (C) 2009-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Paul Eggert, Glen Lenker, and Bruno Haible. */ | ||
| 19 | |||
| 20 | #if __GNUC__ >= 3 | ||
| 21 | @PRAGMA_SYSTEM_HEADER@ | ||
| 22 | #endif | ||
| 23 | @PRAGMA_COLUMNS@ | ||
| 24 | |||
| 25 | #if defined _@GUARD_PREFIX@_ALREADY_INCLUDING_PTHREAD_H | ||
| 26 | /* Special invocation convention: | ||
| 27 | On Android, we have a sequence of nested includes | ||
| 28 | <pthread.h> -> <time.h> -> <sys/time.h> -> <sys/select.h> -> | ||
| 29 | <signal.h> -> <pthread.h>. | ||
| 30 | In this situation, PTHREAD_COND_INITIALIZER is not yet defined, | ||
| 31 | therefore we should not attempt to define PTHREAD_MUTEX_NORMAL etc. */ | ||
| 32 | |||
| 33 | #@INCLUDE_NEXT@ @NEXT_PTHREAD_H@ | ||
| 34 | |||
| 35 | #else | ||
| 36 | /* Normal invocation convention. */ | ||
| 37 | |||
| 38 | #ifndef _@GUARD_PREFIX@_PTHREAD_H_ | ||
| 39 | |||
| 40 | #if @HAVE_PTHREAD_H@ | ||
| 41 | |||
| 42 | # define _@GUARD_PREFIX@_ALREADY_INCLUDING_PTHREAD_H | ||
| 43 | |||
| 44 | /* The include_next requires a split double-inclusion guard. */ | ||
| 45 | # @INCLUDE_NEXT@ @NEXT_PTHREAD_H@ | ||
| 46 | |||
| 47 | # undef _@GUARD_PREFIX@_ALREADY_INCLUDING_PTHREAD_H | ||
| 48 | |||
| 49 | #endif | ||
| 50 | |||
| 51 | #ifndef _@GUARD_PREFIX@_PTHREAD_H_ | ||
| 52 | #define _@GUARD_PREFIX@_PTHREAD_H_ | ||
| 53 | |||
| 54 | /* This file uses _Noreturn, _GL_ATTRIBUTE_PURE, GNULIB_POSIXCHECK, | ||
| 55 | HAVE_RAW_DECL_*. */ | ||
| 56 | #if !_GL_CONFIG_H_INCLUDED | ||
| 57 | #error "Please include config.h first." | ||
| 58 | #endif | ||
| 59 | |||
| 60 | #define __need_system_stdlib_h | ||
| 61 | #include <stdlib.h> | ||
| 62 | #undef __need_system_stdlib_h | ||
| 63 | |||
| 64 | |||
| 65 | /* The pthreads-win32 <pthread.h> defines a couple of broken macros. */ | ||
| 66 | #undef asctime_r | ||
| 67 | #undef ctime_r | ||
| 68 | #undef gmtime_r | ||
| 69 | #undef localtime_r | ||
| 70 | #undef rand_r | ||
| 71 | #undef strtok_r | ||
| 72 | |||
| 73 | #include <errno.h> | ||
| 74 | #include <sched.h> | ||
| 75 | #include <sys/types.h> | ||
| 76 | #include <time.h> | ||
| 77 | |||
| 78 | /* The __attribute__ feature is available in gcc versions 2.5 and later. | ||
| 79 | The attribute __pure__ was added in gcc 2.96. */ | ||
| 80 | #ifndef _GL_ATTRIBUTE_PURE | ||
| 81 | # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ | ||
| 82 | # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) | ||
| 83 | # else | ||
| 84 | # define _GL_ATTRIBUTE_PURE /* empty */ | ||
| 85 | # endif | ||
| 86 | #endif | ||
| 87 | |||
| 88 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | ||
| 89 | |||
| 90 | /* The definition of _Noreturn is copied here. */ | ||
| 91 | |||
| 92 | /* The definition of _GL_ARG_NONNULL is copied here. */ | ||
| 93 | |||
| 94 | /* The definition of _GL_WARN_ON_USE is copied here. */ | ||
| 95 | |||
| 96 | /* =========== Thread types and macros =========== */ | ||
| 97 | |||
| 98 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 99 | # if @GNULIB_PTHREAD_THREAD@ | ||
| 100 | # include "windows-thread.h" | ||
| 101 | # if @HAVE_PTHREAD_T@ | ||
| 102 | # define pthread_t rpl_pthread_t | ||
| 103 | # define pthread_attr_t rpl_pthread_attr_t | ||
| 104 | # endif | ||
| 105 | # if !GNULIB_defined_pthread_thread_types | ||
| 106 | typedef glwthread_thread_t pthread_t; | ||
| 107 | typedef unsigned int pthread_attr_t; | ||
| 108 | # define GNULIB_defined_pthread_thread_types 1 | ||
| 109 | # endif | ||
| 110 | # else | ||
| 111 | # if @HAVE_PTHREAD_T@ | ||
| 112 | # define pthread_t rpl_pthread_t | ||
| 113 | # define pthread_attr_t rpl_pthread_attr_t | ||
| 114 | # endif | ||
| 115 | # if !GNULIB_defined_pthread_thread_types | ||
| 116 | typedef int pthread_t; | ||
| 117 | typedef unsigned int pthread_attr_t; | ||
| 118 | # define GNULIB_defined_pthread_thread_types 1 | ||
| 119 | # endif | ||
| 120 | # endif | ||
| 121 | # undef PTHREAD_CREATE_JOINABLE | ||
| 122 | # undef PTHREAD_CREATE_DETACHED | ||
| 123 | # define PTHREAD_CREATE_JOINABLE 0 | ||
| 124 | # define PTHREAD_CREATE_DETACHED 1 | ||
| 125 | #else | ||
| 126 | # if !@HAVE_PTHREAD_T@ | ||
| 127 | # if !GNULIB_defined_pthread_thread_types | ||
| 128 | typedef int pthread_t; | ||
| 129 | typedef unsigned int pthread_attr_t; | ||
| 130 | # define GNULIB_defined_pthread_thread_types 1 | ||
| 131 | # endif | ||
| 132 | # endif | ||
| 133 | # if !@HAVE_PTHREAD_CREATE_DETACHED@ | ||
| 134 | # define PTHREAD_CREATE_JOINABLE 0 | ||
| 135 | # define PTHREAD_CREATE_DETACHED 1 | ||
| 136 | # endif | ||
| 137 | #endif | ||
| 138 | |||
| 139 | /* =========== Once-only control (initialization) types and macros ========== */ | ||
| 140 | |||
| 141 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 142 | # if @GNULIB_PTHREAD_ONCE@ | ||
| 143 | # include "windows-once.h" | ||
| 144 | # if @HAVE_PTHREAD_T@ | ||
| 145 | # define pthread_once_t rpl_pthread_once_t | ||
| 146 | # endif | ||
| 147 | # if !GNULIB_defined_pthread_once_types | ||
| 148 | typedef glwthread_once_t pthread_once_t; | ||
| 149 | # define GNULIB_defined_pthread_once_types 1 | ||
| 150 | # endif | ||
| 151 | # undef PTHREAD_ONCE_INIT | ||
| 152 | # define PTHREAD_ONCE_INIT GLWTHREAD_ONCE_INIT | ||
| 153 | # else | ||
| 154 | # if @HAVE_PTHREAD_T@ | ||
| 155 | # define pthread_once_t rpl_pthread_once_t | ||
| 156 | # endif | ||
| 157 | # if !GNULIB_defined_pthread_once_types | ||
| 158 | typedef int pthread_once_t; | ||
| 159 | # define GNULIB_defined_pthread_once_types 1 | ||
| 160 | # endif | ||
| 161 | # undef PTHREAD_ONCE_INIT | ||
| 162 | # define PTHREAD_ONCE_INIT { 0 } | ||
| 163 | # endif | ||
| 164 | #else | ||
| 165 | # if !@HAVE_PTHREAD_T@ | ||
| 166 | # if !GNULIB_defined_pthread_once_types | ||
| 167 | typedef int pthread_once_t; | ||
| 168 | # define GNULIB_defined_pthread_once_types 1 | ||
| 169 | # endif | ||
| 170 | # undef PTHREAD_ONCE_INIT | ||
| 171 | # define PTHREAD_ONCE_INIT { 0 } | ||
| 172 | # endif | ||
| 173 | #endif | ||
| 174 | |||
| 175 | /* =========== Mutex types and macros =========== */ | ||
| 176 | |||
| 177 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 178 | # if @GNULIB_PTHREAD_MUTEX@ | ||
| 179 | # include "windows-timedmutex.h" | ||
| 180 | # include "windows-timedrecmutex.h" | ||
| 181 | # if @HAVE_PTHREAD_T@ | ||
| 182 | # define pthread_mutex_t rpl_pthread_mutex_t | ||
| 183 | # define pthread_mutexattr_t rpl_pthread_mutexattr_t | ||
| 184 | # endif | ||
| 185 | # if !GNULIB_defined_pthread_mutex_types | ||
| 186 | typedef struct | ||
| 187 | { | ||
| 188 | int type; | ||
| 189 | union | ||
| 190 | { | ||
| 191 | glwthread_timedmutex_t u_timedmutex; | ||
| 192 | glwthread_timedrecmutex_t u_timedrecmutex; | ||
| 193 | } | ||
| 194 | u; | ||
| 195 | } | ||
| 196 | pthread_mutex_t; | ||
| 197 | typedef unsigned int pthread_mutexattr_t; | ||
| 198 | # define GNULIB_defined_pthread_mutex_types 1 | ||
| 199 | # endif | ||
| 200 | # undef PTHREAD_MUTEX_INITIALIZER | ||
| 201 | # define PTHREAD_MUTEX_INITIALIZER { 1, { GLWTHREAD_TIMEDMUTEX_INIT } } | ||
| 202 | # else | ||
| 203 | # if @HAVE_PTHREAD_T@ | ||
| 204 | # define pthread_mutex_t rpl_pthread_mutex_t | ||
| 205 | # define pthread_mutexattr_t rpl_pthread_mutexattr_t | ||
| 206 | # endif | ||
| 207 | # if !GNULIB_defined_pthread_mutex_types | ||
| 208 | typedef int pthread_mutex_t; | ||
| 209 | typedef unsigned int pthread_mutexattr_t; | ||
| 210 | # define GNULIB_defined_pthread_mutex_types 1 | ||
| 211 | # endif | ||
| 212 | # undef PTHREAD_MUTEX_INITIALIZER | ||
| 213 | # define PTHREAD_MUTEX_INITIALIZER { 0 } | ||
| 214 | # endif | ||
| 215 | # undef PTHREAD_MUTEX_DEFAULT | ||
| 216 | # undef PTHREAD_MUTEX_NORMAL | ||
| 217 | # undef PTHREAD_MUTEX_ERRORCHECK | ||
| 218 | # undef PTHREAD_MUTEX_RECURSIVE | ||
| 219 | # define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL | ||
| 220 | # define PTHREAD_MUTEX_NORMAL 0 | ||
| 221 | # define PTHREAD_MUTEX_ERRORCHECK 1 | ||
| 222 | # define PTHREAD_MUTEX_RECURSIVE 2 | ||
| 223 | # undef PTHREAD_MUTEX_STALLED | ||
| 224 | # undef PTHREAD_MUTEX_ROBUST | ||
| 225 | # define PTHREAD_MUTEX_STALLED 0 | ||
| 226 | # define PTHREAD_MUTEX_ROBUST 1 | ||
| 227 | #else | ||
| 228 | # if !@HAVE_PTHREAD_T@ | ||
| 229 | # if !GNULIB_defined_pthread_mutex_types | ||
| 230 | typedef int pthread_mutex_t; | ||
| 231 | typedef unsigned int pthread_mutexattr_t; | ||
| 232 | # define GNULIB_defined_pthread_mutex_types 1 | ||
| 233 | # endif | ||
| 234 | # undef PTHREAD_MUTEX_INITIALIZER | ||
| 235 | # define PTHREAD_MUTEX_INITIALIZER { 0 } | ||
| 236 | # endif | ||
| 237 | # if !@HAVE_PTHREAD_MUTEX_RECURSIVE@ | ||
| 238 | # define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL | ||
| 239 | # define PTHREAD_MUTEX_NORMAL 0 | ||
| 240 | # define PTHREAD_MUTEX_ERRORCHECK 1 | ||
| 241 | # define PTHREAD_MUTEX_RECURSIVE 2 | ||
| 242 | # endif | ||
| 243 | # if !@HAVE_PTHREAD_MUTEX_ROBUST@ | ||
| 244 | # define PTHREAD_MUTEX_STALLED 0 | ||
| 245 | # define PTHREAD_MUTEX_ROBUST 1 | ||
| 246 | # endif | ||
| 247 | #endif | ||
| 248 | |||
| 249 | /* =========== Read-write lock types and macros =========== */ | ||
| 250 | |||
| 251 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 252 | # if @GNULIB_PTHREAD_RWLOCK@ | ||
| 253 | # include "windows-timedrwlock.h" | ||
| 254 | # if @HAVE_PTHREAD_T@ | ||
| 255 | # define pthread_rwlock_t rpl_pthread_rwlock_t | ||
| 256 | # define pthread_rwlockattr_t rpl_pthread_rwlockattr_t | ||
| 257 | # endif | ||
| 258 | # if !GNULIB_defined_pthread_rwlock_types | ||
| 259 | typedef glwthread_timedrwlock_t pthread_rwlock_t; | ||
| 260 | typedef unsigned int pthread_rwlockattr_t; | ||
| 261 | # define GNULIB_defined_pthread_rwlock_types 1 | ||
| 262 | # endif | ||
| 263 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 264 | # define PTHREAD_RWLOCK_INITIALIZER GLWTHREAD_TIMEDRWLOCK_INIT | ||
| 265 | # else | ||
| 266 | # if @HAVE_PTHREAD_T@ | ||
| 267 | # define pthread_rwlock_t rpl_pthread_rwlock_t | ||
| 268 | # define pthread_rwlockattr_t rpl_pthread_rwlockattr_t | ||
| 269 | # endif | ||
| 270 | # if !GNULIB_defined_pthread_rwlock_types | ||
| 271 | typedef int pthread_rwlock_t; | ||
| 272 | typedef unsigned int pthread_rwlockattr_t; | ||
| 273 | # define GNULIB_defined_pthread_rwlock_types 1 | ||
| 274 | # endif | ||
| 275 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 276 | # define PTHREAD_RWLOCK_INITIALIZER { 0 } | ||
| 277 | # endif | ||
| 278 | #elif @GNULIB_PTHREAD_RWLOCK@ && @REPLACE_PTHREAD_RWLOCK_DESTROY@ /* i.e. PTHREAD_RWLOCK_UNIMPLEMENTED */ | ||
| 279 | # if @HAVE_PTHREAD_T@ | ||
| 280 | # define pthread_rwlock_t rpl_pthread_rwlock_t | ||
| 281 | # define pthread_rwlockattr_t rpl_pthread_rwlockattr_t | ||
| 282 | # endif | ||
| 283 | # if !GNULIB_defined_pthread_rwlock_types | ||
| 284 | typedef struct | ||
| 285 | { | ||
| 286 | pthread_mutex_t lock; /* protects the remaining fields */ | ||
| 287 | pthread_cond_t waiting_readers; /* waiting readers */ | ||
| 288 | pthread_cond_t waiting_writers; /* waiting writers */ | ||
| 289 | unsigned int waiting_writers_count; /* number of waiting writers */ | ||
| 290 | int runcount; /* number of readers running, or -1 when a writer runs */ | ||
| 291 | } | ||
| 292 | pthread_rwlock_t; | ||
| 293 | typedef unsigned int pthread_rwlockattr_t; | ||
| 294 | # define GNULIB_defined_pthread_rwlock_types 1 | ||
| 295 | # endif | ||
| 296 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 297 | # define PTHREAD_RWLOCK_INITIALIZER \ | ||
| 298 | { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 } | ||
| 299 | #elif @GNULIB_PTHREAD_RWLOCK@ && @REPLACE_PTHREAD_RWLOCK_INIT@ /* i.e. PTHREAD_RWLOCK_BAD_WAITQUEUE */ | ||
| 300 | /* Use rwlocks of kind PREFER_WRITER or PREFER_WRITER_NONRECURSIVE instead of | ||
| 301 | the DEFAULT. */ | ||
| 302 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 303 | # define PTHREAD_RWLOCK_INITIALIZER PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP | ||
| 304 | #else | ||
| 305 | # if @HAVE_PTHREAD_T@ | ||
| 306 | # if !defined PTHREAD_RWLOCK_INITIALIZER && defined PTHREAD_RWLOCK_INITIALIZER_NP /* z/OS */ | ||
| 307 | # define PTHREAD_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER_NP | ||
| 308 | # endif | ||
| 309 | # else | ||
| 310 | # if !GNULIB_defined_pthread_rwlock_types | ||
| 311 | typedef int pthread_rwlock_t; | ||
| 312 | typedef unsigned int pthread_rwlockattr_t; | ||
| 313 | # define GNULIB_defined_pthread_rwlock_types 1 | ||
| 314 | # endif | ||
| 315 | # undef PTHREAD_RWLOCK_INITIALIZER | ||
| 316 | # define PTHREAD_RWLOCK_INITIALIZER { 0 } | ||
| 317 | # endif | ||
| 318 | #endif | ||
| 319 | |||
| 320 | /* =========== Condition variable types and macros =========== */ | ||
| 321 | |||
| 322 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 323 | # if @GNULIB_PTHREAD_COND@ | ||
| 324 | # include "windows-cond.h" | ||
| 325 | # if @HAVE_PTHREAD_T@ | ||
| 326 | # define pthread_cond_t rpl_pthread_cond_t | ||
| 327 | # define pthread_condattr_t rpl_pthread_condattr_t | ||
| 328 | # endif | ||
| 329 | # if !GNULIB_defined_pthread_cond_types | ||
| 330 | typedef glwthread_cond_t pthread_cond_t; | ||
| 331 | typedef unsigned int pthread_condattr_t; | ||
| 332 | # define GNULIB_defined_pthread_cond_types 1 | ||
| 333 | # endif | ||
| 334 | # undef PTHREAD_COND_INITIALIZER | ||
| 335 | # define PTHREAD_COND_INITIALIZER GLWTHREAD_COND_INIT | ||
| 336 | # else | ||
| 337 | # if @HAVE_PTHREAD_T@ | ||
| 338 | # define pthread_cond_t rpl_pthread_cond_t | ||
| 339 | # define pthread_condattr_t rpl_pthread_condattr_t | ||
| 340 | # endif | ||
| 341 | # if !GNULIB_defined_pthread_cond_types | ||
| 342 | typedef int pthread_cond_t; | ||
| 343 | typedef unsigned int pthread_condattr_t; | ||
| 344 | # define GNULIB_defined_pthread_cond_types 1 | ||
| 345 | # endif | ||
| 346 | # undef PTHREAD_COND_INITIALIZER | ||
| 347 | # define PTHREAD_COND_INITIALIZER { 0 } | ||
| 348 | # endif | ||
| 349 | #else | ||
| 350 | # if !@HAVE_PTHREAD_T@ | ||
| 351 | # if !GNULIB_defined_pthread_cond_types | ||
| 352 | typedef int pthread_cond_t; | ||
| 353 | typedef unsigned int pthread_condattr_t; | ||
| 354 | # define GNULIB_defined_pthread_cond_types 1 | ||
| 355 | # endif | ||
| 356 | # undef PTHREAD_COND_INITIALIZER | ||
| 357 | # define PTHREAD_COND_INITIALIZER { 0 } | ||
| 358 | # endif | ||
| 359 | #endif | ||
| 360 | |||
| 361 | /* =========== Thread-specific storage types and macros =========== */ | ||
| 362 | |||
| 363 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 364 | # if @GNULIB_PTHREAD_TSS@ | ||
| 365 | # include "windows-tls.h" | ||
| 366 | # if @HAVE_PTHREAD_T@ | ||
| 367 | # define pthread_key_t rpl_pthread_key_t | ||
| 368 | # endif | ||
| 369 | # if !GNULIB_defined_pthread_tss_types | ||
| 370 | typedef glwthread_tls_key_t pthread_key_t; | ||
| 371 | # define GNULIB_defined_pthread_tss_types 1 | ||
| 372 | # endif | ||
| 373 | # undef PTHREAD_DESTRUCTOR_ITERATIONS | ||
| 374 | # define PTHREAD_DESTRUCTOR_ITERATIONS GLWTHREAD_DESTRUCTOR_ITERATIONS | ||
| 375 | # else | ||
| 376 | # if @HAVE_PTHREAD_T@ | ||
| 377 | # define pthread_key_t rpl_pthread_key_t | ||
| 378 | # endif | ||
| 379 | # if !GNULIB_defined_pthread_tss_types | ||
| 380 | typedef void ** pthread_key_t; | ||
| 381 | # define GNULIB_defined_pthread_tss_types 1 | ||
| 382 | # endif | ||
| 383 | # undef PTHREAD_DESTRUCTOR_ITERATIONS | ||
| 384 | # define PTHREAD_DESTRUCTOR_ITERATIONS 0 | ||
| 385 | # endif | ||
| 386 | #else | ||
| 387 | # if !@HAVE_PTHREAD_T@ | ||
| 388 | # if !GNULIB_defined_pthread_tss_types | ||
| 389 | typedef void ** pthread_key_t; | ||
| 390 | # define GNULIB_defined_pthread_tss_types 1 | ||
| 391 | # endif | ||
| 392 | # undef PTHREAD_DESTRUCTOR_ITERATIONS | ||
| 393 | # define PTHREAD_DESTRUCTOR_ITERATIONS 0 | ||
| 394 | # endif | ||
| 395 | #endif | ||
| 396 | |||
| 397 | /* =========== Spinlock types and macros =========== */ | ||
| 398 | |||
| 399 | #if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS | ||
| 400 | # if @GNULIB_PTHREAD_SPIN@ | ||
| 401 | # include "windows-spin.h" | ||
| 402 | # if @HAVE_PTHREAD_T@ | ||
| 403 | # define pthread_spinlock_t rpl_pthread_spinlock_t | ||
| 404 | # endif | ||
| 405 | # if !GNULIB_defined_pthread_spin_types | ||
| 406 | typedef glwthread_spinlock_t pthread_spinlock_t; | ||
| 407 | # define GNULIB_defined_pthread_spin_types 1 | ||
| 408 | # endif | ||
| 409 | # else | ||
| 410 | # if @HAVE_PTHREAD_T@ | ||
| 411 | # define pthread_spinlock_t rpl_pthread_spinlock_t | ||
| 412 | # endif | ||
| 413 | # if !GNULIB_defined_pthread_spin_types | ||
| 414 | typedef pthread_mutex_t pthread_spinlock_t; | ||
| 415 | # define GNULIB_defined_pthread_spin_types 1 | ||
| 416 | # endif | ||
| 417 | # endif | ||
| 418 | # undef PTHREAD_PROCESS_PRIVATE | ||
| 419 | # undef PTHREAD_PROCESS_SHARED | ||
| 420 | # define PTHREAD_PROCESS_PRIVATE 0 | ||
| 421 | # define PTHREAD_PROCESS_SHARED 1 | ||
| 422 | #else | ||
| 423 | # if @HAVE_PTHREAD_SPINLOCK_T@ | ||
| 424 | /* <pthread.h> exists and defines pthread_spinlock_t. */ | ||
| 425 | # if !@HAVE_PTHREAD_SPIN_INIT@ || @REPLACE_PTHREAD_SPIN_INIT@ | ||
| 426 | /* If the 'pthread-spin' module is in use, it defines all the pthread_spin* | ||
| 427 | functions. Prepare for it by overriding pthread_spinlock_t if that might | ||
| 428 | be needed. */ | ||
| 429 | # if !(((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) \ | ||
| 430 | || __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 1)) \ | ||
| 431 | || (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \ | ||
| 432 | && !defined __ANDROID__) \ | ||
| 433 | || __clang_major__ >= 3)) \ | ||
| 434 | && !defined __ibmxl__) | ||
| 435 | /* We can't use GCC built-ins. Approximate spinlocks with mutexes. */ | ||
| 436 | # if !GNULIB_defined_pthread_spin_types | ||
| 437 | # define pthread_spinlock_t pthread_mutex_t | ||
| 438 | # define GNULIB_defined_pthread_spin_types 1 | ||
| 439 | # endif | ||
| 440 | # endif | ||
| 441 | # endif | ||
| 442 | # else | ||
| 443 | /* Approximate spinlocks with mutexes. */ | ||
| 444 | # if !GNULIB_defined_pthread_spin_types | ||
| 445 | typedef pthread_mutex_t pthread_spinlock_t; | ||
| 446 | # define GNULIB_defined_pthread_spin_types 1 | ||
| 447 | # endif | ||
| 448 | # endif | ||
| 449 | # if !@HAVE_PTHREAD_PROCESS_SHARED@ | ||
| 450 | # define PTHREAD_PROCESS_PRIVATE 0 | ||
| 451 | # define PTHREAD_PROCESS_SHARED 1 | ||
| 452 | # endif | ||
| 453 | #endif | ||
| 454 | |||
| 455 | /* =========== Other types and macros =========== */ | ||
| 456 | |||
| 457 | #if !@HAVE_PTHREAD_T@ | ||
| 458 | # if !GNULIB_defined_other_pthread_types | ||
| 459 | typedef int pthread_barrier_t; | ||
| 460 | typedef unsigned int pthread_barrierattr_t; | ||
| 461 | # define GNULIB_defined_other_pthread_types 1 | ||
| 462 | # endif | ||
| 463 | #endif | ||
| 464 | |||
| 465 | #if !defined PTHREAD_CANCELED | ||
| 466 | |||
| 467 | # define PTHREAD_BARRIER_SERIAL_THREAD (-1) | ||
| 468 | |||
| 469 | # define PTHREAD_CANCEL_DEFERRED 0 | ||
| 470 | # define PTHREAD_CANCEL_ASYNCHRONOUS 1 | ||
| 471 | |||
| 472 | # define PTHREAD_CANCEL_ENABLE 0 | ||
| 473 | # define PTHREAD_CANCEL_DISABLE 1 | ||
| 474 | |||
| 475 | # define PTHREAD_CANCELED ((void *) -1) | ||
| 476 | |||
| 477 | # define PTHREAD_INHERIT_SCHED 0 | ||
| 478 | # define PTHREAD_EXPLICIT_SCHED 1 | ||
| 479 | |||
| 480 | # define PTHREAD_PRIO_NONE 0 | ||
| 481 | # define PTHREAD_PRIO_INHERIT 1 | ||
| 482 | # define PTHREAD_PRIO_PROTECT 2 | ||
| 483 | |||
| 484 | # define PTHREAD_SCOPE_SYSTEM 0 | ||
| 485 | # define PTHREAD_SCOPE_PROCESS 1 | ||
| 486 | |||
| 487 | #endif | ||
| 488 | |||
| 489 | /* =========== Thread functions =========== */ | ||
| 490 | |||
| 491 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 492 | /* The 'restrict' qualifier on ARG is nonsense, but POSIX specifies it this way. | ||
| 493 | Sigh. */ | ||
| 494 | # if @REPLACE_PTHREAD_CREATE@ | ||
| 495 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 496 | # undef pthread_create | ||
| 497 | # define pthread_create rpl_pthread_create | ||
| 498 | # endif | ||
| 499 | _GL_FUNCDECL_RPL (pthread_create, int, | ||
| 500 | (pthread_t *restrict threadp, | ||
| 501 | const pthread_attr_t *restrict attr, | ||
| 502 | void * (*mainfunc) (void *), void *restrict arg), | ||
| 503 | _GL_ARG_NONNULL ((1, 3))); | ||
| 504 | _GL_CXXALIAS_RPL (pthread_create, int, | ||
| 505 | (pthread_t *restrict threadp, | ||
| 506 | const pthread_attr_t *restrict attr, | ||
| 507 | void * (*mainfunc) (void *), void *restrict arg)); | ||
| 508 | # else | ||
| 509 | # if !@HAVE_PTHREAD_CREATE@ | ||
| 510 | _GL_FUNCDECL_SYS (pthread_create, int, | ||
| 511 | (pthread_t *restrict threadp, | ||
| 512 | const pthread_attr_t *restrict attr, | ||
| 513 | void * (*mainfunc) (void *), void *restrict arg), | ||
| 514 | _GL_ARG_NONNULL ((1, 3))); | ||
| 515 | # endif | ||
| 516 | _GL_CXXALIAS_SYS_CAST (pthread_create, int, | ||
| 517 | (pthread_t *restrict threadp, | ||
| 518 | const pthread_attr_t *restrict attr, | ||
| 519 | void * (*mainfunc) (void *), void *restrict arg)); | ||
| 520 | # endif | ||
| 521 | # if __GLIBC__ >= 2 | ||
| 522 | _GL_CXXALIASWARN (pthread_create); | ||
| 523 | # endif | ||
| 524 | #elif defined GNULIB_POSIXCHECK | ||
| 525 | # undef pthread_create | ||
| 526 | # if HAVE_RAW_DECL_PTHREAD_CREATE | ||
| 527 | _GL_WARN_ON_USE (pthread_create, "pthread_create is not portable - " | ||
| 528 | "use gnulib module pthread-thread for portability"); | ||
| 529 | # endif | ||
| 530 | #endif | ||
| 531 | |||
| 532 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 533 | # if @REPLACE_PTHREAD_ATTR_INIT@ | ||
| 534 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 535 | # undef pthread_attr_init | ||
| 536 | # define pthread_attr_init rpl_pthread_attr_init | ||
| 537 | # endif | ||
| 538 | _GL_FUNCDECL_RPL (pthread_attr_init, int, (pthread_attr_t *attr), | ||
| 539 | _GL_ARG_NONNULL ((1))); | ||
| 540 | _GL_CXXALIAS_RPL (pthread_attr_init, int, (pthread_attr_t *attr)); | ||
| 541 | # else | ||
| 542 | # if !@HAVE_PTHREAD_ATTR_INIT@ | ||
| 543 | _GL_FUNCDECL_SYS (pthread_attr_init, int, (pthread_attr_t *attr), | ||
| 544 | _GL_ARG_NONNULL ((1))); | ||
| 545 | # endif | ||
| 546 | _GL_CXXALIAS_SYS (pthread_attr_init, int, (pthread_attr_t *attr)); | ||
| 547 | # endif | ||
| 548 | # if __GLIBC__ >= 2 | ||
| 549 | _GL_CXXALIASWARN (pthread_attr_init); | ||
| 550 | # endif | ||
| 551 | #elif defined GNULIB_POSIXCHECK | ||
| 552 | # undef pthread_attr_init | ||
| 553 | # if HAVE_RAW_DECL_PTHREAD_ATTR_INIT | ||
| 554 | _GL_WARN_ON_USE (pthread_attr_init, "pthread_attr_init is not portable - " | ||
| 555 | "use gnulib module pthread-thread for portability"); | ||
| 556 | # endif | ||
| 557 | #endif | ||
| 558 | |||
| 559 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 560 | # if @REPLACE_PTHREAD_ATTR_GETDETACHSTATE@ | ||
| 561 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 562 | # undef pthread_attr_getdetachstate | ||
| 563 | # define pthread_attr_getdetachstate rpl_pthread_attr_getdetachstate | ||
| 564 | # endif | ||
| 565 | _GL_FUNCDECL_RPL (pthread_attr_getdetachstate, int, | ||
| 566 | (const pthread_attr_t *attr, int *detachstatep), | ||
| 567 | _GL_ARG_NONNULL ((1, 2))); | ||
| 568 | _GL_CXXALIAS_RPL (pthread_attr_getdetachstate, int, | ||
| 569 | (const pthread_attr_t *attr, int *detachstatep)); | ||
| 570 | # else | ||
| 571 | # if !@HAVE_PTHREAD_ATTR_GETDETACHSTATE@ | ||
| 572 | _GL_FUNCDECL_SYS (pthread_attr_getdetachstate, int, | ||
| 573 | (const pthread_attr_t *attr, int *detachstatep), | ||
| 574 | _GL_ARG_NONNULL ((1, 2))); | ||
| 575 | # endif | ||
| 576 | _GL_CXXALIAS_SYS (pthread_attr_getdetachstate, int, | ||
| 577 | (const pthread_attr_t *attr, int *detachstatep)); | ||
| 578 | # endif | ||
| 579 | # if __GLIBC__ >= 2 | ||
| 580 | _GL_CXXALIASWARN (pthread_attr_getdetachstate); | ||
| 581 | # endif | ||
| 582 | #elif defined GNULIB_POSIXCHECK | ||
| 583 | # undef pthread_attr_getdetachstate | ||
| 584 | # if HAVE_RAW_DECL_PTHREAD_ATTR_GETDETACHSTATE | ||
| 585 | _GL_WARN_ON_USE (pthread_attr_getdetachstate, "pthread_attr_getdetachstate is not portable - " | ||
| 586 | "use gnulib module pthread-thread for portability"); | ||
| 587 | # endif | ||
| 588 | #endif | ||
| 589 | |||
| 590 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 591 | # if @REPLACE_PTHREAD_ATTR_SETDETACHSTATE@ | ||
| 592 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 593 | # undef pthread_attr_setdetachstate | ||
| 594 | # define pthread_attr_setdetachstate rpl_pthread_attr_setdetachstate | ||
| 595 | # endif | ||
| 596 | _GL_FUNCDECL_RPL (pthread_attr_setdetachstate, int, | ||
| 597 | (pthread_attr_t *attr, int detachstate), | ||
| 598 | _GL_ARG_NONNULL ((1))); | ||
| 599 | _GL_CXXALIAS_RPL (pthread_attr_setdetachstate, int, | ||
| 600 | (pthread_attr_t *attr, int detachstate)); | ||
| 601 | # else | ||
| 602 | # if !@HAVE_PTHREAD_ATTR_SETDETACHSTATE@ | ||
| 603 | _GL_FUNCDECL_SYS (pthread_attr_setdetachstate, int, | ||
| 604 | (pthread_attr_t *attr, int detachstate), | ||
| 605 | _GL_ARG_NONNULL ((1))); | ||
| 606 | # endif | ||
| 607 | _GL_CXXALIAS_SYS (pthread_attr_setdetachstate, int, | ||
| 608 | (pthread_attr_t *attr, int detachstate)); | ||
| 609 | # endif | ||
| 610 | # if __GLIBC__ >= 2 | ||
| 611 | _GL_CXXALIASWARN (pthread_attr_setdetachstate); | ||
| 612 | # endif | ||
| 613 | #elif defined GNULIB_POSIXCHECK | ||
| 614 | # undef pthread_attr_setdetachstate | ||
| 615 | # if HAVE_RAW_DECL_PTHREAD_ATTR_SETDETACHSTATE | ||
| 616 | _GL_WARN_ON_USE (pthread_attr_setdetachstate, "pthread_attr_setdetachstate is not portable - " | ||
| 617 | "use gnulib module pthread-thread for portability"); | ||
| 618 | # endif | ||
| 619 | #endif | ||
| 620 | |||
| 621 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 622 | # if @REPLACE_PTHREAD_ATTR_DESTROY@ | ||
| 623 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 624 | # undef pthread_attr_destroy | ||
| 625 | # define pthread_attr_destroy rpl_pthread_attr_destroy | ||
| 626 | # endif | ||
| 627 | _GL_FUNCDECL_RPL (pthread_attr_destroy, int, (pthread_attr_t *attr), | ||
| 628 | _GL_ARG_NONNULL ((1))); | ||
| 629 | _GL_CXXALIAS_RPL (pthread_attr_destroy, int, (pthread_attr_t *attr)); | ||
| 630 | # else | ||
| 631 | # if !@HAVE_PTHREAD_ATTR_DESTROY@ | ||
| 632 | _GL_FUNCDECL_SYS (pthread_attr_destroy, int, (pthread_attr_t *attr), | ||
| 633 | _GL_ARG_NONNULL ((1))); | ||
| 634 | # endif | ||
| 635 | _GL_CXXALIAS_SYS (pthread_attr_destroy, int, (pthread_attr_t *attr)); | ||
| 636 | # endif | ||
| 637 | # if __GLIBC__ >= 2 | ||
| 638 | _GL_CXXALIASWARN (pthread_attr_destroy); | ||
| 639 | # endif | ||
| 640 | #elif defined GNULIB_POSIXCHECK | ||
| 641 | # undef pthread_attr_destroy | ||
| 642 | # if HAVE_RAW_DECL_PTHREAD_ATTR_DESTROY | ||
| 643 | _GL_WARN_ON_USE (pthread_attr_destroy, "pthread_attr_destroy is not portable - " | ||
| 644 | "use gnulib module pthread-thread for portability"); | ||
| 645 | # endif | ||
| 646 | #endif | ||
| 647 | |||
| 648 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 649 | # if @REPLACE_PTHREAD_SELF@ | ||
| 650 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 651 | # undef pthread_self | ||
| 652 | # define pthread_self rpl_pthread_self | ||
| 653 | # endif | ||
| 654 | _GL_FUNCDECL_RPL (pthread_self, pthread_t, (void), _GL_ATTRIBUTE_PURE); | ||
| 655 | _GL_CXXALIAS_RPL (pthread_self, pthread_t, (void)); | ||
| 656 | # else | ||
| 657 | # if !@HAVE_PTHREAD_SELF@ | ||
| 658 | _GL_FUNCDECL_SYS (pthread_self, pthread_t, (void), _GL_ATTRIBUTE_PURE); | ||
| 659 | # endif | ||
| 660 | _GL_CXXALIAS_SYS (pthread_self, pthread_t, (void)); | ||
| 661 | # endif | ||
| 662 | # if __GLIBC__ >= 2 | ||
| 663 | _GL_CXXALIASWARN (pthread_self); | ||
| 664 | # endif | ||
| 665 | #elif defined GNULIB_POSIXCHECK | ||
| 666 | # undef pthread_self | ||
| 667 | # if HAVE_RAW_DECL_PTHREAD_SELF | ||
| 668 | _GL_WARN_ON_USE (pthread_self, "pthread_self is not portable - " | ||
| 669 | "use gnulib module pthread-thread for portability"); | ||
| 670 | # endif | ||
| 671 | #endif | ||
| 672 | |||
| 673 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 674 | # if @REPLACE_PTHREAD_EQUAL@ | ||
| 675 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 676 | # undef pthread_equal | ||
| 677 | # define pthread_equal rpl_pthread_equal | ||
| 678 | # endif | ||
| 679 | _GL_FUNCDECL_RPL (pthread_equal, int, (pthread_t thread1, pthread_t thread2), ); | ||
| 680 | _GL_CXXALIAS_RPL (pthread_equal, int, (pthread_t thread1, pthread_t thread2)); | ||
| 681 | # else | ||
| 682 | # if !@HAVE_PTHREAD_EQUAL@ | ||
| 683 | _GL_FUNCDECL_SYS (pthread_equal, int, (pthread_t thread1, pthread_t thread2), ); | ||
| 684 | # endif | ||
| 685 | _GL_CXXALIAS_SYS (pthread_equal, int, (pthread_t thread1, pthread_t thread2)); | ||
| 686 | # endif | ||
| 687 | # if __GLIBC__ >= 2 | ||
| 688 | _GL_CXXALIASWARN (pthread_equal); | ||
| 689 | # endif | ||
| 690 | #elif defined GNULIB_POSIXCHECK | ||
| 691 | # undef pthread_equal | ||
| 692 | # if HAVE_RAW_DECL_PTHREAD_EQUAL | ||
| 693 | _GL_WARN_ON_USE (pthread_equal, "pthread_equal is not portable - " | ||
| 694 | "use gnulib module pthread-thread for portability"); | ||
| 695 | # endif | ||
| 696 | #endif | ||
| 697 | |||
| 698 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 699 | # if @REPLACE_PTHREAD_DETACH@ | ||
| 700 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 701 | # undef pthread_detach | ||
| 702 | # define pthread_detach rpl_pthread_detach | ||
| 703 | # endif | ||
| 704 | _GL_FUNCDECL_RPL (pthread_detach, int, (pthread_t thread), ); | ||
| 705 | _GL_CXXALIAS_RPL (pthread_detach, int, (pthread_t thread)); | ||
| 706 | # else | ||
| 707 | # if !@HAVE_PTHREAD_DETACH@ | ||
| 708 | _GL_FUNCDECL_SYS (pthread_detach, int, (pthread_t thread), ); | ||
| 709 | # endif | ||
| 710 | _GL_CXXALIAS_SYS (pthread_detach, int, (pthread_t thread)); | ||
| 711 | # endif | ||
| 712 | # if __GLIBC__ >= 2 | ||
| 713 | _GL_CXXALIASWARN (pthread_detach); | ||
| 714 | # endif | ||
| 715 | #elif defined GNULIB_POSIXCHECK | ||
| 716 | # undef pthread_detach | ||
| 717 | # if HAVE_RAW_DECL_PTHREAD_DETACH | ||
| 718 | _GL_WARN_ON_USE (pthread_detach, "pthread_detach is not portable - " | ||
| 719 | "use gnulib module pthread-thread for portability"); | ||
| 720 | # endif | ||
| 721 | #endif | ||
| 722 | |||
| 723 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 724 | # if @REPLACE_PTHREAD_JOIN@ | ||
| 725 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 726 | # undef pthread_join | ||
| 727 | # define pthread_join rpl_pthread_join | ||
| 728 | # endif | ||
| 729 | _GL_FUNCDECL_RPL (pthread_join, int, (pthread_t thread, void **valuep), ); | ||
| 730 | _GL_CXXALIAS_RPL (pthread_join, int, (pthread_t thread, void **valuep)); | ||
| 731 | # else | ||
| 732 | # if !@HAVE_PTHREAD_JOIN@ | ||
| 733 | _GL_FUNCDECL_SYS (pthread_join, int, (pthread_t thread, void **valuep), ); | ||
| 734 | # endif | ||
| 735 | _GL_CXXALIAS_SYS (pthread_join, int, (pthread_t thread, void **valuep)); | ||
| 736 | # endif | ||
| 737 | # if __GLIBC__ >= 2 | ||
| 738 | _GL_CXXALIASWARN (pthread_join); | ||
| 739 | # endif | ||
| 740 | #elif defined GNULIB_POSIXCHECK | ||
| 741 | # undef pthread_join | ||
| 742 | # if HAVE_RAW_DECL_PTHREAD_JOIN | ||
| 743 | _GL_WARN_ON_USE (pthread_join, "pthread_join is not portable - " | ||
| 744 | "use gnulib module pthread-thread for portability"); | ||
| 745 | # endif | ||
| 746 | #endif | ||
| 747 | |||
| 748 | #if @GNULIB_PTHREAD_THREAD@ | ||
| 749 | # if @REPLACE_PTHREAD_EXIT@ | ||
| 750 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 751 | # undef pthread_exit | ||
| 752 | # define pthread_exit rpl_pthread_exit | ||
| 753 | # endif | ||
| 754 | _GL_FUNCDECL_RPL (pthread_exit, _Noreturn void, (void *value), ); | ||
| 755 | _GL_CXXALIAS_RPL (pthread_exit, void, (void *value)); | ||
| 756 | # else | ||
| 757 | # if !@HAVE_PTHREAD_EXIT@ | ||
| 758 | _GL_FUNCDECL_SYS (pthread_exit, _Noreturn void, (void *value), ); | ||
| 759 | # endif | ||
| 760 | /* Need to cast because of AIX with xlclang++. */ | ||
| 761 | _GL_CXXALIAS_SYS_CAST (pthread_exit, void, (void *value)); | ||
| 762 | # endif | ||
| 763 | # if __GLIBC__ >= 2 | ||
| 764 | _GL_CXXALIASWARN (pthread_exit); | ||
| 765 | # endif | ||
| 766 | #elif defined GNULIB_POSIXCHECK | ||
| 767 | # undef pthread_exit | ||
| 768 | # if HAVE_RAW_DECL_PTHREAD_EXIT | ||
| 769 | _GL_WARN_ON_USE (pthread_exit, "pthread_exit is not portable - " | ||
| 770 | "use gnulib module pthread-thread for portability"); | ||
| 771 | # endif | ||
| 772 | #endif | ||
| 773 | |||
| 774 | /* =========== Once-only control (initialization) functions =========== */ | ||
| 775 | |||
| 776 | #if @GNULIB_PTHREAD_ONCE@ | ||
| 777 | # if @REPLACE_PTHREAD_ONCE@ | ||
| 778 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 779 | # undef pthread_once | ||
| 780 | # define pthread_once rpl_pthread_once | ||
| 781 | # endif | ||
| 782 | _GL_FUNCDECL_RPL (pthread_once, int, | ||
| 783 | (pthread_once_t *once_control, void (*initfunction) (void)), | ||
| 784 | _GL_ARG_NONNULL ((1, 2))); | ||
| 785 | _GL_CXXALIAS_RPL (pthread_once, int, | ||
| 786 | (pthread_once_t *once_control, void (*initfunction) (void))); | ||
| 787 | # else | ||
| 788 | # if !@HAVE_PTHREAD_ONCE@ | ||
| 789 | _GL_FUNCDECL_SYS (pthread_once, int, | ||
| 790 | (pthread_once_t *once_control, void (*initfunction) (void)), | ||
| 791 | _GL_ARG_NONNULL ((1, 2))); | ||
| 792 | # endif | ||
| 793 | _GL_CXXALIAS_SYS_CAST (pthread_once, int, | ||
| 794 | (pthread_once_t *once_control, | ||
| 795 | void (*initfunction) (void))); | ||
| 796 | # endif | ||
| 797 | # if __GLIBC__ >= 2 | ||
| 798 | _GL_CXXALIASWARN (pthread_once); | ||
| 799 | # endif | ||
| 800 | #elif defined GNULIB_POSIXCHECK | ||
| 801 | # undef pthread_once | ||
| 802 | # if HAVE_RAW_DECL_PTHREAD_ONCE | ||
| 803 | _GL_WARN_ON_USE (pthread_once, "pthread_once is not portable - " | ||
| 804 | "use gnulib module pthread-once for portability"); | ||
| 805 | # endif | ||
| 806 | #endif | ||
| 807 | |||
| 808 | /* =========== Mutex functions =========== */ | ||
| 809 | |||
| 810 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 811 | # if @REPLACE_PTHREAD_MUTEX_INIT@ | ||
| 812 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 813 | # undef pthread_mutex_init | ||
| 814 | # define pthread_mutex_init rpl_pthread_mutex_init | ||
| 815 | # endif | ||
| 816 | _GL_FUNCDECL_RPL (pthread_mutex_init, int, | ||
| 817 | (pthread_mutex_t *restrict mutex, | ||
| 818 | const pthread_mutexattr_t *restrict attr), | ||
| 819 | _GL_ARG_NONNULL ((1))); | ||
| 820 | _GL_CXXALIAS_RPL (pthread_mutex_init, int, | ||
| 821 | (pthread_mutex_t *restrict mutex, | ||
| 822 | const pthread_mutexattr_t *restrict attr)); | ||
| 823 | # else | ||
| 824 | # if !@HAVE_PTHREAD_MUTEX_INIT@ | ||
| 825 | _GL_FUNCDECL_SYS (pthread_mutex_init, int, | ||
| 826 | (pthread_mutex_t *restrict mutex, | ||
| 827 | const pthread_mutexattr_t *restrict attr), | ||
| 828 | _GL_ARG_NONNULL ((1))); | ||
| 829 | # endif | ||
| 830 | _GL_CXXALIAS_SYS (pthread_mutex_init, int, | ||
| 831 | (pthread_mutex_t *restrict mutex, | ||
| 832 | const pthread_mutexattr_t *restrict attr)); | ||
| 833 | # endif | ||
| 834 | # if __GLIBC__ >= 2 | ||
| 835 | _GL_CXXALIASWARN (pthread_mutex_init); | ||
| 836 | # endif | ||
| 837 | #elif defined GNULIB_POSIXCHECK | ||
| 838 | # undef pthread_mutex_init | ||
| 839 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_INIT | ||
| 840 | _GL_WARN_ON_USE (pthread_mutex_init, "pthread_mutex_init is not portable - " | ||
| 841 | "use gnulib module pthread-mutex for portability"); | ||
| 842 | # endif | ||
| 843 | #endif | ||
| 844 | |||
| 845 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 846 | # if @REPLACE_PTHREAD_MUTEXATTR_INIT@ | ||
| 847 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 848 | # undef pthread_mutexattr_init | ||
| 849 | # define pthread_mutexattr_init rpl_pthread_mutexattr_init | ||
| 850 | # endif | ||
| 851 | _GL_FUNCDECL_RPL (pthread_mutexattr_init, int, (pthread_mutexattr_t *attr), | ||
| 852 | _GL_ARG_NONNULL ((1))); | ||
| 853 | _GL_CXXALIAS_RPL (pthread_mutexattr_init, int, (pthread_mutexattr_t *attr)); | ||
| 854 | # else | ||
| 855 | # if !@HAVE_PTHREAD_MUTEXATTR_INIT@ | ||
| 856 | _GL_FUNCDECL_SYS (pthread_mutexattr_init, int, (pthread_mutexattr_t *attr), | ||
| 857 | _GL_ARG_NONNULL ((1))); | ||
| 858 | # endif | ||
| 859 | _GL_CXXALIAS_SYS (pthread_mutexattr_init, int, (pthread_mutexattr_t *attr)); | ||
| 860 | # endif | ||
| 861 | # if __GLIBC__ >= 2 | ||
| 862 | _GL_CXXALIASWARN (pthread_mutexattr_init); | ||
| 863 | # endif | ||
| 864 | #elif defined GNULIB_POSIXCHECK | ||
| 865 | # undef pthread_mutexattr_init | ||
| 866 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_INIT | ||
| 867 | _GL_WARN_ON_USE (pthread_mutexattr_init, "pthread_mutexattr_init is not portable - " | ||
| 868 | "use gnulib module pthread-mutex for portability"); | ||
| 869 | # endif | ||
| 870 | #endif | ||
| 871 | |||
| 872 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 873 | # if @REPLACE_PTHREAD_MUTEXATTR_GETTYPE@ | ||
| 874 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 875 | # undef pthread_mutexattr_gettype | ||
| 876 | # define pthread_mutexattr_gettype rpl_pthread_mutexattr_gettype | ||
| 877 | # endif | ||
| 878 | _GL_FUNCDECL_RPL (pthread_mutexattr_gettype, int, | ||
| 879 | (const pthread_mutexattr_t *restrict attr, | ||
| 880 | int *restrict typep), | ||
| 881 | _GL_ARG_NONNULL ((1, 2))); | ||
| 882 | _GL_CXXALIAS_RPL (pthread_mutexattr_gettype, int, | ||
| 883 | (const pthread_mutexattr_t *restrict attr, | ||
| 884 | int *restrict typep)); | ||
| 885 | # else | ||
| 886 | # if !@HAVE_PTHREAD_MUTEXATTR_GETTYPE@ | ||
| 887 | _GL_FUNCDECL_SYS (pthread_mutexattr_gettype, int, | ||
| 888 | (const pthread_mutexattr_t *restrict attr, | ||
| 889 | int *restrict typep), | ||
| 890 | _GL_ARG_NONNULL ((1, 2))); | ||
| 891 | # endif | ||
| 892 | /* Need to cast, because on FreeBSD the first parameter is | ||
| 893 | pthread_mutexattr_t *attr. */ | ||
| 894 | _GL_CXXALIAS_SYS_CAST (pthread_mutexattr_gettype, int, | ||
| 895 | (const pthread_mutexattr_t *restrict attr, | ||
| 896 | int *restrict typep)); | ||
| 897 | # endif | ||
| 898 | # if __GLIBC__ >= 2 | ||
| 899 | _GL_CXXALIASWARN (pthread_mutexattr_gettype); | ||
| 900 | # endif | ||
| 901 | #elif defined GNULIB_POSIXCHECK | ||
| 902 | # undef pthread_mutexattr_gettype | ||
| 903 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_GETTYPE | ||
| 904 | _GL_WARN_ON_USE (pthread_mutexattr_gettype, "pthread_mutexattr_gettype is not portable - " | ||
| 905 | "use gnulib module pthread-mutex for portability"); | ||
| 906 | # endif | ||
| 907 | #endif | ||
| 908 | |||
| 909 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 910 | # if @REPLACE_PTHREAD_MUTEXATTR_SETTYPE@ | ||
| 911 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 912 | # undef pthread_mutexattr_settype | ||
| 913 | # define pthread_mutexattr_settype rpl_pthread_mutexattr_settype | ||
| 914 | # endif | ||
| 915 | _GL_FUNCDECL_RPL (pthread_mutexattr_settype, int, | ||
| 916 | (pthread_mutexattr_t *attr, int type), _GL_ARG_NONNULL ((1))); | ||
| 917 | _GL_CXXALIAS_RPL (pthread_mutexattr_settype, int, | ||
| 918 | (pthread_mutexattr_t *attr, int type)); | ||
| 919 | # else | ||
| 920 | # if !@HAVE_PTHREAD_MUTEXATTR_SETTYPE@ | ||
| 921 | _GL_FUNCDECL_SYS (pthread_mutexattr_settype, int, | ||
| 922 | (pthread_mutexattr_t *attr, int type), _GL_ARG_NONNULL ((1))); | ||
| 923 | # endif | ||
| 924 | _GL_CXXALIAS_SYS (pthread_mutexattr_settype, int, | ||
| 925 | (pthread_mutexattr_t *attr, int type)); | ||
| 926 | # endif | ||
| 927 | # if __GLIBC__ >= 2 | ||
| 928 | _GL_CXXALIASWARN (pthread_mutexattr_settype); | ||
| 929 | # endif | ||
| 930 | #elif defined GNULIB_POSIXCHECK | ||
| 931 | # undef pthread_mutexattr_settype | ||
| 932 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_SETTYPE | ||
| 933 | _GL_WARN_ON_USE (pthread_mutexattr_settype, "pthread_mutexattr_settype is not portable - " | ||
| 934 | "use gnulib module pthread-mutex for portability"); | ||
| 935 | # endif | ||
| 936 | #endif | ||
| 937 | |||
| 938 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 939 | # if @REPLACE_PTHREAD_MUTEXATTR_GETROBUST@ | ||
| 940 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 941 | # undef pthread_mutexattr_getrobust | ||
| 942 | # define pthread_mutexattr_getrobust rpl_pthread_mutexattr_getrobust | ||
| 943 | # endif | ||
| 944 | _GL_FUNCDECL_RPL (pthread_mutexattr_getrobust, int, | ||
| 945 | (const pthread_mutexattr_t *restrict attr, | ||
| 946 | int *restrict robustp), | ||
| 947 | _GL_ARG_NONNULL ((1, 2))); | ||
| 948 | _GL_CXXALIAS_RPL (pthread_mutexattr_getrobust, int, | ||
| 949 | (const pthread_mutexattr_t *restrict attr, | ||
| 950 | int *restrict robustp)); | ||
| 951 | # else | ||
| 952 | # if !@HAVE_PTHREAD_MUTEXATTR_GETROBUST@ | ||
| 953 | _GL_FUNCDECL_SYS (pthread_mutexattr_getrobust, int, | ||
| 954 | (const pthread_mutexattr_t *restrict attr, | ||
| 955 | int *restrict robustp), | ||
| 956 | _GL_ARG_NONNULL ((1, 2))); | ||
| 957 | # endif | ||
| 958 | /* Need to cast, because on FreeBSD the first parameter is | ||
| 959 | pthread_mutexattr_t *attr. */ | ||
| 960 | _GL_CXXALIAS_SYS_CAST (pthread_mutexattr_getrobust, int, | ||
| 961 | (const pthread_mutexattr_t *restrict attr, | ||
| 962 | int *restrict robustp)); | ||
| 963 | # endif | ||
| 964 | # if __GLIBC__ >= 2 | ||
| 965 | _GL_CXXALIASWARN (pthread_mutexattr_getrobust); | ||
| 966 | # endif | ||
| 967 | #elif defined GNULIB_POSIXCHECK | ||
| 968 | # undef pthread_mutexattr_getrobust | ||
| 969 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_GETROBUST | ||
| 970 | _GL_WARN_ON_USE (pthread_mutexattr_getrobust, "pthread_mutexattr_getrobust is not portable - " | ||
| 971 | "use gnulib module pthread-mutex for portability"); | ||
| 972 | # endif | ||
| 973 | #endif | ||
| 974 | |||
| 975 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 976 | # if @REPLACE_PTHREAD_MUTEXATTR_SETROBUST@ | ||
| 977 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 978 | # undef pthread_mutexattr_setrobust | ||
| 979 | # define pthread_mutexattr_setrobust rpl_pthread_mutexattr_setrobust | ||
| 980 | # endif | ||
| 981 | _GL_FUNCDECL_RPL (pthread_mutexattr_setrobust, int, | ||
| 982 | (pthread_mutexattr_t *attr, int robust), | ||
| 983 | _GL_ARG_NONNULL ((1))); | ||
| 984 | _GL_CXXALIAS_RPL (pthread_mutexattr_setrobust, int, | ||
| 985 | (pthread_mutexattr_t *attr, int robust)); | ||
| 986 | # else | ||
| 987 | # if !@HAVE_PTHREAD_MUTEXATTR_SETROBUST@ | ||
| 988 | _GL_FUNCDECL_SYS (pthread_mutexattr_setrobust, int, | ||
| 989 | (pthread_mutexattr_t *attr, int robust), | ||
| 990 | _GL_ARG_NONNULL ((1))); | ||
| 991 | # endif | ||
| 992 | _GL_CXXALIAS_SYS (pthread_mutexattr_setrobust, int, | ||
| 993 | (pthread_mutexattr_t *attr, int robust)); | ||
| 994 | # endif | ||
| 995 | # if __GLIBC__ >= 2 | ||
| 996 | _GL_CXXALIASWARN (pthread_mutexattr_setrobust); | ||
| 997 | # endif | ||
| 998 | #elif defined GNULIB_POSIXCHECK | ||
| 999 | # undef pthread_mutexattr_setrobust | ||
| 1000 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_SETROBUST | ||
| 1001 | _GL_WARN_ON_USE (pthread_mutexattr_setrobust, "pthread_mutexattr_setrobust is not portable - " | ||
| 1002 | "use gnulib module pthread-mutex for portability"); | ||
| 1003 | # endif | ||
| 1004 | #endif | ||
| 1005 | |||
| 1006 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 1007 | # if @REPLACE_PTHREAD_MUTEXATTR_DESTROY@ | ||
| 1008 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1009 | # undef pthread_mutexattr_destroy | ||
| 1010 | # define pthread_mutexattr_destroy rpl_pthread_mutexattr_destroy | ||
| 1011 | # endif | ||
| 1012 | _GL_FUNCDECL_RPL (pthread_mutexattr_destroy, int, (pthread_mutexattr_t *attr), | ||
| 1013 | _GL_ARG_NONNULL ((1))); | ||
| 1014 | _GL_CXXALIAS_RPL (pthread_mutexattr_destroy, int, (pthread_mutexattr_t *attr)); | ||
| 1015 | # else | ||
| 1016 | # if !@HAVE_PTHREAD_MUTEXATTR_DESTROY@ | ||
| 1017 | _GL_FUNCDECL_SYS (pthread_mutexattr_destroy, int, (pthread_mutexattr_t *attr), | ||
| 1018 | _GL_ARG_NONNULL ((1))); | ||
| 1019 | # endif | ||
| 1020 | _GL_CXXALIAS_SYS (pthread_mutexattr_destroy, int, (pthread_mutexattr_t *attr)); | ||
| 1021 | # endif | ||
| 1022 | # if __GLIBC__ >= 2 | ||
| 1023 | _GL_CXXALIASWARN (pthread_mutexattr_destroy); | ||
| 1024 | # endif | ||
| 1025 | #elif defined GNULIB_POSIXCHECK | ||
| 1026 | # undef pthread_mutexattr_destroy | ||
| 1027 | # if HAVE_RAW_DECL_PTHREAD_MUTEXATTR_DESTROY | ||
| 1028 | _GL_WARN_ON_USE (pthread_mutexattr_destroy, "pthread_mutexattr_destroy is not portable - " | ||
| 1029 | "use gnulib module pthread-mutex for portability"); | ||
| 1030 | # endif | ||
| 1031 | #endif | ||
| 1032 | |||
| 1033 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 1034 | # if @REPLACE_PTHREAD_MUTEX_LOCK@ | ||
| 1035 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1036 | # undef pthread_mutex_lock | ||
| 1037 | # define pthread_mutex_lock rpl_pthread_mutex_lock | ||
| 1038 | # endif | ||
| 1039 | _GL_FUNCDECL_RPL (pthread_mutex_lock, int, (pthread_mutex_t *mutex), | ||
| 1040 | _GL_ARG_NONNULL ((1))); | ||
| 1041 | _GL_CXXALIAS_RPL (pthread_mutex_lock, int, (pthread_mutex_t *mutex)); | ||
| 1042 | # else | ||
| 1043 | # if !@HAVE_PTHREAD_MUTEX_LOCK@ | ||
| 1044 | _GL_FUNCDECL_SYS (pthread_mutex_lock, int, (pthread_mutex_t *mutex), | ||
| 1045 | _GL_ARG_NONNULL ((1))); | ||
| 1046 | # endif | ||
| 1047 | _GL_CXXALIAS_SYS (pthread_mutex_lock, int, (pthread_mutex_t *mutex)); | ||
| 1048 | # endif | ||
| 1049 | # if __GLIBC__ >= 2 | ||
| 1050 | _GL_CXXALIASWARN (pthread_mutex_lock); | ||
| 1051 | # endif | ||
| 1052 | #elif defined GNULIB_POSIXCHECK | ||
| 1053 | # undef pthread_mutex_lock | ||
| 1054 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_LOCK | ||
| 1055 | _GL_WARN_ON_USE (pthread_mutex_lock, "pthread_mutex_lock is not portable - " | ||
| 1056 | "use gnulib module pthread-mutex for portability"); | ||
| 1057 | # endif | ||
| 1058 | #endif | ||
| 1059 | |||
| 1060 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 1061 | # if @REPLACE_PTHREAD_MUTEX_TRYLOCK@ | ||
| 1062 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1063 | # undef pthread_mutex_trylock | ||
| 1064 | # define pthread_mutex_trylock rpl_pthread_mutex_trylock | ||
| 1065 | # endif | ||
| 1066 | _GL_FUNCDECL_RPL (pthread_mutex_trylock, int, (pthread_mutex_t *mutex), | ||
| 1067 | _GL_ARG_NONNULL ((1))); | ||
| 1068 | _GL_CXXALIAS_RPL (pthread_mutex_trylock, int, (pthread_mutex_t *mutex)); | ||
| 1069 | # else | ||
| 1070 | # if !@HAVE_PTHREAD_MUTEX_TRYLOCK@ | ||
| 1071 | _GL_FUNCDECL_SYS (pthread_mutex_trylock, int, (pthread_mutex_t *mutex), | ||
| 1072 | _GL_ARG_NONNULL ((1))); | ||
| 1073 | # endif | ||
| 1074 | _GL_CXXALIAS_SYS (pthread_mutex_trylock, int, (pthread_mutex_t *mutex)); | ||
| 1075 | # endif | ||
| 1076 | # if __GLIBC__ >= 2 | ||
| 1077 | _GL_CXXALIASWARN (pthread_mutex_trylock); | ||
| 1078 | # endif | ||
| 1079 | #elif defined GNULIB_POSIXCHECK | ||
| 1080 | # undef pthread_mutex_trylock | ||
| 1081 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_TRYLOCK | ||
| 1082 | _GL_WARN_ON_USE (pthread_mutex_trylock, "pthread_mutex_trylock is not portable - " | ||
| 1083 | "use gnulib module pthread-mutex for portability"); | ||
| 1084 | # endif | ||
| 1085 | #endif | ||
| 1086 | |||
| 1087 | #if @GNULIB_PTHREAD_MUTEX_TIMEDLOCK@ | ||
| 1088 | # if @REPLACE_PTHREAD_MUTEX_TIMEDLOCK@ | ||
| 1089 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1090 | # undef pthread_mutex_timedlock | ||
| 1091 | # define pthread_mutex_timedlock rpl_pthread_mutex_timedlock | ||
| 1092 | # endif | ||
| 1093 | _GL_FUNCDECL_RPL (pthread_mutex_timedlock, int, | ||
| 1094 | (pthread_mutex_t *restrict mutex, | ||
| 1095 | const struct timespec *restrict abstime), | ||
| 1096 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1097 | _GL_CXXALIAS_RPL (pthread_mutex_timedlock, int, | ||
| 1098 | (pthread_mutex_t *restrict mutex, | ||
| 1099 | const struct timespec *restrict abstime)); | ||
| 1100 | # else | ||
| 1101 | # if !@HAVE_PTHREAD_MUTEX_TIMEDLOCK@ | ||
| 1102 | _GL_FUNCDECL_SYS (pthread_mutex_timedlock, int, | ||
| 1103 | (pthread_mutex_t *restrict mutex, | ||
| 1104 | const struct timespec *restrict abstime), | ||
| 1105 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1106 | # endif | ||
| 1107 | _GL_CXXALIAS_SYS (pthread_mutex_timedlock, int, | ||
| 1108 | (pthread_mutex_t *restrict mutex, | ||
| 1109 | const struct timespec *restrict abstime)); | ||
| 1110 | # endif | ||
| 1111 | # if __GLIBC__ >= 2 | ||
| 1112 | _GL_CXXALIASWARN (pthread_mutex_timedlock); | ||
| 1113 | # endif | ||
| 1114 | #elif defined GNULIB_POSIXCHECK | ||
| 1115 | # undef pthread_mutex_timedlock | ||
| 1116 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_TIMEDLOCK | ||
| 1117 | _GL_WARN_ON_USE (pthread_mutex_timedlock, "pthread_mutex_timedlock is not portable - " | ||
| 1118 | "use gnulib module pthread_mutex_timedlock for portability"); | ||
| 1119 | # endif | ||
| 1120 | #endif | ||
| 1121 | |||
| 1122 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 1123 | # if @REPLACE_PTHREAD_MUTEX_UNLOCK@ | ||
| 1124 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1125 | # undef pthread_mutex_unlock | ||
| 1126 | # define pthread_mutex_unlock rpl_pthread_mutex_unlock | ||
| 1127 | # endif | ||
| 1128 | _GL_FUNCDECL_RPL (pthread_mutex_unlock, int, (pthread_mutex_t *mutex), | ||
| 1129 | _GL_ARG_NONNULL ((1))); | ||
| 1130 | _GL_CXXALIAS_RPL (pthread_mutex_unlock, int, (pthread_mutex_t *mutex)); | ||
| 1131 | # else | ||
| 1132 | # if !@HAVE_PTHREAD_MUTEX_UNLOCK@ | ||
| 1133 | _GL_FUNCDECL_SYS (pthread_mutex_unlock, int, (pthread_mutex_t *mutex), | ||
| 1134 | _GL_ARG_NONNULL ((1))); | ||
| 1135 | # endif | ||
| 1136 | _GL_CXXALIAS_SYS (pthread_mutex_unlock, int, (pthread_mutex_t *mutex)); | ||
| 1137 | # endif | ||
| 1138 | # if __GLIBC__ >= 2 | ||
| 1139 | _GL_CXXALIASWARN (pthread_mutex_unlock); | ||
| 1140 | # endif | ||
| 1141 | #elif defined GNULIB_POSIXCHECK | ||
| 1142 | # undef pthread_mutex_unlock | ||
| 1143 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_UNLOCK | ||
| 1144 | _GL_WARN_ON_USE (pthread_mutex_unlock, "pthread_mutex_unlock is not portable - " | ||
| 1145 | "use gnulib module pthread-mutex for portability"); | ||
| 1146 | # endif | ||
| 1147 | #endif | ||
| 1148 | |||
| 1149 | #if @GNULIB_PTHREAD_MUTEX@ | ||
| 1150 | # if @REPLACE_PTHREAD_MUTEX_DESTROY@ | ||
| 1151 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1152 | # undef pthread_mutex_destroy | ||
| 1153 | # define pthread_mutex_destroy rpl_pthread_mutex_destroy | ||
| 1154 | # endif | ||
| 1155 | _GL_FUNCDECL_RPL (pthread_mutex_destroy, int, (pthread_mutex_t *mutex), | ||
| 1156 | _GL_ARG_NONNULL ((1))); | ||
| 1157 | _GL_CXXALIAS_RPL (pthread_mutex_destroy, int, (pthread_mutex_t *mutex)); | ||
| 1158 | # else | ||
| 1159 | # if !@HAVE_PTHREAD_MUTEX_DESTROY@ | ||
| 1160 | _GL_FUNCDECL_SYS (pthread_mutex_destroy, int, (pthread_mutex_t *mutex), | ||
| 1161 | _GL_ARG_NONNULL ((1))); | ||
| 1162 | # endif | ||
| 1163 | _GL_CXXALIAS_SYS (pthread_mutex_destroy, int, (pthread_mutex_t *mutex)); | ||
| 1164 | # endif | ||
| 1165 | # if __GLIBC__ >= 2 | ||
| 1166 | _GL_CXXALIASWARN (pthread_mutex_destroy); | ||
| 1167 | # endif | ||
| 1168 | #elif defined GNULIB_POSIXCHECK | ||
| 1169 | # undef pthread_mutex_destroy | ||
| 1170 | # if HAVE_RAW_DECL_PTHREAD_MUTEX_DESTROY | ||
| 1171 | _GL_WARN_ON_USE (pthread_mutex_destroy, "pthread_mutex_destroy is not portable - " | ||
| 1172 | "use gnulib module pthread-mutex for portability"); | ||
| 1173 | # endif | ||
| 1174 | #endif | ||
| 1175 | |||
| 1176 | /* =========== Read-write lock functions =========== */ | ||
| 1177 | |||
| 1178 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1179 | # if @REPLACE_PTHREAD_RWLOCK_INIT@ | ||
| 1180 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1181 | # undef pthread_rwlock_init | ||
| 1182 | # define pthread_rwlock_init rpl_pthread_rwlock_init | ||
| 1183 | # endif | ||
| 1184 | _GL_FUNCDECL_RPL (pthread_rwlock_init, int, | ||
| 1185 | (pthread_rwlock_t *restrict lock, | ||
| 1186 | const pthread_rwlockattr_t *restrict attr), | ||
| 1187 | _GL_ARG_NONNULL ((1))); | ||
| 1188 | _GL_CXXALIAS_RPL (pthread_rwlock_init, int, | ||
| 1189 | (pthread_rwlock_t *restrict lock, | ||
| 1190 | const pthread_rwlockattr_t *restrict attr)); | ||
| 1191 | # else | ||
| 1192 | # if !@HAVE_PTHREAD_RWLOCK_INIT@ | ||
| 1193 | _GL_FUNCDECL_SYS (pthread_rwlock_init, int, | ||
| 1194 | (pthread_rwlock_t *restrict lock, | ||
| 1195 | const pthread_rwlockattr_t *restrict attr), | ||
| 1196 | _GL_ARG_NONNULL ((1))); | ||
| 1197 | # endif | ||
| 1198 | _GL_CXXALIAS_SYS (pthread_rwlock_init, int, | ||
| 1199 | (pthread_rwlock_t *restrict lock, | ||
| 1200 | const pthread_rwlockattr_t *restrict attr)); | ||
| 1201 | # endif | ||
| 1202 | # if __GLIBC__ >= 2 | ||
| 1203 | _GL_CXXALIASWARN (pthread_rwlock_init); | ||
| 1204 | # endif | ||
| 1205 | #elif defined GNULIB_POSIXCHECK | ||
| 1206 | # undef pthread_rwlock_init | ||
| 1207 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_INIT | ||
| 1208 | _GL_WARN_ON_USE (pthread_rwlock_init, "pthread_rwlock_init is not portable - " | ||
| 1209 | "use gnulib module pthread-rwlock for portability"); | ||
| 1210 | # endif | ||
| 1211 | #endif | ||
| 1212 | |||
| 1213 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1214 | # if @REPLACE_PTHREAD_RWLOCKATTR_INIT@ | ||
| 1215 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1216 | # undef pthread_rwlockattr_init | ||
| 1217 | # define pthread_rwlockattr_init rpl_pthread_rwlockattr_init | ||
| 1218 | # endif | ||
| 1219 | _GL_FUNCDECL_RPL (pthread_rwlockattr_init, int, (pthread_rwlockattr_t *attr), | ||
| 1220 | _GL_ARG_NONNULL ((1))); | ||
| 1221 | _GL_CXXALIAS_RPL (pthread_rwlockattr_init, int, (pthread_rwlockattr_t *attr)); | ||
| 1222 | # else | ||
| 1223 | # if !@HAVE_PTHREAD_RWLOCKATTR_INIT@ | ||
| 1224 | _GL_FUNCDECL_SYS (pthread_rwlockattr_init, int, (pthread_rwlockattr_t *attr), | ||
| 1225 | _GL_ARG_NONNULL ((1))); | ||
| 1226 | # endif | ||
| 1227 | _GL_CXXALIAS_SYS (pthread_rwlockattr_init, int, (pthread_rwlockattr_t *attr)); | ||
| 1228 | # endif | ||
| 1229 | # if __GLIBC__ >= 2 | ||
| 1230 | _GL_CXXALIASWARN (pthread_rwlockattr_init); | ||
| 1231 | # endif | ||
| 1232 | #elif defined GNULIB_POSIXCHECK | ||
| 1233 | # undef pthread_rwlockattr_init | ||
| 1234 | # if HAVE_RAW_DECL_PTHREAD_RWLOCKATTR_INIT | ||
| 1235 | _GL_WARN_ON_USE (pthread_rwlockattr_init, "pthread_rwlockattr_init is not portable - " | ||
| 1236 | "use gnulib module pthread-rwlock for portability"); | ||
| 1237 | # endif | ||
| 1238 | #endif | ||
| 1239 | |||
| 1240 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1241 | # if @REPLACE_PTHREAD_RWLOCKATTR_DESTROY@ | ||
| 1242 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1243 | # undef pthread_rwlockattr_destroy | ||
| 1244 | # define pthread_rwlockattr_destroy rpl_pthread_rwlockattr_destroy | ||
| 1245 | # endif | ||
| 1246 | _GL_FUNCDECL_RPL (pthread_rwlockattr_destroy, int, | ||
| 1247 | (pthread_rwlockattr_t *attr), _GL_ARG_NONNULL ((1))); | ||
| 1248 | _GL_CXXALIAS_RPL (pthread_rwlockattr_destroy, int, | ||
| 1249 | (pthread_rwlockattr_t *attr)); | ||
| 1250 | # else | ||
| 1251 | # if !@HAVE_PTHREAD_RWLOCKATTR_DESTROY@ | ||
| 1252 | _GL_FUNCDECL_SYS (pthread_rwlockattr_destroy, int, | ||
| 1253 | (pthread_rwlockattr_t *attr), _GL_ARG_NONNULL ((1))); | ||
| 1254 | # endif | ||
| 1255 | _GL_CXXALIAS_SYS (pthread_rwlockattr_destroy, int, | ||
| 1256 | (pthread_rwlockattr_t *attr)); | ||
| 1257 | # endif | ||
| 1258 | # if __GLIBC__ >= 2 | ||
| 1259 | _GL_CXXALIASWARN (pthread_rwlockattr_destroy); | ||
| 1260 | # endif | ||
| 1261 | #elif defined GNULIB_POSIXCHECK | ||
| 1262 | # undef pthread_rwlockattr_destroy | ||
| 1263 | # if HAVE_RAW_DECL_PTHREAD_RWLOCKATTR_DESTROY | ||
| 1264 | _GL_WARN_ON_USE (pthread_rwlockattr_destroy, "pthread_rwlockattr_destroy is not portable - " | ||
| 1265 | "use gnulib module pthread-rwlock for portability"); | ||
| 1266 | # endif | ||
| 1267 | #endif | ||
| 1268 | |||
| 1269 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1270 | # if @REPLACE_PTHREAD_RWLOCK_RDLOCK@ | ||
| 1271 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1272 | # undef pthread_rwlock_rdlock | ||
| 1273 | # define pthread_rwlock_rdlock rpl_pthread_rwlock_rdlock | ||
| 1274 | # endif | ||
| 1275 | _GL_FUNCDECL_RPL (pthread_rwlock_rdlock, int, (pthread_rwlock_t *lock), | ||
| 1276 | _GL_ARG_NONNULL ((1))); | ||
| 1277 | _GL_CXXALIAS_RPL (pthread_rwlock_rdlock, int, (pthread_rwlock_t *lock)); | ||
| 1278 | # else | ||
| 1279 | # if !@HAVE_PTHREAD_RWLOCK_RDLOCK@ | ||
| 1280 | _GL_FUNCDECL_SYS (pthread_rwlock_rdlock, int, (pthread_rwlock_t *lock), | ||
| 1281 | _GL_ARG_NONNULL ((1))); | ||
| 1282 | # endif | ||
| 1283 | _GL_CXXALIAS_SYS (pthread_rwlock_rdlock, int, (pthread_rwlock_t *lock)); | ||
| 1284 | # endif | ||
| 1285 | # if __GLIBC__ >= 2 | ||
| 1286 | _GL_CXXALIASWARN (pthread_rwlock_rdlock); | ||
| 1287 | # endif | ||
| 1288 | #elif defined GNULIB_POSIXCHECK | ||
| 1289 | # undef pthread_rwlock_rdlock | ||
| 1290 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_RDLOCK | ||
| 1291 | _GL_WARN_ON_USE (pthread_rwlock_rdlock, "pthread_rwlock_rdlock is not portable - " | ||
| 1292 | "use gnulib module pthread-rwlock for portability"); | ||
| 1293 | # endif | ||
| 1294 | #endif | ||
| 1295 | |||
| 1296 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1297 | # if @REPLACE_PTHREAD_RWLOCK_WRLOCK@ | ||
| 1298 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1299 | # undef pthread_rwlock_wrlock | ||
| 1300 | # define pthread_rwlock_wrlock rpl_pthread_rwlock_wrlock | ||
| 1301 | # endif | ||
| 1302 | _GL_FUNCDECL_RPL (pthread_rwlock_wrlock, int, (pthread_rwlock_t *lock), | ||
| 1303 | _GL_ARG_NONNULL ((1))); | ||
| 1304 | _GL_CXXALIAS_RPL (pthread_rwlock_wrlock, int, (pthread_rwlock_t *lock)); | ||
| 1305 | # else | ||
| 1306 | # if !@HAVE_PTHREAD_RWLOCK_WRLOCK@ | ||
| 1307 | _GL_FUNCDECL_SYS (pthread_rwlock_wrlock, int, (pthread_rwlock_t *lock), | ||
| 1308 | _GL_ARG_NONNULL ((1))); | ||
| 1309 | # endif | ||
| 1310 | _GL_CXXALIAS_SYS (pthread_rwlock_wrlock, int, (pthread_rwlock_t *lock)); | ||
| 1311 | # endif | ||
| 1312 | # if __GLIBC__ >= 2 | ||
| 1313 | _GL_CXXALIASWARN (pthread_rwlock_wrlock); | ||
| 1314 | # endif | ||
| 1315 | #elif defined GNULIB_POSIXCHECK | ||
| 1316 | # undef pthread_rwlock_wrlock | ||
| 1317 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_WRLOCK | ||
| 1318 | _GL_WARN_ON_USE (pthread_rwlock_wrlock, "pthread_rwlock_wrlock is not portable - " | ||
| 1319 | "use gnulib module pthread-rwlock for portability"); | ||
| 1320 | # endif | ||
| 1321 | #endif | ||
| 1322 | |||
| 1323 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1324 | # if @REPLACE_PTHREAD_RWLOCK_TRYRDLOCK@ | ||
| 1325 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1326 | # undef pthread_rwlock_tryrdlock | ||
| 1327 | # define pthread_rwlock_tryrdlock rpl_pthread_rwlock_tryrdlock | ||
| 1328 | # endif | ||
| 1329 | _GL_FUNCDECL_RPL (pthread_rwlock_tryrdlock, int, (pthread_rwlock_t *lock), | ||
| 1330 | _GL_ARG_NONNULL ((1))); | ||
| 1331 | _GL_CXXALIAS_RPL (pthread_rwlock_tryrdlock, int, (pthread_rwlock_t *lock)); | ||
| 1332 | # else | ||
| 1333 | # if !@HAVE_PTHREAD_RWLOCK_TRYRDLOCK@ | ||
| 1334 | _GL_FUNCDECL_SYS (pthread_rwlock_tryrdlock, int, (pthread_rwlock_t *lock), | ||
| 1335 | _GL_ARG_NONNULL ((1))); | ||
| 1336 | # endif | ||
| 1337 | _GL_CXXALIAS_SYS (pthread_rwlock_tryrdlock, int, (pthread_rwlock_t *lock)); | ||
| 1338 | # endif | ||
| 1339 | # if __GLIBC__ >= 2 | ||
| 1340 | _GL_CXXALIASWARN (pthread_rwlock_tryrdlock); | ||
| 1341 | # endif | ||
| 1342 | #elif defined GNULIB_POSIXCHECK | ||
| 1343 | # undef pthread_rwlock_tryrdlock | ||
| 1344 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_TRYRDLOCK | ||
| 1345 | _GL_WARN_ON_USE (pthread_rwlock_tryrdlock, "pthread_rwlock_tryrdlock is not portable - " | ||
| 1346 | "use gnulib module pthread-rwlock for portability"); | ||
| 1347 | # endif | ||
| 1348 | #endif | ||
| 1349 | |||
| 1350 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1351 | # if @REPLACE_PTHREAD_RWLOCK_TRYWRLOCK@ | ||
| 1352 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1353 | # undef pthread_rwlock_trywrlock | ||
| 1354 | # define pthread_rwlock_trywrlock rpl_pthread_rwlock_trywrlock | ||
| 1355 | # endif | ||
| 1356 | _GL_FUNCDECL_RPL (pthread_rwlock_trywrlock, int, (pthread_rwlock_t *lock), | ||
| 1357 | _GL_ARG_NONNULL ((1))); | ||
| 1358 | _GL_CXXALIAS_RPL (pthread_rwlock_trywrlock, int, (pthread_rwlock_t *lock)); | ||
| 1359 | # else | ||
| 1360 | # if !@HAVE_PTHREAD_RWLOCK_TRYWRLOCK@ | ||
| 1361 | _GL_FUNCDECL_SYS (pthread_rwlock_trywrlock, int, (pthread_rwlock_t *lock), | ||
| 1362 | _GL_ARG_NONNULL ((1))); | ||
| 1363 | # endif | ||
| 1364 | _GL_CXXALIAS_SYS (pthread_rwlock_trywrlock, int, (pthread_rwlock_t *lock)); | ||
| 1365 | # endif | ||
| 1366 | # if __GLIBC__ >= 2 | ||
| 1367 | _GL_CXXALIASWARN (pthread_rwlock_trywrlock); | ||
| 1368 | # endif | ||
| 1369 | #elif defined GNULIB_POSIXCHECK | ||
| 1370 | # undef pthread_rwlock_trywrlock | ||
| 1371 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_TRYWRLOCK | ||
| 1372 | _GL_WARN_ON_USE (pthread_rwlock_trywrlock, "pthread_rwlock_trywrlock is not portable - " | ||
| 1373 | "use gnulib module pthread-rwlock for portability"); | ||
| 1374 | # endif | ||
| 1375 | #endif | ||
| 1376 | |||
| 1377 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1378 | # if @REPLACE_PTHREAD_RWLOCK_TIMEDRDLOCK@ | ||
| 1379 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1380 | # undef pthread_rwlock_timedrdlock | ||
| 1381 | # define pthread_rwlock_timedrdlock rpl_pthread_rwlock_timedrdlock | ||
| 1382 | # endif | ||
| 1383 | _GL_FUNCDECL_RPL (pthread_rwlock_timedrdlock, int, | ||
| 1384 | (pthread_rwlock_t *restrict lock, | ||
| 1385 | const struct timespec *restrict abstime), | ||
| 1386 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1387 | _GL_CXXALIAS_RPL (pthread_rwlock_timedrdlock, int, | ||
| 1388 | (pthread_rwlock_t *restrict lock, | ||
| 1389 | const struct timespec *restrict abstime)); | ||
| 1390 | # else | ||
| 1391 | # if !@HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK@ | ||
| 1392 | _GL_FUNCDECL_SYS (pthread_rwlock_timedrdlock, int, | ||
| 1393 | (pthread_rwlock_t *restrict lock, | ||
| 1394 | const struct timespec *restrict abstime), | ||
| 1395 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1396 | # endif | ||
| 1397 | _GL_CXXALIAS_SYS (pthread_rwlock_timedrdlock, int, | ||
| 1398 | (pthread_rwlock_t *restrict lock, | ||
| 1399 | const struct timespec *restrict abstime)); | ||
| 1400 | # endif | ||
| 1401 | # if __GLIBC__ >= 2 | ||
| 1402 | _GL_CXXALIASWARN (pthread_rwlock_timedrdlock); | ||
| 1403 | # endif | ||
| 1404 | #elif defined GNULIB_POSIXCHECK | ||
| 1405 | # undef pthread_rwlock_timedrdlock | ||
| 1406 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_TIMEDRDLOCK | ||
| 1407 | _GL_WARN_ON_USE (pthread_rwlock_timedrdlock, "pthread_rwlock_timedrdlock is not portable - " | ||
| 1408 | "use gnulib module pthread-rwlock for portability"); | ||
| 1409 | # endif | ||
| 1410 | #endif | ||
| 1411 | |||
| 1412 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1413 | # if @REPLACE_PTHREAD_RWLOCK_TIMEDWRLOCK@ | ||
| 1414 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1415 | # undef pthread_rwlock_timedwrlock | ||
| 1416 | # define pthread_rwlock_timedwrlock rpl_pthread_rwlock_timedwrlock | ||
| 1417 | # endif | ||
| 1418 | _GL_FUNCDECL_RPL (pthread_rwlock_timedwrlock, int, | ||
| 1419 | (pthread_rwlock_t *restrict lock, | ||
| 1420 | const struct timespec *restrict abstime), | ||
| 1421 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1422 | _GL_CXXALIAS_RPL (pthread_rwlock_timedwrlock, int, | ||
| 1423 | (pthread_rwlock_t *restrict lock, | ||
| 1424 | const struct timespec *restrict abstime)); | ||
| 1425 | # else | ||
| 1426 | # if !@HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK@ | ||
| 1427 | _GL_FUNCDECL_SYS (pthread_rwlock_timedwrlock, int, | ||
| 1428 | (pthread_rwlock_t *restrict lock, | ||
| 1429 | const struct timespec *restrict abstime), | ||
| 1430 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1431 | # endif | ||
| 1432 | _GL_CXXALIAS_SYS (pthread_rwlock_timedwrlock, int, | ||
| 1433 | (pthread_rwlock_t *restrict lock, | ||
| 1434 | const struct timespec *restrict abstime)); | ||
| 1435 | # endif | ||
| 1436 | # if __GLIBC__ >= 2 | ||
| 1437 | _GL_CXXALIASWARN (pthread_rwlock_timedwrlock); | ||
| 1438 | # endif | ||
| 1439 | #elif defined GNULIB_POSIXCHECK | ||
| 1440 | # undef pthread_rwlock_timedwrlock | ||
| 1441 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_TIMEDWRLOCK | ||
| 1442 | _GL_WARN_ON_USE (pthread_rwlock_timedwrlock, "pthread_rwlock_timedwrlock is not portable - " | ||
| 1443 | "use gnulib module pthread-rwlock for portability"); | ||
| 1444 | # endif | ||
| 1445 | #endif | ||
| 1446 | |||
| 1447 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1448 | # if @REPLACE_PTHREAD_RWLOCK_UNLOCK@ | ||
| 1449 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1450 | # undef pthread_rwlock_unlock | ||
| 1451 | # define pthread_rwlock_unlock rpl_pthread_rwlock_unlock | ||
| 1452 | # endif | ||
| 1453 | _GL_FUNCDECL_RPL (pthread_rwlock_unlock, int, (pthread_rwlock_t *lock), | ||
| 1454 | _GL_ARG_NONNULL ((1))); | ||
| 1455 | _GL_CXXALIAS_RPL (pthread_rwlock_unlock, int, (pthread_rwlock_t *lock)); | ||
| 1456 | # else | ||
| 1457 | # if !@HAVE_PTHREAD_RWLOCK_UNLOCK@ | ||
| 1458 | _GL_FUNCDECL_SYS (pthread_rwlock_unlock, int, (pthread_rwlock_t *lock), | ||
| 1459 | _GL_ARG_NONNULL ((1))); | ||
| 1460 | # endif | ||
| 1461 | _GL_CXXALIAS_SYS (pthread_rwlock_unlock, int, (pthread_rwlock_t *lock)); | ||
| 1462 | # endif | ||
| 1463 | # if __GLIBC__ >= 2 | ||
| 1464 | _GL_CXXALIASWARN (pthread_rwlock_unlock); | ||
| 1465 | # endif | ||
| 1466 | #elif defined GNULIB_POSIXCHECK | ||
| 1467 | # undef pthread_rwlock_unlock | ||
| 1468 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_UNLOCK | ||
| 1469 | _GL_WARN_ON_USE (pthread_rwlock_unlock, "pthread_rwlock_unlock is not portable - " | ||
| 1470 | "use gnulib module pthread-rwlock for portability"); | ||
| 1471 | # endif | ||
| 1472 | #endif | ||
| 1473 | |||
| 1474 | #if @GNULIB_PTHREAD_RWLOCK@ | ||
| 1475 | # if @REPLACE_PTHREAD_RWLOCK_DESTROY@ | ||
| 1476 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1477 | # undef pthread_rwlock_destroy | ||
| 1478 | # define pthread_rwlock_destroy rpl_pthread_rwlock_destroy | ||
| 1479 | # endif | ||
| 1480 | _GL_FUNCDECL_RPL (pthread_rwlock_destroy, int, (pthread_rwlock_t *lock), | ||
| 1481 | _GL_ARG_NONNULL ((1))); | ||
| 1482 | _GL_CXXALIAS_RPL (pthread_rwlock_destroy, int, (pthread_rwlock_t *lock)); | ||
| 1483 | # else | ||
| 1484 | # if !@HAVE_PTHREAD_RWLOCK_DESTROY@ | ||
| 1485 | _GL_FUNCDECL_SYS (pthread_rwlock_destroy, int, (pthread_rwlock_t *lock), | ||
| 1486 | _GL_ARG_NONNULL ((1))); | ||
| 1487 | # endif | ||
| 1488 | _GL_CXXALIAS_SYS (pthread_rwlock_destroy, int, (pthread_rwlock_t *lock)); | ||
| 1489 | # endif | ||
| 1490 | # if __GLIBC__ >= 2 | ||
| 1491 | _GL_CXXALIASWARN (pthread_rwlock_destroy); | ||
| 1492 | # endif | ||
| 1493 | #elif defined GNULIB_POSIXCHECK | ||
| 1494 | # undef pthread_rwlock_destroy | ||
| 1495 | # if HAVE_RAW_DECL_PTHREAD_RWLOCK_DESTROY | ||
| 1496 | _GL_WARN_ON_USE (pthread_rwlock_destroy, "pthread_rwlock_destroy is not portable - " | ||
| 1497 | "use gnulib module pthread-rwlock for portability"); | ||
| 1498 | # endif | ||
| 1499 | #endif | ||
| 1500 | |||
| 1501 | /* =========== Condition variable functions =========== */ | ||
| 1502 | |||
| 1503 | #if @GNULIB_PTHREAD_COND@ | ||
| 1504 | # if @REPLACE_PTHREAD_COND_INIT@ | ||
| 1505 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1506 | # undef pthread_cond_init | ||
| 1507 | # define pthread_cond_init rpl_pthread_cond_init | ||
| 1508 | # endif | ||
| 1509 | _GL_FUNCDECL_RPL (pthread_cond_init, int, | ||
| 1510 | (pthread_cond_t *restrict cond, | ||
| 1511 | const pthread_condattr_t *restrict attr), | ||
| 1512 | _GL_ARG_NONNULL ((1))); | ||
| 1513 | _GL_CXXALIAS_RPL (pthread_cond_init, int, | ||
| 1514 | (pthread_cond_t *restrict cond, | ||
| 1515 | const pthread_condattr_t *restrict attr)); | ||
| 1516 | # else | ||
| 1517 | # if !@HAVE_PTHREAD_COND_INIT@ | ||
| 1518 | _GL_FUNCDECL_SYS (pthread_cond_init, int, | ||
| 1519 | (pthread_cond_t *restrict cond, | ||
| 1520 | const pthread_condattr_t *restrict attr), | ||
| 1521 | _GL_ARG_NONNULL ((1))); | ||
| 1522 | # endif | ||
| 1523 | _GL_CXXALIAS_SYS (pthread_cond_init, int, | ||
| 1524 | (pthread_cond_t *restrict cond, | ||
| 1525 | const pthread_condattr_t *restrict attr)); | ||
| 1526 | # endif | ||
| 1527 | # if __GLIBC__ >= 2 | ||
| 1528 | _GL_CXXALIASWARN (pthread_cond_init); | ||
| 1529 | # endif | ||
| 1530 | #elif defined GNULIB_POSIXCHECK | ||
| 1531 | # undef pthread_cond_init | ||
| 1532 | # if HAVE_RAW_DECL_PTHREAD_COND_INIT | ||
| 1533 | _GL_WARN_ON_USE (pthread_cond_init, "pthread_cond_init is not portable - " | ||
| 1534 | "use gnulib module pthread-cond for portability"); | ||
| 1535 | # endif | ||
| 1536 | #endif | ||
| 1537 | |||
| 1538 | #if @GNULIB_PTHREAD_COND@ | ||
| 1539 | # if @REPLACE_PTHREAD_CONDATTR_INIT@ | ||
| 1540 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1541 | # undef pthread_condattr_init | ||
| 1542 | # define pthread_condattr_init rpl_pthread_condattr_init | ||
| 1543 | # endif | ||
| 1544 | _GL_FUNCDECL_RPL (pthread_condattr_init, int, (pthread_condattr_t *attr), | ||
| 1545 | _GL_ARG_NONNULL ((1))); | ||
| 1546 | _GL_CXXALIAS_RPL (pthread_condattr_init, int, (pthread_condattr_t *attr)); | ||
| 1547 | # else | ||
| 1548 | # if !@HAVE_PTHREAD_CONDATTR_INIT@ | ||
| 1549 | _GL_FUNCDECL_SYS (pthread_condattr_init, int, (pthread_condattr_t *attr), | ||
| 1550 | _GL_ARG_NONNULL ((1))); | ||
| 1551 | # endif | ||
| 1552 | _GL_CXXALIAS_SYS (pthread_condattr_init, int, (pthread_condattr_t *attr)); | ||
| 1553 | # endif | ||
| 1554 | # if __GLIBC__ >= 2 | ||
| 1555 | _GL_CXXALIASWARN (pthread_condattr_init); | ||
| 1556 | # endif | ||
| 1557 | #elif defined GNULIB_POSIXCHECK | ||
| 1558 | # undef pthread_condattr_init | ||
| 1559 | # if HAVE_RAW_DECL_PTHREAD_CONDATTR_INIT | ||
| 1560 | _GL_WARN_ON_USE (pthread_condattr_init, "pthread_condattr_init is not portable - " | ||
| 1561 | "use gnulib module pthread-cond for portability"); | ||
| 1562 | # endif | ||
| 1563 | #endif | ||
| 1564 | |||
| 1565 | #if @GNULIB_PTHREAD_COND@ | ||
| 1566 | # if @REPLACE_PTHREAD_CONDATTR_DESTROY@ | ||
| 1567 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1568 | # undef pthread_condattr_destroy | ||
| 1569 | # define pthread_condattr_destroy rpl_pthread_condattr_destroy | ||
| 1570 | # endif | ||
| 1571 | _GL_FUNCDECL_RPL (pthread_condattr_destroy, int, (pthread_condattr_t *attr), | ||
| 1572 | _GL_ARG_NONNULL ((1))); | ||
| 1573 | _GL_CXXALIAS_RPL (pthread_condattr_destroy, int, (pthread_condattr_t *attr)); | ||
| 1574 | # else | ||
| 1575 | # if !@HAVE_PTHREAD_CONDATTR_DESTROY@ | ||
| 1576 | _GL_FUNCDECL_SYS (pthread_condattr_destroy, int, (pthread_condattr_t *attr), | ||
| 1577 | _GL_ARG_NONNULL ((1))); | ||
| 1578 | # endif | ||
| 1579 | _GL_CXXALIAS_SYS (pthread_condattr_destroy, int, (pthread_condattr_t *attr)); | ||
| 1580 | # endif | ||
| 1581 | # if __GLIBC__ >= 2 | ||
| 1582 | _GL_CXXALIASWARN (pthread_condattr_destroy); | ||
| 1583 | # endif | ||
| 1584 | #elif defined GNULIB_POSIXCHECK | ||
| 1585 | # undef pthread_condattr_destroy | ||
| 1586 | # if HAVE_RAW_DECL_PTHREAD_CONDATTR_DESTROY | ||
| 1587 | _GL_WARN_ON_USE (pthread_condattr_destroy, "pthread_condattr_destroy is not portable - " | ||
| 1588 | "use gnulib module pthread-cond for portability"); | ||
| 1589 | # endif | ||
| 1590 | #endif | ||
| 1591 | |||
| 1592 | #if @GNULIB_PTHREAD_COND@ | ||
| 1593 | # if @REPLACE_PTHREAD_COND_WAIT@ | ||
| 1594 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1595 | # undef pthread_cond_wait | ||
| 1596 | # define pthread_cond_wait rpl_pthread_cond_wait | ||
| 1597 | # endif | ||
| 1598 | _GL_FUNCDECL_RPL (pthread_cond_wait, int, | ||
| 1599 | (pthread_cond_t *restrict cond, | ||
| 1600 | pthread_mutex_t *restrict mutex), | ||
| 1601 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1602 | _GL_CXXALIAS_RPL (pthread_cond_wait, int, | ||
| 1603 | (pthread_cond_t *restrict cond, | ||
| 1604 | pthread_mutex_t *restrict mutex)); | ||
| 1605 | # else | ||
| 1606 | # if !@HAVE_PTHREAD_COND_WAIT@ | ||
| 1607 | _GL_FUNCDECL_SYS (pthread_cond_wait, int, | ||
| 1608 | (pthread_cond_t *restrict cond, | ||
| 1609 | pthread_mutex_t *restrict mutex), | ||
| 1610 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1611 | # endif | ||
| 1612 | _GL_CXXALIAS_SYS (pthread_cond_wait, int, | ||
| 1613 | (pthread_cond_t *restrict cond, | ||
| 1614 | pthread_mutex_t *restrict mutex)); | ||
| 1615 | # endif | ||
| 1616 | # if __GLIBC__ >= 2 | ||
| 1617 | _GL_CXXALIASWARN (pthread_cond_wait); | ||
| 1618 | # endif | ||
| 1619 | #elif defined GNULIB_POSIXCHECK | ||
| 1620 | # undef pthread_cond_wait | ||
| 1621 | # if HAVE_RAW_DECL_PTHREAD_COND_WAIT | ||
| 1622 | _GL_WARN_ON_USE (pthread_cond_wait, "pthread_cond_wait is not portable - " | ||
| 1623 | "use gnulib module pthread-cond for portability"); | ||
| 1624 | # endif | ||
| 1625 | #endif | ||
| 1626 | |||
| 1627 | #if @GNULIB_PTHREAD_COND@ | ||
| 1628 | # if @REPLACE_PTHREAD_COND_TIMEDWAIT@ | ||
| 1629 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1630 | # undef pthread_cond_timedwait | ||
| 1631 | # define pthread_cond_timedwait rpl_pthread_cond_timedwait | ||
| 1632 | # endif | ||
| 1633 | _GL_FUNCDECL_RPL (pthread_cond_timedwait, int, | ||
| 1634 | (pthread_cond_t *restrict cond, | ||
| 1635 | pthread_mutex_t *restrict mutex, | ||
| 1636 | const struct timespec *restrict abstime), | ||
| 1637 | _GL_ARG_NONNULL ((1, 2, 3))); | ||
| 1638 | _GL_CXXALIAS_RPL (pthread_cond_timedwait, int, | ||
| 1639 | (pthread_cond_t *restrict cond, | ||
| 1640 | pthread_mutex_t *restrict mutex, | ||
| 1641 | const struct timespec *restrict abstime)); | ||
| 1642 | # else | ||
| 1643 | # if !@HAVE_PTHREAD_COND_TIMEDWAIT@ | ||
| 1644 | _GL_FUNCDECL_SYS (pthread_cond_timedwait, int, | ||
| 1645 | (pthread_cond_t *restrict cond, | ||
| 1646 | pthread_mutex_t *restrict mutex, | ||
| 1647 | const struct timespec *restrict abstime), | ||
| 1648 | _GL_ARG_NONNULL ((1, 2, 3))); | ||
| 1649 | # endif | ||
| 1650 | _GL_CXXALIAS_SYS (pthread_cond_timedwait, int, | ||
| 1651 | (pthread_cond_t *restrict cond, | ||
| 1652 | pthread_mutex_t *restrict mutex, | ||
| 1653 | const struct timespec *restrict abstime)); | ||
| 1654 | # endif | ||
| 1655 | # if __GLIBC__ >= 2 | ||
| 1656 | _GL_CXXALIASWARN (pthread_cond_timedwait); | ||
| 1657 | # endif | ||
| 1658 | #elif defined GNULIB_POSIXCHECK | ||
| 1659 | # undef pthread_cond_timedwait | ||
| 1660 | # if HAVE_RAW_DECL_PTHREAD_COND_TIMEDWAIT | ||
| 1661 | _GL_WARN_ON_USE (pthread_cond_timedwait, "pthread_cond_timedwait is not portable - " | ||
| 1662 | "use gnulib module pthread-cond for portability"); | ||
| 1663 | # endif | ||
| 1664 | #endif | ||
| 1665 | |||
| 1666 | #if @GNULIB_PTHREAD_COND@ | ||
| 1667 | # if @REPLACE_PTHREAD_COND_SIGNAL@ | ||
| 1668 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1669 | # undef pthread_cond_signal | ||
| 1670 | # define pthread_cond_signal rpl_pthread_cond_signal | ||
| 1671 | # endif | ||
| 1672 | _GL_FUNCDECL_RPL (pthread_cond_signal, int, (pthread_cond_t *cond), | ||
| 1673 | _GL_ARG_NONNULL ((1))); | ||
| 1674 | _GL_CXXALIAS_RPL (pthread_cond_signal, int, (pthread_cond_t *cond)); | ||
| 1675 | # else | ||
| 1676 | # if !@HAVE_PTHREAD_COND_SIGNAL@ | ||
| 1677 | _GL_FUNCDECL_SYS (pthread_cond_signal, int, (pthread_cond_t *cond), | ||
| 1678 | _GL_ARG_NONNULL ((1))); | ||
| 1679 | # endif | ||
| 1680 | _GL_CXXALIAS_SYS (pthread_cond_signal, int, (pthread_cond_t *cond)); | ||
| 1681 | # endif | ||
| 1682 | # if __GLIBC__ >= 2 | ||
| 1683 | _GL_CXXALIASWARN (pthread_cond_signal); | ||
| 1684 | # endif | ||
| 1685 | #elif defined GNULIB_POSIXCHECK | ||
| 1686 | # undef pthread_cond_signal | ||
| 1687 | # if HAVE_RAW_DECL_PTHREAD_COND_SIGNAL | ||
| 1688 | _GL_WARN_ON_USE (pthread_cond_signal, "pthread_cond_signal is not portable - " | ||
| 1689 | "use gnulib module pthread-cond for portability"); | ||
| 1690 | # endif | ||
| 1691 | #endif | ||
| 1692 | |||
| 1693 | #if @GNULIB_PTHREAD_COND@ | ||
| 1694 | # if @REPLACE_PTHREAD_COND_BROADCAST@ | ||
| 1695 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1696 | # undef pthread_cond_broadcast | ||
| 1697 | # define pthread_cond_broadcast rpl_pthread_cond_broadcast | ||
| 1698 | # endif | ||
| 1699 | _GL_FUNCDECL_RPL (pthread_cond_broadcast, int, (pthread_cond_t *cond), | ||
| 1700 | _GL_ARG_NONNULL ((1))); | ||
| 1701 | _GL_CXXALIAS_RPL (pthread_cond_broadcast, int, (pthread_cond_t *cond)); | ||
| 1702 | # else | ||
| 1703 | # if !@HAVE_PTHREAD_COND_BROADCAST@ | ||
| 1704 | _GL_FUNCDECL_SYS (pthread_cond_broadcast, int, (pthread_cond_t *cond), | ||
| 1705 | _GL_ARG_NONNULL ((1))); | ||
| 1706 | # endif | ||
| 1707 | _GL_CXXALIAS_SYS (pthread_cond_broadcast, int, (pthread_cond_t *cond)); | ||
| 1708 | # endif | ||
| 1709 | # if __GLIBC__ >= 2 | ||
| 1710 | _GL_CXXALIASWARN (pthread_cond_broadcast); | ||
| 1711 | # endif | ||
| 1712 | #elif defined GNULIB_POSIXCHECK | ||
| 1713 | # undef pthread_cond_broadcast | ||
| 1714 | # if HAVE_RAW_DECL_PTHREAD_COND_BROADCAST | ||
| 1715 | _GL_WARN_ON_USE (pthread_cond_broadcast, "pthread_cond_broadcast is not portable - " | ||
| 1716 | "use gnulib module pthread-cond for portability"); | ||
| 1717 | # endif | ||
| 1718 | #endif | ||
| 1719 | |||
| 1720 | #if @GNULIB_PTHREAD_COND@ | ||
| 1721 | # if @REPLACE_PTHREAD_COND_DESTROY@ | ||
| 1722 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1723 | # undef pthread_cond_destroy | ||
| 1724 | # define pthread_cond_destroy rpl_pthread_cond_destroy | ||
| 1725 | # endif | ||
| 1726 | _GL_FUNCDECL_RPL (pthread_cond_destroy, int, (pthread_cond_t *cond), | ||
| 1727 | _GL_ARG_NONNULL ((1))); | ||
| 1728 | _GL_CXXALIAS_RPL (pthread_cond_destroy, int, (pthread_cond_t *cond)); | ||
| 1729 | # else | ||
| 1730 | # if !@HAVE_PTHREAD_COND_DESTROY@ | ||
| 1731 | _GL_FUNCDECL_SYS (pthread_cond_destroy, int, (pthread_cond_t *cond), | ||
| 1732 | _GL_ARG_NONNULL ((1))); | ||
| 1733 | # endif | ||
| 1734 | _GL_CXXALIAS_SYS (pthread_cond_destroy, int, (pthread_cond_t *cond)); | ||
| 1735 | # endif | ||
| 1736 | # if __GLIBC__ >= 2 | ||
| 1737 | _GL_CXXALIASWARN (pthread_cond_destroy); | ||
| 1738 | # endif | ||
| 1739 | #elif defined GNULIB_POSIXCHECK | ||
| 1740 | # undef pthread_cond_destroy | ||
| 1741 | # if HAVE_RAW_DECL_PTHREAD_COND_DESTROY | ||
| 1742 | _GL_WARN_ON_USE (pthread_cond_destroy, "pthread_cond_destroy is not portable - " | ||
| 1743 | "use gnulib module pthread-cond for portability"); | ||
| 1744 | # endif | ||
| 1745 | #endif | ||
| 1746 | |||
| 1747 | /* =========== Thread-specific storage functions =========== */ | ||
| 1748 | |||
| 1749 | #if @GNULIB_PTHREAD_TSS@ | ||
| 1750 | # if @REPLACE_PTHREAD_KEY_CREATE@ | ||
| 1751 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1752 | # undef pthread_key_create | ||
| 1753 | # define pthread_key_create rpl_pthread_key_create | ||
| 1754 | # endif | ||
| 1755 | _GL_FUNCDECL_RPL (pthread_key_create, int, | ||
| 1756 | (pthread_key_t *keyp, void (*destructor) (void *)), | ||
| 1757 | _GL_ARG_NONNULL ((1))); | ||
| 1758 | _GL_CXXALIAS_RPL (pthread_key_create, int, | ||
| 1759 | (pthread_key_t *keyp, void (*destructor) (void *))); | ||
| 1760 | # else | ||
| 1761 | # if !@HAVE_PTHREAD_KEY_CREATE@ | ||
| 1762 | _GL_FUNCDECL_SYS (pthread_key_create, int, | ||
| 1763 | (pthread_key_t *keyp, void (*destructor) (void *)), | ||
| 1764 | _GL_ARG_NONNULL ((1))); | ||
| 1765 | # endif | ||
| 1766 | _GL_CXXALIAS_SYS_CAST (pthread_key_create, int, | ||
| 1767 | (pthread_key_t *keyp, void (*destructor) (void *))); | ||
| 1768 | # endif | ||
| 1769 | # if __GLIBC__ >= 2 | ||
| 1770 | _GL_CXXALIASWARN (pthread_key_create); | ||
| 1771 | # endif | ||
| 1772 | #elif defined GNULIB_POSIXCHECK | ||
| 1773 | # undef pthread_key_create | ||
| 1774 | # if HAVE_RAW_DECL_PTHREAD_KEY_CREATE | ||
| 1775 | _GL_WARN_ON_USE (pthread_key_create, "pthread_key_create is not portable - " | ||
| 1776 | "use gnulib module pthread-tss for portability"); | ||
| 1777 | # endif | ||
| 1778 | #endif | ||
| 1779 | |||
| 1780 | #if @GNULIB_PTHREAD_TSS@ | ||
| 1781 | # if @REPLACE_PTHREAD_SETSPECIFIC@ | ||
| 1782 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1783 | # undef pthread_setspecific | ||
| 1784 | # define pthread_setspecific rpl_pthread_setspecific | ||
| 1785 | # endif | ||
| 1786 | _GL_FUNCDECL_RPL (pthread_setspecific, int, | ||
| 1787 | (pthread_key_t key, const void *value), ); | ||
| 1788 | _GL_CXXALIAS_RPL (pthread_setspecific, int, | ||
| 1789 | (pthread_key_t key, const void *value)); | ||
| 1790 | # else | ||
| 1791 | # if !@HAVE_PTHREAD_SETSPECIFIC@ | ||
| 1792 | _GL_FUNCDECL_SYS (pthread_setspecific, int, | ||
| 1793 | (pthread_key_t key, const void *value), ); | ||
| 1794 | # endif | ||
| 1795 | _GL_CXXALIAS_SYS (pthread_setspecific, int, | ||
| 1796 | (pthread_key_t key, const void *value)); | ||
| 1797 | # endif | ||
| 1798 | # if __GLIBC__ >= 2 | ||
| 1799 | _GL_CXXALIASWARN (pthread_setspecific); | ||
| 1800 | # endif | ||
| 1801 | #elif defined GNULIB_POSIXCHECK | ||
| 1802 | # undef pthread_setspecific | ||
| 1803 | # if HAVE_RAW_DECL_PTHREAD_SETSPECIFIC | ||
| 1804 | _GL_WARN_ON_USE (pthread_setspecific, "pthread_setspecific is not portable - " | ||
| 1805 | "use gnulib module pthread-tss for portability"); | ||
| 1806 | # endif | ||
| 1807 | #endif | ||
| 1808 | |||
| 1809 | #if @GNULIB_PTHREAD_TSS@ | ||
| 1810 | # if @REPLACE_PTHREAD_GETSPECIFIC@ | ||
| 1811 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1812 | # undef pthread_getspecific | ||
| 1813 | # define pthread_getspecific rpl_pthread_getspecific | ||
| 1814 | # endif | ||
| 1815 | _GL_FUNCDECL_RPL (pthread_getspecific, void *, (pthread_key_t key), ); | ||
| 1816 | _GL_CXXALIAS_RPL (pthread_getspecific, void *, (pthread_key_t key)); | ||
| 1817 | # else | ||
| 1818 | # if !@HAVE_PTHREAD_GETSPECIFIC@ | ||
| 1819 | _GL_FUNCDECL_SYS (pthread_getspecific, void *, (pthread_key_t key), ); | ||
| 1820 | # endif | ||
| 1821 | _GL_CXXALIAS_SYS (pthread_getspecific, void *, (pthread_key_t key)); | ||
| 1822 | # endif | ||
| 1823 | # if __GLIBC__ >= 2 | ||
| 1824 | _GL_CXXALIASWARN (pthread_getspecific); | ||
| 1825 | # endif | ||
| 1826 | #elif defined GNULIB_POSIXCHECK | ||
| 1827 | # undef pthread_getspecific | ||
| 1828 | # if HAVE_RAW_DECL_PTHREAD_GETSPECIFIC | ||
| 1829 | _GL_WARN_ON_USE (pthread_getspecific, "pthread_getspecific is not portable - " | ||
| 1830 | "use gnulib module pthread-tss for portability"); | ||
| 1831 | # endif | ||
| 1832 | #endif | ||
| 1833 | |||
| 1834 | #if @GNULIB_PTHREAD_TSS@ | ||
| 1835 | # if @REPLACE_PTHREAD_KEY_DELETE@ | ||
| 1836 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1837 | # undef pthread_key_delete | ||
| 1838 | # define pthread_key_delete rpl_pthread_key_delete | ||
| 1839 | # endif | ||
| 1840 | _GL_FUNCDECL_RPL (pthread_key_delete, int, (pthread_key_t key), ); | ||
| 1841 | _GL_CXXALIAS_RPL (pthread_key_delete, int, (pthread_key_t key)); | ||
| 1842 | # else | ||
| 1843 | # if !@HAVE_PTHREAD_KEY_DELETE@ | ||
| 1844 | _GL_FUNCDECL_SYS (pthread_key_delete, int, (pthread_key_t key), ); | ||
| 1845 | # endif | ||
| 1846 | _GL_CXXALIAS_SYS (pthread_key_delete, int, (pthread_key_t key)); | ||
| 1847 | # endif | ||
| 1848 | # if __GLIBC__ >= 2 | ||
| 1849 | _GL_CXXALIASWARN (pthread_key_delete); | ||
| 1850 | # endif | ||
| 1851 | #elif defined GNULIB_POSIXCHECK | ||
| 1852 | # undef pthread_key_delete | ||
| 1853 | # if HAVE_RAW_DECL_PTHREAD_KEY_DELETE | ||
| 1854 | _GL_WARN_ON_USE (pthread_key_delete, "pthread_key_delete is not portable - " | ||
| 1855 | "use gnulib module pthread-tss for portability"); | ||
| 1856 | # endif | ||
| 1857 | #endif | ||
| 1858 | |||
| 1859 | /* =========== Spinlock functions =========== */ | ||
| 1860 | |||
| 1861 | #if @GNULIB_PTHREAD_SPIN@ | ||
| 1862 | # if @REPLACE_PTHREAD_SPIN_INIT@ | ||
| 1863 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1864 | # undef pthread_spin_init | ||
| 1865 | # define pthread_spin_init rpl_pthread_spin_init | ||
| 1866 | # endif | ||
| 1867 | _GL_FUNCDECL_RPL (pthread_spin_init, int, | ||
| 1868 | (pthread_spinlock_t *lock, int shared_across_processes), | ||
| 1869 | _GL_ARG_NONNULL ((1))); | ||
| 1870 | _GL_CXXALIAS_RPL (pthread_spin_init, int, | ||
| 1871 | (pthread_spinlock_t *lock, int shared_across_processes)); | ||
| 1872 | # else | ||
| 1873 | # if !@HAVE_PTHREAD_SPIN_INIT@ | ||
| 1874 | _GL_FUNCDECL_SYS (pthread_spin_init, int, | ||
| 1875 | (pthread_spinlock_t *lock, int shared_across_processes), | ||
| 1876 | _GL_ARG_NONNULL ((1))); | ||
| 1877 | # endif | ||
| 1878 | _GL_CXXALIAS_SYS (pthread_spin_init, int, | ||
| 1879 | (pthread_spinlock_t *lock, int shared_across_processes)); | ||
| 1880 | # endif | ||
| 1881 | # if __GLIBC__ >= 2 | ||
| 1882 | _GL_CXXALIASWARN (pthread_spin_init); | ||
| 1883 | # endif | ||
| 1884 | #elif defined GNULIB_POSIXCHECK | ||
| 1885 | # undef pthread_spin_init | ||
| 1886 | # if HAVE_RAW_DECL_PTHREAD_SPIN_INIT | ||
| 1887 | _GL_WARN_ON_USE (pthread_spin_init, "pthread_spin_init is not portable - " | ||
| 1888 | "use gnulib module pthread-spin for portability"); | ||
| 1889 | # endif | ||
| 1890 | #endif | ||
| 1891 | |||
| 1892 | #if @GNULIB_PTHREAD_SPIN@ | ||
| 1893 | # if @REPLACE_PTHREAD_SPIN_LOCK@ | ||
| 1894 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1895 | # undef pthread_spin_lock | ||
| 1896 | # define pthread_spin_lock rpl_pthread_spin_lock | ||
| 1897 | # endif | ||
| 1898 | _GL_FUNCDECL_RPL (pthread_spin_lock, int, (pthread_spinlock_t *lock), | ||
| 1899 | _GL_ARG_NONNULL ((1))); | ||
| 1900 | _GL_CXXALIAS_RPL (pthread_spin_lock, int, (pthread_spinlock_t *lock)); | ||
| 1901 | # else | ||
| 1902 | # if !@HAVE_PTHREAD_SPIN_LOCK@ | ||
| 1903 | _GL_FUNCDECL_SYS (pthread_spin_lock, int, (pthread_spinlock_t *lock), | ||
| 1904 | _GL_ARG_NONNULL ((1))); | ||
| 1905 | # endif | ||
| 1906 | _GL_CXXALIAS_SYS (pthread_spin_lock, int, (pthread_spinlock_t *lock)); | ||
| 1907 | # endif | ||
| 1908 | # if __GLIBC__ >= 2 | ||
| 1909 | _GL_CXXALIASWARN (pthread_spin_lock); | ||
| 1910 | # endif | ||
| 1911 | #elif defined GNULIB_POSIXCHECK | ||
| 1912 | # undef pthread_spin_lock | ||
| 1913 | # if HAVE_RAW_DECL_PTHREAD_SPIN_LOCK | ||
| 1914 | _GL_WARN_ON_USE (pthread_spin_lock, "pthread_spin_lock is not portable - " | ||
| 1915 | "use gnulib module pthread-spin for portability"); | ||
| 1916 | # endif | ||
| 1917 | #endif | ||
| 1918 | |||
| 1919 | #if @GNULIB_PTHREAD_SPIN@ | ||
| 1920 | # if @REPLACE_PTHREAD_SPIN_TRYLOCK@ | ||
| 1921 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1922 | # undef pthread_spin_trylock | ||
| 1923 | # define pthread_spin_trylock rpl_pthread_spin_trylock | ||
| 1924 | # endif | ||
| 1925 | _GL_FUNCDECL_RPL (pthread_spin_trylock, int, (pthread_spinlock_t *lock), | ||
| 1926 | _GL_ARG_NONNULL ((1))); | ||
| 1927 | _GL_CXXALIAS_RPL (pthread_spin_trylock, int, (pthread_spinlock_t *lock)); | ||
| 1928 | # else | ||
| 1929 | # if !@HAVE_PTHREAD_SPIN_TRYLOCK@ | ||
| 1930 | _GL_FUNCDECL_SYS (pthread_spin_trylock, int, (pthread_spinlock_t *lock), | ||
| 1931 | _GL_ARG_NONNULL ((1))); | ||
| 1932 | # endif | ||
| 1933 | _GL_CXXALIAS_SYS (pthread_spin_trylock, int, (pthread_spinlock_t *lock)); | ||
| 1934 | # endif | ||
| 1935 | # if __GLIBC__ >= 2 | ||
| 1936 | _GL_CXXALIASWARN (pthread_spin_trylock); | ||
| 1937 | # endif | ||
| 1938 | #elif defined GNULIB_POSIXCHECK | ||
| 1939 | # undef pthread_spin_trylock | ||
| 1940 | # if HAVE_RAW_DECL_PTHREAD_SPIN_TRYLOCK | ||
| 1941 | _GL_WARN_ON_USE (pthread_spin_trylock, "pthread_spin_trylock is not portable - " | ||
| 1942 | "use gnulib module pthread-spin for portability"); | ||
| 1943 | # endif | ||
| 1944 | #endif | ||
| 1945 | |||
| 1946 | #if @GNULIB_PTHREAD_SPIN@ | ||
| 1947 | # if @REPLACE_PTHREAD_SPIN_UNLOCK@ | ||
| 1948 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1949 | # undef pthread_spin_unlock | ||
| 1950 | # define pthread_spin_unlock rpl_pthread_spin_unlock | ||
| 1951 | # endif | ||
| 1952 | _GL_FUNCDECL_RPL (pthread_spin_unlock, int, (pthread_spinlock_t *lock), | ||
| 1953 | _GL_ARG_NONNULL ((1))); | ||
| 1954 | _GL_CXXALIAS_RPL (pthread_spin_unlock, int, (pthread_spinlock_t *lock)); | ||
| 1955 | # else | ||
| 1956 | # if !@HAVE_PTHREAD_SPIN_UNLOCK@ | ||
| 1957 | _GL_FUNCDECL_SYS (pthread_spin_unlock, int, (pthread_spinlock_t *lock), | ||
| 1958 | _GL_ARG_NONNULL ((1))); | ||
| 1959 | # endif | ||
| 1960 | _GL_CXXALIAS_SYS (pthread_spin_unlock, int, (pthread_spinlock_t *lock)); | ||
| 1961 | # endif | ||
| 1962 | # if __GLIBC__ >= 2 | ||
| 1963 | _GL_CXXALIASWARN (pthread_spin_unlock); | ||
| 1964 | # endif | ||
| 1965 | #elif defined GNULIB_POSIXCHECK | ||
| 1966 | # undef pthread_spin_unlock | ||
| 1967 | # if HAVE_RAW_DECL_PTHREAD_SPIN_UNLOCK | ||
| 1968 | _GL_WARN_ON_USE (pthread_spin_unlock, "pthread_spin_unlock is not portable - " | ||
| 1969 | "use gnulib module pthread-spin for portability"); | ||
| 1970 | # endif | ||
| 1971 | #endif | ||
| 1972 | |||
| 1973 | #if @GNULIB_PTHREAD_SPIN@ | ||
| 1974 | # if @REPLACE_PTHREAD_SPIN_DESTROY@ | ||
| 1975 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1976 | # undef pthread_spin_destroy | ||
| 1977 | # define pthread_spin_destroy rpl_pthread_spin_destroy | ||
| 1978 | # endif | ||
| 1979 | _GL_FUNCDECL_RPL (pthread_spin_destroy, int, (pthread_spinlock_t *lock), | ||
| 1980 | _GL_ARG_NONNULL ((1))); | ||
| 1981 | _GL_CXXALIAS_RPL (pthread_spin_destroy, int, (pthread_spinlock_t *lock)); | ||
| 1982 | # else | ||
| 1983 | # if !@HAVE_PTHREAD_SPIN_DESTROY@ | ||
| 1984 | _GL_FUNCDECL_SYS (pthread_spin_destroy, int, (pthread_spinlock_t *lock), | ||
| 1985 | _GL_ARG_NONNULL ((1))); | ||
| 1986 | # endif | ||
| 1987 | _GL_CXXALIAS_SYS (pthread_spin_destroy, int, (pthread_spinlock_t *lock)); | ||
| 1988 | # endif | ||
| 1989 | # if __GLIBC__ >= 2 | ||
| 1990 | _GL_CXXALIASWARN (pthread_spin_destroy); | ||
| 1991 | # endif | ||
| 1992 | #elif defined GNULIB_POSIXCHECK | ||
| 1993 | # undef pthread_spin_destroy | ||
| 1994 | # if HAVE_RAW_DECL_PTHREAD_SPIN_DESTROY | ||
| 1995 | _GL_WARN_ON_USE (pthread_spin_destroy, "pthread_spin_destroy is not portable - " | ||
| 1996 | "use gnulib module pthread-spin for portability"); | ||
| 1997 | # endif | ||
| 1998 | #endif | ||
| 1999 | |||
| 2000 | |||
| 2001 | #if defined __cplusplus && defined GNULIB_NAMESPACE && !@HAVE_PTHREAD_H@ && defined __MINGW32__ | ||
| 2002 | /* Provide the symbols required by mingw's <bits/gthr-default.h>. */ | ||
| 2003 | using GNULIB_NAMESPACE::pthread_create; | ||
| 2004 | using GNULIB_NAMESPACE::pthread_self; | ||
| 2005 | using GNULIB_NAMESPACE::pthread_equal; | ||
| 2006 | using GNULIB_NAMESPACE::pthread_detach; | ||
| 2007 | using GNULIB_NAMESPACE::pthread_join; | ||
| 2008 | using GNULIB_NAMESPACE::pthread_once; | ||
| 2009 | using GNULIB_NAMESPACE::pthread_mutex_init; | ||
| 2010 | using GNULIB_NAMESPACE::pthread_mutexattr_init; | ||
| 2011 | using GNULIB_NAMESPACE::pthread_mutexattr_settype; | ||
| 2012 | using GNULIB_NAMESPACE::pthread_mutexattr_destroy; | ||
| 2013 | using GNULIB_NAMESPACE::pthread_mutex_lock; | ||
| 2014 | using GNULIB_NAMESPACE::pthread_mutex_trylock; | ||
| 2015 | using GNULIB_NAMESPACE::pthread_mutex_timedlock; | ||
| 2016 | using GNULIB_NAMESPACE::pthread_mutex_unlock; | ||
| 2017 | using GNULIB_NAMESPACE::pthread_mutex_destroy; | ||
| 2018 | using GNULIB_NAMESPACE::pthread_cond_wait; | ||
| 2019 | using GNULIB_NAMESPACE::pthread_cond_timedwait; | ||
| 2020 | using GNULIB_NAMESPACE::pthread_cond_signal; | ||
| 2021 | using GNULIB_NAMESPACE::pthread_cond_broadcast; | ||
| 2022 | using GNULIB_NAMESPACE::pthread_cond_destroy; | ||
| 2023 | using GNULIB_NAMESPACE::pthread_key_create; | ||
| 2024 | using GNULIB_NAMESPACE::pthread_setspecific; | ||
| 2025 | using GNULIB_NAMESPACE::pthread_getspecific; | ||
| 2026 | using GNULIB_NAMESPACE::pthread_key_delete; | ||
| 2027 | #endif | ||
| 2028 | |||
| 2029 | |||
| 2030 | #endif /* _@GUARD_PREFIX@_PTHREAD_H_ */ | ||
| 2031 | #endif /* _@GUARD_PREFIX@_PTHREAD_H_ */ | ||
| 2032 | #endif | ||
diff --git a/gl/realloc.c b/gl/realloc.c index 05731396..04a28561 100644 --- a/gl/realloc.c +++ b/gl/realloc.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* realloc() function that is glibc compatible. | 1 | /* realloc() function that is glibc compatible. |
| 2 | 2 | ||
| 3 | Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2024 Free Software | 3 | Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
| @@ -18,17 +18,21 @@ | |||
| 18 | 18 | ||
| 19 | /* written by Jim Meyering and Bruno Haible */ | 19 | /* written by Jim Meyering and Bruno Haible */ |
| 20 | 20 | ||
| 21 | /* Ensure that we call the system's realloc() below. */ | ||
| 22 | #define _GL_USE_STDLIB_ALLOC 1 | ||
| 21 | #include <config.h> | 23 | #include <config.h> |
| 22 | 24 | ||
| 25 | #define _GL_REALLOC_INLINE _GL_EXTERN_INLINE | ||
| 23 | #include <stdlib.h> | 26 | #include <stdlib.h> |
| 24 | 27 | ||
| 25 | #include <errno.h> | 28 | #include <errno.h> |
| 29 | #include <stdckdint.h> | ||
| 26 | 30 | ||
| 27 | #include "xalloc-oversized.h" | 31 | #ifdef __CHERI_PURE_CAPABILITY__ |
| 32 | # include <cheri.h> | ||
| 33 | #endif | ||
| 28 | 34 | ||
| 29 | /* Call the system's realloc below. This file does not define | 35 | #ifndef _GL_INLINE_RPL_REALLOC |
| 30 | _GL_USE_STDLIB_ALLOC because it needs Gnulib's malloc if present. */ | ||
| 31 | #undef realloc | ||
| 32 | 36 | ||
| 33 | /* Change the size of an allocated block of memory P to N bytes, | 37 | /* Change the size of an allocated block of memory P to N bytes, |
| 34 | with error checking. If P is NULL, use malloc. Otherwise if N is zero, | 38 | with error checking. If P is NULL, use malloc. Otherwise if N is zero, |
| @@ -37,27 +41,70 @@ | |||
| 37 | void * | 41 | void * |
| 38 | rpl_realloc (void *p, size_t n) | 42 | rpl_realloc (void *p, size_t n) |
| 39 | { | 43 | { |
| 40 | if (p == NULL) | 44 | size_t n1 = n; |
| 41 | return malloc (n); | ||
| 42 | 45 | ||
| 43 | if (n == 0) | 46 | if (n == 0) |
| 44 | { | 47 | { |
| 45 | free (p); | 48 | # if NEED_SANITIZED_REALLOC |
| 46 | return NULL; | 49 | /* When P is non-null, ISO C23 §7.24.3.7.(3) says realloc (P, 0) has |
| 50 | undefined behavior even though C17 and earlier partially defined | ||
| 51 | the behavior. Let the programmer know. | ||
| 52 | When the undefined-behaviour sanitizers report this case, i.e. when | ||
| 53 | <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117233> and | ||
| 54 | <https://github.com/llvm/llvm-project/issues/113065> | ||
| 55 | have been closed and new releases of GCC and clang have been made, | ||
| 56 | we can revisit this code. */ | ||
| 57 | if (p != NULL) | ||
| 58 | abort (); | ||
| 59 | # endif | ||
| 60 | |||
| 61 | /* realloc (NULL, 0) acts like glibc malloc (0), i.e., like malloc (1) | ||
| 62 | except the caller cannot dereference any non-null return. | ||
| 63 | |||
| 64 | realloc (P, 0) with non-null P is a messier situation. | ||
| 65 | As mentioned above, C23 says behavior is undefined. | ||
| 66 | POSIX.1-2024 extends C17 to say realloc (P, 0) | ||
| 67 | either fails by setting errno and returning a null pointer, | ||
| 68 | or succeeds by freeing P and then either: | ||
| 69 | (a) setting errno=EINVAL and returning a null pointer; or | ||
| 70 | (b) acting like a successful malloc (0). | ||
| 71 | glibc 1 through 2.1 realloc acted like (b), | ||
| 72 | which conforms to C17, to C23 and to POSIX.1-2024. | ||
| 73 | glibc 2.1.1+ realloc acts like (a) except it does not set errno; | ||
| 74 | this conforms to C17 and to C23 but not to POSIX.1-2024. | ||
| 75 | Quite possibly future versions of POSIX will change, | ||
| 76 | due either to C23 or to (a)'s semantics being messy. | ||
| 77 | Act like (b), as that's easy, matches GNU, BSD and V7 malloc, | ||
| 78 | matches BSD and V7 realloc, and requires no extra code at | ||
| 79 | caller sites. */ | ||
| 80 | |||
| 81 | # if !HAVE_REALLOC_0_NONNULL | ||
| 82 | n1 = 1; | ||
| 83 | # endif | ||
| 47 | } | 84 | } |
| 48 | 85 | ||
| 49 | if (xalloc_oversized (n, 1)) | 86 | # if !HAVE_MALLOC_PTRDIFF |
| 87 | ptrdiff_t signed_n; | ||
| 88 | if (ckd_add (&signed_n, n, 0)) | ||
| 50 | { | 89 | { |
| 51 | errno = ENOMEM; | 90 | errno = ENOMEM; |
| 52 | return NULL; | 91 | return NULL; |
| 53 | } | 92 | } |
| 93 | # endif | ||
| 54 | 94 | ||
| 55 | void *result = realloc (p, n); | 95 | void *result = realloc (p, n1); |
| 56 | 96 | ||
| 57 | #if !HAVE_MALLOC_POSIX | 97 | # if !HAVE_REALLOC_POSIX |
| 58 | if (result == NULL) | 98 | if (result == NULL) |
| 59 | errno = ENOMEM; | 99 | errno = ENOMEM; |
| 60 | #endif | 100 | # endif |
| 101 | |||
| 102 | # ifdef __CHERI_PURE_CAPABILITY__ | ||
| 103 | if (result != NULL) | ||
| 104 | result = cheri_bounds_set (result, n); | ||
| 105 | # endif | ||
| 61 | 106 | ||
| 62 | return result; | 107 | return result; |
| 63 | } | 108 | } |
| 109 | |||
| 110 | #endif | ||
diff --git a/gl/reallocarray.c b/gl/reallocarray.c index 09711a0e..77e8d84c 100644 --- a/gl/reallocarray.c +++ b/gl/reallocarray.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* reallocarray function that is glibc compatible. | 1 | /* reallocarray function that is glibc compatible. |
| 2 | 2 | ||
| 3 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -33,6 +33,6 @@ reallocarray (void *ptr, size_t nmemb, size_t size) | |||
| 33 | return NULL; | 33 | return NULL; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | /* Rely on the semantics of GNU realloc. */ | 36 | /* Call realloc, setting errno to ENOMEM on failure. */ |
| 37 | return realloc (ptr, nbytes); | 37 | return realloc (ptr, nbytes); |
| 38 | } | 38 | } |
diff --git a/gl/regcomp.c b/gl/regcomp.c index 696cf813..878b65ba 100644 --- a/gl/regcomp.c +++ b/gl/regcomp.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Extended regular expression matching and search library. | 1 | /* Extended regular expression matching and search library. |
| 2 | Copyright (C) 2002-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. | 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. |
| 5 | 5 | ||
| @@ -831,7 +831,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) | |||
| 831 | if (table_size > pat_len) | 831 | if (table_size > pat_len) |
| 832 | break; | 832 | break; |
| 833 | 833 | ||
| 834 | dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size); | 834 | dfa->state_table = calloc (table_size, sizeof (struct re_state_table_entry)); |
| 835 | dfa->state_hash_mask = table_size - 1; | 835 | dfa->state_hash_mask = table_size - 1; |
| 836 | 836 | ||
| 837 | dfa->mb_cur_max = MB_CUR_MAX; | 837 | dfa->mb_cur_max = MB_CUR_MAX; |
| @@ -862,7 +862,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) | |||
| 862 | { | 862 | { |
| 863 | int i, j, ch; | 863 | int i, j, ch; |
| 864 | 864 | ||
| 865 | dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); | 865 | dfa->sb_char = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t)); |
| 866 | if (__glibc_unlikely (dfa->sb_char == NULL)) | 866 | if (__glibc_unlikely (dfa->sb_char == NULL)) |
| 867 | return REG_ESPACE; | 867 | return REG_ESPACE; |
| 868 | 868 | ||
| @@ -1001,21 +1001,25 @@ create_initial_state (re_dfa_t *dfa) | |||
| 1001 | Idx dest_idx = dfa->edests[node_idx].elems[0]; | 1001 | Idx dest_idx = dfa->edests[node_idx].elems[0]; |
| 1002 | if (!re_node_set_contains (&init_nodes, dest_idx)) | 1002 | if (!re_node_set_contains (&init_nodes, dest_idx)) |
| 1003 | { | 1003 | { |
| 1004 | reg_errcode_t merge_err | 1004 | err |
| 1005 | = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); | 1005 | = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); |
| 1006 | if (merge_err != REG_NOERROR) | 1006 | if (err != REG_NOERROR) |
| 1007 | return merge_err; | 1007 | break; |
| 1008 | i = 0; | 1008 | i = 0; |
| 1009 | } | 1009 | } |
| 1010 | } | 1010 | } |
| 1011 | } | 1011 | } |
| 1012 | 1012 | ||
| 1013 | /* It must be the first time to invoke acquire_state. */ | 1013 | /* It must be the first time to invoke acquire_state. */ |
| 1014 | dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0); | 1014 | dfa->init_state |
| 1015 | /* We don't check ERR here, since the initial state must not be NULL. */ | 1015 | = (err == REG_NOERROR |
| 1016 | ? re_acquire_state_context (&err, dfa, &init_nodes, 0) | ||
| 1017 | : NULL); | ||
| 1016 | if (__glibc_unlikely (dfa->init_state == NULL)) | 1018 | if (__glibc_unlikely (dfa->init_state == NULL)) |
| 1017 | return err; | 1019 | { |
| 1018 | if (dfa->init_state->has_constraint) | 1020 | /* Don't check ERR here, as the initial state must not be null. */ |
| 1021 | } | ||
| 1022 | else if (dfa->init_state->has_constraint) | ||
| 1019 | { | 1023 | { |
| 1020 | dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, | 1024 | dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, |
| 1021 | CONTEXT_WORD); | 1025 | CONTEXT_WORD); |
| @@ -1025,17 +1029,13 @@ create_initial_state (re_dfa_t *dfa) | |||
| 1025 | &init_nodes, | 1029 | &init_nodes, |
| 1026 | CONTEXT_NEWLINE | 1030 | CONTEXT_NEWLINE |
| 1027 | | CONTEXT_BEGBUF); | 1031 | | CONTEXT_BEGBUF); |
| 1028 | if (__glibc_unlikely (dfa->init_state_word == NULL | ||
| 1029 | || dfa->init_state_nl == NULL | ||
| 1030 | || dfa->init_state_begbuf == NULL)) | ||
| 1031 | return err; | ||
| 1032 | } | 1032 | } |
| 1033 | else | 1033 | else |
| 1034 | dfa->init_state_word = dfa->init_state_nl | 1034 | dfa->init_state_word = dfa->init_state_nl |
| 1035 | = dfa->init_state_begbuf = dfa->init_state; | 1035 | = dfa->init_state_begbuf = dfa->init_state; |
| 1036 | 1036 | ||
| 1037 | re_node_set_free (&init_nodes); | 1037 | re_node_set_free (&init_nodes); |
| 1038 | return REG_NOERROR; | 1038 | return err; |
| 1039 | } | 1039 | } |
| 1040 | 1040 | ||
| 1041 | /* If it is possible to do searching in single byte encoding instead of UTF-8 | 1041 | /* If it is possible to do searching in single byte encoding instead of UTF-8 |
| @@ -1677,12 +1677,11 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) | |||
| 1677 | { | 1677 | { |
| 1678 | err = duplicate_node_closure (dfa, node, node, node, | 1678 | err = duplicate_node_closure (dfa, node, node, node, |
| 1679 | dfa->nodes[node].constraint); | 1679 | dfa->nodes[node].constraint); |
| 1680 | if (__glibc_unlikely (err != REG_NOERROR)) | ||
| 1681 | return err; | ||
| 1682 | } | 1680 | } |
| 1683 | 1681 | ||
| 1684 | /* Expand each epsilon destination nodes. */ | 1682 | /* Expand each epsilon destination nodes. */ |
| 1685 | if (IS_EPSILON_NODE(dfa->nodes[node].type)) | 1683 | if (__glibc_likely (err == REG_NOERROR) |
| 1684 | && IS_EPSILON_NODE (dfa->nodes[node].type)) | ||
| 1686 | for (i = 0; i < dfa->edests[node].nelem; ++i) | 1685 | for (i = 0; i < dfa->edests[node].nelem; ++i) |
| 1687 | { | 1686 | { |
| 1688 | re_node_set eclosure_elem; | 1687 | re_node_set eclosure_elem; |
| @@ -1700,14 +1699,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) | |||
| 1700 | { | 1699 | { |
| 1701 | err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); | 1700 | err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); |
| 1702 | if (__glibc_unlikely (err != REG_NOERROR)) | 1701 | if (__glibc_unlikely (err != REG_NOERROR)) |
| 1703 | return err; | 1702 | break; |
| 1704 | } | 1703 | } |
| 1705 | else | 1704 | else |
| 1706 | eclosure_elem = dfa->eclosures[edest]; | 1705 | eclosure_elem = dfa->eclosures[edest]; |
| 1707 | /* Merge the epsilon closure of 'edest'. */ | 1706 | /* Merge the epsilon closure of 'edest'. */ |
| 1708 | err = re_node_set_merge (&eclosure, &eclosure_elem); | 1707 | err = re_node_set_merge (&eclosure, &eclosure_elem); |
| 1709 | if (__glibc_unlikely (err != REG_NOERROR)) | 1708 | if (__glibc_unlikely (err != REG_NOERROR)) |
| 1710 | return err; | 1709 | break; |
| 1711 | /* If the epsilon closure of 'edest' is incomplete, | 1710 | /* If the epsilon closure of 'edest' is incomplete, |
| 1712 | the epsilon closure of this node is also incomplete. */ | 1711 | the epsilon closure of this node is also incomplete. */ |
| 1713 | if (dfa->eclosures[edest].nelem == 0) | 1712 | if (dfa->eclosures[edest].nelem == 0) |
| @@ -1717,12 +1716,18 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) | |||
| 1717 | } | 1716 | } |
| 1718 | } | 1717 | } |
| 1719 | 1718 | ||
| 1720 | if (incomplete && !root) | 1719 | if (err != REG_NOERROR) |
| 1721 | dfa->eclosures[node].nelem = 0; | 1720 | re_node_set_free (&eclosure); |
| 1722 | else | 1721 | else |
| 1723 | dfa->eclosures[node] = eclosure; | 1722 | { |
| 1724 | *new_set = eclosure; | 1723 | if (incomplete && !root) |
| 1725 | return REG_NOERROR; | 1724 | dfa->eclosures[node].nelem = 0; |
| 1725 | else | ||
| 1726 | dfa->eclosures[node] = eclosure; | ||
| 1727 | *new_set = eclosure; | ||
| 1728 | } | ||
| 1729 | |||
| 1730 | return err; | ||
| 1726 | } | 1731 | } |
| 1727 | 1732 | ||
| 1728 | /* Functions for token which are used in the parser. */ | 1733 | /* Functions for token which are used in the parser. */ |
| @@ -3055,8 +3060,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, | |||
| 3055 | _NL_COLLATE_SYMB_EXTRAMB); | 3060 | _NL_COLLATE_SYMB_EXTRAMB); |
| 3056 | } | 3061 | } |
| 3057 | #endif | 3062 | #endif |
| 3058 | sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); | 3063 | sbcset = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t)); |
| 3059 | mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); | 3064 | mbcset = (re_charset_t *) calloc (1, sizeof (re_charset_t)); |
| 3060 | if (__glibc_unlikely (sbcset == NULL || mbcset == NULL)) | 3065 | if (__glibc_unlikely (sbcset == NULL || mbcset == NULL)) |
| 3061 | { | 3066 | { |
| 3062 | re_free (sbcset); | 3067 | re_free (sbcset); |
| @@ -3275,6 +3280,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, | |||
| 3275 | else | 3280 | else |
| 3276 | { | 3281 | { |
| 3277 | free_charset (mbcset); | 3282 | free_charset (mbcset); |
| 3283 | mbcset = NULL; | ||
| 3278 | /* Build a tree for simple bracket. */ | 3284 | /* Build a tree for simple bracket. */ |
| 3279 | br_token.type = SIMPLE_BRACKET; | 3285 | br_token.type = SIMPLE_BRACKET; |
| 3280 | br_token.opr.sbcset = sbcset; | 3286 | br_token.opr.sbcset = sbcset; |
| @@ -3288,7 +3294,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, | |||
| 3288 | *err = REG_ESPACE; | 3294 | *err = REG_ESPACE; |
| 3289 | parse_bracket_exp_free_return: | 3295 | parse_bracket_exp_free_return: |
| 3290 | re_free (sbcset); | 3296 | re_free (sbcset); |
| 3291 | free_charset (mbcset); | 3297 | if (__glibc_likely (mbcset != NULL)) |
| 3298 | free_charset (mbcset); | ||
| 3292 | return NULL; | 3299 | return NULL; |
| 3293 | } | 3300 | } |
| 3294 | 3301 | ||
| @@ -3548,13 +3555,13 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, | |||
| 3548 | reg_errcode_t ret; | 3555 | reg_errcode_t ret; |
| 3549 | bin_tree_t *tree; | 3556 | bin_tree_t *tree; |
| 3550 | 3557 | ||
| 3551 | sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); | 3558 | sbcset = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t)); |
| 3552 | if (__glibc_unlikely (sbcset == NULL)) | 3559 | if (__glibc_unlikely (sbcset == NULL)) |
| 3553 | { | 3560 | { |
| 3554 | *err = REG_ESPACE; | 3561 | *err = REG_ESPACE; |
| 3555 | return NULL; | 3562 | return NULL; |
| 3556 | } | 3563 | } |
| 3557 | mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); | 3564 | mbcset = (re_charset_t *) calloc (1, sizeof (re_charset_t)); |
| 3558 | if (__glibc_unlikely (mbcset == NULL)) | 3565 | if (__glibc_unlikely (mbcset == NULL)) |
| 3559 | { | 3566 | { |
| 3560 | re_free (sbcset); | 3567 | re_free (sbcset); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Extended regular expression matching and search library. | 1 | /* Extended regular expression matching and search library. |
| 2 | Copyright (C) 2002-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. | 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. |
| 5 | 5 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Definitions for data structures and routines for the regular | 1 | /* Definitions for data structures and routines for the regular |
| 2 | expression library. | 2 | expression library. |
| 3 | Copyright (C) 1985, 1989-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1985, 1989-2025 Free Software Foundation, Inc. |
| 4 | This file is part of the GNU C Library. | 4 | This file is part of the GNU C Library. |
| 5 | 5 | ||
| 6 | The GNU C Library is free software; you can redistribute it and/or | 6 | The GNU C Library is free software; you can redistribute it and/or |
| @@ -66,15 +66,14 @@ typedef unsigned long int active_reg_t; | |||
| 66 | 66 | ||
| 67 | /* The following bits are used to determine the regexp syntax we | 67 | /* The following bits are used to determine the regexp syntax we |
| 68 | recognize. The set/not-set meanings are chosen so that Emacs syntax | 68 | recognize. The set/not-set meanings are chosen so that Emacs syntax |
| 69 | remains the value 0. The bits are given in alphabetical order, and | 69 | is the value 0 for Emacs 20 (2000) and earlier, and the value |
| 70 | the definitions shifted by one from the previous bit; thus, when we | 70 | RE_SYNTAX_EMACS for Emacs 21 (2001) and later. */ |
| 71 | add or remove a bit, only one other definition need change. */ | ||
| 72 | typedef unsigned long int reg_syntax_t; | 71 | typedef unsigned long int reg_syntax_t; |
| 73 | 72 | ||
| 74 | #ifdef __USE_GNU | 73 | #ifdef __USE_GNU |
| 75 | /* If this bit is not set, then \ inside a bracket expression is literal. | 74 | /* If this bit is not set, then \ inside a bracket expression is literal. |
| 76 | If set, then such a \ quotes the following character. */ | 75 | If set, then such a \ quotes the following character. */ |
| 77 | # define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) | 76 | # define RE_BACKSLASH_ESCAPE_IN_LISTS 1ul |
| 78 | 77 | ||
| 79 | /* If this bit is not set, then + and ? are operators, and \+ and \? are | 78 | /* If this bit is not set, then + and ? are operators, and \+ and \? are |
| 80 | literals. | 79 | literals. |
| @@ -215,7 +214,8 @@ extern reg_syntax_t re_syntax_options; | |||
| 215 | (The [[[ comments delimit what gets put into the Texinfo file, so | 214 | (The [[[ comments delimit what gets put into the Texinfo file, so |
| 216 | don't delete them!) */ | 215 | don't delete them!) */ |
| 217 | /* [[[begin syntaxes]]] */ | 216 | /* [[[begin syntaxes]]] */ |
| 218 | # define RE_SYNTAX_EMACS 0 | 217 | # define RE_SYNTAX_EMACS \ |
| 218 | (RE_CHAR_CLASSES | RE_INTERVALS) | ||
| 219 | 219 | ||
| 220 | # define RE_SYNTAX_AWK \ | 220 | # define RE_SYNTAX_AWK \ |
| 221 | (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ | 221 | (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ |
| @@ -522,20 +522,6 @@ typedef struct | |||
| 522 | 522 | ||
| 523 | /* Declarations for routines. */ | 523 | /* Declarations for routines. */ |
| 524 | 524 | ||
| 525 | #ifndef _REGEX_NELTS | ||
| 526 | # if (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \ | ||
| 527 | && !defined __STDC_NO_VLA__) | ||
| 528 | # define _REGEX_NELTS(n) n | ||
| 529 | # else | ||
| 530 | # define _REGEX_NELTS(n) | ||
| 531 | # endif | ||
| 532 | #endif | ||
| 533 | |||
| 534 | #if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) | ||
| 535 | # pragma GCC diagnostic push | ||
| 536 | # pragma GCC diagnostic ignored "-Wvla" | ||
| 537 | #endif | ||
| 538 | |||
| 539 | #ifndef _Attr_access_ | 525 | #ifndef _Attr_access_ |
| 540 | # ifdef __attr_access | 526 | # ifdef __attr_access |
| 541 | # define _Attr_access_(arg) __attr_access (arg) | 527 | # define _Attr_access_(arg) __attr_access (arg) |
| @@ -647,10 +633,12 @@ extern int re_exec (const char *); | |||
| 647 | || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \ | 633 | || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \ |
| 648 | || __clang_major__ >= 3 | 634 | || __clang_major__ >= 3 |
| 649 | # define _Restrict_ __restrict | 635 | # define _Restrict_ __restrict |
| 650 | # elif 199901L <= __STDC_VERSION__ || defined restrict | ||
| 651 | # define _Restrict_ restrict | ||
| 652 | # else | 636 | # else |
| 653 | # define _Restrict_ | 637 | # if 199901L <= __STDC_VERSION__ || defined restrict |
| 638 | # define _Restrict_ restrict | ||
| 639 | # else | ||
| 640 | # define _Restrict_ | ||
| 641 | # endif | ||
| 654 | # endif | 642 | # endif |
| 655 | #endif | 643 | #endif |
| 656 | /* For the ISO C99 syntax | 644 | /* For the ISO C99 syntax |
| @@ -661,13 +649,15 @@ extern int re_exec (const char *); | |||
| 661 | #ifndef _Restrict_arr_ | 649 | #ifndef _Restrict_arr_ |
| 662 | # ifdef __restrict_arr | 650 | # ifdef __restrict_arr |
| 663 | # define _Restrict_arr_ __restrict_arr | 651 | # define _Restrict_arr_ __restrict_arr |
| 664 | # elif ((199901L <= __STDC_VERSION__ \ | 652 | # else |
| 653 | # if ((199901L <= __STDC_VERSION__ \ | ||
| 665 | || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \ | 654 | || 3 < __GNUC__ + (1 <= __GNUC_MINOR__) \ |
| 666 | || __clang_major__ >= 3) \ | 655 | || __clang_major__ >= 3) \ |
| 667 | && !defined __cplusplus) | 656 | && !defined __cplusplus) |
| 668 | # define _Restrict_arr_ _Restrict_ | 657 | # define _Restrict_arr_ _Restrict_ |
| 669 | # else | 658 | # else |
| 670 | # define _Restrict_arr_ | 659 | # define _Restrict_arr_ |
| 660 | # endif | ||
| 671 | # endif | 661 | # endif |
| 672 | #endif | 662 | #endif |
| 673 | 663 | ||
| @@ -678,8 +668,7 @@ extern int regcomp (regex_t *_Restrict_ __preg, | |||
| 678 | 668 | ||
| 679 | extern int regexec (const regex_t *_Restrict_ __preg, | 669 | extern int regexec (const regex_t *_Restrict_ __preg, |
| 680 | const char *_Restrict_ __String, size_t __nmatch, | 670 | const char *_Restrict_ __String, size_t __nmatch, |
| 681 | regmatch_t __pmatch[_Restrict_arr_ | 671 | regmatch_t __pmatch[_Restrict_arr_], |
| 682 | _REGEX_NELTS (__nmatch)], | ||
| 683 | int __eflags); | 672 | int __eflags); |
| 684 | 673 | ||
| 685 | extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, | 674 | extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, |
| @@ -688,10 +677,6 @@ extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, | |||
| 688 | 677 | ||
| 689 | extern void regfree (regex_t *__preg); | 678 | extern void regfree (regex_t *__preg); |
| 690 | 679 | ||
| 691 | #if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) | ||
| 692 | # pragma GCC diagnostic pop | ||
| 693 | #endif | ||
| 694 | |||
| 695 | #ifdef __cplusplus | 680 | #ifdef __cplusplus |
| 696 | } | 681 | } |
| 697 | #endif /* C++ */ | 682 | #endif /* C++ */ |
diff --git a/gl/regex_internal.c b/gl/regex_internal.c index 8cd096eb..9b89cc93 100644 --- a/gl/regex_internal.c +++ b/gl/regex_internal.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Extended regular expression matching and search library. | 1 | /* Extended regular expression matching and search library. |
| 2 | Copyright (C) 2002-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. | 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. |
| 5 | 5 | ||
| @@ -937,8 +937,7 @@ re_node_set_alloc (re_node_set *set, Idx size) | |||
| 937 | set->alloc = size; | 937 | set->alloc = size; |
| 938 | set->nelem = 0; | 938 | set->nelem = 0; |
| 939 | set->elems = re_malloc (Idx, size); | 939 | set->elems = re_malloc (Idx, size); |
| 940 | if (__glibc_unlikely (set->elems == NULL) | 940 | if (__glibc_unlikely (set->elems == NULL)) |
| 941 | && (MALLOC_0_IS_NONNULL || size != 0)) | ||
| 942 | return REG_ESPACE; | 941 | return REG_ESPACE; |
| 943 | return REG_NOERROR; | 942 | return REG_NOERROR; |
| 944 | } | 943 | } |
| @@ -1596,7 +1595,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, | |||
| 1596 | reg_errcode_t err; | 1595 | reg_errcode_t err; |
| 1597 | re_dfastate_t *newstate; | 1596 | re_dfastate_t *newstate; |
| 1598 | 1597 | ||
| 1599 | newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); | 1598 | newstate = (re_dfastate_t *) calloc (1, sizeof (re_dfastate_t)); |
| 1600 | if (__glibc_unlikely (newstate == NULL)) | 1599 | if (__glibc_unlikely (newstate == NULL)) |
| 1601 | return NULL; | 1600 | return NULL; |
| 1602 | err = re_node_set_init_copy (&newstate->nodes, nodes); | 1601 | err = re_node_set_init_copy (&newstate->nodes, nodes); |
| @@ -1644,7 +1643,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, | |||
| 1644 | reg_errcode_t err; | 1643 | reg_errcode_t err; |
| 1645 | re_dfastate_t *newstate; | 1644 | re_dfastate_t *newstate; |
| 1646 | 1645 | ||
| 1647 | newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); | 1646 | newstate = (re_dfastate_t *) calloc (1, sizeof (re_dfastate_t)); |
| 1648 | if (__glibc_unlikely (newstate == NULL)) | 1647 | if (__glibc_unlikely (newstate == NULL)) |
| 1649 | return NULL; | 1648 | return NULL; |
| 1650 | err = re_node_set_init_copy (&newstate->nodes, nodes); | 1649 | err = re_node_set_init_copy (&newstate->nodes, nodes); |
diff --git a/gl/regex_internal.h b/gl/regex_internal.h index 6165cb17..1f297299 100644 --- a/gl/regex_internal.h +++ b/gl/regex_internal.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Extended regular expression matching and search library. | 1 | /* Extended regular expression matching and search library. |
| 2 | Copyright (C) 2002-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. | 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. |
| 5 | 5 | ||
| @@ -100,10 +100,12 @@ | |||
| 100 | /* This is for other GNU distributions with internationalized messages. */ | 100 | /* This is for other GNU distributions with internationalized messages. */ |
| 101 | #if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC | 101 | #if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC |
| 102 | # include <libintl.h> | 102 | # include <libintl.h> |
| 103 | # undef gettext | ||
| 103 | # ifdef _LIBC | 104 | # ifdef _LIBC |
| 104 | # undef gettext | ||
| 105 | # define gettext(msgid) \ | 105 | # define gettext(msgid) \ |
| 106 | __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) | 106 | __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) |
| 107 | # else | ||
| 108 | # define gettext(msgid) dgettext ("gnulib", msgid) | ||
| 107 | # endif | 109 | # endif |
| 108 | #else | 110 | #else |
| 109 | # undef gettext | 111 | # undef gettext |
| @@ -436,12 +438,6 @@ typedef struct re_dfa_t re_dfa_t; | |||
| 436 | #define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) | 438 | #define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) |
| 437 | #define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) | 439 | #define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) |
| 438 | 440 | ||
| 439 | #ifdef _LIBC | ||
| 440 | # define MALLOC_0_IS_NONNULL 1 | ||
| 441 | #elif !defined MALLOC_0_IS_NONNULL | ||
| 442 | # define MALLOC_0_IS_NONNULL 0 | ||
| 443 | #endif | ||
| 444 | |||
| 445 | #ifndef MAX | 441 | #ifndef MAX |
| 446 | # define MAX(a,b) ((a) < (b) ? (b) : (a)) | 442 | # define MAX(a,b) ((a) < (b) ? (b) : (a)) |
| 447 | #endif | 443 | #endif |
diff --git a/gl/regexec.c b/gl/regexec.c index 9f065dfa..0d14ac35 100644 --- a/gl/regexec.c +++ b/gl/regexec.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Extended regular expression matching and search library. | 1 | /* Extended regular expression matching and search library. |
| 2 | Copyright (C) 2002-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. | 4 | Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>. |
| 5 | 5 | ||
| @@ -185,7 +185,7 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len); | |||
| 185 | 185 | ||
| 186 | int | 186 | int |
| 187 | regexec (const regex_t *__restrict preg, const char *__restrict string, | 187 | regexec (const regex_t *__restrict preg, const char *__restrict string, |
| 188 | size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) | 188 | size_t nmatch, regmatch_t pmatch[], int eflags) |
| 189 | { | 189 | { |
| 190 | reg_errcode_t err; | 190 | reg_errcode_t err; |
| 191 | Idx start, length; | 191 | Idx start, length; |
| @@ -229,7 +229,7 @@ int | |||
| 229 | attribute_compat_text_section | 229 | attribute_compat_text_section |
| 230 | __compat_regexec (const regex_t *__restrict preg, | 230 | __compat_regexec (const regex_t *__restrict preg, |
| 231 | const char *__restrict string, size_t nmatch, | 231 | const char *__restrict string, size_t nmatch, |
| 232 | regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) | 232 | regmatch_t pmatch[], int eflags) |
| 233 | { | 233 | { |
| 234 | return regexec (preg, string, nmatch, pmatch, | 234 | return regexec (preg, string, nmatch, pmatch, |
| 235 | eflags & (REG_NOTBOL | REG_NOTEOL)); | 235 | eflags & (REG_NOTBOL | REG_NOTEOL)); |
| @@ -2271,7 +2271,7 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, | |||
| 2271 | these destinations and the results of the transition table. */ | 2271 | these destinations and the results of the transition table. */ |
| 2272 | pstate = mctx->state_log[cur_idx]; | 2272 | pstate = mctx->state_log[cur_idx]; |
| 2273 | log_nodes = pstate->entrance_nodes; | 2273 | log_nodes = pstate->entrance_nodes; |
| 2274 | if (next_state != NULL) | 2274 | if (next_state != NULL && next_state->entrance_nodes != NULL) |
| 2275 | { | 2275 | { |
| 2276 | table_nodes = next_state->entrance_nodes; | 2276 | table_nodes = next_state->entrance_nodes; |
| 2277 | *err = re_node_set_init_union (&next_nodes, table_nodes, | 2277 | *err = re_node_set_init_union (&next_nodes, table_nodes, |
| @@ -2721,8 +2721,8 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) | |||
| 2721 | continue; /* No. */ | 2721 | continue; /* No. */ |
| 2722 | if (sub_top->path == NULL) | 2722 | if (sub_top->path == NULL) |
| 2723 | { | 2723 | { |
| 2724 | sub_top->path = calloc (sizeof (state_array_t), | 2724 | sub_top->path = calloc (sl_str - sub_top->str_idx + 1, |
| 2725 | sl_str - sub_top->str_idx + 1); | 2725 | sizeof (state_array_t)); |
| 2726 | if (sub_top->path == NULL) | 2726 | if (sub_top->path == NULL) |
| 2727 | return REG_ESPACE; | 2727 | return REG_ESPACE; |
| 2728 | } | 2728 | } |
| @@ -3266,7 +3266,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) | |||
| 3266 | if (ndests == 0) | 3266 | if (ndests == 0) |
| 3267 | { | 3267 | { |
| 3268 | state->trtable = (re_dfastate_t **) | 3268 | state->trtable = (re_dfastate_t **) |
| 3269 | calloc (sizeof (re_dfastate_t *), SBC_MAX); | 3269 | calloc (SBC_MAX, sizeof (re_dfastate_t *)); |
| 3270 | if (__glibc_unlikely (state->trtable == NULL)) | 3270 | if (__glibc_unlikely (state->trtable == NULL)) |
| 3271 | return false; | 3271 | return false; |
| 3272 | return true; | 3272 | return true; |
| @@ -3338,7 +3338,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) | |||
| 3338 | discern by looking at the character code: allocate a | 3338 | discern by looking at the character code: allocate a |
| 3339 | 256-entry transition table. */ | 3339 | 256-entry transition table. */ |
| 3340 | trtable = state->trtable = | 3340 | trtable = state->trtable = |
| 3341 | (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); | 3341 | (re_dfastate_t **) calloc (SBC_MAX, sizeof (re_dfastate_t *)); |
| 3342 | if (__glibc_unlikely (trtable == NULL)) | 3342 | if (__glibc_unlikely (trtable == NULL)) |
| 3343 | goto out_free; | 3343 | goto out_free; |
| 3344 | 3344 | ||
| @@ -3369,7 +3369,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) | |||
| 3369 | transition tables, one starting at trtable[0] and one | 3369 | transition tables, one starting at trtable[0] and one |
| 3370 | starting at trtable[SBC_MAX]. */ | 3370 | starting at trtable[SBC_MAX]. */ |
| 3371 | trtable = state->word_trtable = | 3371 | trtable = state->word_trtable = |
| 3372 | (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX); | 3372 | (re_dfastate_t **) calloc (2 * SBC_MAX, sizeof (re_dfastate_t *)); |
| 3373 | if (__glibc_unlikely (trtable == NULL)) | 3373 | if (__glibc_unlikely (trtable == NULL)) |
| 3374 | goto out_free; | 3374 | goto out_free; |
| 3375 | 3375 | ||
diff --git a/gl/sched.h b/gl/sched.h new file mode 100644 index 00000000..4d9d546d --- /dev/null +++ b/gl/sched.h | |||
| @@ -0,0 +1,631 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* A GNU-like <sched.h>. | ||
| 3 | Copyright (C) 2008-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #ifndef _GL_SCHED_H | ||
| 19 | |||
| 20 | #if __GNUC__ >= 3 | ||
| 21 | #pragma GCC system_header | ||
| 22 | #endif | ||
| 23 | |||
| 24 | |||
| 25 | /* This file uses #include_next of a system file that defines time_t. | ||
| 26 | For the 'year2038' module to work right, <config.h> needs to have been | ||
| 27 | included before. */ | ||
| 28 | #if !_GL_CONFIG_H_INCLUDED | ||
| 29 | #error "Please include config.h first." | ||
| 30 | #endif | ||
| 31 | |||
| 32 | /* The include_next requires a split double-inclusion guard. */ | ||
| 33 | #if 1 | ||
| 34 | # if 1 | ||
| 35 | # include <sys/cdefs.h> | ||
| 36 | # endif | ||
| 37 | # include_next <sched.h> | ||
| 38 | #endif | ||
| 39 | |||
| 40 | #ifndef _GL_SCHED_H | ||
| 41 | #define _GL_SCHED_H | ||
| 42 | |||
| 43 | /* This file uses GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ | ||
| 44 | #if !_GL_CONFIG_H_INCLUDED | ||
| 45 | #error "Please include config.h first." | ||
| 46 | #endif | ||
| 47 | |||
| 48 | /* Get pid_t. | ||
| 49 | This is needed on glibc 2.11 (see | ||
| 50 | glibc bug <https://sourceware.org/PR13198>) | ||
| 51 | and Mac OS X 10.5. */ | ||
| 52 | #include <sys/types.h> | ||
| 53 | |||
| 54 | #ifdef __KLIBC__ | ||
| 55 | /* On OS/2 kLIBC, struct sched_param is in spawn.h. */ | ||
| 56 | # include <spawn.h> | ||
| 57 | #endif | ||
| 58 | |||
| 59 | #ifdef __VMS | ||
| 60 | /* On OpenVMS, struct sched_param is in <pthread.h>. */ | ||
| 61 | # include <pthread.h> | ||
| 62 | #endif | ||
| 63 | |||
| 64 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | ||
| 65 | /* C++ compatible function declaration macros. | ||
| 66 | Copyright (C) 2010-2025 Free Software Foundation, Inc. | ||
| 67 | |||
| 68 | This program is free software: you can redistribute it and/or modify it | ||
| 69 | under the terms of the GNU Lesser General Public License as published | ||
| 70 | by the Free Software Foundation; either version 2 of the License, or | ||
| 71 | (at your option) any later version. | ||
| 72 | |||
| 73 | This program is distributed in the hope that it will be useful, | ||
| 74 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 75 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 76 | Lesser General Public License for more details. | ||
| 77 | |||
| 78 | You should have received a copy of the GNU Lesser General Public License | ||
| 79 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 80 | |||
| 81 | #ifndef _GL_CXXDEFS_H | ||
| 82 | #define _GL_CXXDEFS_H | ||
| 83 | |||
| 84 | /* Begin/end the GNULIB_NAMESPACE namespace. */ | ||
| 85 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 86 | # define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE { | ||
| 87 | # define _GL_END_NAMESPACE } | ||
| 88 | #else | ||
| 89 | # define _GL_BEGIN_NAMESPACE | ||
| 90 | # define _GL_END_NAMESPACE | ||
| 91 | #endif | ||
| 92 | |||
| 93 | /* The three most frequent use cases of these macros are: | ||
| 94 | |||
| 95 | * For providing a substitute for a function that is missing on some | ||
| 96 | platforms, but is declared and works fine on the platforms on which | ||
| 97 | it exists: | ||
| 98 | |||
| 99 | #if @GNULIB_FOO@ | ||
| 100 | # if !@HAVE_FOO@ | ||
| 101 | _GL_FUNCDECL_SYS (foo, ...); | ||
| 102 | # endif | ||
| 103 | _GL_CXXALIAS_SYS (foo, ...); | ||
| 104 | _GL_CXXALIASWARN (foo); | ||
| 105 | #elif defined GNULIB_POSIXCHECK | ||
| 106 | ... | ||
| 107 | #endif | ||
| 108 | |||
| 109 | * For providing a replacement for a function that exists on all platforms, | ||
| 110 | but is broken/insufficient and needs to be replaced on some platforms: | ||
| 111 | |||
| 112 | #if @GNULIB_FOO@ | ||
| 113 | # if @REPLACE_FOO@ | ||
| 114 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 115 | # undef foo | ||
| 116 | # define foo rpl_foo | ||
| 117 | # endif | ||
| 118 | _GL_FUNCDECL_RPL (foo, ...); | ||
| 119 | _GL_CXXALIAS_RPL (foo, ...); | ||
| 120 | # else | ||
| 121 | _GL_CXXALIAS_SYS (foo, ...); | ||
| 122 | # endif | ||
| 123 | _GL_CXXALIASWARN (foo); | ||
| 124 | #elif defined GNULIB_POSIXCHECK | ||
| 125 | ... | ||
| 126 | #endif | ||
| 127 | |||
| 128 | * For providing a replacement for a function that exists on some platforms | ||
| 129 | but is broken/insufficient and needs to be replaced on some of them and | ||
| 130 | is additionally either missing or undeclared on some other platforms: | ||
| 131 | |||
| 132 | #if @GNULIB_FOO@ | ||
| 133 | # if @REPLACE_FOO@ | ||
| 134 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 135 | # undef foo | ||
| 136 | # define foo rpl_foo | ||
| 137 | # endif | ||
| 138 | _GL_FUNCDECL_RPL (foo, ...); | ||
| 139 | _GL_CXXALIAS_RPL (foo, ...); | ||
| 140 | # else | ||
| 141 | # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ | ||
| 142 | _GL_FUNCDECL_SYS (foo, ...); | ||
| 143 | # endif | ||
| 144 | _GL_CXXALIAS_SYS (foo, ...); | ||
| 145 | # endif | ||
| 146 | _GL_CXXALIASWARN (foo); | ||
| 147 | #elif defined GNULIB_POSIXCHECK | ||
| 148 | ... | ||
| 149 | #endif | ||
| 150 | */ | ||
| 151 | |||
| 152 | /* _GL_EXTERN_C declaration; | ||
| 153 | performs the declaration with C linkage. */ | ||
| 154 | #if defined __cplusplus | ||
| 155 | # define _GL_EXTERN_C extern "C" | ||
| 156 | #else | ||
| 157 | # define _GL_EXTERN_C extern | ||
| 158 | #endif | ||
| 159 | |||
| 160 | /* _GL_EXTERN_C_FUNC declaration; | ||
| 161 | performs the declaration of a function with C linkage. */ | ||
| 162 | #if defined __cplusplus | ||
| 163 | # define _GL_EXTERN_C_FUNC extern "C" | ||
| 164 | #else | ||
| 165 | /* In C mode, omit the 'extern' keyword, because attributes in bracket syntax | ||
| 166 | are not allowed between 'extern' and the return type (see gnulib-common.m4). | ||
| 167 | */ | ||
| 168 | # define _GL_EXTERN_C_FUNC | ||
| 169 | #endif | ||
| 170 | |||
| 171 | /* _GL_FUNCDECL_RPL (func, rettype, parameters, [attributes]); | ||
| 172 | declares a replacement function, named rpl_func, with the given prototype, | ||
| 173 | consisting of return type, parameters, and attributes. | ||
| 174 | Although attributes are optional, the comma before them is required | ||
| 175 | for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW, | ||
| 176 | if needed, must be placed after the _GL_FUNCDECL_RPL invocation, | ||
| 177 | at the end of the declaration. | ||
| 178 | Examples: | ||
| 179 | _GL_FUNCDECL_RPL (free, void, (void *ptr), ) _GL_ATTRIBUTE_NOTHROW; | ||
| 180 | _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...), | ||
| 181 | _GL_ARG_NONNULL ((1))); | ||
| 182 | |||
| 183 | Note: Attributes, such as _GL_ATTRIBUTE_DEPRECATED, are supported in front | ||
| 184 | of a _GL_FUNCDECL_RPL invocation only in C mode, not in C++ mode. (That's | ||
| 185 | because | ||
| 186 | [[...]] extern "C" <declaration>; | ||
| 187 | is invalid syntax in C++.) | ||
| 188 | */ | ||
| 189 | #define _GL_FUNCDECL_RPL(func,rettype,parameters,...) \ | ||
| 190 | _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters, __VA_ARGS__) | ||
| 191 | #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \ | ||
| 192 | _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters | ||
| 193 | |||
| 194 | /* _GL_FUNCDECL_SYS_NAME (func) expands to plain func if C++, and to | ||
| 195 | parenthesized func otherwise. Parenthesization is needed in C23 if | ||
| 196 | the function is like strchr and so is a qualifier-generic macro | ||
| 197 | that expands to something more complicated. */ | ||
| 198 | #ifdef __cplusplus | ||
| 199 | # define _GL_FUNCDECL_SYS_NAME(func) func | ||
| 200 | #else | ||
| 201 | # define _GL_FUNCDECL_SYS_NAME(func) (func) | ||
| 202 | #endif | ||
| 203 | |||
| 204 | /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]); | ||
| 205 | declares the system function, named func, with the given prototype, | ||
| 206 | consisting of return type, parameters, and attributes. | ||
| 207 | Although attributes are optional, the comma before them is required | ||
| 208 | for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW, | ||
| 209 | if needed, must be placed after the _GL_FUNCDECL_RPL invocation, | ||
| 210 | at the end of the declaration. | ||
| 211 | Examples: | ||
| 212 | _GL_FUNCDECL_SYS (getumask, mode_t, (void), ) _GL_ATTRIBUTE_NOTHROW; | ||
| 213 | _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD); | ||
| 214 | */ | ||
| 215 | #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \ | ||
| 216 | _GL_EXTERN_C_FUNC __VA_ARGS__ rettype _GL_FUNCDECL_SYS_NAME (func) parameters | ||
| 217 | |||
| 218 | /* _GL_CXXALIAS_RPL (func, rettype, parameters); | ||
| 219 | declares a C++ alias called GNULIB_NAMESPACE::func | ||
| 220 | that redirects to rpl_func, if GNULIB_NAMESPACE is defined. | ||
| 221 | Example: | ||
| 222 | _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); | ||
| 223 | |||
| 224 | Wrapping rpl_func in an object with an inline conversion operator | ||
| 225 | avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is | ||
| 226 | actually used in the program. */ | ||
| 227 | #define _GL_CXXALIAS_RPL(func,rettype,parameters) \ | ||
| 228 | _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) | ||
| 229 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 230 | # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ | ||
| 231 | namespace GNULIB_NAMESPACE \ | ||
| 232 | { \ | ||
| 233 | static const struct _gl_ ## func ## _wrapper \ | ||
| 234 | { \ | ||
| 235 | typedef rettype (*type) parameters; \ | ||
| 236 | \ | ||
| 237 | inline operator type () const \ | ||
| 238 | { \ | ||
| 239 | return ::rpl_func; \ | ||
| 240 | } \ | ||
| 241 | } func = {}; \ | ||
| 242 | } \ | ||
| 243 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 244 | #else | ||
| 245 | # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ | ||
| 246 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 247 | #endif | ||
| 248 | |||
| 249 | /* _GL_CXXALIAS_MDA (func, rettype, parameters); | ||
| 250 | is to be used when func is a Microsoft deprecated alias, on native Windows. | ||
| 251 | It declares a C++ alias called GNULIB_NAMESPACE::func | ||
| 252 | that redirects to _func, if GNULIB_NAMESPACE is defined. | ||
| 253 | Example: | ||
| 254 | _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...)); | ||
| 255 | */ | ||
| 256 | #define _GL_CXXALIAS_MDA(func,rettype,parameters) \ | ||
| 257 | _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters) | ||
| 258 | |||
| 259 | /* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); | ||
| 260 | is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); | ||
| 261 | except that the C function rpl_func may have a slightly different | ||
| 262 | declaration. A cast is used to silence the "invalid conversion" error | ||
| 263 | that would otherwise occur. */ | ||
| 264 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 265 | # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ | ||
| 266 | namespace GNULIB_NAMESPACE \ | ||
| 267 | { \ | ||
| 268 | static const struct _gl_ ## func ## _wrapper \ | ||
| 269 | { \ | ||
| 270 | typedef rettype (*type) parameters; \ | ||
| 271 | \ | ||
| 272 | inline operator type () const \ | ||
| 273 | { \ | ||
| 274 | return reinterpret_cast<type>(::rpl_func); \ | ||
| 275 | } \ | ||
| 276 | } func = {}; \ | ||
| 277 | } \ | ||
| 278 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 279 | #else | ||
| 280 | # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ | ||
| 281 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 282 | #endif | ||
| 283 | |||
| 284 | /* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters); | ||
| 285 | is like _GL_CXXALIAS_MDA (func, rettype, parameters); | ||
| 286 | except that the C function func may have a slightly different declaration. | ||
| 287 | A cast is used to silence the "invalid conversion" error that would | ||
| 288 | otherwise occur. */ | ||
| 289 | #define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \ | ||
| 290 | _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters) | ||
| 291 | |||
| 292 | /* _GL_CXXALIAS_SYS (func, rettype, parameters); | ||
| 293 | declares a C++ alias called GNULIB_NAMESPACE::func | ||
| 294 | that redirects to the system provided function func, if GNULIB_NAMESPACE | ||
| 295 | is defined. | ||
| 296 | Example: | ||
| 297 | _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); | ||
| 298 | |||
| 299 | Wrapping func in an object with an inline conversion operator | ||
| 300 | avoids a reference to func unless GNULIB_NAMESPACE::func is | ||
| 301 | actually used in the program. */ | ||
| 302 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 303 | # define _GL_CXXALIAS_SYS(func,rettype,parameters) \ | ||
| 304 | namespace GNULIB_NAMESPACE \ | ||
| 305 | { \ | ||
| 306 | static const struct _gl_ ## func ## _wrapper \ | ||
| 307 | { \ | ||
| 308 | typedef rettype (*type) parameters; \ | ||
| 309 | \ | ||
| 310 | inline operator type () const \ | ||
| 311 | { \ | ||
| 312 | return ::func; \ | ||
| 313 | } \ | ||
| 314 | } func = {}; \ | ||
| 315 | } \ | ||
| 316 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 317 | #else | ||
| 318 | # define _GL_CXXALIAS_SYS(func,rettype,parameters) \ | ||
| 319 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 320 | #endif | ||
| 321 | |||
| 322 | /* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); | ||
| 323 | is like _GL_CXXALIAS_SYS (func, rettype, parameters); | ||
| 324 | except that the C function func may have a slightly different declaration. | ||
| 325 | A cast is used to silence the "invalid conversion" error that would | ||
| 326 | otherwise occur. */ | ||
| 327 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 328 | # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ | ||
| 329 | namespace GNULIB_NAMESPACE \ | ||
| 330 | { \ | ||
| 331 | static const struct _gl_ ## func ## _wrapper \ | ||
| 332 | { \ | ||
| 333 | typedef rettype (*type) parameters; \ | ||
| 334 | \ | ||
| 335 | inline operator type () const \ | ||
| 336 | { \ | ||
| 337 | return reinterpret_cast<type>(::func); \ | ||
| 338 | } \ | ||
| 339 | } func = {}; \ | ||
| 340 | } \ | ||
| 341 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 342 | #else | ||
| 343 | # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ | ||
| 344 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 345 | #endif | ||
| 346 | |||
| 347 | /* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); | ||
| 348 | is like _GL_CXXALIAS_SYS (func, rettype, parameters); | ||
| 349 | except that the C function is picked among a set of overloaded functions, | ||
| 350 | namely the one with rettype2 and parameters2. Two consecutive casts | ||
| 351 | are used to silence the "cannot find a match" and "invalid conversion" | ||
| 352 | errors that would otherwise occur. */ | ||
| 353 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 354 | /* The outer cast must be a reinterpret_cast. | ||
| 355 | The inner cast: When the function is defined as a set of overloaded | ||
| 356 | functions, it works as a static_cast<>, choosing the designated variant. | ||
| 357 | When the function is defined as a single variant, it works as a | ||
| 358 | reinterpret_cast<>. The parenthesized cast syntax works both ways. */ | ||
| 359 | # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ | ||
| 360 | namespace GNULIB_NAMESPACE \ | ||
| 361 | { \ | ||
| 362 | static const struct _gl_ ## func ## _wrapper \ | ||
| 363 | { \ | ||
| 364 | typedef rettype (*type) parameters; \ | ||
| 365 | \ | ||
| 366 | inline operator type () const \ | ||
| 367 | { \ | ||
| 368 | return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \ | ||
| 369 | } \ | ||
| 370 | } func = {}; \ | ||
| 371 | } \ | ||
| 372 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 373 | #else | ||
| 374 | # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ | ||
| 375 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 376 | #endif | ||
| 377 | |||
| 378 | /* _GL_CXXALIASWARN (func); | ||
| 379 | causes a warning to be emitted when ::func is used but not when | ||
| 380 | GNULIB_NAMESPACE::func is used. func must be defined without overloaded | ||
| 381 | variants. */ | ||
| 382 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 383 | # define _GL_CXXALIASWARN(func) \ | ||
| 384 | _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) | ||
| 385 | # define _GL_CXXALIASWARN_1(func,namespace) \ | ||
| 386 | _GL_CXXALIASWARN_2 (func, namespace) | ||
| 387 | /* To work around GCC bug <https://gcc.gnu.org/PR43881>, | ||
| 388 | we enable the warning only when not optimizing. */ | ||
| 389 | # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) | ||
| 390 | # define _GL_CXXALIASWARN_2(func,namespace) \ | ||
| 391 | _GL_WARN_ON_USE (func, \ | ||
| 392 | "The symbol ::" #func " refers to the system function. " \ | ||
| 393 | "Use " #namespace "::" #func " instead.") | ||
| 394 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING | ||
| 395 | # define _GL_CXXALIASWARN_2(func,namespace) \ | ||
| 396 | extern __typeof__ (func) func | ||
| 397 | # else | ||
| 398 | # define _GL_CXXALIASWARN_2(func,namespace) \ | ||
| 399 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 400 | # endif | ||
| 401 | #else | ||
| 402 | # define _GL_CXXALIASWARN(func) \ | ||
| 403 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 404 | #endif | ||
| 405 | |||
| 406 | /* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); | ||
| 407 | causes a warning to be emitted when the given overloaded variant of ::func | ||
| 408 | is used but not when GNULIB_NAMESPACE::func is used. */ | ||
| 409 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 410 | # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ | ||
| 411 | _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ | ||
| 412 | GNULIB_NAMESPACE) | ||
| 413 | # define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ | ||
| 414 | _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) | ||
| 415 | /* To work around GCC bug <https://gcc.gnu.org/PR43881>, | ||
| 416 | we enable the warning only when not optimizing. */ | ||
| 417 | # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) | ||
| 418 | # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ | ||
| 419 | _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \ | ||
| 420 | "The symbol ::" #func " refers to the system function. " \ | ||
| 421 | "Use " #namespace "::" #func " instead.") | ||
| 422 | # else | ||
| 423 | # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ | ||
| 424 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 425 | # endif | ||
| 426 | #else | ||
| 427 | # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ | ||
| 428 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 429 | #endif | ||
| 430 | |||
| 431 | #endif /* _GL_CXXDEFS_H */ | ||
| 432 | |||
| 433 | /* The definition of _GL_WARN_ON_USE is copied here. */ | ||
| 434 | /* A C macro for emitting warnings if a function is used. | ||
| 435 | Copyright (C) 2010-2025 Free Software Foundation, Inc. | ||
| 436 | |||
| 437 | This program is free software: you can redistribute it and/or modify it | ||
| 438 | under the terms of the GNU Lesser General Public License as published | ||
| 439 | by the Free Software Foundation; either version 2 of the License, or | ||
| 440 | (at your option) any later version. | ||
| 441 | |||
| 442 | This program is distributed in the hope that it will be useful, | ||
| 443 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 444 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 445 | Lesser General Public License for more details. | ||
| 446 | |||
| 447 | You should have received a copy of the GNU Lesser General Public License | ||
| 448 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 449 | |||
| 450 | /* _GL_WARN_ON_USE (function, "literal string") issues a declaration | ||
| 451 | for FUNCTION which will then trigger a compiler warning containing | ||
| 452 | the text of "literal string" anywhere that function is called, if | ||
| 453 | supported by the compiler. If the compiler does not support this | ||
| 454 | feature, the macro expands to an unused extern declaration. | ||
| 455 | |||
| 456 | _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the | ||
| 457 | attribute used in _GL_WARN_ON_USE. If the compiler does not support | ||
| 458 | this feature, it expands to empty. | ||
| 459 | |||
| 460 | These macros are useful for marking a function as a potential | ||
| 461 | portability trap, with the intent that "literal string" include | ||
| 462 | instructions on the replacement function that should be used | ||
| 463 | instead. | ||
| 464 | _GL_WARN_ON_USE is for functions with 'extern' linkage. | ||
| 465 | _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline' | ||
| 466 | linkage. | ||
| 467 | |||
| 468 | _GL_WARN_ON_USE should not be used more than once for a given function | ||
| 469 | in a given compilation unit (because this may generate a warning even | ||
| 470 | if the function is never called). | ||
| 471 | |||
| 472 | However, one of the reasons that a function is a portability trap is | ||
| 473 | if it has the wrong signature. Declaring FUNCTION with a different | ||
| 474 | signature in C is a compilation error, so this macro must use the | ||
| 475 | same type as any existing declaration so that programs that avoid | ||
| 476 | the problematic FUNCTION do not fail to compile merely because they | ||
| 477 | included a header that poisoned the function. But this implies that | ||
| 478 | _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already | ||
| 479 | have a declaration. Use of this macro implies that there must not | ||
| 480 | be any other macro hiding the declaration of FUNCTION; but | ||
| 481 | undefining FUNCTION first is part of the poisoning process anyway | ||
| 482 | (although for symbols that are provided only via a macro, the result | ||
| 483 | is a compilation error rather than a warning containing | ||
| 484 | "literal string"). Also note that in C++, it is only safe to use if | ||
| 485 | FUNCTION has no overloads. | ||
| 486 | |||
| 487 | For an example, it is possible to poison 'getline' by: | ||
| 488 | - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]], | ||
| 489 | [getline]) in configure.ac, which potentially defines | ||
| 490 | HAVE_RAW_DECL_GETLINE | ||
| 491 | - adding this code to a header that wraps the system <stdio.h>: | ||
| 492 | #undef getline | ||
| 493 | #if HAVE_RAW_DECL_GETLINE | ||
| 494 | _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but" | ||
| 495 | "not universally present; use the gnulib module getline"); | ||
| 496 | #endif | ||
| 497 | |||
| 498 | It is not possible to directly poison global variables. But it is | ||
| 499 | possible to write a wrapper accessor function, and poison that | ||
| 500 | (less common usage, like &environ, will cause a compilation error | ||
| 501 | rather than issue the nice warning, but the end result of informing | ||
| 502 | the developer about their portability problem is still achieved): | ||
| 503 | #if HAVE_RAW_DECL_ENVIRON | ||
| 504 | static char *** | ||
| 505 | rpl_environ (void) { return &environ; } | ||
| 506 | _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared"); | ||
| 507 | # undef environ | ||
| 508 | # define environ (*rpl_environ ()) | ||
| 509 | #endif | ||
| 510 | or better (avoiding contradictory use of 'static' and 'extern'): | ||
| 511 | #if HAVE_RAW_DECL_ENVIRON | ||
| 512 | static char *** | ||
| 513 | _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared") | ||
| 514 | rpl_environ (void) { return &environ; } | ||
| 515 | # undef environ | ||
| 516 | # define environ (*rpl_environ ()) | ||
| 517 | #endif | ||
| 518 | */ | ||
| 519 | #ifndef _GL_WARN_ON_USE | ||
| 520 | |||
| 521 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ | ||
| 522 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ | ||
| 523 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 524 | _GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message))) | ||
| 525 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) \ | ||
| 526 | __attribute__ ((__warning__ (message))) | ||
| 527 | # elif __clang_major__ >= 4 | ||
| 528 | /* Another compiler attribute is available in clang. */ | ||
| 529 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 530 | _GL_WARN_EXTERN_C __typeof__ (function) function \ | ||
| 531 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) | ||
| 532 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) \ | ||
| 533 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) | ||
| 534 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING | ||
| 535 | /* Verify the existence of the function. */ | ||
| 536 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 537 | _GL_WARN_EXTERN_C __typeof__ (function) function | ||
| 538 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) | ||
| 539 | # else /* Unsupported. */ | ||
| 540 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 541 | _GL_WARN_EXTERN_C int _gl_warn_on_use | ||
| 542 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) | ||
| 543 | # endif | ||
| 544 | #endif | ||
| 545 | |||
| 546 | /* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message") | ||
| 547 | is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode the | ||
| 548 | function is declared with the given prototype, consisting of return type, | ||
| 549 | parameters, and attributes. | ||
| 550 | This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does | ||
| 551 | not work in this case. */ | ||
| 552 | #ifndef _GL_WARN_ON_USE_CXX | ||
| 553 | # if !defined __cplusplus | ||
| 554 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 555 | _GL_WARN_ON_USE (function, msg) | ||
| 556 | # else | ||
| 557 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ | ||
| 558 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ | ||
| 559 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 560 | extern rettype_gcc function parameters_and_attributes \ | ||
| 561 | __attribute__ ((__warning__ (msg))) | ||
| 562 | # elif __clang_major__ >= 4 | ||
| 563 | /* Another compiler attribute is available in clang. */ | ||
| 564 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 565 | extern rettype_clang function parameters_and_attributes \ | ||
| 566 | __attribute__ ((__diagnose_if__ (1, msg, "warning"))) | ||
| 567 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING | ||
| 568 | /* Verify the existence of the function. */ | ||
| 569 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 570 | extern rettype_gcc function parameters_and_attributes | ||
| 571 | # else /* Unsupported. */ | ||
| 572 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 573 | _GL_WARN_EXTERN_C int _gl_warn_on_use | ||
| 574 | # endif | ||
| 575 | # endif | ||
| 576 | #endif | ||
| 577 | |||
| 578 | /* _GL_WARN_EXTERN_C declaration; | ||
| 579 | performs the declaration with C linkage. */ | ||
| 580 | #ifndef _GL_WARN_EXTERN_C | ||
| 581 | # if defined __cplusplus | ||
| 582 | # define _GL_WARN_EXTERN_C extern "C" | ||
| 583 | # else | ||
| 584 | # define _GL_WARN_EXTERN_C extern | ||
| 585 | # endif | ||
| 586 | #endif | ||
| 587 | |||
| 588 | #if !1 | ||
| 589 | |||
| 590 | # if !GNULIB_defined_struct_sched_param | ||
| 591 | struct sched_param | ||
| 592 | { | ||
| 593 | int sched_priority; | ||
| 594 | }; | ||
| 595 | # define GNULIB_defined_struct_sched_param 1 | ||
| 596 | # endif | ||
| 597 | |||
| 598 | #endif | ||
| 599 | |||
| 600 | #if !(defined SCHED_FIFO && defined SCHED_RR && defined SCHED_OTHER) | ||
| 601 | # define SCHED_FIFO 1 | ||
| 602 | # define SCHED_RR 2 | ||
| 603 | # define SCHED_OTHER 0 | ||
| 604 | #endif | ||
| 605 | |||
| 606 | #if 0 | ||
| 607 | # if 0 | ||
| 608 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 609 | # undef sched_yield | ||
| 610 | # define sched_yield rpl_sched_yield | ||
| 611 | # endif | ||
| 612 | _GL_FUNCDECL_RPL (sched_yield, int, (void), ); | ||
| 613 | _GL_CXXALIAS_RPL (sched_yield, int, (void)); | ||
| 614 | # else | ||
| 615 | # if !1 | ||
| 616 | _GL_FUNCDECL_SYS (sched_yield, int, (void), ); | ||
| 617 | # endif | ||
| 618 | _GL_CXXALIAS_SYS (sched_yield, int, (void)); | ||
| 619 | # endif | ||
| 620 | # if __GLIBC__ >= 2 | ||
| 621 | _GL_CXXALIASWARN (sched_yield); | ||
| 622 | # endif | ||
| 623 | #elif defined GNULIB_POSIXCHECK | ||
| 624 | # if HAVE_RAW_DECL_SCHED_YIELD | ||
| 625 | _GL_WARN_ON_USE (sched_yield, "sched_yield is not portable - " | ||
| 626 | "use gnulib module sched_yield for portability"); | ||
| 627 | # endif | ||
| 628 | #endif | ||
| 629 | |||
| 630 | #endif /* _GL_SCHED_H */ | ||
| 631 | #endif /* _GL_SCHED_H */ | ||
diff --git a/gl/sched.in.h b/gl/sched.in.h new file mode 100644 index 00000000..5b4034c3 --- /dev/null +++ b/gl/sched.in.h | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | /* A GNU-like <sched.h>. | ||
| 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #ifndef _@GUARD_PREFIX@_SCHED_H | ||
| 18 | |||
| 19 | #if __GNUC__ >= 3 | ||
| 20 | @PRAGMA_SYSTEM_HEADER@ | ||
| 21 | #endif | ||
| 22 | @PRAGMA_COLUMNS@ | ||
| 23 | |||
| 24 | /* This file uses #include_next of a system file that defines time_t. | ||
| 25 | For the 'year2038' module to work right, <config.h> needs to have been | ||
| 26 | included before. */ | ||
| 27 | #if !_GL_CONFIG_H_INCLUDED | ||
| 28 | #error "Please include config.h first." | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* The include_next requires a split double-inclusion guard. */ | ||
| 32 | #if @HAVE_SCHED_H@ | ||
| 33 | # if @HAVE_SYS_CDEFS_H@ | ||
| 34 | # include <sys/cdefs.h> | ||
| 35 | # endif | ||
| 36 | # @INCLUDE_NEXT@ @NEXT_SCHED_H@ | ||
| 37 | #endif | ||
| 38 | |||
| 39 | #ifndef _@GUARD_PREFIX@_SCHED_H | ||
| 40 | #define _@GUARD_PREFIX@_SCHED_H | ||
| 41 | |||
| 42 | /* This file uses GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ | ||
| 43 | #if !_GL_CONFIG_H_INCLUDED | ||
| 44 | #error "Please include config.h first." | ||
| 45 | #endif | ||
| 46 | |||
| 47 | /* Get pid_t. | ||
| 48 | This is needed on glibc 2.11 (see | ||
| 49 | glibc bug <https://sourceware.org/bugzilla/show_bug.cgi?id=13198>) | ||
| 50 | and Mac OS X 10.5. */ | ||
| 51 | #include <sys/types.h> | ||
| 52 | |||
| 53 | #ifdef __KLIBC__ | ||
| 54 | /* On OS/2 kLIBC, struct sched_param is in spawn.h. */ | ||
| 55 | # include <spawn.h> | ||
| 56 | #endif | ||
| 57 | |||
| 58 | #ifdef __VMS | ||
| 59 | /* On OpenVMS, struct sched_param is in <pthread.h>. */ | ||
| 60 | # include <pthread.h> | ||
| 61 | #endif | ||
| 62 | |||
| 63 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | ||
| 64 | |||
| 65 | /* The definition of _GL_WARN_ON_USE is copied here. */ | ||
| 66 | |||
| 67 | #if !@HAVE_STRUCT_SCHED_PARAM@ | ||
| 68 | |||
| 69 | # if !GNULIB_defined_struct_sched_param | ||
| 70 | struct sched_param | ||
| 71 | { | ||
| 72 | int sched_priority; | ||
| 73 | }; | ||
| 74 | # define GNULIB_defined_struct_sched_param 1 | ||
| 75 | # endif | ||
| 76 | |||
| 77 | #endif | ||
| 78 | |||
| 79 | #if !(defined SCHED_FIFO && defined SCHED_RR && defined SCHED_OTHER) | ||
| 80 | # define SCHED_FIFO 1 | ||
| 81 | # define SCHED_RR 2 | ||
| 82 | # define SCHED_OTHER 0 | ||
| 83 | #endif | ||
| 84 | |||
| 85 | #if @GNULIB_SCHED_YIELD@ | ||
| 86 | # if @REPLACE_SCHED_YIELD@ | ||
| 87 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 88 | # undef sched_yield | ||
| 89 | # define sched_yield rpl_sched_yield | ||
| 90 | # endif | ||
| 91 | _GL_FUNCDECL_RPL (sched_yield, int, (void), ); | ||
| 92 | _GL_CXXALIAS_RPL (sched_yield, int, (void)); | ||
| 93 | # else | ||
| 94 | # if !@HAVE_SCHED_YIELD@ | ||
| 95 | _GL_FUNCDECL_SYS (sched_yield, int, (void), ); | ||
| 96 | # endif | ||
| 97 | _GL_CXXALIAS_SYS (sched_yield, int, (void)); | ||
| 98 | # endif | ||
| 99 | # if __GLIBC__ >= 2 | ||
| 100 | _GL_CXXALIASWARN (sched_yield); | ||
| 101 | # endif | ||
| 102 | #elif defined GNULIB_POSIXCHECK | ||
| 103 | # undef sched_yield | ||
| 104 | # if HAVE_RAW_DECL_SCHED_YIELD | ||
| 105 | _GL_WARN_ON_USE (sched_yield, "sched_yield is not portable - " | ||
| 106 | "use gnulib module sched_yield for portability"); | ||
| 107 | # endif | ||
| 108 | #endif | ||
| 109 | |||
| 110 | #endif /* _@GUARD_PREFIX@_SCHED_H */ | ||
| 111 | #endif /* _@GUARD_PREFIX@_SCHED_H */ | ||
diff --git a/gl/setenv.c b/gl/setenv.c index 9e2e9e2f..ef301d41 100644 --- a/gl/setenv.c +++ b/gl/setenv.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 1992, 1995-2003, 2005-2024 Free Software Foundation, Inc. | 1 | /* Copyright (C) 1992, 1995-2003, 2005-2025 Free Software Foundation, Inc. |
| 2 | This file is part of the GNU C Library. | 2 | This file is part of the GNU C Library. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| @@ -38,11 +38,23 @@ | |||
| 38 | # include <unistd.h> | 38 | # include <unistd.h> |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | #if defined _WIN32 && ! defined __CYGWIN__ | ||
| 42 | # define WIN32_LEAN_AND_MEAN | ||
| 43 | # include <windows.h> | ||
| 44 | #endif | ||
| 45 | |||
| 41 | #if !_LIBC | 46 | #if !_LIBC |
| 42 | # include "malloca.h" | 47 | # include "malloca.h" |
| 43 | #endif | 48 | #endif |
| 44 | 49 | ||
| 50 | #if defined _WIN32 && ! defined __CYGWIN__ | ||
| 51 | /* Don't assume that UNICODE is not defined. */ | ||
| 52 | # undef SetEnvironmentVariable | ||
| 53 | # define SetEnvironmentVariable SetEnvironmentVariableA | ||
| 54 | #endif | ||
| 55 | |||
| 45 | #if _LIBC || !HAVE_SETENV | 56 | #if _LIBC || !HAVE_SETENV |
| 57 | #if !HAVE_DECL__PUTENV | ||
| 46 | 58 | ||
| 47 | #if !_LIBC | 59 | #if !_LIBC |
| 48 | # define __environ environ | 60 | # define __environ environ |
| @@ -215,8 +227,7 @@ __add_to_environ (const char *name, const char *value, const char *combined, | |||
| 215 | } | 227 | } |
| 216 | 228 | ||
| 217 | if (__environ != last_environ) | 229 | if (__environ != last_environ) |
| 218 | memcpy ((char *) new_environ, (char *) __environ, | 230 | memcpy (new_environ, __environ, size * sizeof (char *)); |
| 219 | size * sizeof (char *)); | ||
| 220 | 231 | ||
| 221 | new_environ[size + 1] = NULL; | 232 | new_environ[size + 1] = NULL; |
| 222 | 233 | ||
| @@ -343,6 +354,84 @@ weak_alias (__setenv, setenv) | |||
| 343 | weak_alias (__clearenv, clearenv) | 354 | weak_alias (__clearenv, clearenv) |
| 344 | #endif | 355 | #endif |
| 345 | 356 | ||
| 357 | #else /* HAVE_DECL__PUTENV */ | ||
| 358 | /* Native Windows */ | ||
| 359 | |||
| 360 | int | ||
| 361 | setenv (const char *name, const char *value, int replace) | ||
| 362 | { | ||
| 363 | if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) | ||
| 364 | { | ||
| 365 | errno = EINVAL; | ||
| 366 | return -1; | ||
| 367 | } | ||
| 368 | |||
| 369 | /* The Microsoft documentation | ||
| 370 | <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/putenv-wputenv> | ||
| 371 | says: | ||
| 372 | "Don't change an environment entry directly: instead, | ||
| 373 | use _putenv or _wputenv to change it." | ||
| 374 | Note: Microsoft's _putenv updates not only the contents of _environ but | ||
| 375 | also the contents of _wenviron, so that both are in kept in sync. */ | ||
| 376 | const char *existing_value = getenv (name); | ||
| 377 | if (existing_value != NULL) | ||
| 378 | { | ||
| 379 | if (replace) | ||
| 380 | { | ||
| 381 | if (strcmp (existing_value, value) == 0) | ||
| 382 | /* No need to allocate memory. */ | ||
| 383 | return 0; | ||
| 384 | } | ||
| 385 | else | ||
| 386 | /* Keep the existing value. */ | ||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | /* Allocate a new environment entry in the heap. */ | ||
| 390 | /* _putenv ("NAME=") unsets NAME, so if VALUE is the empty string, invoke | ||
| 391 | _putenv ("NAME= ") and fix up the result afterwards. */ | ||
| 392 | const char *value_ = (value[0] == '\0' ? " " : value); | ||
| 393 | size_t name_len = strlen (name); | ||
| 394 | size_t value_len = strlen (value_); | ||
| 395 | char *string = (char *) malloc (name_len + 1 + value_len + 1); | ||
| 396 | if (string == NULL) | ||
| 397 | return -1; | ||
| 398 | memcpy (string, name, name_len); | ||
| 399 | string[name_len] = '='; | ||
| 400 | memcpy (&string[name_len + 1], value_, value_len + 1); | ||
| 401 | /* Use _putenv. */ | ||
| 402 | if (_putenv (string) < 0) | ||
| 403 | return -1; | ||
| 404 | if (value[0] == '\0') | ||
| 405 | { | ||
| 406 | /* Fix up the result. */ | ||
| 407 | char *new_value = getenv (name); | ||
| 408 | if (new_value != NULL && new_value[0] == ' ' && new_value[1] == '\0') | ||
| 409 | new_value[0] = '\0'; | ||
| 410 | # if defined _WIN32 && ! defined __CYGWIN__ | ||
| 411 | /* _putenv propagated "NAME= " into the subprocess environment; | ||
| 412 | fix that by calling SetEnvironmentVariable directly. */ | ||
| 413 | /* Documentation: | ||
| 414 | <https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setenvironmentvariable> */ | ||
| 415 | if (!SetEnvironmentVariable (name, "")) | ||
| 416 | { | ||
| 417 | switch (GetLastError ()) | ||
| 418 | { | ||
| 419 | case ERROR_NOT_ENOUGH_MEMORY: | ||
| 420 | case ERROR_OUTOFMEMORY: | ||
| 421 | errno = ENOMEM; | ||
| 422 | break; | ||
| 423 | default: | ||
| 424 | errno = EINVAL; | ||
| 425 | break; | ||
| 426 | } | ||
| 427 | return -1; | ||
| 428 | } | ||
| 429 | # endif | ||
| 430 | } | ||
| 431 | return 0; | ||
| 432 | } | ||
| 433 | |||
| 434 | #endif /* HAVE_DECL__PUTENV */ | ||
| 346 | #endif /* _LIBC || !HAVE_SETENV */ | 435 | #endif /* _LIBC || !HAVE_SETENV */ |
| 347 | 436 | ||
| 348 | /* The rest of this file is called into use when replacing an existing | 437 | /* The rest of this file is called into use when replacing an existing |
| @@ -360,7 +449,7 @@ int | |||
| 360 | rpl_setenv (const char *name, const char *value, int replace) | 449 | rpl_setenv (const char *name, const char *value, int replace) |
| 361 | { | 450 | { |
| 362 | int result; | 451 | int result; |
| 363 | if (!name || !*name || strchr (name, '=')) | 452 | if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) |
| 364 | { | 453 | { |
| 365 | errno = EINVAL; | 454 | errno = EINVAL; |
| 366 | return -1; | 455 | return -1; |
diff --git a/gl/setlocale-lock.c b/gl/setlocale-lock.c index 192489c4..87e0048c 100644 --- a/gl/setlocale-lock.c +++ b/gl/setlocale-lock.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Return the internal lock used by setlocale_null_r. | 1 | /* Return the internal lock used by setlocale_null_r. |
| 2 | Copyright (C) 2019-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/setlocale_null-unlocked.c b/gl/setlocale_null-unlocked.c index 0a86f0df..72729e6b 100644 --- a/gl/setlocale_null-unlocked.c +++ b/gl/setlocale_null-unlocked.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Query the name of the current global locale, without locking. | 1 | /* Query the name of the current global locale, without locking. |
| 2 | Copyright (C) 2019-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/setlocale_null.c b/gl/setlocale_null.c index 5ecf413d..29889642 100644 --- a/gl/setlocale_null.c +++ b/gl/setlocale_null.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Query the name of the current global locale. | 1 | /* Query the name of the current global locale. |
| 2 | Copyright (C) 2019-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/setlocale_null.h b/gl/setlocale_null.h index 966c53cf..3fcb7a82 100644 --- a/gl/setlocale_null.h +++ b/gl/setlocale_null.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Query the name of the current global locale. | 1 | /* Query the name of the current global locale. |
| 2 | Copyright (C) 2019-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/sha256-stream.c b/gl/sha256-stream.c index 08d24b7b..e2668078 100644 --- a/gl/sha256-stream.c +++ b/gl/sha256-stream.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* sha256.c - Functions to compute SHA256 and SHA224 message digest of files or | 1 | /* sha256.c - Functions to compute SHA256 and SHA224 message digest of files or |
| 2 | memory blocks according to the NIST specification FIPS-180-2. | 2 | memory blocks according to the NIST specification FIPS-180-2. |
| 3 | 3 | ||
| 4 | Copyright (C) 2005-2006, 2008-2024 Free Software Foundation, Inc. | 4 | Copyright (C) 2005-2006, 2008-2025 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
| 7 | it under the terms of the GNU Lesser General Public License as | 7 | it under the terms of the GNU Lesser General Public License as |
| @@ -23,9 +23,6 @@ | |||
| 23 | #include <config.h> | 23 | #include <config.h> |
| 24 | 24 | ||
| 25 | /* Specification. */ | 25 | /* Specification. */ |
| 26 | #if HAVE_OPENSSL_SHA256 | ||
| 27 | # define GL_OPENSSL_INLINE _GL_EXTERN_INLINE | ||
| 28 | #endif | ||
| 29 | #include "sha256.h" | 26 | #include "sha256.h" |
| 30 | 27 | ||
| 31 | #include <stdlib.h> | 28 | #include <stdlib.h> |
| @@ -136,10 +133,3 @@ sha224_stream (FILE *stream, void *resblock) | |||
| 136 | return shaxxx_stream (stream, "sha224", resblock, SHA224_DIGEST_SIZE, | 133 | return shaxxx_stream (stream, "sha224", resblock, SHA224_DIGEST_SIZE, |
| 137 | sha224_init_ctx, sha224_finish_ctx); | 134 | sha224_init_ctx, sha224_finish_ctx); |
| 138 | } | 135 | } |
| 139 | |||
| 140 | /* | ||
| 141 | * Hey Emacs! | ||
| 142 | * Local Variables: | ||
| 143 | * coding: utf-8 | ||
| 144 | * End: | ||
| 145 | */ | ||
diff --git a/gl/sha256.c b/gl/sha256.c index fe7c5446..9358faff 100644 --- a/gl/sha256.c +++ b/gl/sha256.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* sha256.c - Functions to compute SHA256 and SHA224 message digest of files or | 1 | /* sha256.c - Functions to compute SHA256 and SHA224 message digest of files or |
| 2 | memory blocks according to the NIST specification FIPS-180-2. | 2 | memory blocks according to the NIST specification FIPS-180-2. |
| 3 | 3 | ||
| 4 | Copyright (C) 2005-2006, 2008-2024 Free Software Foundation, Inc. | 4 | Copyright (C) 2005-2006, 2008-2025 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
| 7 | it under the terms of the GNU Lesser General Public License as | 7 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/sha256.h b/gl/sha256.h index a9d7abb8..cd1a9fe3 100644 --- a/gl/sha256.h +++ b/gl/sha256.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Declarations of functions and data types used for SHA256 and SHA224 sum | 1 | /* Declarations of functions and data types used for SHA256 and SHA224 sum |
| 2 | library functions. | 2 | library functions. |
| 3 | Copyright (C) 2005-2006, 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2005-2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/size_max.h b/gl/size_max.h index bd2eb43e..93eb96a6 100644 --- a/gl/size_max.h +++ b/gl/size_max.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* size_max.h -- declare SIZE_MAX through system headers | 1 | /* size_max.h -- declare SIZE_MAX through system headers |
| 2 | Copyright (C) 2005-2006, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2006, 2009-2025 Free Software Foundation, Inc. |
| 3 | Written by Simon Josefsson. | 3 | Written by Simon Josefsson. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/snprintf.c b/gl/snprintf.c index c1b93562..edeee083 100644 --- a/gl/snprintf.c +++ b/gl/snprintf.c | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* Formatted output to strings. | 1 | /* Formatted output to strings. |
| 2 | Copyright (C) 2004, 2006-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2004, 2006-2025 Free Software Foundation, Inc. |
| 3 | Written by Simon Josefsson and Paul Eggert. | ||
| 4 | 3 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -23,49 +22,25 @@ | |||
| 23 | #include <errno.h> | 22 | #include <errno.h> |
| 24 | #include <limits.h> | 23 | #include <limits.h> |
| 25 | #include <stdarg.h> | 24 | #include <stdarg.h> |
| 26 | #include <stdlib.h> | 25 | #include <stdint.h> |
| 27 | #include <string.h> | ||
| 28 | 26 | ||
| 29 | #include "vasnprintf.h" | ||
| 30 | |||
| 31 | /* Print formatted output to string STR. Similar to sprintf, but | ||
| 32 | additional length SIZE limit how much is written into STR. Returns | ||
| 33 | string length of formatted string (which may be larger than SIZE). | ||
| 34 | STR may be NULL, in which case nothing will be written. On error, | ||
| 35 | return a negative value. */ | ||
| 36 | int | 27 | int |
| 37 | snprintf (char *str, size_t size, const char *format, ...) | 28 | snprintf (char *str, size_t size, const char *format, ...) |
| 38 | { | 29 | { |
| 39 | char *output; | ||
| 40 | size_t len; | ||
| 41 | size_t lenbuf = size; | ||
| 42 | va_list args; | 30 | va_list args; |
| 31 | ptrdiff_t ret; | ||
| 43 | 32 | ||
| 44 | va_start (args, format); | 33 | va_start (args, format); |
| 45 | output = vasnprintf (str, &lenbuf, format, args); | 34 | ret = vsnzprintf (str, size, format, args); |
| 46 | len = lenbuf; | ||
| 47 | va_end (args); | 35 | va_end (args); |
| 48 | 36 | ||
| 49 | if (!output) | 37 | #if PTRDIFF_MAX > INT_MAX |
| 50 | return -1; | 38 | if (ret > INT_MAX) |
| 51 | |||
| 52 | if (output != str) | ||
| 53 | { | ||
| 54 | if (size) | ||
| 55 | { | ||
| 56 | size_t pruned_len = (len < size ? len : size - 1); | ||
| 57 | memcpy (str, output, pruned_len); | ||
| 58 | str[pruned_len] = '\0'; | ||
| 59 | } | ||
| 60 | |||
| 61 | free (output); | ||
| 62 | } | ||
| 63 | |||
| 64 | if (INT_MAX < len) | ||
| 65 | { | 39 | { |
| 66 | errno = EOVERFLOW; | 40 | errno = EOVERFLOW; |
| 67 | return -1; | 41 | return -1; |
| 68 | } | 42 | } |
| 43 | #endif | ||
| 69 | 44 | ||
| 70 | return len; | 45 | return ret; |
| 71 | } | 46 | } |
diff --git a/gl/sockets.c b/gl/sockets.c index 92beb7d3..7accfdd3 100644 --- a/gl/sockets.c +++ b/gl/sockets.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* sockets.c --- wrappers for Windows socket functions | 1 | /* sockets.c --- wrappers for Windows socket functions |
| 2 | 2 | ||
| 3 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/sockets.h b/gl/sockets.h index 55077ae9..5be5d3f6 100644 --- a/gl/sockets.h +++ b/gl/sockets.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* sockets.h - wrappers for Windows socket functions | 1 | /* sockets.h - wrappers for Windows socket functions |
| 2 | 2 | ||
| 3 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -52,7 +52,7 @@ int gl_sockets_cleanup (void) | |||
| 52 | #endif | 52 | #endif |
| 53 | 53 | ||
| 54 | 54 | ||
| 55 | /* This function is useful it you create a socket using gnulib's | 55 | /* This function is useful if you create a socket using gnulib's |
| 56 | Winsock wrappers but needs to pass on the socket handle to some | 56 | Winsock wrappers but needs to pass on the socket handle to some |
| 57 | other library that only accepts sockets. */ | 57 | other library that only accepts sockets. */ |
| 58 | #ifdef WINDOWS_SOCKETS | 58 | #ifdef WINDOWS_SOCKETS |
diff --git a/gl/stat-time.c b/gl/stat-time.c index 1ab01f53..fa93e16c 100644 --- a/gl/stat-time.c +++ b/gl/stat-time.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* stat-related time functions. | 1 | /* stat-related time functions. |
| 2 | 2 | ||
| 3 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2012-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/stat-time.h b/gl/stat-time.h index 3cd8478f..38315b9f 100644 --- a/gl/stat-time.h +++ b/gl/stat-time.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* stat-related time functions. | 1 | /* stat-related time functions. |
| 2 | 2 | ||
| 3 | Copyright (C) 2005, 2007, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2005, 2007, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -117,6 +117,31 @@ get_stat_birthtime_ns (_GL_UNUSED struct stat const *st) | |||
| 117 | # endif | 117 | # endif |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | /* Constructs a 'struct timespec' with the given contents. | ||
| 121 | This macro / function is private to stat-time.h. */ | ||
| 122 | #if !defined __cplusplus | ||
| 123 | /* Use a C99 compound literal. | ||
| 124 | This is guaranteed to initialize also the padding bits, for example on | ||
| 125 | platforms where tv_sec is 64 bits and tv_nsec is 32 bits, thus avoiding | ||
| 126 | gcc -Wuse-of-uninitialized-value warnings. */ | ||
| 127 | # define _gl_make_timespec(sec,nsec) \ | ||
| 128 | (struct timespec) { .tv_sec = (sec), .tv_nsec = (nsec) } | ||
| 129 | #else | ||
| 130 | /* C++ does not have C99 compound literals. | ||
| 131 | A constructor invocation | ||
| 132 | timespec { (sec), (nsec) } | ||
| 133 | would make assumptions about the order of the fields of 'struct timespec', | ||
| 134 | which are not guaranteed by POSIX. So, use an inline function. */ | ||
| 135 | static inline struct timespec | ||
| 136 | _gl_make_timespec (time_t sec, long nsec) | ||
| 137 | { | ||
| 138 | struct timespec ts; | ||
| 139 | ts.tv_sec = sec; | ||
| 140 | ts.tv_nsec = nsec; | ||
| 141 | return ts; | ||
| 142 | } | ||
| 143 | #endif | ||
| 144 | |||
| 120 | /* Return *ST's access time. */ | 145 | /* Return *ST's access time. */ |
| 121 | _GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE | 146 | _GL_STAT_TIME_INLINE struct timespec _GL_ATTRIBUTE_PURE |
| 122 | get_stat_atime (struct stat const *st) | 147 | get_stat_atime (struct stat const *st) |
| @@ -124,8 +149,7 @@ get_stat_atime (struct stat const *st) | |||
| 124 | #ifdef STAT_TIMESPEC | 149 | #ifdef STAT_TIMESPEC |
| 125 | return STAT_TIMESPEC (st, st_atim); | 150 | return STAT_TIMESPEC (st, st_atim); |
| 126 | #else | 151 | #else |
| 127 | return (struct timespec) { .tv_sec = st->st_atime, | 152 | return _gl_make_timespec (st->st_atime, get_stat_atime_ns (st)); |
| 128 | .tv_nsec = get_stat_atime_ns (st) }; | ||
| 129 | #endif | 153 | #endif |
| 130 | } | 154 | } |
| 131 | 155 | ||
| @@ -136,8 +160,7 @@ get_stat_ctime (struct stat const *st) | |||
| 136 | #ifdef STAT_TIMESPEC | 160 | #ifdef STAT_TIMESPEC |
| 137 | return STAT_TIMESPEC (st, st_ctim); | 161 | return STAT_TIMESPEC (st, st_ctim); |
| 138 | #else | 162 | #else |
| 139 | return (struct timespec) { .tv_sec = st->st_ctime, | 163 | return _gl_make_timespec (st->st_ctime, get_stat_ctime_ns (st)); |
| 140 | .tv_nsec = get_stat_ctime_ns (st) }; | ||
| 141 | #endif | 164 | #endif |
| 142 | } | 165 | } |
| 143 | 166 | ||
| @@ -148,8 +171,7 @@ get_stat_mtime (struct stat const *st) | |||
| 148 | #ifdef STAT_TIMESPEC | 171 | #ifdef STAT_TIMESPEC |
| 149 | return STAT_TIMESPEC (st, st_mtim); | 172 | return STAT_TIMESPEC (st, st_mtim); |
| 150 | #else | 173 | #else |
| 151 | return (struct timespec) { .tv_sec = st->st_mtime, | 174 | return _gl_make_timespec (st->st_mtime, get_stat_mtime_ns (st)); |
| 152 | .tv_nsec = get_stat_mtime_ns (st) }; | ||
| 153 | #endif | 175 | #endif |
| 154 | } | 176 | } |
| 155 | 177 | ||
| @@ -164,8 +186,7 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st) | |||
| 164 | || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) | 186 | || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) |
| 165 | t = STAT_TIMESPEC (st, st_birthtim); | 187 | t = STAT_TIMESPEC (st, st_birthtim); |
| 166 | #elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC | 188 | #elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC |
| 167 | t = (struct timespec) { .tv_sec = st->st_birthtime, | 189 | t = _gl_make_timespec (st->st_birthtime, st->st_birthtimensec); |
| 168 | .tv_nsec = st->st_birthtimensec }; | ||
| 169 | #elif defined _WIN32 && ! defined __CYGWIN__ | 190 | #elif defined _WIN32 && ! defined __CYGWIN__ |
| 170 | /* Native Windows platforms (but not Cygwin) put the "file creation | 191 | /* Native Windows platforms (but not Cygwin) put the "file creation |
| 171 | time" in st_ctime (!). See | 192 | time" in st_ctime (!). See |
| @@ -173,11 +194,11 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st) | |||
| 173 | # if _GL_WINDOWS_STAT_TIMESPEC | 194 | # if _GL_WINDOWS_STAT_TIMESPEC |
| 174 | t = st->st_ctim; | 195 | t = st->st_ctim; |
| 175 | # else | 196 | # else |
| 176 | t = (struct timespec) { .tv_sec = st->st_ctime }; | 197 | t = _gl_make_timespec (st->st_ctime, 0); |
| 177 | # endif | 198 | # endif |
| 178 | #else | 199 | #else |
| 179 | /* Birth time is not supported. */ | 200 | /* Birth time is not supported. */ |
| 180 | t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 }; | 201 | t = _gl_make_timespec (-1, -1); |
| 181 | #endif | 202 | #endif |
| 182 | 203 | ||
| 183 | #if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ | 204 | #if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ |
| @@ -189,7 +210,7 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st) | |||
| 189 | sometimes returns junk in the birth time fields; work around this | 210 | sometimes returns junk in the birth time fields; work around this |
| 190 | bug if it is detected. */ | 211 | bug if it is detected. */ |
| 191 | if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) | 212 | if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) |
| 192 | t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 }; | 213 | t = _gl_make_timespec (-1, -1); |
| 193 | #endif | 214 | #endif |
| 194 | 215 | ||
| 195 | return t; | 216 | return t; |
diff --git a/gl/stat-w32.c b/gl/stat-w32.c index ddd6f598..8da8fe5c 100644 --- a/gl/stat-w32.c +++ b/gl/stat-w32.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Core of implementation of fstat and stat for native Windows. | 1 | /* Core of implementation of fstat and stat for native Windows. |
| 2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/stat-w32.h b/gl/stat-w32.h index 392faed1..c70c1be3 100644 --- a/gl/stat-w32.h +++ b/gl/stat-w32.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Core of implementation of fstat and stat for native Windows. | 1 | /* Core of implementation of fstat and stat for native Windows. |
| 2 | Copyright (C) 2017-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Work around platform bugs in stat. | 1 | /* Work around platform bugs in stat. |
| 2 | Copyright (C) 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -118,6 +118,10 @@ rpl_stat (char const *name, struct stat *buf) | |||
| 118 | around length limitations | 118 | around length limitations |
| 119 | <https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file> ? */ | 119 | <https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file> ? */ |
| 120 | 120 | ||
| 121 | /* To ease portability. Like in open.c. */ | ||
| 122 | if (strcmp (name, "/dev/null") == 0) | ||
| 123 | name = "NUL"; | ||
| 124 | |||
| 121 | /* POSIX <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13> | 125 | /* POSIX <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13> |
| 122 | specifies: "More than two leading <slash> characters shall be treated as | 126 | specifies: "More than two leading <slash> characters shall be treated as |
| 123 | a single <slash> character." */ | 127 | a single <slash> character." */ |
diff --git a/gl/stdckdint.in.h b/gl/stdckdint.in.h index 91848806..bb9089b4 100644 --- a/gl/stdckdint.in.h +++ b/gl/stdckdint.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* stdckdint.h -- checked integer arithmetic | 1 | /* stdckdint.h -- checked integer arithmetic |
| 2 | 2 | ||
| 3 | Copyright 2022-2024 Free Software Foundation, Inc. | 3 | Copyright 2022-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software: you can redistribute it and/or modify it | 5 | This program is free software: you can redistribute it and/or modify it |
| 6 | under the terms of the GNU Lesser General Public License as published | 6 | under the terms of the GNU Lesser General Public License as published |
| @@ -15,10 +15,30 @@ | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | 15 | You should have received a copy of the GNU Lesser General Public License |
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
| 17 | 17 | ||
| 18 | #ifndef _GL_STDCKDINT_H | 18 | #if __GNUC__ >= 3 |
| 19 | #define _GL_STDCKDINT_H | 19 | @PRAGMA_SYSTEM_HEADER@ |
| 20 | #endif | ||
| 21 | @PRAGMA_COLUMNS@ | ||
| 20 | 22 | ||
| 21 | #include "intprops-internal.h" | 23 | #ifndef _@GUARD_PREFIX@_STDCKDINT_H |
| 24 | |||
| 25 | /* The include_next requires a split double-inclusion guard. */ | ||
| 26 | #if defined __cplusplus ? @HAVE_CXX_STDCKDINT_H@ : @HAVE_C_STDCKDINT_H@ | ||
| 27 | # @INCLUDE_NEXT@ @NEXT_STDCKDINT_H@ | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #ifndef _@GUARD_PREFIX@_STDCKDINT_H | ||
| 31 | #define _@GUARD_PREFIX@_STDCKDINT_H | ||
| 32 | |||
| 33 | /* Do nothing but include the system header if it works properly. */ | ||
| 34 | # if defined __cplusplus ? !@HAVE_WORKING_CXX_STDCKDINT_H@ : !@HAVE_WORKING_C_STDCKDINT_H@ | ||
| 35 | |||
| 36 | /* Avoid redefining macros. */ | ||
| 37 | # undef ckd_add | ||
| 38 | # undef ckd_sub | ||
| 39 | # undef ckd_mul | ||
| 40 | |||
| 41 | # include "intprops-internal.h" | ||
| 22 | 42 | ||
| 23 | /* Store into *R the low-order bits of A + B, A - B, A * B, respectively. | 43 | /* Store into *R the low-order bits of A + B, A - B, A * B, respectively. |
| 24 | Return 1 if the result overflows, 0 otherwise. | 44 | Return 1 if the result overflows, 0 otherwise. |
| @@ -26,10 +46,13 @@ | |||
| 26 | bit-precise integer type, or an enumeration type. | 46 | bit-precise integer type, or an enumeration type. |
| 27 | 47 | ||
| 28 | These are like the standard macros introduced in C23, except that | 48 | These are like the standard macros introduced in C23, except that |
| 29 | arguments should not have side effects. */ | 49 | arguments should not have side effects. The C++26 standard is |
| 50 | expected to add this header and it's macros. */ | ||
| 30 | 51 | ||
| 31 | #define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r)) | 52 | # define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r)) |
| 32 | #define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r)) | 53 | # define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r)) |
| 33 | #define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r)) | 54 | # define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r)) |
| 34 | 55 | ||
| 35 | #endif /* _GL_STDCKDINT_H */ | 56 | # endif /* defined __cplusplus ? @HAVE_WORKING_CXX_STDCKDINT_H@ : @HAVE_WORKING_C_STDCKDINT_H@ */ |
| 57 | #endif /* _@GUARD_PREFIX@_STDCKDINT_H */ | ||
| 58 | #endif /* _@GUARD_PREFIX@_STDCKDINT_H */ | ||
diff --git a/gl/stddef.in.h b/gl/stddef.in.h index fa8998d9..e8c55ff1 100644 --- a/gl/stddef.in.h +++ b/gl/stddef.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues. | 1 | /* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues. |
| 2 | 2 | ||
| 3 | Copyright (C) 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -27,13 +27,21 @@ | |||
| 27 | #endif | 27 | #endif |
| 28 | @PRAGMA_COLUMNS@ | 28 | @PRAGMA_COLUMNS@ |
| 29 | 29 | ||
| 30 | #if defined __need_wchar_t || defined __need_size_t \ | 30 | #if (defined __need_wchar_t || defined __need_size_t \ |
| 31 | || defined __need_ptrdiff_t || defined __need_NULL \ | 31 | || defined __need_ptrdiff_t || defined __need_NULL \ |
| 32 | || defined __need_wint_t | 32 | || defined __need_wint_t) \ |
| 33 | /* Avoid warning triggered by "gcc -std=gnu23 -Wsystem-headers" \ | ||
| 34 | in GCC 13.3 and 14.2 \ | ||
| 35 | <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114870>. */ \ | ||
| 36 | && !@STDDEF_NOT_IDEMPOTENT@ | ||
| 33 | /* Special invocation convention inside gcc header files. In | 37 | /* Special invocation convention inside gcc header files. In |
| 34 | particular, gcc provides a version of <stddef.h> that blindly | 38 | particular, <stddef.h> in some ancient versions of GCC blindly |
| 35 | redefines NULL even when __need_wint_t was defined, even though | 39 | redefined NULL when __need_wint_t was defined, even though wint_t |
| 36 | wint_t is not normally provided by <stddef.h>. Hence, we must | 40 | is not normally provided by <stddef.h>. |
| 41 | (FIXME: It's not clear what GCC versions those were - perhaps so | ||
| 42 | ancient that we can stop worrying about this?) | ||
| 43 | Although glibc 2.26 (2017) and later do not use __need_wint_t, | ||
| 44 | for portability to macOS, Cygwin, Haiku, and older Glibc + GCC, | ||
| 37 | remember if special invocation has ever been used to obtain wint_t, | 45 | remember if special invocation has ever been used to obtain wint_t, |
| 38 | in which case we need to clean up NULL yet again. */ | 46 | in which case we need to clean up NULL yet again. */ |
| 39 | 47 | ||
| @@ -52,6 +60,13 @@ | |||
| 52 | # endif | 60 | # endif |
| 53 | 61 | ||
| 54 | #else | 62 | #else |
| 63 | /* For @STDDEF_NOT_IDEMPOTENT@. */ | ||
| 64 | # undef __need_wchar_t | ||
| 65 | # undef __need_size_t | ||
| 66 | # undef __need_ptrdiff_t | ||
| 67 | # undef __need_NULL | ||
| 68 | # undef __need_wint_t | ||
| 69 | |||
| 55 | /* Normal invocation convention. */ | 70 | /* Normal invocation convention. */ |
| 56 | 71 | ||
| 57 | # ifndef _@GUARD_PREFIX@_STDDEF_H | 72 | # ifndef _@GUARD_PREFIX@_STDDEF_H |
| @@ -74,6 +89,12 @@ typedef long max_align_t; | |||
| 74 | # endif | 89 | # endif |
| 75 | # endif | 90 | # endif |
| 76 | 91 | ||
| 92 | # if !defined _GCC_NULLPTR_T && !@NULLPTR_T_NEEDS_STDDEF@ | ||
| 93 | /* Suppress unwanted nullptr_t typedef. See | ||
| 94 | <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114869>. */ | ||
| 95 | # define _GCC_NULLPTR_T | ||
| 96 | # endif | ||
| 97 | |||
| 77 | /* The include_next requires a split double-inclusion guard. */ | 98 | /* The include_next requires a split double-inclusion guard. */ |
| 78 | 99 | ||
| 79 | # @INCLUDE_NEXT@ @NEXT_STDDEF_H@ | 100 | # @INCLUDE_NEXT@ @NEXT_STDDEF_H@ |
| @@ -110,7 +131,7 @@ typedef long max_align_t; | |||
| 110 | */ | 131 | */ |
| 111 | #ifndef _GL_ATTRIBUTE_NOTHROW | 132 | #ifndef _GL_ATTRIBUTE_NOTHROW |
| 112 | # if defined __cplusplus | 133 | # if defined __cplusplus |
| 113 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major >= 4 | 134 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major__ >= 4 |
| 114 | # if __cplusplus >= 201103L | 135 | # if __cplusplus >= 201103L |
| 115 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) | 136 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) |
| 116 | # else | 137 | # else |
| @@ -128,11 +149,6 @@ typedef long max_align_t; | |||
| 128 | # endif | 149 | # endif |
| 129 | #endif | 150 | #endif |
| 130 | 151 | ||
| 131 | /* Some platforms lack wchar_t. */ | ||
| 132 | #if !@HAVE_WCHAR_T@ | ||
| 133 | # define wchar_t int | ||
| 134 | #endif | ||
| 135 | |||
| 136 | /* Some platforms lack max_align_t. The check for _GCC_MAX_ALIGN_T is | 152 | /* Some platforms lack max_align_t. The check for _GCC_MAX_ALIGN_T is |
| 137 | a hack in case the configure-time test was done with g++ even though | 153 | a hack in case the configure-time test was done with g++ even though |
| 138 | we are currently compiling with gcc. | 154 | we are currently compiling with gcc. |
| @@ -172,38 +188,57 @@ typedef union | |||
| 172 | #endif | 188 | #endif |
| 173 | 189 | ||
| 174 | /* ISO C 23 § 7.21.1 The unreachable macro */ | 190 | /* ISO C 23 § 7.21.1 The unreachable macro */ |
| 175 | #ifndef unreachable | 191 | /* This macro is only usable in C, not in C++. |
| 192 | There is no way to define it as a macro in C++, because that would break code | ||
| 193 | that does | ||
| 194 | #include <utility> | ||
| 195 | ... std::unreachable() ... | ||
| 196 | Similarly, there is no way to define it as an inline function in C++, because | ||
| 197 | that would break code that does | ||
| 198 | #include <utility> | ||
| 199 | using std::unreachable; | ||
| 200 | As a workaround, we define a macro gl_unreachable, that is like unreachable, | ||
| 201 | but is usable in both C and C++. */ | ||
| 176 | 202 | ||
| 177 | /* Code borrowed from verify.h. */ | 203 | /* Code borrowed from verify.h. */ |
| 178 | # ifndef _GL_HAS_BUILTIN_UNREACHABLE | 204 | #ifndef _GL_HAS_BUILTIN_UNREACHABLE |
| 179 | # if defined __clang_major__ && __clang_major__ < 5 | 205 | # if defined __clang_major__ && __clang_major__ < 5 |
| 180 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | 206 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 |
| 181 | # elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) | 207 | # elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) && !defined __clang__ |
| 182 | # define _GL_HAS_BUILTIN_UNREACHABLE 1 | 208 | # define _GL_HAS_BUILTIN_UNREACHABLE 1 |
| 183 | # elif defined __has_builtin | 209 | # elif defined __has_builtin |
| 184 | # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) | 210 | # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) |
| 185 | # else | 211 | # else |
| 186 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | 212 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 |
| 187 | # endif | ||
| 188 | # endif | 213 | # endif |
| 214 | #endif | ||
| 189 | 215 | ||
| 190 | # if _GL_HAS_BUILTIN_UNREACHABLE | 216 | #if _GL_HAS_BUILTIN_UNREACHABLE |
| 191 | # define unreachable() __builtin_unreachable () | 217 | # define gl_unreachable() __builtin_unreachable () |
| 192 | # elif 1200 <= _MSC_VER | 218 | #elif 1200 <= _MSC_VER |
| 193 | # define unreachable() __assume (0) | 219 | # define gl_unreachable() __assume (0) |
| 194 | # else | 220 | #elif !defined __cplusplus && @HAVE_C_UNREACHABLE@ |
| 221 | # define gl_unreachable() unreachable () | ||
| 222 | #else | ||
| 195 | /* Declare abort(), without including <stdlib.h>. */ | 223 | /* Declare abort(), without including <stdlib.h>. */ |
| 196 | extern | 224 | extern |
| 197 | # if defined __cplusplus | 225 | # if defined __cplusplus |
| 198 | "C" | 226 | "C" |
| 199 | # endif | 227 | # endif |
| 200 | _Noreturn | 228 | _Noreturn |
| 201 | void abort (void) | 229 | void abort (void) |
| 202 | # if defined __cplusplus && (__GLIBC__ >= 2) | 230 | # if defined __cplusplus && (__GLIBC__ >= 2) |
| 203 | _GL_ATTRIBUTE_NOTHROW | 231 | _GL_ATTRIBUTE_NOTHROW |
| 204 | # endif | 232 | # endif |
| 205 | ; | 233 | ; |
| 206 | # define unreachable() abort () | 234 | # define gl_unreachable() abort () |
| 235 | #endif | ||
| 236 | |||
| 237 | #if !defined __cplusplus && !@HAVE_C_UNREACHABLE@ | ||
| 238 | /* In C, define unreachable as a macro. */ | ||
| 239 | |||
| 240 | # ifndef unreachable | ||
| 241 | # define unreachable() gl_unreachable () | ||
| 207 | # endif | 242 | # endif |
| 208 | 243 | ||
| 209 | #endif | 244 | #endif |
diff --git a/gl/stdint.in.h b/gl/stdint.in.h index fea7483b..ca566b30 100644 --- a/gl/stdint.in.h +++ b/gl/stdint.in.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 2001-2002, 2004-2024 Free Software Foundation, Inc. | 1 | /* Copyright (C) 2001-2002, 2004-2025 Free Software Foundation, Inc. |
| 2 | Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. | 2 | Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. |
| 3 | This file is part of gnulib. | 3 | This file is part of gnulib. |
| 4 | 4 | ||
| @@ -80,7 +80,7 @@ | |||
| 80 | #define _@GUARD_PREFIX@_STDINT_H | 80 | #define _@GUARD_PREFIX@_STDINT_H |
| 81 | 81 | ||
| 82 | /* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, | 82 | /* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, |
| 83 | LONG_MIN, LONG_MAX, ULONG_MAX, _GL_INTEGER_WIDTH. */ | 83 | LONG_MIN, LONG_MAX, ULONG_MAX, CHAR_BIT, _GL_INTEGER_WIDTH. */ |
| 84 | #include <limits.h> | 84 | #include <limits.h> |
| 85 | 85 | ||
| 86 | /* Override WINT_MIN and WINT_MAX if gnulib's <wchar.h> or <wctype.h> overrides | 86 | /* Override WINT_MIN and WINT_MAX if gnulib's <wchar.h> or <wctype.h> overrides |
| @@ -189,6 +189,10 @@ typedef __int64 gl_int64_t; | |||
| 189 | # define int64_t gl_int64_t | 189 | # define int64_t gl_int64_t |
| 190 | # define GL_INT64_T | 190 | # define GL_INT64_T |
| 191 | # else | 191 | # else |
| 192 | /* Verify that 'long long' has exactly 64 bits. */ | ||
| 193 | typedef _gl_verify_int64_bits[ | ||
| 194 | _STDINT_MAX (1, sizeof (long long) * CHAR_BIT, 0ll) >> 31 >> 31 == 1 | ||
| 195 | ? 1 : -1]; | ||
| 192 | # undef int64_t | 196 | # undef int64_t |
| 193 | typedef long long int gl_int64_t; | 197 | typedef long long int gl_int64_t; |
| 194 | # define int64_t gl_int64_t | 198 | # define int64_t gl_int64_t |
| @@ -210,6 +214,11 @@ typedef unsigned __int64 gl_uint64_t; | |||
| 210 | # define uint64_t gl_uint64_t | 214 | # define uint64_t gl_uint64_t |
| 211 | # define GL_UINT64_T | 215 | # define GL_UINT64_T |
| 212 | # else | 216 | # else |
| 217 | /* Verify that 'unsigned long long' has exactly 64 bits. */ | ||
| 218 | typedef _gl_verify_uint64_bits[ | ||
| 219 | _STDINT_MAX (0, sizeof (unsigned long long) * CHAR_BIT, 0ull) | ||
| 220 | >> 31 >> 31 >> 1 == 1 | ||
| 221 | ? 1 : -1]; | ||
| 213 | # undef uint64_t | 222 | # undef uint64_t |
| 214 | typedef unsigned long long int gl_uint64_t; | 223 | typedef unsigned long long int gl_uint64_t; |
| 215 | # define uint64_t gl_uint64_t | 224 | # define uint64_t gl_uint64_t |
diff --git a/gl/stdio-consolesafe.c b/gl/stdio-consolesafe.c new file mode 100644 index 00000000..80561a6d --- /dev/null +++ b/gl/stdio-consolesafe.c | |||
| @@ -0,0 +1,199 @@ | |||
| 1 | /* msvcrt workarounds. | ||
| 2 | Copyright (C) 2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | /* Specification. */ | ||
| 20 | #include <stdio.h> | ||
| 21 | |||
| 22 | #include <stdckdint.h> | ||
| 23 | #include <stdlib.h> | ||
| 24 | #include <string.h> | ||
| 25 | |||
| 26 | /* Outputs N bytes starting at S to FP. | ||
| 27 | These N bytes are known to be followed by a NUL. | ||
| 28 | Finally frees the string at S. | ||
| 29 | Returns the number of written bytes. */ | ||
| 30 | static size_t | ||
| 31 | workaround_fwrite0 (char *s, size_t n, FILE *fp) | ||
| 32 | { | ||
| 33 | const char *ptr = s; | ||
| 34 | /* Use fputs instead of fwrite, which is buggy in msvcrt. */ | ||
| 35 | size_t written = 0; | ||
| 36 | while (n > 0) | ||
| 37 | { | ||
| 38 | size_t l = strlen (ptr); /* 0 <= l <= n */ | ||
| 39 | if (l > 0) | ||
| 40 | { | ||
| 41 | if (fputs (ptr, fp) == EOF) | ||
| 42 | break; | ||
| 43 | written += l; | ||
| 44 | n -= l; | ||
| 45 | } | ||
| 46 | if (n == 0) | ||
| 47 | break; | ||
| 48 | if (fputc ('\0', fp) == EOF) | ||
| 49 | break; | ||
| 50 | written++; | ||
| 51 | n--; | ||
| 52 | ptr += l + 1; | ||
| 53 | } | ||
| 54 | free (s); | ||
| 55 | return written; | ||
| 56 | } | ||
| 57 | |||
| 58 | size_t | ||
| 59 | gl_consolesafe_fwrite (const void *ptr, size_t size, size_t nmemb, FILE *fp) | ||
| 60 | { | ||
| 61 | size_t nbytes; | ||
| 62 | if (ckd_mul (&nbytes, size, nmemb) || nbytes == 0) | ||
| 63 | /* Overflow, or nothing to do. */ | ||
| 64 | return 0; | ||
| 65 | char *tmp = malloc (nbytes + 1); | ||
| 66 | if (tmp == NULL) | ||
| 67 | return 0; | ||
| 68 | memcpy (tmp, ptr, nbytes); | ||
| 69 | tmp[nbytes] = '\0'; | ||
| 70 | size_t written = workaround_fwrite0 (tmp, nbytes, fp); | ||
| 71 | return written / size; | ||
| 72 | } | ||
| 73 | |||
| 74 | #if defined __MINGW32__ && __USE_MINGW_ANSI_STDIO | ||
| 75 | |||
| 76 | # include "fseterr.h" | ||
| 77 | # include <stdarg.h> | ||
| 78 | |||
| 79 | # if !HAVE_VASPRINTF | ||
| 80 | |||
| 81 | # include <errno.h> | ||
| 82 | |||
| 83 | /* The old mingw (before mingw-w64) does not have the vasprintf function. | ||
| 84 | Define a suitable replacement here, that supports the same format | ||
| 85 | specifiers as the mingw *printf functions. */ | ||
| 86 | |||
| 87 | static int | ||
| 88 | vasprintf (char **resultp, const char *format, va_list args) | ||
| 89 | { | ||
| 90 | /* First try: Use a stack-allocated buffer. */ | ||
| 91 | char buf[2048]; | ||
| 92 | size_t bufsize = sizeof (buf); | ||
| 93 | int ret = __mingw_vsnprintf (buf, bufsize, format, args); | ||
| 94 | if (ret < 0) | ||
| 95 | return -1; | ||
| 96 | size_t nbytes = ret; | ||
| 97 | char *mem = (char *) malloc (nbytes + 1); | ||
| 98 | if (mem == NULL) | ||
| 99 | { | ||
| 100 | errno = ENOMEM; | ||
| 101 | return -1; | ||
| 102 | } | ||
| 103 | if (ret < bufsize) | ||
| 104 | { | ||
| 105 | /* The buffer was sufficiently large. */ | ||
| 106 | memcpy (mem, buf, nbytes + 1); | ||
| 107 | } | ||
| 108 | else | ||
| 109 | { | ||
| 110 | /* Second try: Use the heap-allocated memory. */ | ||
| 111 | ret = __mingw_vsnprintf (mem, nbytes + 1, format, args); | ||
| 112 | if (ret < 0) | ||
| 113 | { | ||
| 114 | int saved_errno = errno; | ||
| 115 | free (mem); | ||
| 116 | errno = saved_errno; | ||
| 117 | return -1; | ||
| 118 | } | ||
| 119 | if (ret != nbytes) | ||
| 120 | abort (); | ||
| 121 | } | ||
| 122 | *resultp = mem; | ||
| 123 | return nbytes; | ||
| 124 | } | ||
| 125 | |||
| 126 | # endif | ||
| 127 | |||
| 128 | /* Bypass the functions __mingw_[v][f]printf, that trigger a bug in msvcrt, | ||
| 129 | but without losing the support for modern format specifiers added by | ||
| 130 | __mingw_*printf. */ | ||
| 131 | |||
| 132 | int | ||
| 133 | gl_consolesafe_fprintf (FILE *restrict fp, const char *restrict format, ...) | ||
| 134 | { | ||
| 135 | va_list args; | ||
| 136 | char *tmpstring; | ||
| 137 | va_start (args, format); | ||
| 138 | int result = vasprintf (&tmpstring, format, args); | ||
| 139 | va_end (args); | ||
| 140 | if (result >= 0) | ||
| 141 | { | ||
| 142 | if (workaround_fwrite0 (tmpstring, result, fp) < result) | ||
| 143 | result = -1; | ||
| 144 | } | ||
| 145 | else | ||
| 146 | fseterr (fp); | ||
| 147 | return result; | ||
| 148 | } | ||
| 149 | |||
| 150 | int | ||
| 151 | gl_consolesafe_printf (const char *restrict format, ...) | ||
| 152 | { | ||
| 153 | va_list args; | ||
| 154 | char *tmpstring; | ||
| 155 | va_start (args, format); | ||
| 156 | int result = vasprintf (&tmpstring, format, args); | ||
| 157 | va_end (args); | ||
| 158 | if (result >= 0) | ||
| 159 | { | ||
| 160 | if (workaround_fwrite0 (tmpstring, result, stdout) < result) | ||
| 161 | result = -1; | ||
| 162 | } | ||
| 163 | else | ||
| 164 | fseterr (stdout); | ||
| 165 | return result; | ||
| 166 | } | ||
| 167 | |||
| 168 | int | ||
| 169 | gl_consolesafe_vfprintf (FILE *restrict fp, | ||
| 170 | const char *restrict format, va_list args) | ||
| 171 | { | ||
| 172 | char *tmpstring; | ||
| 173 | int result = vasprintf (&tmpstring, format, args); | ||
| 174 | if (result >= 0) | ||
| 175 | { | ||
| 176 | if (workaround_fwrite0 (tmpstring, result, fp) < result) | ||
| 177 | result = -1; | ||
| 178 | } | ||
| 179 | else | ||
| 180 | fseterr (fp); | ||
| 181 | return result; | ||
| 182 | } | ||
| 183 | |||
| 184 | int | ||
| 185 | gl_consolesafe_vprintf (const char *restrict format, va_list args) | ||
| 186 | { | ||
| 187 | char *tmpstring; | ||
| 188 | int result = vasprintf (&tmpstring, format, args); | ||
| 189 | if (result >= 0) | ||
| 190 | { | ||
| 191 | if (workaround_fwrite0 (tmpstring, result, stdout) < result) | ||
| 192 | result = -1; | ||
| 193 | } | ||
| 194 | else | ||
| 195 | fseterr (stdout); | ||
| 196 | return result; | ||
| 197 | } | ||
| 198 | |||
| 199 | #endif | ||
diff --git a/gl/stdio-impl.h b/gl/stdio-impl.h index 63ebf7c6..e4a69a8d 100644 --- a/gl/stdio-impl.h +++ b/gl/stdio-impl.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Implementation details of FILE streams. | 1 | /* Implementation details of FILE streams. |
| 2 | Copyright (C) 2007-2008, 2010-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2008, 2010-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -30,6 +30,49 @@ | |||
| 30 | # endif | 30 | # endif |
| 31 | #endif | 31 | #endif |
| 32 | 32 | ||
| 33 | /* Haiku stdio implementation. */ | ||
| 34 | #if defined __HAIKU__ | ||
| 35 | # include <stdint.h> | ||
| 36 | /* This FILE structure was made into an incomplete type in 2025. | ||
| 37 | See <https://cgit.haiku-os.org/haiku/tree/src/system/libroot/posix/glibc/libio/libio.h>. */ | ||
| 38 | # define fp_ ((struct { int _flags; \ | ||
| 39 | char *_IO_read_ptr; \ | ||
| 40 | char *_IO_read_end; \ | ||
| 41 | char *_IO_read_base; \ | ||
| 42 | char *_IO_write_base; \ | ||
| 43 | char *_IO_write_ptr; \ | ||
| 44 | char *_IO_write_end; \ | ||
| 45 | char *_IO_buf_base; \ | ||
| 46 | char *_IO_buf_end; \ | ||
| 47 | char *_IO_save_base; \ | ||
| 48 | char *_IO_backup_base; \ | ||
| 49 | char *_IO_save_end; \ | ||
| 50 | void *_markers; \ | ||
| 51 | void *_chain; \ | ||
| 52 | int _fileno; \ | ||
| 53 | int _flags2; \ | ||
| 54 | off_t _old_offset; \ | ||
| 55 | unsigned short _cur_column; \ | ||
| 56 | signed char _vtable_offset; \ | ||
| 57 | char _shortbuf[1]; \ | ||
| 58 | void *_lock; \ | ||
| 59 | int64_t _offset; \ | ||
| 60 | /* More fields, not relevant here. */ \ | ||
| 61 | } *) fp) | ||
| 62 | # if !defined _IO_UNBUFFERED | ||
| 63 | # define _IO_UNBUFFERED 0x2 | ||
| 64 | # endif | ||
| 65 | # if !defined _IO_EOF_SEEN | ||
| 66 | # define _IO_EOF_SEEN 0x10 | ||
| 67 | # endif | ||
| 68 | # if !defined _IO_IN_BACKUP | ||
| 69 | # define _IO_IN_BACKUP 0x100 | ||
| 70 | # endif | ||
| 71 | # if !defined _IO_LINE_BUF | ||
| 72 | # define _IO_LINE_BUF 0x200 | ||
| 73 | # endif | ||
| 74 | #endif | ||
| 75 | |||
| 33 | /* BSD stdio derived implementations. */ | 76 | /* BSD stdio derived implementations. */ |
| 34 | 77 | ||
| 35 | #if defined __NetBSD__ /* NetBSD */ | 78 | #if defined __NetBSD__ /* NetBSD */ |
| @@ -39,7 +82,7 @@ | |||
| 39 | 82 | ||
| 40 | #include <errno.h> /* For detecting Plan9. */ | 83 | #include <errno.h> /* For detecting Plan9. */ |
| 41 | 84 | ||
| 42 | #if defined __sferror || defined __DragonFly__ || defined __ANDROID__ | 85 | #if defined __sferror || defined __OpenBSD__ || defined __DragonFly__ || defined __ANDROID__ |
| 43 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ | 86 | /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ |
| 44 | 87 | ||
| 45 | # if defined __DragonFly__ /* DragonFly */ | 88 | # if defined __DragonFly__ /* DragonFly */ |
| @@ -65,13 +108,59 @@ | |||
| 65 | # define _flags pub._flags | 108 | # define _flags pub._flags |
| 66 | # define _r pub._r | 109 | # define _r pub._r |
| 67 | # define _w pub._w | 110 | # define _w pub._w |
| 68 | # elif defined __ANDROID__ /* Android */ | 111 | # elif defined __OpenBSD__ /* OpenBSD */ |
| 69 | # ifdef __LP64__ | 112 | # if defined __sferror /* OpenBSD <= 7.7 */ |
| 113 | # define _gl_flags_file_t short | ||
| 114 | # else /* OpenBSD >= 7.8 */ | ||
| 115 | # define _gl_flags_file_t int | ||
| 116 | # endif | ||
| 117 | /* Up to this commit from 2025-07-16 | ||
| 118 | <https://github.com/openbsd/src/commit/b7f6c2eb760a2da367dd51d539ef06f5f3553790> | ||
| 119 | the innards of FILE were public. After this commit, the innards of FILE | ||
| 120 | are hidden. In this commit | ||
| 121 | <https://github.com/openbsd/src/commit/9063a2f1ec94013fb0e2c7ec851495108e788a6e> | ||
| 122 | they were reshuffled. */ | ||
| 123 | # if defined __sferror /* OpenBSD <= 7.7 */ | ||
| 124 | # define fp_ ((struct { unsigned char *_p; \ | ||
| 125 | int _r; \ | ||
| 126 | int _w; \ | ||
| 127 | _gl_flags_file_t _flags; \ | ||
| 128 | _gl_flags_file_t _file; \ | ||
| 129 | struct { unsigned char *_base; size_t _size; } _bf; \ | ||
| 130 | int _lbfsize; \ | ||
| 131 | void *_cookie; \ | ||
| 132 | void *_close; \ | ||
| 133 | void *_read; \ | ||
| 134 | void *_seek; \ | ||
| 135 | void *_write; \ | ||
| 136 | struct { unsigned char *_base; size_t _size; } _ext; \ | ||
| 137 | unsigned char *_up; \ | ||
| 138 | int _ur; \ | ||
| 139 | unsigned char _ubuf[3]; \ | ||
| 140 | unsigned char _nbuf[1]; \ | ||
| 141 | struct { unsigned char *_base; size_t _size; } _lb; \ | ||
| 142 | int _blksize; \ | ||
| 143 | fpos_t _offset; \ | ||
| 144 | /* More fields, not relevant here. */ \ | ||
| 145 | } *) fp) | ||
| 146 | # else /* OpenBSD >= 7.8 */ | ||
| 147 | # define fp_ ((struct { _gl_flags_file_t _flags; \ | ||
| 148 | _gl_flags_file_t _file; \ | ||
| 149 | unsigned char *_p; \ | ||
| 150 | int _r; \ | ||
| 151 | int _w; \ | ||
| 152 | struct { unsigned char *_base; size_t _size; } _bf; \ | ||
| 153 | int _lbfsize; \ | ||
| 154 | /* More fields, not relevant here. */ \ | ||
| 155 | } *) fp) | ||
| 156 | # endif | ||
| 157 | # elif defined __ANDROID__ /* Android */ | ||
| 158 | # if defined __LP64__ | ||
| 70 | # define _gl_flags_file_t int | 159 | # define _gl_flags_file_t int |
| 71 | # else | 160 | # else |
| 72 | # define _gl_flags_file_t short | 161 | # define _gl_flags_file_t short |
| 73 | # endif | 162 | # endif |
| 74 | # ifdef __LP64__ | 163 | # if defined __LP64__ |
| 75 | # define _gl_file_offset_t int64_t | 164 | # define _gl_file_offset_t int64_t |
| 76 | # else | 165 | # else |
| 77 | /* see https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */ | 166 | /* see https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */ |
| @@ -79,7 +168,7 @@ | |||
| 79 | # endif | 168 | # endif |
| 80 | /* Up to this commit from 2015-10-12 | 169 | /* Up to this commit from 2015-10-12 |
| 81 | <https://android.googlesource.com/platform/bionic.git/+/f0141dfab10a4b332769d52fa76631a64741297a> | 170 | <https://android.googlesource.com/platform/bionic.git/+/f0141dfab10a4b332769d52fa76631a64741297a> |
| 82 | the innards of FILE were public, and fp_ub could be defined like for OpenBSD, | 171 | the innards of FILE were public, |
| 83 | see <https://android.googlesource.com/platform/bionic.git/+/e78392637d5086384a5631ddfdfa8d7ec8326ee3/libc/stdio/fileext.h> | 172 | see <https://android.googlesource.com/platform/bionic.git/+/e78392637d5086384a5631ddfdfa8d7ec8326ee3/libc/stdio/fileext.h> |
| 84 | and <https://android.googlesource.com/platform/bionic.git/+/e78392637d5086384a5631ddfdfa8d7ec8326ee3/libc/stdio/local.h>. | 173 | and <https://android.googlesource.com/platform/bionic.git/+/e78392637d5086384a5631ddfdfa8d7ec8326ee3/libc/stdio/local.h>. |
| 85 | After this commit, the innards of FILE are hidden. */ | 174 | After this commit, the innards of FILE are hidden. */ |
| @@ -109,9 +198,8 @@ | |||
| 109 | # define fp_ fp | 198 | # define fp_ fp |
| 110 | # endif | 199 | # endif |
| 111 | 200 | ||
| 112 | # if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ || defined __minix /* NetBSD >= 1.5ZA, OpenBSD, Minix 3 */ | 201 | # if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __minix /* NetBSD >= 1.5ZA, Minix 3 */ |
| 113 | /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> | 202 | /* See <https://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> |
| 114 | and <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> | ||
| 115 | and <https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/master/lib/libc/stdio/fileext.h> */ | 203 | and <https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/master/lib/libc/stdio/fileext.h> */ |
| 116 | struct __sfileext | 204 | struct __sfileext |
| 117 | { | 205 | { |
| @@ -119,7 +207,7 @@ | |||
| 119 | /* More fields, not relevant here. */ | 207 | /* More fields, not relevant here. */ |
| 120 | }; | 208 | }; |
| 121 | # define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub | 209 | # define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub |
| 122 | # elif defined __ANDROID__ /* Android */ | 210 | # elif defined __ANDROID__ || defined __OpenBSD__ /* Android, OpenBSD */ |
| 123 | struct __sfileext | 211 | struct __sfileext |
| 124 | { | 212 | { |
| 125 | struct { unsigned char *_base; size_t _size; } _ub; /* ungetc buffer */ | 213 | struct { unsigned char *_base; size_t _size; } _ub; /* ungetc buffer */ |
| @@ -132,9 +220,11 @@ | |||
| 132 | 220 | ||
| 133 | # define HASUB(fp) (fp_ub._base != NULL) | 221 | # define HASUB(fp) (fp_ub._base != NULL) |
| 134 | 222 | ||
| 135 | # if defined __ANDROID__ /* Android */ | 223 | # if defined __ANDROID__ || defined __OpenBSD__ /* Android, OpenBSD */ |
| 136 | /* Needed after this commit from 2016-01-25 | 224 | /* Needed after this Android commit from 2016-01-25 |
| 137 | <https://android.googlesource.com/platform/bionic.git/+/e70e0e9267d069bf56a5078c99307e08a7280de7> */ | 225 | <https://android.googlesource.com/platform/bionic.git/+/e70e0e9267d069bf56a5078c99307e08a7280de7> |
| 226 | And after this OpenBSD commit from 2025-07-16 | ||
| 227 | <https://github.com/openbsd/src/commit/b7f6c2eb760a2da367dd51d539ef06f5f3553790>. */ | ||
| 138 | # ifndef __SEOF | 228 | # ifndef __SEOF |
| 139 | # define __SLBF 1 | 229 | # define __SLBF 1 |
| 140 | # define __SNBF 2 | 230 | # define __SNBF 2 |
diff --git a/gl/stdio-read.c b/gl/stdio-read.c index 253b8aa4..70452b48 100644 --- a/gl/stdio-read.c +++ b/gl/stdio-read.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* POSIX compatible FILE stream read function. | 1 | /* POSIX compatible FILE stream read function. |
| 2 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/stdio-write.c b/gl/stdio-write.c index ca6aa00c..59ba8fc4 100644 --- a/gl/stdio-write.c +++ b/gl/stdio-write.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* POSIX compatible FILE stream write function. | 1 | /* POSIX compatible FILE stream write function. |
| 2 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -162,6 +162,9 @@ vprintf (const char *format, va_list args) | |||
| 162 | int | 162 | int |
| 163 | vfprintf (FILE *stream, const char *format, va_list args) | 163 | vfprintf (FILE *stream, const char *format, va_list args) |
| 164 | #undef vfprintf | 164 | #undef vfprintf |
| 165 | #if defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO | ||
| 166 | # define vfprintf gl_consolesafe_vfprintf | ||
| 167 | #endif | ||
| 165 | { | 168 | { |
| 166 | CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF) | 169 | CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF) |
| 167 | } | 170 | } |
| @@ -198,6 +201,9 @@ puts (const char *string) | |||
| 198 | size_t | 201 | size_t |
| 199 | fwrite (const void *ptr, size_t s, size_t n, FILE *stream) | 202 | fwrite (const void *ptr, size_t s, size_t n, FILE *stream) |
| 200 | #undef fwrite | 203 | #undef fwrite |
| 204 | #if (defined _WIN32 && !defined __CYGWIN__) && !defined _UCRT | ||
| 205 | # define fwrite gl_consolesafe_fwrite | ||
| 206 | #endif | ||
| 201 | { | 207 | { |
| 202 | CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n) | 208 | CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n) |
| 203 | } | 209 | } |
diff --git a/gl/stdio.in.h b/gl/stdio.in.h index 35b9f748..bc454454 100644 --- a/gl/stdio.in.h +++ b/gl/stdio.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A GNU-like <stdio.h>. | 1 | /* A GNU-like <stdio.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2004, 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2004, 2007-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -20,7 +20,7 @@ | |||
| 20 | #endif | 20 | #endif |
| 21 | @PRAGMA_COLUMNS@ | 21 | @PRAGMA_COLUMNS@ |
| 22 | 22 | ||
| 23 | #if defined __need_FILE || defined __need___FILE || defined _GL_ALREADY_INCLUDING_STDIO_H | 23 | #if defined __need_FILE || defined __need___FILE || defined _@GUARD_PREFIX@_ALREADY_INCLUDING_STDIO_H || defined _GL_SKIP_GNULIB_STDIO_H |
| 24 | /* Special invocation convention: | 24 | /* Special invocation convention: |
| 25 | - Inside glibc header files. | 25 | - Inside glibc header files. |
| 26 | - On OSF/1 5.1 we have a sequence of nested includes | 26 | - On OSF/1 5.1 we have a sequence of nested includes |
| @@ -48,12 +48,12 @@ | |||
| 48 | # endif | 48 | # endif |
| 49 | #endif | 49 | #endif |
| 50 | 50 | ||
| 51 | #define _GL_ALREADY_INCLUDING_STDIO_H | 51 | #define _@GUARD_PREFIX@_ALREADY_INCLUDING_STDIO_H |
| 52 | 52 | ||
| 53 | /* The include_next requires a split double-inclusion guard. */ | 53 | /* The include_next requires a split double-inclusion guard. */ |
| 54 | #@INCLUDE_NEXT@ @NEXT_STDIO_H@ | 54 | #@INCLUDE_NEXT@ @NEXT_STDIO_H@ |
| 55 | 55 | ||
| 56 | #undef _GL_ALREADY_INCLUDING_STDIO_H | 56 | #undef _@GUARD_PREFIX@_ALREADY_INCLUDING_STDIO_H |
| 57 | 57 | ||
| 58 | #ifdef _GL_DEFINED__POSIX_C_SOURCE | 58 | #ifdef _GL_DEFINED__POSIX_C_SOURCE |
| 59 | # undef _GL_DEFINED__POSIX_C_SOURCE | 59 | # undef _GL_DEFINED__POSIX_C_SOURCE |
| @@ -64,8 +64,8 @@ | |||
| 64 | #define _@GUARD_PREFIX@_STDIO_H | 64 | #define _@GUARD_PREFIX@_STDIO_H |
| 65 | 65 | ||
| 66 | /* This file uses _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_FORMAT, | 66 | /* This file uses _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_FORMAT, |
| 67 | _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_NOTHROW, GNULIB_POSIXCHECK, | 67 | _GL_ATTRIBUTE_MALLOC, _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOTHROW, |
| 68 | HAVE_RAW_DECL_*. */ | 68 | GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ |
| 69 | #if !_GL_CONFIG_H_INCLUDED | 69 | #if !_GL_CONFIG_H_INCLUDED |
| 70 | #error "Please include config.h first." | 70 | #error "Please include config.h first." |
| 71 | #endif | 71 | #endif |
| @@ -77,7 +77,8 @@ | |||
| 77 | 77 | ||
| 78 | /* Get off_t and ssize_t. Needed on many systems, including glibc 2.8 | 78 | /* Get off_t and ssize_t. Needed on many systems, including glibc 2.8 |
| 79 | and eglibc 2.11.2. | 79 | and eglibc 2.11.2. |
| 80 | May also define off_t to a 64-bit type on native Windows. */ | 80 | May also define off_t to a 64-bit type on native Windows. |
| 81 | Also defines off64_t on macOS, NetBSD, OpenBSD, MSVC, Cygwin, Haiku. */ | ||
| 81 | #include <sys/types.h> | 82 | #include <sys/types.h> |
| 82 | 83 | ||
| 83 | /* Solaris 10 and NetBSD 7.0 declare renameat in <unistd.h>, not in <stdio.h>. */ | 84 | /* Solaris 10 and NetBSD 7.0 declare renameat in <unistd.h>, not in <stdio.h>. */ |
| @@ -119,7 +120,7 @@ | |||
| 119 | that can be freed by passing them as the Ith argument to the | 120 | that can be freed by passing them as the Ith argument to the |
| 120 | function F. */ | 121 | function F. */ |
| 121 | #ifndef _GL_ATTRIBUTE_DEALLOC | 122 | #ifndef _GL_ATTRIBUTE_DEALLOC |
| 122 | # if __GNUC__ >= 11 | 123 | # if __GNUC__ >= 11 && !defined __clang__ |
| 123 | # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) | 124 | # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) |
| 124 | # else | 125 | # else |
| 125 | # define _GL_ATTRIBUTE_DEALLOC(f, i) | 126 | # define _GL_ATTRIBUTE_DEALLOC(f, i) |
| @@ -154,7 +155,7 @@ | |||
| 154 | */ | 155 | */ |
| 155 | #ifndef _GL_ATTRIBUTE_NOTHROW | 156 | #ifndef _GL_ATTRIBUTE_NOTHROW |
| 156 | # if defined __cplusplus | 157 | # if defined __cplusplus |
| 157 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major >= 4 | 158 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major__ >= 4 |
| 158 | # if __cplusplus >= 201103L | 159 | # if __cplusplus >= 201103L |
| 159 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) | 160 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) |
| 160 | # else | 161 | # else |
| @@ -177,7 +178,7 @@ | |||
| 177 | standardized by ISO C99 and POSIX. | 178 | standardized by ISO C99 and POSIX. |
| 178 | _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD */ | 179 | _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD */ |
| 179 | /* __gnu_printf__ is supported in GCC >= 4.4. */ | 180 | /* __gnu_printf__ is supported in GCC >= 4.4. */ |
| 180 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) | 181 | #if (__GNUC__ + (__GNUC_MINOR__ >= 4) > 4) && !defined __clang__ |
| 181 | # define _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD __gnu_printf__ | 182 | # define _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD __gnu_printf__ |
| 182 | #else | 183 | #else |
| 183 | # define _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD __printf__ | 184 | # define _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD __printf__ |
| @@ -279,18 +280,64 @@ | |||
| 279 | #endif | 280 | #endif |
| 280 | 281 | ||
| 281 | 282 | ||
| 283 | #if (defined _WIN32 && !defined __CYGWIN__) && !defined _UCRT | ||
| 284 | /* Workarounds against msvcrt bugs. */ | ||
| 285 | _GL_FUNCDECL_SYS (gl_consolesafe_fwrite, size_t, | ||
| 286 | (const void *ptr, size_t size, size_t nmemb, FILE *fp), | ||
| 287 | _GL_ARG_NONNULL ((1, 4))); | ||
| 288 | # if defined __MINGW32__ | ||
| 289 | _GL_FUNCDECL_SYS (gl_consolesafe_fprintf, int, | ||
| 290 | (FILE *restrict fp, const char *restrict format, ...), | ||
| 291 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | ||
| 292 | _GL_ARG_NONNULL ((1, 2))); | ||
| 293 | _GL_FUNCDECL_SYS (gl_consolesafe_printf, int, | ||
| 294 | (const char *restrict format, ...), | ||
| 295 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) | ||
| 296 | _GL_ARG_NONNULL ((1))); | ||
| 297 | _GL_FUNCDECL_SYS (gl_consolesafe_vfprintf, int, | ||
| 298 | (FILE *restrict fp, | ||
| 299 | const char *restrict format, va_list args), | ||
| 300 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | ||
| 301 | _GL_ARG_NONNULL ((1, 2))); | ||
| 302 | _GL_FUNCDECL_SYS (gl_consolesafe_vprintf, int, | ||
| 303 | (const char *restrict format, va_list args), | ||
| 304 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0) | ||
| 305 | _GL_ARG_NONNULL ((1))); | ||
| 306 | # endif | ||
| 307 | #endif | ||
| 308 | |||
| 309 | |||
| 310 | #if @GNULIB_DZPRINTF@ | ||
| 311 | /* Prints formatted output to file descriptor FD. | ||
| 312 | Returns the number of bytes written to the file descriptor. Upon | ||
| 313 | failure, returns -1 with errno set. | ||
| 314 | Failure code EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 315 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 316 | directives nor widths, the only possible failure codes are ENOMEM | ||
| 317 | and the possible failure codes from write(), excluding EINTR. */ | ||
| 318 | _GL_FUNCDECL_SYS (dzprintf, off64_t, | ||
| 319 | (int fd, const char *restrict format, ...), | ||
| 320 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | ||
| 321 | _GL_ARG_NONNULL ((2))); | ||
| 322 | _GL_CXXALIAS_SYS (dzprintf, off64_t, | ||
| 323 | (int fd, const char *restrict format, ...)); | ||
| 324 | #endif | ||
| 325 | |||
| 282 | #if @GNULIB_DPRINTF@ | 326 | #if @GNULIB_DPRINTF@ |
| 327 | /* Prints formatted output to file descriptor FD. | ||
| 328 | Returns the number of bytes written to the file descriptor. Upon | ||
| 329 | failure, returns a negative value. */ | ||
| 283 | # if @REPLACE_DPRINTF@ | 330 | # if @REPLACE_DPRINTF@ |
| 284 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 331 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 285 | # define dprintf rpl_dprintf | 332 | # define dprintf rpl_dprintf |
| 286 | # endif | 333 | # endif |
| 287 | _GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *restrict format, ...) | 334 | _GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *restrict format, ...), |
| 288 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | 335 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) |
| 289 | _GL_ARG_NONNULL ((2))); | 336 | _GL_ARG_NONNULL ((2))); |
| 290 | _GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *restrict format, ...)); | 337 | _GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *restrict format, ...)); |
| 291 | # else | 338 | # else |
| 292 | # if !@HAVE_DPRINTF@ | 339 | # if !@HAVE_DPRINTF@ |
| 293 | _GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *restrict format, ...) | 340 | _GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *restrict format, ...), |
| 294 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | 341 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) |
| 295 | _GL_ARG_NONNULL ((2))); | 342 | _GL_ARG_NONNULL ((2))); |
| 296 | # endif | 343 | # endif |
| @@ -313,7 +360,7 @@ _GL_WARN_ON_USE (dprintf, "dprintf is unportable - " | |||
| 313 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 360 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 314 | # define fclose rpl_fclose | 361 | # define fclose rpl_fclose |
| 315 | # endif | 362 | # endif |
| 316 | _GL_FUNCDECL_RPL (fclose, int, (FILE *stream) _GL_ARG_NONNULL ((1))); | 363 | _GL_FUNCDECL_RPL (fclose, int, (FILE *stream), _GL_ARG_NONNULL ((1))); |
| 317 | _GL_CXXALIAS_RPL (fclose, int, (FILE *stream)); | 364 | _GL_CXXALIAS_RPL (fclose, int, (FILE *stream)); |
| 318 | # else | 365 | # else |
| 319 | _GL_CXXALIAS_SYS (fclose, int, (FILE *stream)); | 366 | _GL_CXXALIAS_SYS (fclose, int, (FILE *stream)); |
| @@ -360,9 +407,10 @@ _GL_CXXALIASWARN (fcloseall); | |||
| 360 | # define fdopen rpl_fdopen | 407 | # define fdopen rpl_fdopen |
| 361 | # endif | 408 | # endif |
| 362 | _GL_FUNCDECL_RPL (fdopen, FILE *, | 409 | _GL_FUNCDECL_RPL (fdopen, FILE *, |
| 363 | (int fd, const char *mode) | 410 | (int fd, const char *mode), |
| 364 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) | 411 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 365 | _GL_ATTRIBUTE_MALLOC); | 412 | _GL_ATTRIBUTE_MALLOC |
| 413 | _GL_ATTRIBUTE_NODISCARD); | ||
| 366 | _GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode)); | 414 | _GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode)); |
| 367 | # elif defined _WIN32 && !defined __CYGWIN__ | 415 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 368 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 416 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -371,36 +419,38 @@ _GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode)); | |||
| 371 | # endif | 419 | # endif |
| 372 | _GL_CXXALIAS_MDA (fdopen, FILE *, (int fd, const char *mode)); | 420 | _GL_CXXALIAS_MDA (fdopen, FILE *, (int fd, const char *mode)); |
| 373 | # else | 421 | # else |
| 374 | # if __GNUC__ >= 11 | 422 | # if __GNUC__ >= 11 && !defined __clang__ |
| 375 | /* For -Wmismatched-dealloc: Associate fdopen with fclose or rpl_fclose. */ | 423 | /* For -Wmismatched-dealloc: Associate fdopen with fclose or rpl_fclose. */ |
| 376 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 424 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 377 | _GL_FUNCDECL_SYS (fdopen, FILE *, | 425 | _GL_FUNCDECL_SYS (fdopen, FILE *, |
| 378 | (int fd, const char *mode) | 426 | (int fd, const char *mode), |
| 379 | _GL_ATTRIBUTE_NOTHROW | ||
| 380 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) | 427 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 381 | _GL_ATTRIBUTE_MALLOC); | 428 | _GL_ATTRIBUTE_MALLOC |
| 429 | _GL_ATTRIBUTE_NODISCARD) | ||
| 430 | _GL_ATTRIBUTE_NOTHROW; | ||
| 382 | # else | 431 | # else |
| 383 | _GL_FUNCDECL_SYS (fdopen, FILE *, | 432 | _GL_FUNCDECL_SYS (fdopen, FILE *, |
| 384 | (int fd, const char *mode) | 433 | (int fd, const char *mode), |
| 385 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) | 434 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 386 | _GL_ATTRIBUTE_MALLOC); | 435 | _GL_ATTRIBUTE_MALLOC |
| 436 | _GL_ATTRIBUTE_NODISCARD); | ||
| 387 | # endif | 437 | # endif |
| 388 | # endif | 438 | # endif |
| 389 | _GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode)); | 439 | _GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode)); |
| 390 | # endif | 440 | # endif |
| 391 | _GL_CXXALIASWARN (fdopen); | 441 | _GL_CXXALIASWARN (fdopen); |
| 392 | #else | 442 | #else |
| 393 | # if @GNULIB_FCLOSE@ && __GNUC__ >= 11 && !defined fdopen | 443 | # if @GNULIB_FCLOSE@ && (__GNUC__ >= 11 && !defined __clang__) && !defined fdopen |
| 394 | /* For -Wmismatched-dealloc: Associate fdopen with fclose or rpl_fclose. */ | 444 | /* For -Wmismatched-dealloc: Associate fdopen with fclose or rpl_fclose. */ |
| 395 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 445 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 396 | _GL_FUNCDECL_SYS (fdopen, FILE *, | 446 | _GL_FUNCDECL_SYS (fdopen, FILE *, |
| 397 | (int fd, const char *mode) | 447 | (int fd, const char *mode), |
| 398 | _GL_ATTRIBUTE_NOTHROW | ||
| 399 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) | 448 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 400 | _GL_ATTRIBUTE_MALLOC); | 449 | _GL_ATTRIBUTE_MALLOC) |
| 450 | _GL_ATTRIBUTE_NOTHROW; | ||
| 401 | # else | 451 | # else |
| 402 | _GL_FUNCDECL_SYS (fdopen, FILE *, | 452 | _GL_FUNCDECL_SYS (fdopen, FILE *, |
| 403 | (int fd, const char *mode) | 453 | (int fd, const char *mode), |
| 404 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) | 454 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 405 | _GL_ATTRIBUTE_MALLOC); | 455 | _GL_ATTRIBUTE_MALLOC); |
| 406 | # endif | 456 | # endif |
| @@ -438,7 +488,7 @@ _GL_CXXALIASWARN (fdopen); | |||
| 438 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 488 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 439 | # define fflush rpl_fflush | 489 | # define fflush rpl_fflush |
| 440 | # endif | 490 | # endif |
| 441 | _GL_FUNCDECL_RPL (fflush, int, (FILE *gl_stream)); | 491 | _GL_FUNCDECL_RPL (fflush, int, (FILE *gl_stream), ); |
| 442 | _GL_CXXALIAS_RPL (fflush, int, (FILE *gl_stream)); | 492 | _GL_CXXALIAS_RPL (fflush, int, (FILE *gl_stream)); |
| 443 | # else | 493 | # else |
| 444 | _GL_CXXALIAS_SYS (fflush, int, (FILE *gl_stream)); | 494 | _GL_CXXALIAS_SYS (fflush, int, (FILE *gl_stream)); |
| @@ -459,7 +509,7 @@ _GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - " | |||
| 459 | # undef fgetc | 509 | # undef fgetc |
| 460 | # define fgetc rpl_fgetc | 510 | # define fgetc rpl_fgetc |
| 461 | # endif | 511 | # endif |
| 462 | _GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1))); | 512 | _GL_FUNCDECL_RPL (fgetc, int, (FILE *stream), _GL_ARG_NONNULL ((1))); |
| 463 | _GL_CXXALIAS_RPL (fgetc, int, (FILE *stream)); | 513 | _GL_CXXALIAS_RPL (fgetc, int, (FILE *stream)); |
| 464 | # else | 514 | # else |
| 465 | _GL_CXXALIAS_SYS (fgetc, int, (FILE *stream)); | 515 | _GL_CXXALIAS_SYS (fgetc, int, (FILE *stream)); |
| @@ -476,8 +526,8 @@ _GL_CXXALIASWARN (fgetc); | |||
| 476 | # define fgets rpl_fgets | 526 | # define fgets rpl_fgets |
| 477 | # endif | 527 | # endif |
| 478 | _GL_FUNCDECL_RPL (fgets, char *, | 528 | _GL_FUNCDECL_RPL (fgets, char *, |
| 479 | (char *restrict s, int n, FILE *restrict stream) | 529 | (char *restrict s, int n, FILE *restrict stream), |
| 480 | _GL_ARG_NONNULL ((1, 3))); | 530 | _GL_ARG_NONNULL ((1, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 481 | _GL_CXXALIAS_RPL (fgets, char *, | 531 | _GL_CXXALIAS_RPL (fgets, char *, |
| 482 | (char *restrict s, int n, FILE *restrict stream)); | 532 | (char *restrict s, int n, FILE *restrict stream)); |
| 483 | # else | 533 | # else |
| @@ -513,17 +563,18 @@ _GL_CXXALIASWARN (fileno); | |||
| 513 | # define fopen rpl_fopen | 563 | # define fopen rpl_fopen |
| 514 | # endif | 564 | # endif |
| 515 | _GL_FUNCDECL_RPL (fopen, FILE *, | 565 | _GL_FUNCDECL_RPL (fopen, FILE *, |
| 516 | (const char *restrict filename, const char *restrict mode) | 566 | (const char *restrict filename, const char *restrict mode), |
| 517 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) | 567 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 518 | _GL_ATTRIBUTE_MALLOC); | 568 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_NODISCARD); |
| 519 | _GL_CXXALIAS_RPL (fopen, FILE *, | 569 | _GL_CXXALIAS_RPL (fopen, FILE *, |
| 520 | (const char *restrict filename, const char *restrict mode)); | 570 | (const char *restrict filename, const char *restrict mode)); |
| 521 | # else | 571 | # else |
| 522 | # if __GNUC__ >= 11 | 572 | # if __GNUC__ >= 11 && !defined __clang__ |
| 523 | /* For -Wmismatched-dealloc: Associate fopen with fclose or rpl_fclose. */ | 573 | /* For -Wmismatched-dealloc: Associate fopen with fclose or rpl_fclose. */ |
| 524 | _GL_FUNCDECL_SYS (fopen, FILE *, | 574 | _GL_FUNCDECL_SYS (fopen, FILE *, |
| 525 | (const char *restrict filename, const char *restrict mode) | 575 | (const char *restrict filename, const char *restrict mode), |
| 526 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1)); | 576 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 577 | _GL_ATTRIBUTE_NODISCARD); | ||
| 527 | # endif | 578 | # endif |
| 528 | _GL_CXXALIAS_SYS (fopen, FILE *, | 579 | _GL_CXXALIAS_SYS (fopen, FILE *, |
| 529 | (const char *restrict filename, const char *restrict mode)); | 580 | (const char *restrict filename, const char *restrict mode)); |
| @@ -532,10 +583,10 @@ _GL_CXXALIAS_SYS (fopen, FILE *, | |||
| 532 | _GL_CXXALIASWARN (fopen); | 583 | _GL_CXXALIASWARN (fopen); |
| 533 | # endif | 584 | # endif |
| 534 | #else | 585 | #else |
| 535 | # if @GNULIB_FCLOSE@ && __GNUC__ >= 11 && !defined fopen | 586 | # if @GNULIB_FCLOSE@ && (__GNUC__ >= 11 && !defined __clang__) && !defined fopen |
| 536 | /* For -Wmismatched-dealloc: Associate fopen with fclose or rpl_fclose. */ | 587 | /* For -Wmismatched-dealloc: Associate fopen with fclose or rpl_fclose. */ |
| 537 | _GL_FUNCDECL_SYS (fopen, FILE *, | 588 | _GL_FUNCDECL_SYS (fopen, FILE *, |
| 538 | (const char *restrict filename, const char *restrict mode) | 589 | (const char *restrict filename, const char *restrict mode), |
| 539 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1)); | 590 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (fclose, 1)); |
| 540 | # endif | 591 | # endif |
| 541 | # if defined GNULIB_POSIXCHECK | 592 | # if defined GNULIB_POSIXCHECK |
| @@ -546,7 +597,26 @@ _GL_WARN_ON_USE (fopen, "fopen on native Windows platforms is not POSIX complian | |||
| 546 | # endif | 597 | # endif |
| 547 | #endif | 598 | #endif |
| 548 | 599 | ||
| 600 | #if @GNULIB_FZPRINTF@ | ||
| 601 | /* Prints formatted output to stream FP. | ||
| 602 | Returns the number of bytes written to the stream. Upon failure, | ||
| 603 | returns -1 with the stream's error indicator set. | ||
| 604 | Failure cause EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 605 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 606 | directives nor widths, the only possible failure causes are ENOMEM | ||
| 607 | and the possible failure causes from fwrite(). */ | ||
| 608 | _GL_FUNCDECL_SYS (fzprintf, off64_t, | ||
| 609 | (FILE *restrict fp, const char *restrict format, ...), | ||
| 610 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | ||
| 611 | _GL_ARG_NONNULL ((1, 2))); | ||
| 612 | _GL_CXXALIAS_SYS (fzprintf, off64_t, | ||
| 613 | (FILE *restrict fp, const char *restrict format, ...)); | ||
| 614 | #endif | ||
| 615 | |||
| 549 | #if @GNULIB_FPRINTF_POSIX@ || @GNULIB_FPRINTF@ | 616 | #if @GNULIB_FPRINTF_POSIX@ || @GNULIB_FPRINTF@ |
| 617 | /* Prints formatted output to stream FP. | ||
| 618 | Returns the number of bytes written to the stream. Upon failure, | ||
| 619 | returns a negative value with the stream's error indicator set. */ | ||
| 550 | # if (@GNULIB_FPRINTF_POSIX@ && @REPLACE_FPRINTF@) \ | 620 | # if (@GNULIB_FPRINTF_POSIX@ && @REPLACE_FPRINTF@) \ |
| 551 | || (@GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) | 621 | || (@GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) |
| 552 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 622 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -555,12 +625,12 @@ _GL_WARN_ON_USE (fopen, "fopen on native Windows platforms is not POSIX complian | |||
| 555 | # define GNULIB_overrides_fprintf 1 | 625 | # define GNULIB_overrides_fprintf 1 |
| 556 | # if @GNULIB_FPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ | 626 | # if @GNULIB_FPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ |
| 557 | _GL_FUNCDECL_RPL (fprintf, int, | 627 | _GL_FUNCDECL_RPL (fprintf, int, |
| 558 | (FILE *restrict fp, const char *restrict format, ...) | 628 | (FILE *restrict fp, const char *restrict format, ...), |
| 559 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | 629 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) |
| 560 | _GL_ARG_NONNULL ((1, 2))); | 630 | _GL_ARG_NONNULL ((1, 2))); |
| 561 | # else | 631 | # else |
| 562 | _GL_FUNCDECL_RPL (fprintf, int, | 632 | _GL_FUNCDECL_RPL (fprintf, int, |
| 563 | (FILE *restrict fp, const char *restrict format, ...) | 633 | (FILE *restrict fp, const char *restrict format, ...), |
| 564 | _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 3) | 634 | _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 3) |
| 565 | _GL_ARG_NONNULL ((1, 2))); | 635 | _GL_ARG_NONNULL ((1, 2))); |
| 566 | # endif | 636 | # endif |
| @@ -573,6 +643,11 @@ _GL_CXXALIAS_SYS (fprintf, int, | |||
| 573 | # if __GLIBC__ >= 2 | 643 | # if __GLIBC__ >= 2 |
| 574 | _GL_CXXALIASWARN (fprintf); | 644 | _GL_CXXALIASWARN (fprintf); |
| 575 | # endif | 645 | # endif |
| 646 | #elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO | ||
| 647 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 648 | # undef fprintf | ||
| 649 | # define fprintf gl_consolesafe_fprintf | ||
| 650 | # endif | ||
| 576 | #endif | 651 | #endif |
| 577 | #if !@GNULIB_FPRINTF_POSIX@ && defined GNULIB_POSIXCHECK | 652 | #if !@GNULIB_FPRINTF_POSIX@ && defined GNULIB_POSIXCHECK |
| 578 | # if !GNULIB_overrides_fprintf | 653 | # if !GNULIB_overrides_fprintf |
| @@ -595,15 +670,17 @@ _GL_WARN_ON_USE (fprintf, "fprintf is not always POSIX compliant - " | |||
| 595 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 670 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 596 | # define fpurge rpl_fpurge | 671 | # define fpurge rpl_fpurge |
| 597 | # endif | 672 | # endif |
| 598 | _GL_FUNCDECL_RPL (fpurge, int, (FILE *gl_stream) _GL_ARG_NONNULL ((1))); | 673 | _GL_FUNCDECL_RPL (fpurge, int, (FILE *gl_stream), _GL_ARG_NONNULL ((1))); |
| 599 | _GL_CXXALIAS_RPL (fpurge, int, (FILE *gl_stream)); | 674 | _GL_CXXALIAS_RPL (fpurge, int, (FILE *gl_stream)); |
| 600 | # else | 675 | # else |
| 601 | # if !@HAVE_DECL_FPURGE@ | 676 | # if !@HAVE_DECL_FPURGE@ |
| 602 | _GL_FUNCDECL_SYS (fpurge, int, (FILE *gl_stream) _GL_ARG_NONNULL ((1))); | 677 | _GL_FUNCDECL_SYS (fpurge, int, (FILE *gl_stream), _GL_ARG_NONNULL ((1))); |
| 603 | # endif | 678 | # endif |
| 604 | _GL_CXXALIAS_SYS (fpurge, int, (FILE *gl_stream)); | 679 | _GL_CXXALIAS_SYS (fpurge, int, (FILE *gl_stream)); |
| 605 | # endif | 680 | # endif |
| 681 | # if __GLIBC__ >= 2 | ||
| 606 | _GL_CXXALIASWARN (fpurge); | 682 | _GL_CXXALIASWARN (fpurge); |
| 683 | # endif | ||
| 607 | #elif defined GNULIB_POSIXCHECK | 684 | #elif defined GNULIB_POSIXCHECK |
| 608 | # undef fpurge | 685 | # undef fpurge |
| 609 | # if HAVE_RAW_DECL_FPURGE | 686 | # if HAVE_RAW_DECL_FPURGE |
| @@ -618,7 +695,7 @@ _GL_WARN_ON_USE (fpurge, "fpurge is not always present - " | |||
| 618 | # undef fputc | 695 | # undef fputc |
| 619 | # define fputc rpl_fputc | 696 | # define fputc rpl_fputc |
| 620 | # endif | 697 | # endif |
| 621 | _GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream) _GL_ARG_NONNULL ((2))); | 698 | _GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream), _GL_ARG_NONNULL ((2))); |
| 622 | _GL_CXXALIAS_RPL (fputc, int, (int c, FILE *stream)); | 699 | _GL_CXXALIAS_RPL (fputc, int, (int c, FILE *stream)); |
| 623 | # else | 700 | # else |
| 624 | _GL_CXXALIAS_SYS (fputc, int, (int c, FILE *stream)); | 701 | _GL_CXXALIAS_SYS (fputc, int, (int c, FILE *stream)); |
| @@ -635,7 +712,7 @@ _GL_CXXALIASWARN (fputc); | |||
| 635 | # define fputs rpl_fputs | 712 | # define fputs rpl_fputs |
| 636 | # endif | 713 | # endif |
| 637 | _GL_FUNCDECL_RPL (fputs, int, | 714 | _GL_FUNCDECL_RPL (fputs, int, |
| 638 | (const char *restrict string, FILE *restrict stream) | 715 | (const char *restrict string, FILE *restrict stream), |
| 639 | _GL_ARG_NONNULL ((1, 2))); | 716 | _GL_ARG_NONNULL ((1, 2))); |
| 640 | _GL_CXXALIAS_RPL (fputs, int, | 717 | _GL_CXXALIAS_RPL (fputs, int, |
| 641 | (const char *restrict string, FILE *restrict stream)); | 718 | (const char *restrict string, FILE *restrict stream)); |
| @@ -656,8 +733,8 @@ _GL_CXXALIASWARN (fputs); | |||
| 656 | # endif | 733 | # endif |
| 657 | _GL_FUNCDECL_RPL (fread, size_t, | 734 | _GL_FUNCDECL_RPL (fread, size_t, |
| 658 | (void *restrict ptr, size_t s, size_t n, | 735 | (void *restrict ptr, size_t s, size_t n, |
| 659 | FILE *restrict stream) | 736 | FILE *restrict stream), |
| 660 | _GL_ARG_NONNULL ((4))); | 737 | _GL_ARG_NONNULL ((4)) _GL_ATTRIBUTE_NODISCARD); |
| 661 | _GL_CXXALIAS_RPL (fread, size_t, | 738 | _GL_CXXALIAS_RPL (fread, size_t, |
| 662 | (void *restrict ptr, size_t s, size_t n, | 739 | (void *restrict ptr, size_t s, size_t n, |
| 663 | FILE *restrict stream)); | 740 | FILE *restrict stream)); |
| @@ -679,8 +756,8 @@ _GL_CXXALIASWARN (fread); | |||
| 679 | # endif | 756 | # endif |
| 680 | _GL_FUNCDECL_RPL (freopen, FILE *, | 757 | _GL_FUNCDECL_RPL (freopen, FILE *, |
| 681 | (const char *restrict filename, const char *restrict mode, | 758 | (const char *restrict filename, const char *restrict mode, |
| 682 | FILE *restrict stream) | 759 | FILE *restrict stream), |
| 683 | _GL_ARG_NONNULL ((2, 3))); | 760 | _GL_ARG_NONNULL ((2, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 684 | _GL_CXXALIAS_RPL (freopen, FILE *, | 761 | _GL_CXXALIAS_RPL (freopen, FILE *, |
| 685 | (const char *restrict filename, const char *restrict mode, | 762 | (const char *restrict filename, const char *restrict mode, |
| 686 | FILE *restrict stream)); | 763 | FILE *restrict stream)); |
| @@ -707,9 +784,9 @@ _GL_WARN_ON_USE (freopen, | |||
| 707 | # define fscanf rpl_fscanf | 784 | # define fscanf rpl_fscanf |
| 708 | # endif | 785 | # endif |
| 709 | _GL_FUNCDECL_RPL (fscanf, int, | 786 | _GL_FUNCDECL_RPL (fscanf, int, |
| 710 | (FILE *restrict stream, const char *restrict format, ...) | 787 | (FILE *restrict stream, const char *restrict format, ...), |
| 711 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3) | 788 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3) |
| 712 | _GL_ARG_NONNULL ((1, 2))); | 789 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_NODISCARD); |
| 713 | _GL_CXXALIAS_RPL (fscanf, int, | 790 | _GL_CXXALIAS_RPL (fscanf, int, |
| 714 | (FILE *restrict stream, const char *restrict format, ...)); | 791 | (FILE *restrict stream, const char *restrict format, ...)); |
| 715 | # else | 792 | # else |
| @@ -763,7 +840,7 @@ _GL_CXXALIASWARN (fscanf); | |||
| 763 | # undef fseek | 840 | # undef fseek |
| 764 | # define fseek rpl_fseek | 841 | # define fseek rpl_fseek |
| 765 | # endif | 842 | # endif |
| 766 | _GL_FUNCDECL_RPL (fseek, int, (FILE *fp, long offset, int whence) | 843 | _GL_FUNCDECL_RPL (fseek, int, (FILE *fp, long offset, int whence), |
| 767 | _GL_ARG_NONNULL ((1))); | 844 | _GL_ARG_NONNULL ((1))); |
| 768 | _GL_CXXALIAS_RPL (fseek, int, (FILE *fp, long offset, int whence)); | 845 | _GL_CXXALIAS_RPL (fseek, int, (FILE *fp, long offset, int whence)); |
| 769 | # else | 846 | # else |
| @@ -786,12 +863,12 @@ _GL_CXXALIASWARN (fseek); | |||
| 786 | # undef fseeko | 863 | # undef fseeko |
| 787 | # define fseeko rpl_fseeko | 864 | # define fseeko rpl_fseeko |
| 788 | # endif | 865 | # endif |
| 789 | _GL_FUNCDECL_RPL (fseeko, int, (FILE *fp, off_t offset, int whence) | 866 | _GL_FUNCDECL_RPL (fseeko, int, (FILE *fp, off_t offset, int whence), |
| 790 | _GL_ARG_NONNULL ((1))); | 867 | _GL_ARG_NONNULL ((1))); |
| 791 | _GL_CXXALIAS_RPL (fseeko, int, (FILE *fp, off_t offset, int whence)); | 868 | _GL_CXXALIAS_RPL (fseeko, int, (FILE *fp, off_t offset, int whence)); |
| 792 | # else | 869 | # else |
| 793 | # if ! @HAVE_DECL_FSEEKO@ | 870 | # if ! @HAVE_DECL_FSEEKO@ |
| 794 | _GL_FUNCDECL_SYS (fseeko, int, (FILE *fp, off_t offset, int whence) | 871 | _GL_FUNCDECL_SYS (fseeko, int, (FILE *fp, off_t offset, int whence), |
| 795 | _GL_ARG_NONNULL ((1))); | 872 | _GL_ARG_NONNULL ((1))); |
| 796 | # endif | 873 | # endif |
| 797 | _GL_CXXALIAS_SYS (fseeko, int, (FILE *fp, off_t offset, int whence)); | 874 | _GL_CXXALIAS_SYS (fseeko, int, (FILE *fp, off_t offset, int whence)); |
| @@ -829,7 +906,8 @@ _GL_WARN_ON_USE (fseek, "fseek cannot handle files larger than 4 GB " | |||
| 829 | # undef ftell | 906 | # undef ftell |
| 830 | # define ftell rpl_ftell | 907 | # define ftell rpl_ftell |
| 831 | # endif | 908 | # endif |
| 832 | _GL_FUNCDECL_RPL (ftell, long, (FILE *fp) _GL_ARG_NONNULL ((1))); | 909 | _GL_FUNCDECL_RPL (ftell, long, (FILE *fp), |
| 910 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 833 | _GL_CXXALIAS_RPL (ftell, long, (FILE *fp)); | 911 | _GL_CXXALIAS_RPL (ftell, long, (FILE *fp)); |
| 834 | # else | 912 | # else |
| 835 | _GL_CXXALIAS_SYS (ftell, long, (FILE *fp)); | 913 | _GL_CXXALIAS_SYS (ftell, long, (FILE *fp)); |
| @@ -849,11 +927,13 @@ _GL_CXXALIASWARN (ftell); | |||
| 849 | # undef ftello | 927 | # undef ftello |
| 850 | # define ftello rpl_ftello | 928 | # define ftello rpl_ftello |
| 851 | # endif | 929 | # endif |
| 852 | _GL_FUNCDECL_RPL (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); | 930 | _GL_FUNCDECL_RPL (ftello, off_t, (FILE *fp), |
| 931 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 853 | _GL_CXXALIAS_RPL (ftello, off_t, (FILE *fp)); | 932 | _GL_CXXALIAS_RPL (ftello, off_t, (FILE *fp)); |
| 854 | # else | 933 | # else |
| 855 | # if ! @HAVE_DECL_FTELLO@ | 934 | # if ! @HAVE_DECL_FTELLO@ |
| 856 | _GL_FUNCDECL_SYS (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); | 935 | _GL_FUNCDECL_SYS (ftello, off_t, (FILE *fp), |
| 936 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 857 | # endif | 937 | # endif |
| 858 | _GL_CXXALIAS_SYS (ftello, off_t, (FILE *fp)); | 938 | _GL_CXXALIAS_SYS (ftello, off_t, (FILE *fp)); |
| 859 | # endif | 939 | # endif |
| @@ -886,7 +966,7 @@ _GL_WARN_ON_USE (ftell, "ftell cannot handle files larger than 4 GB " | |||
| 886 | # endif | 966 | # endif |
| 887 | _GL_FUNCDECL_RPL (fwrite, size_t, | 967 | _GL_FUNCDECL_RPL (fwrite, size_t, |
| 888 | (const void *restrict ptr, size_t s, size_t n, | 968 | (const void *restrict ptr, size_t s, size_t n, |
| 889 | FILE *restrict stream) | 969 | FILE *restrict stream), |
| 890 | _GL_ARG_NONNULL ((1, 4))); | 970 | _GL_ARG_NONNULL ((1, 4))); |
| 891 | _GL_CXXALIAS_RPL (fwrite, size_t, | 971 | _GL_CXXALIAS_RPL (fwrite, size_t, |
| 892 | (const void *restrict ptr, size_t s, size_t n, | 972 | (const void *restrict ptr, size_t s, size_t n, |
| @@ -901,9 +981,9 @@ _GL_CXXALIAS_SYS (fwrite, size_t, | |||
| 901 | which sometimes causes an unwanted diagnostic for fwrite calls. | 981 | which sometimes causes an unwanted diagnostic for fwrite calls. |
| 902 | This affects only function declaration attributes under certain | 982 | This affects only function declaration attributes under certain |
| 903 | versions of gcc and clang, and is not needed for C++. */ | 983 | versions of gcc and clang, and is not needed for C++. */ |
| 904 | # if (0 < __USE_FORTIFY_LEVEL \ | 984 | # if (0 < __USE_FORTIFY_LEVEL \ |
| 905 | && __GLIBC__ == 2 && 4 <= __GLIBC_MINOR__ && __GLIBC_MINOR__ <= 15 \ | 985 | && __GLIBC__ == 2 && 4 <= __GLIBC_MINOR__ && __GLIBC_MINOR__ <= 15 \ |
| 906 | && 3 < __GNUC__ + (4 <= __GNUC_MINOR__) \ | 986 | && (3 < __GNUC__ + (4 <= __GNUC_MINOR__) || defined __clang__) \ |
| 907 | && !defined __cplusplus) | 987 | && !defined __cplusplus) |
| 908 | # undef fwrite | 988 | # undef fwrite |
| 909 | # undef fwrite_unlocked | 989 | # undef fwrite_unlocked |
| @@ -922,6 +1002,11 @@ _GL_EXTERN_C size_t __REDIRECT (rpl_fwrite_unlocked, | |||
| 922 | # if __GLIBC__ >= 2 | 1002 | # if __GLIBC__ >= 2 |
| 923 | _GL_CXXALIASWARN (fwrite); | 1003 | _GL_CXXALIASWARN (fwrite); |
| 924 | # endif | 1004 | # endif |
| 1005 | #elif (defined _WIN32 && !defined __CYGWIN__) && !defined _UCRT | ||
| 1006 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1007 | # undef fwrite | ||
| 1008 | # define fwrite gl_consolesafe_fwrite | ||
| 1009 | # endif | ||
| 925 | #endif | 1010 | #endif |
| 926 | 1011 | ||
| 927 | #if @GNULIB_GETC@ | 1012 | #if @GNULIB_GETC@ |
| @@ -930,7 +1015,7 @@ _GL_CXXALIASWARN (fwrite); | |||
| 930 | # undef getc | 1015 | # undef getc |
| 931 | # define getc rpl_fgetc | 1016 | # define getc rpl_fgetc |
| 932 | # endif | 1017 | # endif |
| 933 | _GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1))); | 1018 | _GL_FUNCDECL_RPL (fgetc, int, (FILE *stream), _GL_ARG_NONNULL ((1))); |
| 934 | _GL_CXXALIAS_RPL_1 (getc, rpl_fgetc, int, (FILE *stream)); | 1019 | _GL_CXXALIAS_RPL_1 (getc, rpl_fgetc, int, (FILE *stream)); |
| 935 | # else | 1020 | # else |
| 936 | _GL_CXXALIAS_SYS (getc, int, (FILE *stream)); | 1021 | _GL_CXXALIAS_SYS (getc, int, (FILE *stream)); |
| @@ -946,7 +1031,7 @@ _GL_CXXALIASWARN (getc); | |||
| 946 | # undef getchar | 1031 | # undef getchar |
| 947 | # define getchar rpl_getchar | 1032 | # define getchar rpl_getchar |
| 948 | # endif | 1033 | # endif |
| 949 | _GL_FUNCDECL_RPL (getchar, int, (void)); | 1034 | _GL_FUNCDECL_RPL (getchar, int, (void), ); |
| 950 | _GL_CXXALIAS_RPL (getchar, int, (void)); | 1035 | _GL_CXXALIAS_RPL (getchar, int, (void)); |
| 951 | # else | 1036 | # else |
| 952 | _GL_CXXALIAS_SYS (getchar, int, (void)); | 1037 | _GL_CXXALIAS_SYS (getchar, int, (void)); |
| @@ -971,8 +1056,8 @@ _GL_CXXALIASWARN (getchar); | |||
| 971 | _GL_FUNCDECL_RPL (getdelim, ssize_t, | 1056 | _GL_FUNCDECL_RPL (getdelim, ssize_t, |
| 972 | (char **restrict lineptr, size_t *restrict linesize, | 1057 | (char **restrict lineptr, size_t *restrict linesize, |
| 973 | int delimiter, | 1058 | int delimiter, |
| 974 | FILE *restrict stream) | 1059 | FILE *restrict stream), |
| 975 | _GL_ARG_NONNULL ((1, 2, 4))); | 1060 | _GL_ARG_NONNULL ((1, 2, 4)) _GL_ATTRIBUTE_NODISCARD); |
| 976 | _GL_CXXALIAS_RPL (getdelim, ssize_t, | 1061 | _GL_CXXALIAS_RPL (getdelim, ssize_t, |
| 977 | (char **restrict lineptr, size_t *restrict linesize, | 1062 | (char **restrict lineptr, size_t *restrict linesize, |
| 978 | int delimiter, | 1063 | int delimiter, |
| @@ -982,8 +1067,8 @@ _GL_CXXALIAS_RPL (getdelim, ssize_t, | |||
| 982 | _GL_FUNCDECL_SYS (getdelim, ssize_t, | 1067 | _GL_FUNCDECL_SYS (getdelim, ssize_t, |
| 983 | (char **restrict lineptr, size_t *restrict linesize, | 1068 | (char **restrict lineptr, size_t *restrict linesize, |
| 984 | int delimiter, | 1069 | int delimiter, |
| 985 | FILE *restrict stream) | 1070 | FILE *restrict stream), |
| 986 | _GL_ARG_NONNULL ((1, 2, 4))); | 1071 | _GL_ARG_NONNULL ((1, 2, 4)) _GL_ATTRIBUTE_NODISCARD); |
| 987 | # endif | 1072 | # endif |
| 988 | _GL_CXXALIAS_SYS (getdelim, ssize_t, | 1073 | _GL_CXXALIAS_SYS (getdelim, ssize_t, |
| 989 | (char **restrict lineptr, size_t *restrict linesize, | 1074 | (char **restrict lineptr, size_t *restrict linesize, |
| @@ -1015,8 +1100,8 @@ _GL_WARN_ON_USE (getdelim, "getdelim is unportable - " | |||
| 1015 | # endif | 1100 | # endif |
| 1016 | _GL_FUNCDECL_RPL (getline, ssize_t, | 1101 | _GL_FUNCDECL_RPL (getline, ssize_t, |
| 1017 | (char **restrict lineptr, size_t *restrict linesize, | 1102 | (char **restrict lineptr, size_t *restrict linesize, |
| 1018 | FILE *restrict stream) | 1103 | FILE *restrict stream), |
| 1019 | _GL_ARG_NONNULL ((1, 2, 3))); | 1104 | _GL_ARG_NONNULL ((1, 2, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 1020 | _GL_CXXALIAS_RPL (getline, ssize_t, | 1105 | _GL_CXXALIAS_RPL (getline, ssize_t, |
| 1021 | (char **restrict lineptr, size_t *restrict linesize, | 1106 | (char **restrict lineptr, size_t *restrict linesize, |
| 1022 | FILE *restrict stream)); | 1107 | FILE *restrict stream)); |
| @@ -1024,8 +1109,8 @@ _GL_CXXALIAS_RPL (getline, ssize_t, | |||
| 1024 | # if !@HAVE_DECL_GETLINE@ | 1109 | # if !@HAVE_DECL_GETLINE@ |
| 1025 | _GL_FUNCDECL_SYS (getline, ssize_t, | 1110 | _GL_FUNCDECL_SYS (getline, ssize_t, |
| 1026 | (char **restrict lineptr, size_t *restrict linesize, | 1111 | (char **restrict lineptr, size_t *restrict linesize, |
| 1027 | FILE *restrict stream) | 1112 | FILE *restrict stream), |
| 1028 | _GL_ARG_NONNULL ((1, 2, 3))); | 1113 | _GL_ARG_NONNULL ((1, 2, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 1029 | # endif | 1114 | # endif |
| 1030 | _GL_CXXALIAS_SYS (getline, ssize_t, | 1115 | _GL_CXXALIAS_SYS (getline, ssize_t, |
| 1031 | (char **restrict lineptr, size_t *restrict linesize, | 1116 | (char **restrict lineptr, size_t *restrict linesize, |
| @@ -1064,7 +1149,7 @@ _GL_CXXALIAS_MDA (getw, int, (FILE *restrict stream)); | |||
| 1064 | # if @HAVE_DECL_GETW@ | 1149 | # if @HAVE_DECL_GETW@ |
| 1065 | # if defined __APPLE__ && defined __MACH__ | 1150 | # if defined __APPLE__ && defined __MACH__ |
| 1066 | /* The presence of the declaration depends on _POSIX_C_SOURCE. */ | 1151 | /* The presence of the declaration depends on _POSIX_C_SOURCE. */ |
| 1067 | _GL_FUNCDECL_SYS (getw, int, (FILE *restrict stream)); | 1152 | _GL_FUNCDECL_SYS (getw, int, (FILE *restrict stream), ); |
| 1068 | # endif | 1153 | # endif |
| 1069 | _GL_CXXALIAS_SYS (getw, int, (FILE *restrict stream)); | 1154 | _GL_CXXALIAS_SYS (getw, int, (FILE *restrict stream)); |
| 1070 | # endif | 1155 | # endif |
| @@ -1074,19 +1159,45 @@ _GL_CXXALIASWARN (getw); | |||
| 1074 | # endif | 1159 | # endif |
| 1075 | #endif | 1160 | #endif |
| 1076 | 1161 | ||
| 1162 | #if @GNULIB_OBSTACK_ZPRINTF@ | ||
| 1163 | struct obstack; | ||
| 1164 | /* Grows an obstack with formatted output. Returns the number of | ||
| 1165 | bytes added to OBS. No trailing nul byte is added, and the | ||
| 1166 | object should be closed with obstack_finish before use. | ||
| 1167 | Upon memory allocation error, calls obstack_alloc_failed_handler. | ||
| 1168 | Upon other error, returns -1 with errno set. | ||
| 1169 | |||
| 1170 | Failure code EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 1171 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 1172 | directives nor widths, the only possible failure code is through | ||
| 1173 | obstack_alloc_failed_handler. */ | ||
| 1174 | _GL_FUNCDECL_SYS (obstack_zprintf, ptrdiff_t, | ||
| 1175 | (struct obstack *obs, const char *format, ...), | ||
| 1176 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | ||
| 1177 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1178 | _GL_CXXALIAS_SYS (obstack_zprintf, ptrdiff_t, | ||
| 1179 | (struct obstack *obs, const char *format, ...)); | ||
| 1180 | _GL_FUNCDECL_SYS (obstack_vzprintf, ptrdiff_t, | ||
| 1181 | (struct obstack *obs, const char *format, va_list args), | ||
| 1182 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | ||
| 1183 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1184 | _GL_CXXALIAS_SYS (obstack_vzprintf, ptrdiff_t, | ||
| 1185 | (struct obstack *obs, const char *format, va_list args)); | ||
| 1186 | #endif | ||
| 1187 | |||
| 1077 | #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ | 1188 | #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ |
| 1078 | struct obstack; | 1189 | struct obstack; |
| 1079 | /* Grow an obstack with formatted output. Return the number of | 1190 | /* Grows an obstack with formatted output. Returns the number of |
| 1080 | bytes added to OBS. No trailing nul byte is added, and the | 1191 | bytes added to OBS. No trailing nul byte is added, and the |
| 1081 | object should be closed with obstack_finish before use. Upon | 1192 | object should be closed with obstack_finish before use. |
| 1082 | memory allocation error, call obstack_alloc_failed_handler. Upon | 1193 | Upon memory allocation error, calls obstack_alloc_failed_handler. |
| 1083 | other error, return -1. */ | 1194 | Upon other error, returns -1. */ |
| 1084 | # if @REPLACE_OBSTACK_PRINTF@ | 1195 | # if @REPLACE_OBSTACK_PRINTF@ |
| 1085 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1196 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1086 | # define obstack_printf rpl_obstack_printf | 1197 | # define obstack_printf rpl_obstack_printf |
| 1087 | # endif | 1198 | # endif |
| 1088 | _GL_FUNCDECL_RPL (obstack_printf, int, | 1199 | _GL_FUNCDECL_RPL (obstack_printf, int, |
| 1089 | (struct obstack *obs, const char *format, ...) | 1200 | (struct obstack *obs, const char *format, ...), |
| 1090 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | 1201 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) |
| 1091 | _GL_ARG_NONNULL ((1, 2))); | 1202 | _GL_ARG_NONNULL ((1, 2))); |
| 1092 | _GL_CXXALIAS_RPL (obstack_printf, int, | 1203 | _GL_CXXALIAS_RPL (obstack_printf, int, |
| @@ -1094,7 +1205,7 @@ _GL_CXXALIAS_RPL (obstack_printf, int, | |||
| 1094 | # else | 1205 | # else |
| 1095 | # if !@HAVE_DECL_OBSTACK_PRINTF@ | 1206 | # if !@HAVE_DECL_OBSTACK_PRINTF@ |
| 1096 | _GL_FUNCDECL_SYS (obstack_printf, int, | 1207 | _GL_FUNCDECL_SYS (obstack_printf, int, |
| 1097 | (struct obstack *obs, const char *format, ...) | 1208 | (struct obstack *obs, const char *format, ...), |
| 1098 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | 1209 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) |
| 1099 | _GL_ARG_NONNULL ((1, 2))); | 1210 | _GL_ARG_NONNULL ((1, 2))); |
| 1100 | # endif | 1211 | # endif |
| @@ -1107,7 +1218,7 @@ _GL_CXXALIASWARN (obstack_printf); | |||
| 1107 | # define obstack_vprintf rpl_obstack_vprintf | 1218 | # define obstack_vprintf rpl_obstack_vprintf |
| 1108 | # endif | 1219 | # endif |
| 1109 | _GL_FUNCDECL_RPL (obstack_vprintf, int, | 1220 | _GL_FUNCDECL_RPL (obstack_vprintf, int, |
| 1110 | (struct obstack *obs, const char *format, va_list args) | 1221 | (struct obstack *obs, const char *format, va_list args), |
| 1111 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | 1222 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) |
| 1112 | _GL_ARG_NONNULL ((1, 2))); | 1223 | _GL_ARG_NONNULL ((1, 2))); |
| 1113 | _GL_CXXALIAS_RPL (obstack_vprintf, int, | 1224 | _GL_CXXALIAS_RPL (obstack_vprintf, int, |
| @@ -1115,7 +1226,7 @@ _GL_CXXALIAS_RPL (obstack_vprintf, int, | |||
| 1115 | # else | 1226 | # else |
| 1116 | # if !@HAVE_DECL_OBSTACK_PRINTF@ | 1227 | # if !@HAVE_DECL_OBSTACK_PRINTF@ |
| 1117 | _GL_FUNCDECL_SYS (obstack_vprintf, int, | 1228 | _GL_FUNCDECL_SYS (obstack_vprintf, int, |
| 1118 | (struct obstack *obs, const char *format, va_list args) | 1229 | (struct obstack *obs, const char *format, va_list args), |
| 1119 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | 1230 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) |
| 1120 | _GL_ARG_NONNULL ((1, 2))); | 1231 | _GL_ARG_NONNULL ((1, 2))); |
| 1121 | # endif | 1232 | # endif |
| @@ -1127,7 +1238,7 @@ _GL_CXXALIASWARN (obstack_vprintf); | |||
| 1127 | 1238 | ||
| 1128 | #if @GNULIB_PCLOSE@ | 1239 | #if @GNULIB_PCLOSE@ |
| 1129 | # if !@HAVE_PCLOSE@ | 1240 | # if !@HAVE_PCLOSE@ |
| 1130 | _GL_FUNCDECL_SYS (pclose, int, (FILE *stream) _GL_ARG_NONNULL ((1))); | 1241 | _GL_FUNCDECL_SYS (pclose, int, (FILE *stream), _GL_ARG_NONNULL ((1))); |
| 1131 | # endif | 1242 | # endif |
| 1132 | _GL_CXXALIAS_SYS (pclose, int, (FILE *stream)); | 1243 | _GL_CXXALIAS_SYS (pclose, int, (FILE *stream)); |
| 1133 | _GL_CXXALIASWARN (pclose); | 1244 | _GL_CXXALIASWARN (pclose); |
| @@ -1147,7 +1258,7 @@ _GL_WARN_ON_USE (pclose, "pclose is unportable - " | |||
| 1147 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1258 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1148 | # define perror rpl_perror | 1259 | # define perror rpl_perror |
| 1149 | # endif | 1260 | # endif |
| 1150 | _GL_FUNCDECL_RPL (perror, void, (const char *string)); | 1261 | _GL_FUNCDECL_RPL (perror, void, (const char *string), ); |
| 1151 | _GL_CXXALIAS_RPL (perror, void, (const char *string)); | 1262 | _GL_CXXALIAS_RPL (perror, void, (const char *string)); |
| 1152 | # else | 1263 | # else |
| 1153 | _GL_CXXALIAS_SYS (perror, void, (const char *string)); | 1264 | _GL_CXXALIAS_SYS (perror, void, (const char *string)); |
| @@ -1169,25 +1280,26 @@ _GL_WARN_ON_USE (perror, "perror is not always POSIX compliant - " | |||
| 1169 | # define popen rpl_popen | 1280 | # define popen rpl_popen |
| 1170 | # endif | 1281 | # endif |
| 1171 | _GL_FUNCDECL_RPL (popen, FILE *, | 1282 | _GL_FUNCDECL_RPL (popen, FILE *, |
| 1172 | (const char *cmd, const char *mode) | 1283 | (const char *cmd, const char *mode), |
| 1173 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1) | 1284 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1) |
| 1174 | _GL_ATTRIBUTE_MALLOC); | 1285 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_NODISCARD); |
| 1175 | _GL_CXXALIAS_RPL (popen, FILE *, (const char *cmd, const char *mode)); | 1286 | _GL_CXXALIAS_RPL (popen, FILE *, (const char *cmd, const char *mode)); |
| 1176 | # else | 1287 | # else |
| 1177 | # if !@HAVE_POPEN@ || __GNUC__ >= 11 | 1288 | # if !@HAVE_POPEN@ || (__GNUC__ >= 11 && !defined __clang__) |
| 1178 | _GL_FUNCDECL_SYS (popen, FILE *, | 1289 | _GL_FUNCDECL_SYS (popen, FILE *, |
| 1179 | (const char *cmd, const char *mode) | 1290 | (const char *cmd, const char *mode), |
| 1180 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1) | 1291 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1) |
| 1181 | _GL_ATTRIBUTE_MALLOC); | 1292 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_NODISCARD); |
| 1182 | # endif | 1293 | # endif |
| 1183 | _GL_CXXALIAS_SYS (popen, FILE *, (const char *cmd, const char *mode)); | 1294 | _GL_CXXALIAS_SYS (popen, FILE *, (const char *cmd, const char *mode)); |
| 1184 | # endif | 1295 | # endif |
| 1185 | _GL_CXXALIASWARN (popen); | 1296 | _GL_CXXALIASWARN (popen); |
| 1186 | #else | 1297 | #else |
| 1187 | # if @GNULIB_PCLOSE@ && __GNUC__ >= 11 && !defined popen | 1298 | # if @GNULIB_PCLOSE@ \ |
| 1299 | && (__GNUC__ >= 11 && !defined __clang__) && !defined popen | ||
| 1188 | /* For -Wmismatched-dealloc: Associate popen with pclose or rpl_pclose. */ | 1300 | /* For -Wmismatched-dealloc: Associate popen with pclose or rpl_pclose. */ |
| 1189 | _GL_FUNCDECL_SYS (popen, FILE *, | 1301 | _GL_FUNCDECL_SYS (popen, FILE *, |
| 1190 | (const char *cmd, const char *mode) | 1302 | (const char *cmd, const char *mode), |
| 1191 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1) | 1303 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_DEALLOC (pclose, 1) |
| 1192 | _GL_ATTRIBUTE_MALLOC); | 1304 | _GL_ATTRIBUTE_MALLOC); |
| 1193 | # endif | 1305 | # endif |
| @@ -1200,7 +1312,24 @@ _GL_WARN_ON_USE (popen, "popen is buggy on some platforms - " | |||
| 1200 | # endif | 1312 | # endif |
| 1201 | #endif | 1313 | #endif |
| 1202 | 1314 | ||
| 1315 | #if @GNULIB_ZPRINTF@ | ||
| 1316 | /* Prints formatted output to standard output. | ||
| 1317 | Returns the number of bytes written to standard output. Upon failure, | ||
| 1318 | returns -1 with stdout's error indicator set. | ||
| 1319 | Failure cause EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 1320 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 1321 | directives nor widths, the only possible failure causes are ENOMEM | ||
| 1322 | and the possible failure causes from fwrite(). */ | ||
| 1323 | _GL_FUNCDECL_SYS (zprintf, off64_t, (const char *restrict format, ...), | ||
| 1324 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) | ||
| 1325 | _GL_ARG_NONNULL ((1))); | ||
| 1326 | _GL_CXXALIAS_SYS (zprintf, off64_t, (const char *restrict format, ...)); | ||
| 1327 | #endif | ||
| 1328 | |||
| 1203 | #if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@ | 1329 | #if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@ |
| 1330 | /* Prints formatted output to standard output. | ||
| 1331 | Returns the number of bytes written to standard output. Upon failure, | ||
| 1332 | returns a negative value with stdout's error indicator set. */ | ||
| 1204 | # if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \ | 1333 | # if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \ |
| 1205 | || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) | 1334 | || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) |
| 1206 | # if defined __GNUC__ || defined __clang__ | 1335 | # if defined __GNUC__ || defined __clang__ |
| @@ -1212,14 +1341,14 @@ _GL_WARN_ON_USE (popen, "popen is buggy on some platforms - " | |||
| 1212 | _GL_FUNCDECL_RPL_1 (__printf__, int, | 1341 | _GL_FUNCDECL_RPL_1 (__printf__, int, |
| 1213 | (const char *restrict format, ...) | 1342 | (const char *restrict format, ...) |
| 1214 | __asm__ (@ASM_SYMBOL_PREFIX@ | 1343 | __asm__ (@ASM_SYMBOL_PREFIX@ |
| 1215 | _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) | 1344 | _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)), |
| 1216 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) | 1345 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) |
| 1217 | _GL_ARG_NONNULL ((1))); | 1346 | _GL_ARG_NONNULL ((1))); |
| 1218 | # else | 1347 | # else |
| 1219 | _GL_FUNCDECL_RPL_1 (__printf__, int, | 1348 | _GL_FUNCDECL_RPL_1 (__printf__, int, |
| 1220 | (const char *restrict format, ...) | 1349 | (const char *restrict format, ...) |
| 1221 | __asm__ (@ASM_SYMBOL_PREFIX@ | 1350 | __asm__ (@ASM_SYMBOL_PREFIX@ |
| 1222 | _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) | 1351 | _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)), |
| 1223 | _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 2) | 1352 | _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 2) |
| 1224 | _GL_ARG_NONNULL ((1))); | 1353 | _GL_ARG_NONNULL ((1))); |
| 1225 | # endif | 1354 | # endif |
| @@ -1229,7 +1358,7 @@ _GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...)); | |||
| 1229 | # define printf rpl_printf | 1358 | # define printf rpl_printf |
| 1230 | # endif | 1359 | # endif |
| 1231 | _GL_FUNCDECL_RPL (printf, int, | 1360 | _GL_FUNCDECL_RPL (printf, int, |
| 1232 | (const char *restrict format, ...) | 1361 | (const char *restrict format, ...), |
| 1233 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) | 1362 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2) |
| 1234 | _GL_ARG_NONNULL ((1))); | 1363 | _GL_ARG_NONNULL ((1))); |
| 1235 | _GL_CXXALIAS_RPL (printf, int, (const char *restrict format, ...)); | 1364 | _GL_CXXALIAS_RPL (printf, int, (const char *restrict format, ...)); |
| @@ -1241,6 +1370,11 @@ _GL_CXXALIAS_SYS (printf, int, (const char *restrict format, ...)); | |||
| 1241 | # if __GLIBC__ >= 2 | 1370 | # if __GLIBC__ >= 2 |
| 1242 | _GL_CXXALIASWARN (printf); | 1371 | _GL_CXXALIASWARN (printf); |
| 1243 | # endif | 1372 | # endif |
| 1373 | #elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO | ||
| 1374 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1375 | # undef printf | ||
| 1376 | # define printf gl_consolesafe_printf | ||
| 1377 | # endif | ||
| 1244 | #endif | 1378 | #endif |
| 1245 | #if !@GNULIB_PRINTF_POSIX@ && defined GNULIB_POSIXCHECK | 1379 | #if !@GNULIB_PRINTF_POSIX@ && defined GNULIB_POSIXCHECK |
| 1246 | # if !GNULIB_overrides_printf | 1380 | # if !GNULIB_overrides_printf |
| @@ -1258,7 +1392,7 @@ _GL_WARN_ON_USE (printf, "printf is not always POSIX compliant - " | |||
| 1258 | # undef putc | 1392 | # undef putc |
| 1259 | # define putc rpl_fputc | 1393 | # define putc rpl_fputc |
| 1260 | # endif | 1394 | # endif |
| 1261 | _GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream) _GL_ARG_NONNULL ((2))); | 1395 | _GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream), _GL_ARG_NONNULL ((2))); |
| 1262 | _GL_CXXALIAS_RPL_1 (putc, rpl_fputc, int, (int c, FILE *stream)); | 1396 | _GL_CXXALIAS_RPL_1 (putc, rpl_fputc, int, (int c, FILE *stream)); |
| 1263 | # else | 1397 | # else |
| 1264 | _GL_CXXALIAS_SYS (putc, int, (int c, FILE *stream)); | 1398 | _GL_CXXALIAS_SYS (putc, int, (int c, FILE *stream)); |
| @@ -1274,7 +1408,7 @@ _GL_CXXALIASWARN (putc); | |||
| 1274 | # undef putchar | 1408 | # undef putchar |
| 1275 | # define putchar rpl_putchar | 1409 | # define putchar rpl_putchar |
| 1276 | # endif | 1410 | # endif |
| 1277 | _GL_FUNCDECL_RPL (putchar, int, (int c)); | 1411 | _GL_FUNCDECL_RPL (putchar, int, (int c), ); |
| 1278 | _GL_CXXALIAS_RPL (putchar, int, (int c)); | 1412 | _GL_CXXALIAS_RPL (putchar, int, (int c)); |
| 1279 | # else | 1413 | # else |
| 1280 | _GL_CXXALIAS_SYS (putchar, int, (int c)); | 1414 | _GL_CXXALIAS_SYS (putchar, int, (int c)); |
| @@ -1290,7 +1424,7 @@ _GL_CXXALIASWARN (putchar); | |||
| 1290 | # undef puts | 1424 | # undef puts |
| 1291 | # define puts rpl_puts | 1425 | # define puts rpl_puts |
| 1292 | # endif | 1426 | # endif |
| 1293 | _GL_FUNCDECL_RPL (puts, int, (const char *string) _GL_ARG_NONNULL ((1))); | 1427 | _GL_FUNCDECL_RPL (puts, int, (const char *string), _GL_ARG_NONNULL ((1))); |
| 1294 | _GL_CXXALIAS_RPL (puts, int, (const char *string)); | 1428 | _GL_CXXALIAS_RPL (puts, int, (const char *string)); |
| 1295 | # else | 1429 | # else |
| 1296 | _GL_CXXALIAS_SYS (puts, int, (const char *string)); | 1430 | _GL_CXXALIAS_SYS (puts, int, (const char *string)); |
| @@ -1314,7 +1448,7 @@ _GL_CXXALIAS_MDA (putw, int, (int w, FILE *restrict stream)); | |||
| 1314 | # if @HAVE_DECL_PUTW@ | 1448 | # if @HAVE_DECL_PUTW@ |
| 1315 | # if defined __APPLE__ && defined __MACH__ | 1449 | # if defined __APPLE__ && defined __MACH__ |
| 1316 | /* The presence of the declaration depends on _POSIX_C_SOURCE. */ | 1450 | /* The presence of the declaration depends on _POSIX_C_SOURCE. */ |
| 1317 | _GL_FUNCDECL_SYS (putw, int, (int w, FILE *restrict stream)); | 1451 | _GL_FUNCDECL_SYS (putw, int, (int w, FILE *restrict stream), ); |
| 1318 | # endif | 1452 | # endif |
| 1319 | _GL_CXXALIAS_SYS (putw, int, (int w, FILE *restrict stream)); | 1453 | _GL_CXXALIAS_SYS (putw, int, (int w, FILE *restrict stream)); |
| 1320 | # endif | 1454 | # endif |
| @@ -1330,7 +1464,7 @@ _GL_CXXALIASWARN (putw); | |||
| 1330 | # undef remove | 1464 | # undef remove |
| 1331 | # define remove rpl_remove | 1465 | # define remove rpl_remove |
| 1332 | # endif | 1466 | # endif |
| 1333 | _GL_FUNCDECL_RPL (remove, int, (const char *name) _GL_ARG_NONNULL ((1))); | 1467 | _GL_FUNCDECL_RPL (remove, int, (const char *name), _GL_ARG_NONNULL ((1))); |
| 1334 | _GL_CXXALIAS_RPL (remove, int, (const char *name)); | 1468 | _GL_CXXALIAS_RPL (remove, int, (const char *name)); |
| 1335 | # else | 1469 | # else |
| 1336 | _GL_CXXALIAS_SYS (remove, int, (const char *name)); | 1470 | _GL_CXXALIAS_SYS (remove, int, (const char *name)); |
| @@ -1352,7 +1486,7 @@ _GL_WARN_ON_USE (remove, "remove cannot handle directories on some platforms - " | |||
| 1352 | # define rename rpl_rename | 1486 | # define rename rpl_rename |
| 1353 | # endif | 1487 | # endif |
| 1354 | _GL_FUNCDECL_RPL (rename, int, | 1488 | _GL_FUNCDECL_RPL (rename, int, |
| 1355 | (const char *old_filename, const char *new_filename) | 1489 | (const char *old_filename, const char *new_filename), |
| 1356 | _GL_ARG_NONNULL ((1, 2))); | 1490 | _GL_ARG_NONNULL ((1, 2))); |
| 1357 | _GL_CXXALIAS_RPL (rename, int, | 1491 | _GL_CXXALIAS_RPL (rename, int, |
| 1358 | (const char *old_filename, const char *new_filename)); | 1492 | (const char *old_filename, const char *new_filename)); |
| @@ -1377,14 +1511,14 @@ _GL_WARN_ON_USE (rename, "rename is buggy on some platforms - " | |||
| 1377 | # define renameat rpl_renameat | 1511 | # define renameat rpl_renameat |
| 1378 | # endif | 1512 | # endif |
| 1379 | _GL_FUNCDECL_RPL (renameat, int, | 1513 | _GL_FUNCDECL_RPL (renameat, int, |
| 1380 | (int fd1, char const *file1, int fd2, char const *file2) | 1514 | (int fd1, char const *file1, int fd2, char const *file2), |
| 1381 | _GL_ARG_NONNULL ((2, 4))); | 1515 | _GL_ARG_NONNULL ((2, 4))); |
| 1382 | _GL_CXXALIAS_RPL (renameat, int, | 1516 | _GL_CXXALIAS_RPL (renameat, int, |
| 1383 | (int fd1, char const *file1, int fd2, char const *file2)); | 1517 | (int fd1, char const *file1, int fd2, char const *file2)); |
| 1384 | # else | 1518 | # else |
| 1385 | # if !@HAVE_RENAMEAT@ | 1519 | # if !@HAVE_RENAMEAT@ |
| 1386 | _GL_FUNCDECL_SYS (renameat, int, | 1520 | _GL_FUNCDECL_SYS (renameat, int, |
| 1387 | (int fd1, char const *file1, int fd2, char const *file2) | 1521 | (int fd1, char const *file1, int fd2, char const *file2), |
| 1388 | _GL_ARG_NONNULL ((2, 4))); | 1522 | _GL_ARG_NONNULL ((2, 4))); |
| 1389 | # endif | 1523 | # endif |
| 1390 | _GL_CXXALIAS_SYS (renameat, int, | 1524 | _GL_CXXALIAS_SYS (renameat, int, |
| @@ -1410,18 +1544,18 @@ _GL_WARN_ON_USE (renameat, "renameat is not portable - " | |||
| 1410 | _GL_FUNCDECL_RPL_1 (__scanf__, int, | 1544 | _GL_FUNCDECL_RPL_1 (__scanf__, int, |
| 1411 | (const char *restrict format, ...) | 1545 | (const char *restrict format, ...) |
| 1412 | __asm__ (@ASM_SYMBOL_PREFIX@ | 1546 | __asm__ (@ASM_SYMBOL_PREFIX@ |
| 1413 | _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_scanf)) | 1547 | _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_scanf)), |
| 1414 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) | 1548 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) |
| 1415 | _GL_ARG_NONNULL ((1))); | 1549 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 1416 | _GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *restrict format, ...)); | 1550 | _GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *restrict format, ...)); |
| 1417 | # else | 1551 | # else |
| 1418 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1552 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1419 | # undef scanf | 1553 | # undef scanf |
| 1420 | # define scanf rpl_scanf | 1554 | # define scanf rpl_scanf |
| 1421 | # endif | 1555 | # endif |
| 1422 | _GL_FUNCDECL_RPL (scanf, int, (const char *restrict format, ...) | 1556 | _GL_FUNCDECL_RPL (scanf, int, (const char *restrict format, ...), |
| 1423 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) | 1557 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) |
| 1424 | _GL_ARG_NONNULL ((1))); | 1558 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 1425 | _GL_CXXALIAS_RPL (scanf, int, (const char *restrict format, ...)); | 1559 | _GL_CXXALIAS_RPL (scanf, int, (const char *restrict format, ...)); |
| 1426 | # endif | 1560 | # endif |
| 1427 | # else | 1561 | # else |
| @@ -1432,7 +1566,31 @@ _GL_CXXALIASWARN (scanf); | |||
| 1432 | # endif | 1566 | # endif |
| 1433 | #endif | 1567 | #endif |
| 1434 | 1568 | ||
| 1569 | #if @GNULIB_SNZPRINTF@ | ||
| 1570 | /* Prints formatted output to string STR. Similar to sprintf, but the | ||
| 1571 | additional parameter SIZE limits how much is written into STR. | ||
| 1572 | STR may be NULL, in which case nothing will be written. | ||
| 1573 | Returns the string length of the formatted string (which may be larger | ||
| 1574 | than SIZE). Upon failure, returns -1 with errno set. | ||
| 1575 | Failure code EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 1576 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 1577 | directives nor widths, the only possible failure code is ENOMEM. */ | ||
| 1578 | _GL_FUNCDECL_SYS (snzprintf, ptrdiff_t, | ||
| 1579 | (char *restrict str, size_t size, | ||
| 1580 | const char *restrict format, ...), | ||
| 1581 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 4) | ||
| 1582 | _GL_ARG_NONNULL ((3))); | ||
| 1583 | _GL_CXXALIAS_SYS (snzprintf, ptrdiff_t, | ||
| 1584 | (char *restrict str, size_t size, | ||
| 1585 | const char *restrict format, ...)); | ||
| 1586 | #endif | ||
| 1587 | |||
| 1435 | #if @GNULIB_SNPRINTF@ | 1588 | #if @GNULIB_SNPRINTF@ |
| 1589 | /* Prints formatted output to string STR. Similar to sprintf, but the | ||
| 1590 | additional parameter SIZE limits how much is written into STR. | ||
| 1591 | STR may be NULL, in which case nothing will be written. | ||
| 1592 | Returns the string length of the formatted string (which may be larger | ||
| 1593 | than SIZE). Upon failure, returns a negative value. */ | ||
| 1436 | # if @REPLACE_SNPRINTF@ | 1594 | # if @REPLACE_SNPRINTF@ |
| 1437 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1595 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1438 | # define snprintf rpl_snprintf | 1596 | # define snprintf rpl_snprintf |
| @@ -1440,7 +1598,7 @@ _GL_CXXALIASWARN (scanf); | |||
| 1440 | # define GNULIB_overrides_snprintf 1 | 1598 | # define GNULIB_overrides_snprintf 1 |
| 1441 | _GL_FUNCDECL_RPL (snprintf, int, | 1599 | _GL_FUNCDECL_RPL (snprintf, int, |
| 1442 | (char *restrict str, size_t size, | 1600 | (char *restrict str, size_t size, |
| 1443 | const char *restrict format, ...) | 1601 | const char *restrict format, ...), |
| 1444 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 4) | 1602 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 4) |
| 1445 | _GL_ARG_NONNULL ((3))); | 1603 | _GL_ARG_NONNULL ((3))); |
| 1446 | _GL_CXXALIAS_RPL (snprintf, int, | 1604 | _GL_CXXALIAS_RPL (snprintf, int, |
| @@ -1450,7 +1608,7 @@ _GL_CXXALIAS_RPL (snprintf, int, | |||
| 1450 | # if !@HAVE_DECL_SNPRINTF@ | 1608 | # if !@HAVE_DECL_SNPRINTF@ |
| 1451 | _GL_FUNCDECL_SYS (snprintf, int, | 1609 | _GL_FUNCDECL_SYS (snprintf, int, |
| 1452 | (char *restrict str, size_t size, | 1610 | (char *restrict str, size_t size, |
| 1453 | const char *restrict format, ...) | 1611 | const char *restrict format, ...), |
| 1454 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 4) | 1612 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 4) |
| 1455 | _GL_ARG_NONNULL ((3))); | 1613 | _GL_ARG_NONNULL ((3))); |
| 1456 | # endif | 1614 | # endif |
| @@ -1469,6 +1627,23 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - " | |||
| 1469 | # endif | 1627 | # endif |
| 1470 | #endif | 1628 | #endif |
| 1471 | 1629 | ||
| 1630 | #if @GNULIB_SZPRINTF@ | ||
| 1631 | /* Prints formatted output to string STR. | ||
| 1632 | Returns the string length of the formatted string. Upon failure, | ||
| 1633 | returns -1 with errno set. | ||
| 1634 | Failure code EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 1635 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 1636 | directives nor widths, the only possible failure code is ENOMEM. */ | ||
| 1637 | _GL_FUNCDECL_SYS (szprintf, ptrdiff_t, | ||
| 1638 | (char *restrict str, | ||
| 1639 | const char *restrict format, ...), | ||
| 1640 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | ||
| 1641 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1642 | _GL_CXXALIAS_SYS (szprintf, ptrdiff_t, | ||
| 1643 | (char *restrict str, | ||
| 1644 | const char *restrict format, ...)); | ||
| 1645 | #endif | ||
| 1646 | |||
| 1472 | /* Some people would argue that all sprintf uses should be warned about | 1647 | /* Some people would argue that all sprintf uses should be warned about |
| 1473 | (for example, OpenBSD issues a link warning for it), | 1648 | (for example, OpenBSD issues a link warning for it), |
| 1474 | since it can cause security holes due to buffer overruns. | 1649 | since it can cause security holes due to buffer overruns. |
| @@ -1479,13 +1654,16 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - " | |||
| 1479 | GNULIB_POSIXCHECK is defined. */ | 1654 | GNULIB_POSIXCHECK is defined. */ |
| 1480 | 1655 | ||
| 1481 | #if @GNULIB_SPRINTF_POSIX@ | 1656 | #if @GNULIB_SPRINTF_POSIX@ |
| 1657 | /* Prints formatted output to string STR. | ||
| 1658 | Returns the string length of the formatted string. Upon failure, | ||
| 1659 | returns a negative value. */ | ||
| 1482 | # if @REPLACE_SPRINTF@ | 1660 | # if @REPLACE_SPRINTF@ |
| 1483 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1661 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1484 | # define sprintf rpl_sprintf | 1662 | # define sprintf rpl_sprintf |
| 1485 | # endif | 1663 | # endif |
| 1486 | # define GNULIB_overrides_sprintf 1 | 1664 | # define GNULIB_overrides_sprintf 1 |
| 1487 | _GL_FUNCDECL_RPL (sprintf, int, | 1665 | _GL_FUNCDECL_RPL (sprintf, int, |
| 1488 | (char *restrict str, const char *restrict format, ...) | 1666 | (char *restrict str, const char *restrict format, ...), |
| 1489 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | 1667 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) |
| 1490 | _GL_ARG_NONNULL ((1, 2))); | 1668 | _GL_ARG_NONNULL ((1, 2))); |
| 1491 | _GL_CXXALIAS_RPL (sprintf, int, | 1669 | _GL_CXXALIAS_RPL (sprintf, int, |
| @@ -1526,16 +1704,18 @@ _GL_CXXALIASWARN (tempnam); | |||
| 1526 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1704 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1527 | # define tmpfile rpl_tmpfile | 1705 | # define tmpfile rpl_tmpfile |
| 1528 | # endif | 1706 | # endif |
| 1529 | _GL_FUNCDECL_RPL (tmpfile, FILE *, (void) | 1707 | _GL_FUNCDECL_RPL (tmpfile, FILE *, (void), |
| 1530 | _GL_ATTRIBUTE_DEALLOC (fclose, 1) | 1708 | _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 1531 | _GL_ATTRIBUTE_MALLOC); | 1709 | _GL_ATTRIBUTE_MALLOC |
| 1710 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1532 | _GL_CXXALIAS_RPL (tmpfile, FILE *, (void)); | 1711 | _GL_CXXALIAS_RPL (tmpfile, FILE *, (void)); |
| 1533 | # else | 1712 | # else |
| 1534 | # if __GNUC__ >= 11 | 1713 | # if __GNUC__ >= 11 && !defined __clang__ |
| 1535 | /* For -Wmismatched-dealloc: Associate tmpfile with fclose or rpl_fclose. */ | 1714 | /* For -Wmismatched-dealloc: Associate tmpfile with fclose or rpl_fclose. */ |
| 1536 | _GL_FUNCDECL_SYS (tmpfile, FILE *, (void) | 1715 | _GL_FUNCDECL_SYS (tmpfile, FILE *, (void), |
| 1537 | _GL_ATTRIBUTE_DEALLOC (fclose, 1) | 1716 | _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 1538 | _GL_ATTRIBUTE_MALLOC); | 1717 | _GL_ATTRIBUTE_MALLOC |
| 1718 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1539 | # endif | 1719 | # endif |
| 1540 | _GL_CXXALIAS_SYS (tmpfile, FILE *, (void)); | 1720 | _GL_CXXALIAS_SYS (tmpfile, FILE *, (void)); |
| 1541 | # endif | 1721 | # endif |
| @@ -1543,9 +1723,10 @@ _GL_CXXALIAS_SYS (tmpfile, FILE *, (void)); | |||
| 1543 | _GL_CXXALIASWARN (tmpfile); | 1723 | _GL_CXXALIASWARN (tmpfile); |
| 1544 | # endif | 1724 | # endif |
| 1545 | #else | 1725 | #else |
| 1546 | # if @GNULIB_FCLOSE@ && __GNUC__ >= 11 && !defined tmpfile | 1726 | # if @GNULIB_FCLOSE@ \ |
| 1727 | && (__GNUC__ >= 11 && !defined __clang__) && !defined tmpfile | ||
| 1547 | /* For -Wmismatched-dealloc: Associate tmpfile with fclose or rpl_fclose. */ | 1728 | /* For -Wmismatched-dealloc: Associate tmpfile with fclose or rpl_fclose. */ |
| 1548 | _GL_FUNCDECL_SYS (tmpfile, FILE *, (void) | 1729 | _GL_FUNCDECL_SYS (tmpfile, FILE *, (void), |
| 1549 | _GL_ATTRIBUTE_DEALLOC (fclose, 1) | 1730 | _GL_ATTRIBUTE_DEALLOC (fclose, 1) |
| 1550 | _GL_ATTRIBUTE_MALLOC); | 1731 | _GL_ATTRIBUTE_MALLOC); |
| 1551 | # endif | 1732 | # endif |
| @@ -1558,6 +1739,31 @@ _GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - " | |||
| 1558 | # endif | 1739 | # endif |
| 1559 | #endif | 1740 | #endif |
| 1560 | 1741 | ||
| 1742 | #if @GNULIB_VASZPRINTF@ | ||
| 1743 | /* Prints formatted output to a string dynamically allocated with malloc(). | ||
| 1744 | If the memory allocation succeeds, it stores the address of the string in | ||
| 1745 | *RESULT and returns the number of resulting bytes, excluding the trailing | ||
| 1746 | NUL. Upon memory allocation error, or some other error, it returns -1 | ||
| 1747 | with errno set. | ||
| 1748 | Failure code EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 1749 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 1750 | directives nor widths, the only possible failure code is ENOMEM. */ | ||
| 1751 | _GL_FUNCDECL_SYS (aszprintf, ptrdiff_t, | ||
| 1752 | (char **result, const char *format, ...), | ||
| 1753 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | ||
| 1754 | _GL_ARG_NONNULL ((1, 2)) | ||
| 1755 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1756 | _GL_CXXALIAS_SYS (aszprintf, ptrdiff_t, | ||
| 1757 | (char **result, const char *format, ...)); | ||
| 1758 | _GL_FUNCDECL_SYS (vaszprintf, ptrdiff_t, | ||
| 1759 | (char **result, const char *format, va_list args), | ||
| 1760 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | ||
| 1761 | _GL_ARG_NONNULL ((1, 2)) | ||
| 1762 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1763 | _GL_CXXALIAS_SYS (vaszprintf, ptrdiff_t, | ||
| 1764 | (char **result, const char *format, va_list args)); | ||
| 1765 | #endif | ||
| 1766 | |||
| 1561 | #if @GNULIB_VASPRINTF@ | 1767 | #if @GNULIB_VASPRINTF@ |
| 1562 | /* Write formatted output to a string dynamically allocated with malloc(). | 1768 | /* Write formatted output to a string dynamically allocated with malloc(). |
| 1563 | If the memory allocation succeeds, store the address of the string in | 1769 | If the memory allocation succeeds, store the address of the string in |
| @@ -1569,17 +1775,19 @@ _GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - " | |||
| 1569 | # endif | 1775 | # endif |
| 1570 | # define GNULIB_overrides_asprintf | 1776 | # define GNULIB_overrides_asprintf |
| 1571 | _GL_FUNCDECL_RPL (asprintf, int, | 1777 | _GL_FUNCDECL_RPL (asprintf, int, |
| 1572 | (char **result, const char *format, ...) | 1778 | (char **result, const char *format, ...), |
| 1573 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | 1779 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) |
| 1574 | _GL_ARG_NONNULL ((1, 2))); | 1780 | _GL_ARG_NONNULL ((1, 2)) |
| 1781 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1575 | _GL_CXXALIAS_RPL (asprintf, int, | 1782 | _GL_CXXALIAS_RPL (asprintf, int, |
| 1576 | (char **result, const char *format, ...)); | 1783 | (char **result, const char *format, ...)); |
| 1577 | # else | 1784 | # else |
| 1578 | # if !@HAVE_VASPRINTF@ | 1785 | # if !@HAVE_VASPRINTF@ |
| 1579 | _GL_FUNCDECL_SYS (asprintf, int, | 1786 | _GL_FUNCDECL_SYS (asprintf, int, |
| 1580 | (char **result, const char *format, ...) | 1787 | (char **result, const char *format, ...), |
| 1581 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) | 1788 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) |
| 1582 | _GL_ARG_NONNULL ((1, 2))); | 1789 | _GL_ARG_NONNULL ((1, 2)) |
| 1790 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1583 | # endif | 1791 | # endif |
| 1584 | _GL_CXXALIAS_SYS (asprintf, int, | 1792 | _GL_CXXALIAS_SYS (asprintf, int, |
| 1585 | (char **result, const char *format, ...)); | 1793 | (char **result, const char *format, ...)); |
| @@ -1591,17 +1799,19 @@ _GL_CXXALIASWARN (asprintf); | |||
| 1591 | # endif | 1799 | # endif |
| 1592 | # define GNULIB_overrides_vasprintf 1 | 1800 | # define GNULIB_overrides_vasprintf 1 |
| 1593 | _GL_FUNCDECL_RPL (vasprintf, int, | 1801 | _GL_FUNCDECL_RPL (vasprintf, int, |
| 1594 | (char **result, const char *format, va_list args) | 1802 | (char **result, const char *format, va_list args), |
| 1595 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | 1803 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) |
| 1596 | _GL_ARG_NONNULL ((1, 2))); | 1804 | _GL_ARG_NONNULL ((1, 2)) |
| 1805 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1597 | _GL_CXXALIAS_RPL (vasprintf, int, | 1806 | _GL_CXXALIAS_RPL (vasprintf, int, |
| 1598 | (char **result, const char *format, va_list args)); | 1807 | (char **result, const char *format, va_list args)); |
| 1599 | # else | 1808 | # else |
| 1600 | # if !@HAVE_VASPRINTF@ | 1809 | # if !@HAVE_VASPRINTF@ |
| 1601 | _GL_FUNCDECL_SYS (vasprintf, int, | 1810 | _GL_FUNCDECL_SYS (vasprintf, int, |
| 1602 | (char **result, const char *format, va_list args) | 1811 | (char **result, const char *format, va_list args), |
| 1603 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | 1812 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) |
| 1604 | _GL_ARG_NONNULL ((1, 2))); | 1813 | _GL_ARG_NONNULL ((1, 2)) |
| 1814 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1605 | # endif | 1815 | # endif |
| 1606 | _GL_CXXALIAS_SYS (vasprintf, int, | 1816 | _GL_CXXALIAS_SYS (vasprintf, int, |
| 1607 | (char **result, const char *format, va_list args)); | 1817 | (char **result, const char *format, va_list args)); |
| @@ -1609,13 +1819,32 @@ _GL_CXXALIAS_SYS (vasprintf, int, | |||
| 1609 | _GL_CXXALIASWARN (vasprintf); | 1819 | _GL_CXXALIASWARN (vasprintf); |
| 1610 | #endif | 1820 | #endif |
| 1611 | 1821 | ||
| 1822 | #if @GNULIB_VDZPRINTF@ | ||
| 1823 | /* Prints formatted output to file descriptor FD. | ||
| 1824 | Returns the number of bytes written to the file descriptor. Upon | ||
| 1825 | failure, returns -1 with errno set. | ||
| 1826 | Failure code EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 1827 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 1828 | directives nor widths, the only possible failure codes are ENOMEM | ||
| 1829 | and the possible failure codes from write(), excluding EINTR. */ | ||
| 1830 | _GL_FUNCDECL_SYS (vdzprintf, off64_t, | ||
| 1831 | (int fd, const char *restrict format, va_list args), | ||
| 1832 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | ||
| 1833 | _GL_ARG_NONNULL ((2))); | ||
| 1834 | _GL_CXXALIAS_SYS (vdzprintf, off64_t, | ||
| 1835 | (int fd, const char *restrict format, va_list args)); | ||
| 1836 | #endif | ||
| 1837 | |||
| 1612 | #if @GNULIB_VDPRINTF@ | 1838 | #if @GNULIB_VDPRINTF@ |
| 1839 | /* Prints formatted output to file descriptor FD. | ||
| 1840 | Returns the number of bytes written to the file descriptor. Upon | ||
| 1841 | failure, returns a negative value. */ | ||
| 1613 | # if @REPLACE_VDPRINTF@ | 1842 | # if @REPLACE_VDPRINTF@ |
| 1614 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1843 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1615 | # define vdprintf rpl_vdprintf | 1844 | # define vdprintf rpl_vdprintf |
| 1616 | # endif | 1845 | # endif |
| 1617 | _GL_FUNCDECL_RPL (vdprintf, int, | 1846 | _GL_FUNCDECL_RPL (vdprintf, int, |
| 1618 | (int fd, const char *restrict format, va_list args) | 1847 | (int fd, const char *restrict format, va_list args), |
| 1619 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | 1848 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) |
| 1620 | _GL_ARG_NONNULL ((2))); | 1849 | _GL_ARG_NONNULL ((2))); |
| 1621 | _GL_CXXALIAS_RPL (vdprintf, int, | 1850 | _GL_CXXALIAS_RPL (vdprintf, int, |
| @@ -1623,7 +1852,7 @@ _GL_CXXALIAS_RPL (vdprintf, int, | |||
| 1623 | # else | 1852 | # else |
| 1624 | # if !@HAVE_VDPRINTF@ | 1853 | # if !@HAVE_VDPRINTF@ |
| 1625 | _GL_FUNCDECL_SYS (vdprintf, int, | 1854 | _GL_FUNCDECL_SYS (vdprintf, int, |
| 1626 | (int fd, const char *restrict format, va_list args) | 1855 | (int fd, const char *restrict format, va_list args), |
| 1627 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | 1856 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) |
| 1628 | _GL_ARG_NONNULL ((2))); | 1857 | _GL_ARG_NONNULL ((2))); |
| 1629 | # endif | 1858 | # endif |
| @@ -1643,7 +1872,28 @@ _GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - " | |||
| 1643 | # endif | 1872 | # endif |
| 1644 | #endif | 1873 | #endif |
| 1645 | 1874 | ||
| 1875 | #if @GNULIB_VFZPRINTF@ | ||
| 1876 | /* Prints formatted output to stream FP. | ||
| 1877 | Returns the number of bytes written to the stream. Upon failure, | ||
| 1878 | returns -1 with the stream's error indicator set. | ||
| 1879 | Failure cause EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 1880 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 1881 | directives nor widths, the only possible failure causes are ENOMEM | ||
| 1882 | and the possible failure causes from fwrite(). */ | ||
| 1883 | _GL_FUNCDECL_SYS (vfzprintf, off64_t, | ||
| 1884 | (FILE *restrict fp, | ||
| 1885 | const char *restrict format, va_list args), | ||
| 1886 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | ||
| 1887 | _GL_ARG_NONNULL ((1, 2))); | ||
| 1888 | _GL_CXXALIAS_SYS (vfzprintf, off64_t, | ||
| 1889 | (FILE *restrict fp, | ||
| 1890 | const char *restrict format, va_list args)); | ||
| 1891 | #endif | ||
| 1892 | |||
| 1646 | #if @GNULIB_VFPRINTF_POSIX@ || @GNULIB_VFPRINTF@ | 1893 | #if @GNULIB_VFPRINTF_POSIX@ || @GNULIB_VFPRINTF@ |
| 1894 | /* Prints formatted output to stream FP. | ||
| 1895 | Returns the number of bytes written to the stream. Upon failure, | ||
| 1896 | returns a negative value with the stream's error indicator set. */ | ||
| 1647 | # if (@GNULIB_VFPRINTF_POSIX@ && @REPLACE_VFPRINTF@) \ | 1897 | # if (@GNULIB_VFPRINTF_POSIX@ && @REPLACE_VFPRINTF@) \ |
| 1648 | || (@GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) | 1898 | || (@GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) |
| 1649 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1899 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -1653,13 +1903,13 @@ _GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - " | |||
| 1653 | # if @GNULIB_VFPRINTF_POSIX@ | 1903 | # if @GNULIB_VFPRINTF_POSIX@ |
| 1654 | _GL_FUNCDECL_RPL (vfprintf, int, | 1904 | _GL_FUNCDECL_RPL (vfprintf, int, |
| 1655 | (FILE *restrict fp, | 1905 | (FILE *restrict fp, |
| 1656 | const char *restrict format, va_list args) | 1906 | const char *restrict format, va_list args), |
| 1657 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | 1907 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) |
| 1658 | _GL_ARG_NONNULL ((1, 2))); | 1908 | _GL_ARG_NONNULL ((1, 2))); |
| 1659 | # else | 1909 | # else |
| 1660 | _GL_FUNCDECL_RPL (vfprintf, int, | 1910 | _GL_FUNCDECL_RPL (vfprintf, int, |
| 1661 | (FILE *restrict fp, | 1911 | (FILE *restrict fp, |
| 1662 | const char *restrict format, va_list args) | 1912 | const char *restrict format, va_list args), |
| 1663 | _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 0) | 1913 | _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 0) |
| 1664 | _GL_ARG_NONNULL ((1, 2))); | 1914 | _GL_ARG_NONNULL ((1, 2))); |
| 1665 | # endif | 1915 | # endif |
| @@ -1677,6 +1927,11 @@ _GL_CXXALIAS_SYS_CAST (vfprintf, int, | |||
| 1677 | # if __GLIBC__ >= 2 | 1927 | # if __GLIBC__ >= 2 |
| 1678 | _GL_CXXALIASWARN (vfprintf); | 1928 | _GL_CXXALIASWARN (vfprintf); |
| 1679 | # endif | 1929 | # endif |
| 1930 | #elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO | ||
| 1931 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1932 | # undef vfprintf | ||
| 1933 | # define vfprintf gl_consolesafe_vfprintf | ||
| 1934 | # endif | ||
| 1680 | #endif | 1935 | #endif |
| 1681 | #if !@GNULIB_VFPRINTF_POSIX@ && defined GNULIB_POSIXCHECK | 1936 | #if !@GNULIB_VFPRINTF_POSIX@ && defined GNULIB_POSIXCHECK |
| 1682 | # if !GNULIB_overrides_vfprintf | 1937 | # if !GNULIB_overrides_vfprintf |
| @@ -1696,9 +1951,9 @@ _GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - " | |||
| 1696 | # endif | 1951 | # endif |
| 1697 | _GL_FUNCDECL_RPL (vfscanf, int, | 1952 | _GL_FUNCDECL_RPL (vfscanf, int, |
| 1698 | (FILE *restrict stream, | 1953 | (FILE *restrict stream, |
| 1699 | const char *restrict format, va_list args) | 1954 | const char *restrict format, va_list args), |
| 1700 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 0) | 1955 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 0) |
| 1701 | _GL_ARG_NONNULL ((1, 2))); | 1956 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_NODISCARD); |
| 1702 | _GL_CXXALIAS_RPL (vfscanf, int, | 1957 | _GL_CXXALIAS_RPL (vfscanf, int, |
| 1703 | (FILE *restrict stream, | 1958 | (FILE *restrict stream, |
| 1704 | const char *restrict format, va_list args)); | 1959 | const char *restrict format, va_list args)); |
| @@ -1712,7 +1967,26 @@ _GL_CXXALIASWARN (vfscanf); | |||
| 1712 | # endif | 1967 | # endif |
| 1713 | #endif | 1968 | #endif |
| 1714 | 1969 | ||
| 1970 | #if @GNULIB_VZPRINTF@ | ||
| 1971 | /* Prints formatted output to standard output. | ||
| 1972 | Returns the number of bytes written to standard output. Upon failure, | ||
| 1973 | returns -1 with stdout's error indicator set. | ||
| 1974 | Failure cause EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 1975 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 1976 | directives nor widths, the only possible failure causes are ENOMEM | ||
| 1977 | and the possible failure causes from fwrite(). */ | ||
| 1978 | _GL_FUNCDECL_SYS (vzprintf, off64_t, | ||
| 1979 | (const char *restrict format, va_list args), | ||
| 1980 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0) | ||
| 1981 | _GL_ARG_NONNULL ((1))); | ||
| 1982 | _GL_CXXALIAS_SYS (vzprintf, off64_t, | ||
| 1983 | (const char *restrict format, va_list args)); | ||
| 1984 | #endif | ||
| 1985 | |||
| 1715 | #if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@ | 1986 | #if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@ |
| 1987 | /* Prints formatted output to standard output. | ||
| 1988 | Returns the number of bytes written to standard output. Upon failure, | ||
| 1989 | returns a negative value with stdout's error indicator set. */ | ||
| 1716 | # if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \ | 1990 | # if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \ |
| 1717 | || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) | 1991 | || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) |
| 1718 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1992 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -1720,11 +1994,11 @@ _GL_CXXALIASWARN (vfscanf); | |||
| 1720 | # endif | 1994 | # endif |
| 1721 | # define GNULIB_overrides_vprintf 1 | 1995 | # define GNULIB_overrides_vprintf 1 |
| 1722 | # if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ | 1996 | # if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ |
| 1723 | _GL_FUNCDECL_RPL (vprintf, int, (const char *restrict format, va_list args) | 1997 | _GL_FUNCDECL_RPL (vprintf, int, (const char *restrict format, va_list args), |
| 1724 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0) | 1998 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0) |
| 1725 | _GL_ARG_NONNULL ((1))); | 1999 | _GL_ARG_NONNULL ((1))); |
| 1726 | # else | 2000 | # else |
| 1727 | _GL_FUNCDECL_RPL (vprintf, int, (const char *restrict format, va_list args) | 2001 | _GL_FUNCDECL_RPL (vprintf, int, (const char *restrict format, va_list args), |
| 1728 | _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 0) | 2002 | _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 0) |
| 1729 | _GL_ARG_NONNULL ((1))); | 2003 | _GL_ARG_NONNULL ((1))); |
| 1730 | # endif | 2004 | # endif |
| @@ -1739,6 +2013,11 @@ _GL_CXXALIAS_SYS_CAST (vprintf, int, | |||
| 1739 | # if __GLIBC__ >= 2 | 2013 | # if __GLIBC__ >= 2 |
| 1740 | _GL_CXXALIASWARN (vprintf); | 2014 | _GL_CXXALIASWARN (vprintf); |
| 1741 | # endif | 2015 | # endif |
| 2016 | #elif defined __MINGW32__ && !defined _UCRT && __USE_MINGW_ANSI_STDIO | ||
| 2017 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 2018 | # undef vprintf | ||
| 2019 | # define vprintf gl_consolesafe_vprintf | ||
| 2020 | # endif | ||
| 1742 | #endif | 2021 | #endif |
| 1743 | #if !@GNULIB_VPRINTF_POSIX@ && defined GNULIB_POSIXCHECK | 2022 | #if !@GNULIB_VPRINTF_POSIX@ && defined GNULIB_POSIXCHECK |
| 1744 | # if !GNULIB_overrides_vprintf | 2023 | # if !GNULIB_overrides_vprintf |
| @@ -1756,9 +2035,9 @@ _GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - " | |||
| 1756 | # undef vscanf | 2035 | # undef vscanf |
| 1757 | # define vscanf rpl_vscanf | 2036 | # define vscanf rpl_vscanf |
| 1758 | # endif | 2037 | # endif |
| 1759 | _GL_FUNCDECL_RPL (vscanf, int, (const char *restrict format, va_list args) | 2038 | _GL_FUNCDECL_RPL (vscanf, int, (const char *restrict format, va_list args), |
| 1760 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 0) | 2039 | _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 0) |
| 1761 | _GL_ARG_NONNULL ((1))); | 2040 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 1762 | _GL_CXXALIAS_RPL (vscanf, int, (const char *restrict format, va_list args)); | 2041 | _GL_CXXALIAS_RPL (vscanf, int, (const char *restrict format, va_list args)); |
| 1763 | # else | 2042 | # else |
| 1764 | _GL_CXXALIAS_SYS (vscanf, int, (const char *restrict format, va_list args)); | 2043 | _GL_CXXALIAS_SYS (vscanf, int, (const char *restrict format, va_list args)); |
| @@ -1768,7 +2047,31 @@ _GL_CXXALIASWARN (vscanf); | |||
| 1768 | # endif | 2047 | # endif |
| 1769 | #endif | 2048 | #endif |
| 1770 | 2049 | ||
| 2050 | #if @GNULIB_VSNZPRINTF@ | ||
| 2051 | /* Prints formatted output to string STR. Similar to sprintf, but the | ||
| 2052 | additional parameter SIZE limits how much is written into STR. | ||
| 2053 | STR may be NULL, in which case nothing will be written. | ||
| 2054 | Returns the string length of the formatted string (which may be larger | ||
| 2055 | than SIZE). Upon failure, returns -1 with errno set. | ||
| 2056 | Failure code EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 2057 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 2058 | directives nor widths, the only possible failure code is ENOMEM. */ | ||
| 2059 | _GL_FUNCDECL_SYS (vsnzprintf, ptrdiff_t, | ||
| 2060 | (char *restrict str, size_t size, | ||
| 2061 | const char *restrict format, va_list args), | ||
| 2062 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) | ||
| 2063 | _GL_ARG_NONNULL ((3))); | ||
| 2064 | _GL_CXXALIAS_SYS (vsnzprintf, ptrdiff_t, | ||
| 2065 | (char *restrict str, size_t size, | ||
| 2066 | const char *restrict format, va_list args)); | ||
| 2067 | #endif | ||
| 2068 | |||
| 1771 | #if @GNULIB_VSNPRINTF@ | 2069 | #if @GNULIB_VSNPRINTF@ |
| 2070 | /* Prints formatted output to string STR. Similar to vsprintf, but the | ||
| 2071 | additional parameter SIZE limits how much is written into STR. | ||
| 2072 | STR may be NULL, in which case nothing will be written. | ||
| 2073 | Returns the string length of the formatted string (which may be larger | ||
| 2074 | than SIZE). Upon failure, returns a negative value. */ | ||
| 1772 | # if @REPLACE_VSNPRINTF@ | 2075 | # if @REPLACE_VSNPRINTF@ |
| 1773 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 2076 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1774 | # define vsnprintf rpl_vsnprintf | 2077 | # define vsnprintf rpl_vsnprintf |
| @@ -1776,7 +2079,7 @@ _GL_CXXALIASWARN (vscanf); | |||
| 1776 | # define GNULIB_overrides_vsnprintf 1 | 2079 | # define GNULIB_overrides_vsnprintf 1 |
| 1777 | _GL_FUNCDECL_RPL (vsnprintf, int, | 2080 | _GL_FUNCDECL_RPL (vsnprintf, int, |
| 1778 | (char *restrict str, size_t size, | 2081 | (char *restrict str, size_t size, |
| 1779 | const char *restrict format, va_list args) | 2082 | const char *restrict format, va_list args), |
| 1780 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) | 2083 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) |
| 1781 | _GL_ARG_NONNULL ((3))); | 2084 | _GL_ARG_NONNULL ((3))); |
| 1782 | _GL_CXXALIAS_RPL (vsnprintf, int, | 2085 | _GL_CXXALIAS_RPL (vsnprintf, int, |
| @@ -1786,7 +2089,7 @@ _GL_CXXALIAS_RPL (vsnprintf, int, | |||
| 1786 | # if !@HAVE_DECL_VSNPRINTF@ | 2089 | # if !@HAVE_DECL_VSNPRINTF@ |
| 1787 | _GL_FUNCDECL_SYS (vsnprintf, int, | 2090 | _GL_FUNCDECL_SYS (vsnprintf, int, |
| 1788 | (char *restrict str, size_t size, | 2091 | (char *restrict str, size_t size, |
| 1789 | const char *restrict format, va_list args) | 2092 | const char *restrict format, va_list args), |
| 1790 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) | 2093 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) |
| 1791 | _GL_ARG_NONNULL ((3))); | 2094 | _GL_ARG_NONNULL ((3))); |
| 1792 | # endif | 2095 | # endif |
| @@ -1805,7 +2108,27 @@ _GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - " | |||
| 1805 | # endif | 2108 | # endif |
| 1806 | #endif | 2109 | #endif |
| 1807 | 2110 | ||
| 2111 | #if @GNULIB_VSZPRINTF@ | ||
| 2112 | /* Prints formatted output to string STR. | ||
| 2113 | Returns the string length of the formatted string. Upon failure, | ||
| 2114 | returns -1 with errno set. | ||
| 2115 | Failure code EOVERFLOW can only occur when a width > INT_MAX is used. | ||
| 2116 | Therefore, if the format string is valid and does not use %ls/%lc | ||
| 2117 | directives nor widths, the only possible failure code is ENOMEM. */ | ||
| 2118 | _GL_FUNCDECL_SYS (vszprintf, ptrdiff_t, | ||
| 2119 | (char *restrict str, | ||
| 2120 | const char *restrict format, va_list args), | ||
| 2121 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | ||
| 2122 | _GL_ARG_NONNULL ((1, 2))); | ||
| 2123 | _GL_CXXALIAS_SYS (vszprintf, ptrdiff_t, | ||
| 2124 | (char *restrict str, | ||
| 2125 | const char *restrict format, va_list args)); | ||
| 2126 | #endif | ||
| 2127 | |||
| 1808 | #if @GNULIB_VSPRINTF_POSIX@ | 2128 | #if @GNULIB_VSPRINTF_POSIX@ |
| 2129 | /* Prints formatted output to string STR. | ||
| 2130 | Returns the string length of the formatted string. Upon failure, | ||
| 2131 | returns a negative value. */ | ||
| 1809 | # if @REPLACE_VSPRINTF@ | 2132 | # if @REPLACE_VSPRINTF@ |
| 1810 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 2133 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1811 | # define vsprintf rpl_vsprintf | 2134 | # define vsprintf rpl_vsprintf |
| @@ -1813,7 +2136,7 @@ _GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - " | |||
| 1813 | # define GNULIB_overrides_vsprintf 1 | 2136 | # define GNULIB_overrides_vsprintf 1 |
| 1814 | _GL_FUNCDECL_RPL (vsprintf, int, | 2137 | _GL_FUNCDECL_RPL (vsprintf, int, |
| 1815 | (char *restrict str, | 2138 | (char *restrict str, |
| 1816 | const char *restrict format, va_list args) | 2139 | const char *restrict format, va_list args), |
| 1817 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) | 2140 | _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) |
| 1818 | _GL_ARG_NONNULL ((1, 2))); | 2141 | _GL_ARG_NONNULL ((1, 2))); |
| 1819 | _GL_CXXALIAS_RPL (vsprintf, int, | 2142 | _GL_CXXALIAS_RPL (vsprintf, int, |
diff --git a/gl/stdlib.c b/gl/stdlib.c new file mode 100644 index 00000000..6a06f5ba --- /dev/null +++ b/gl/stdlib.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Inline functions for <stdlib.h>. | ||
| 2 | |||
| 3 | Copyright (C) 2024-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #define _GL_STDLIB_INLINE _GL_EXTERN_INLINE | ||
| 19 | #include <config.h> | ||
| 20 | |||
| 21 | #include <stdlib.h> | ||
diff --git a/gl/stdlib.in.h b/gl/stdlib.in.h index e74e7c18..1342db48 100644 --- a/gl/stdlib.in.h +++ b/gl/stdlib.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A GNU-like <stdlib.h>. | 1 | /* A GNU-like <stdlib.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 1995, 2001-2004, 2006-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1995, 2001-2004, 2006-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -20,12 +20,27 @@ | |||
| 20 | #endif | 20 | #endif |
| 21 | @PRAGMA_COLUMNS@ | 21 | @PRAGMA_COLUMNS@ |
| 22 | 22 | ||
| 23 | #if defined __need_system_stdlib_h || defined __need_malloc_and_calloc | 23 | #if ((defined __need_system_stdlib_h && !defined _GLIBCXX_STDLIB_H) \ |
| 24 | || defined __need_malloc_and_calloc) \ | ||
| 25 | && !defined __SUNPRO_CC | ||
| 24 | /* Special invocation conventions inside some gnulib header files, | 26 | /* Special invocation conventions inside some gnulib header files, |
| 25 | and inside some glibc header files, respectively. */ | 27 | and inside some glibc header files, respectively. |
| 28 | Do not recognize this special invocation convention when GCC's | ||
| 29 | c++/11/stdlib.h is being included or has been included. This is needed | ||
| 30 | to support the use of clang+llvm binaries on Ubuntu 22.04 with | ||
| 31 | CXX="$clangdir/bin/clang++ -I/usr/include/c++/11 \ | ||
| 32 | -I/usr/include/x86_64-linux-gnu/c++/11 | ||
| 33 | -L/usr/lib/gcc/x86_64-linux-gnu/11 | ||
| 34 | -Wl,-rpath,$clangdir/lib" | ||
| 35 | because in this case /usr/include/c++/11/stdlib.h (which does not support | ||
| 36 | the convention) is seen before the gnulib-generated stdlib.h. */ | ||
| 26 | 37 | ||
| 27 | #@INCLUDE_NEXT@ @NEXT_STDLIB_H@ | 38 | #@INCLUDE_NEXT@ @NEXT_STDLIB_H@ |
| 28 | 39 | ||
| 40 | /* Make sure that the macros that indicate the special invocation convention | ||
| 41 | get undefined. This is needed at least on CentOS 7. */ | ||
| 42 | #undef __need_malloc_and_calloc | ||
| 43 | |||
| 29 | #else | 44 | #else |
| 30 | /* Normal invocation convention. */ | 45 | /* Normal invocation convention. */ |
| 31 | 46 | ||
| @@ -38,8 +53,8 @@ | |||
| 38 | #define _@GUARD_PREFIX@_STDLIB_H | 53 | #define _@GUARD_PREFIX@_STDLIB_H |
| 39 | 54 | ||
| 40 | /* This file uses _Noreturn, _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_MALLOC, | 55 | /* This file uses _Noreturn, _GL_ATTRIBUTE_DEALLOC, _GL_ATTRIBUTE_MALLOC, |
| 41 | _GL_ATTRIBUTE_NOTHROW, _GL_ATTRIBUTE_PURE, GNULIB_POSIXCHECK, | 56 | _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOTHROW, _GL_ATTRIBUTE_PURE, |
| 42 | HAVE_RAW_DECL_*. */ | 57 | _GL_INLINE_HEADER_BEGIN, GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ |
| 43 | #if !_GL_CONFIG_H_INCLUDED | 58 | #if !_GL_CONFIG_H_INCLUDED |
| 44 | #error "Please include config.h first." | 59 | #error "Please include config.h first." |
| 45 | #endif | 60 | #endif |
| @@ -47,8 +62,9 @@ | |||
| 47 | /* NetBSD 5.0 mis-defines NULL. */ | 62 | /* NetBSD 5.0 mis-defines NULL. */ |
| 48 | #include <stddef.h> | 63 | #include <stddef.h> |
| 49 | 64 | ||
| 50 | /* MirBSD 10 defines WEXITSTATUS in <sys/wait.h>, not in <stdlib.h>. */ | 65 | /* MirBSD 10 defines WEXITSTATUS in <sys/wait.h>, not in <stdlib.h>. |
| 51 | #if @GNULIB_SYSTEM_POSIX@ && !defined WEXITSTATUS | 66 | glibc 2.41 defines WCOREDUMP in <sys/wait.h>, not in <stdlib.h>. */ |
| 67 | #if @GNULIB_SYSTEM_POSIX@ && !(defined WEXITSTATUS && defined WCOREDUMP) | ||
| 52 | # include <sys/wait.h> | 68 | # include <sys/wait.h> |
| 53 | #endif | 69 | #endif |
| 54 | 70 | ||
| @@ -104,11 +120,30 @@ struct random_data | |||
| 104 | # include <unistd.h> | 120 | # include <unistd.h> |
| 105 | #endif | 121 | #endif |
| 106 | 122 | ||
| 123 | #if ((@GNULIB_STRTOL@ && @REPLACE_STRTOL@) || (@GNULIB_STRTOLL@ && @REPLACE_STRTOLL@) || (@GNULIB_STRTOUL@ && @REPLACE_STRTOUL@) || (@GNULIB_STRTOULL@ && @REPLACE_STRTOULL@)) && defined __cplusplus && !defined GNULIB_NAMESPACE && defined __GNUG__ && !defined __clang__ && (defined __sun || defined _AIX) | ||
| 124 | /* When strtol, strtoll, strtoul, or strtoull is going to be defined as a macro | ||
| 125 | below, this may cause compilation errors later in the libstdc++ header files | ||
| 126 | (that are part of GCC), such as: | ||
| 127 | error: 'rpl_strtol' is not a member of 'std' | ||
| 128 | To avoid this, include the relevant header files here, before these symbols | ||
| 129 | get defined as macros. But do so only on Solaris 11 and AIX (where it is | ||
| 130 | needed), not on mingw (where it would cause other compilation errors). */ | ||
| 131 | # include <string> | ||
| 132 | #endif | ||
| 133 | |||
| 134 | _GL_INLINE_HEADER_BEGIN | ||
| 135 | #ifndef _GL_STDLIB_INLINE | ||
| 136 | # define _GL_STDLIB_INLINE _GL_INLINE | ||
| 137 | #endif | ||
| 138 | #ifndef _GL_REALLOC_INLINE | ||
| 139 | # define _GL_REALLOC_INLINE _GL_INLINE | ||
| 140 | #endif | ||
| 141 | |||
| 107 | /* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers | 142 | /* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers |
| 108 | that can be freed by passing them as the Ith argument to the | 143 | that can be freed by passing them as the Ith argument to the |
| 109 | function F. */ | 144 | function F. */ |
| 110 | #ifndef _GL_ATTRIBUTE_DEALLOC | 145 | #ifndef _GL_ATTRIBUTE_DEALLOC |
| 111 | # if __GNUC__ >= 11 | 146 | # if __GNUC__ >= 11 && !defined __clang__ |
| 112 | # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) | 147 | # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) |
| 113 | # else | 148 | # else |
| 114 | # define _GL_ATTRIBUTE_DEALLOC(f, i) | 149 | # define _GL_ATTRIBUTE_DEALLOC(f, i) |
| @@ -133,11 +168,23 @@ struct random_data | |||
| 133 | # endif | 168 | # endif |
| 134 | #endif | 169 | #endif |
| 135 | 170 | ||
| 171 | /* _GL_ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) declares that the argument NP | ||
| 172 | (a pointer) must not be NULL if the argument NI (an integer) is != 0. */ | ||
| 173 | /* Applies to: functions. */ | ||
| 174 | #ifndef _GL_ATTRIBUTE_NONNULL_IF_NONZERO | ||
| 175 | # if __GNUC__ >= 15 && !defined __clang__ | ||
| 176 | # define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) \ | ||
| 177 | __attribute__ ((__nonnull_if_nonzero__ (np, ni))) | ||
| 178 | # else | ||
| 179 | # define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) | ||
| 180 | # endif | ||
| 181 | #endif | ||
| 182 | |||
| 136 | /* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. | 183 | /* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. |
| 137 | */ | 184 | */ |
| 138 | #ifndef _GL_ATTRIBUTE_NOTHROW | 185 | #ifndef _GL_ATTRIBUTE_NOTHROW |
| 139 | # if defined __cplusplus | 186 | # if defined __cplusplus |
| 140 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major >= 4 | 187 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major__ >= 4 |
| 141 | # if __cplusplus >= 201103L | 188 | # if __cplusplus >= 201103L |
| 142 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) | 189 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) |
| 143 | # else | 190 | # else |
| @@ -188,6 +235,18 @@ struct random_data | |||
| 188 | #endif | 235 | #endif |
| 189 | 236 | ||
| 190 | 237 | ||
| 238 | /* Declarations for ISO C N3322. */ | ||
| 239 | #if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ | ||
| 240 | _GL_EXTERN_C void *bsearch (const void *__key, | ||
| 241 | const void *__base, size_t __nmemb, size_t __size, | ||
| 242 | int (*__compare) (const void *, const void *)) | ||
| 243 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3) _GL_ARG_NONNULL ((5)); | ||
| 244 | _GL_EXTERN_C void qsort (void *__base, size_t __nmemb, size_t __size, | ||
| 245 | int (*__compare) (const void *, const void *)) | ||
| 246 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) _GL_ARG_NONNULL ((4)); | ||
| 247 | #endif | ||
| 248 | |||
| 249 | |||
| 191 | #if @GNULIB__EXIT@ | 250 | #if @GNULIB__EXIT@ |
| 192 | /* Terminate the current process with the given return code, without running | 251 | /* Terminate the current process with the given return code, without running |
| 193 | the 'atexit' handlers. */ | 252 | the 'atexit' handlers. */ |
| @@ -196,11 +255,11 @@ struct random_data | |||
| 196 | # undef _Exit | 255 | # undef _Exit |
| 197 | # define _Exit rpl__Exit | 256 | # define _Exit rpl__Exit |
| 198 | # endif | 257 | # endif |
| 199 | _GL_FUNCDECL_RPL (_Exit, _Noreturn void, (int status)); | 258 | _GL_FUNCDECL_RPL (_Exit, _Noreturn void, (int status), ); |
| 200 | _GL_CXXALIAS_RPL (_Exit, void, (int status)); | 259 | _GL_CXXALIAS_RPL (_Exit, void, (int status)); |
| 201 | # else | 260 | # else |
| 202 | # if !@HAVE__EXIT@ | 261 | # if !@HAVE__EXIT@ |
| 203 | _GL_FUNCDECL_SYS (_Exit, _Noreturn void, (int status)); | 262 | _GL_FUNCDECL_SYS (_Exit, _Noreturn void, (int status), ); |
| 204 | # endif | 263 | # endif |
| 205 | _GL_CXXALIAS_SYS (_Exit, void, (int status)); | 264 | _GL_CXXALIAS_SYS (_Exit, void, (int status)); |
| 206 | # endif | 265 | # endif |
| @@ -216,6 +275,26 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - " | |||
| 216 | #endif | 275 | #endif |
| 217 | 276 | ||
| 218 | 277 | ||
| 278 | #if @GNULIB_ABORT_DEBUG@ | ||
| 279 | /* Terminates the current process with signal SIGABRT. | ||
| 280 | Note: While the original abort() function is safe to call in signal handlers, | ||
| 281 | the overridden abort() function is not. */ | ||
| 282 | # if @REPLACE_ABORT@ | ||
| 283 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 284 | # undef abort | ||
| 285 | # define abort rpl_abort | ||
| 286 | # endif | ||
| 287 | _GL_FUNCDECL_RPL (abort, _Noreturn void, (void), ); | ||
| 288 | _GL_CXXALIAS_RPL (abort, void, (void)); | ||
| 289 | # else | ||
| 290 | _GL_CXXALIAS_SYS (abort, void, (void)); | ||
| 291 | # endif | ||
| 292 | # if __GLIBC__ >= 2 | ||
| 293 | _GL_CXXALIASWARN (abort); | ||
| 294 | # endif | ||
| 295 | #endif | ||
| 296 | |||
| 297 | |||
| 219 | #if @GNULIB_FREE_POSIX@ | 298 | #if @GNULIB_FREE_POSIX@ |
| 220 | # if @REPLACE_FREE@ | 299 | # if @REPLACE_FREE@ |
| 221 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 300 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -223,9 +302,9 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - " | |||
| 223 | # define free rpl_free | 302 | # define free rpl_free |
| 224 | # endif | 303 | # endif |
| 225 | # if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) | 304 | # if defined __cplusplus && (__GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2) |
| 226 | _GL_FUNCDECL_RPL (free, void, (void *ptr) _GL_ATTRIBUTE_NOTHROW); | 305 | _GL_FUNCDECL_RPL (free, void, (void *ptr), ) _GL_ATTRIBUTE_NOTHROW; |
| 227 | # else | 306 | # else |
| 228 | _GL_FUNCDECL_RPL (free, void, (void *ptr)); | 307 | _GL_FUNCDECL_RPL (free, void, (void *ptr), ); |
| 229 | # endif | 308 | # endif |
| 230 | _GL_CXXALIAS_RPL (free, void, (void *ptr)); | 309 | _GL_CXXALIAS_RPL (free, void, (void *ptr)); |
| 231 | # else | 310 | # else |
| @@ -237,8 +316,8 @@ _GL_CXXALIASWARN (free); | |||
| 237 | #elif defined GNULIB_POSIXCHECK | 316 | #elif defined GNULIB_POSIXCHECK |
| 238 | # undef free | 317 | # undef free |
| 239 | /* Assume free is always declared. */ | 318 | /* Assume free is always declared. */ |
| 240 | _GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - " | 319 | _GL_WARN_ON_USE (free, "free is not POSIX:2024 compliant everywhere - " |
| 241 | "use gnulib module free for portability"); | 320 | "use gnulib module free-posix for portability"); |
| 242 | #endif | 321 | #endif |
| 243 | 322 | ||
| 244 | 323 | ||
| @@ -250,22 +329,25 @@ _GL_WARN_ON_USE (free, "free is not future POSIX compliant everywhere - " | |||
| 250 | # define aligned_alloc rpl_aligned_alloc | 329 | # define aligned_alloc rpl_aligned_alloc |
| 251 | # endif | 330 | # endif |
| 252 | _GL_FUNCDECL_RPL (aligned_alloc, void *, | 331 | _GL_FUNCDECL_RPL (aligned_alloc, void *, |
| 253 | (size_t alignment, size_t size) | 332 | (size_t alignment, size_t size), |
| 254 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 333 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 334 | _GL_ATTRIBUTE_NODISCARD); | ||
| 255 | _GL_CXXALIAS_RPL (aligned_alloc, void *, (size_t alignment, size_t size)); | 335 | _GL_CXXALIAS_RPL (aligned_alloc, void *, (size_t alignment, size_t size)); |
| 256 | # else | 336 | # else |
| 257 | # if @HAVE_ALIGNED_ALLOC@ | 337 | # if @HAVE_ALIGNED_ALLOC@ |
| 258 | # if __GNUC__ >= 11 | 338 | # if __GNUC__ >= 11 && !defined __clang__ |
| 259 | /* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */ | 339 | /* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */ |
| 260 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 | 340 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 |
| 261 | _GL_FUNCDECL_SYS (aligned_alloc, void *, | 341 | _GL_FUNCDECL_SYS (aligned_alloc, void *, |
| 262 | (size_t alignment, size_t size) | 342 | (size_t alignment, size_t size), |
| 263 | _GL_ATTRIBUTE_NOTHROW | 343 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 264 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 344 | _GL_ATTRIBUTE_NODISCARD) |
| 345 | _GL_ATTRIBUTE_NOTHROW; | ||
| 265 | # else | 346 | # else |
| 266 | _GL_FUNCDECL_SYS (aligned_alloc, void *, | 347 | _GL_FUNCDECL_SYS (aligned_alloc, void *, |
| 267 | (size_t alignment, size_t size) | 348 | (size_t alignment, size_t size), |
| 268 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 349 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 350 | _GL_ATTRIBUTE_NODISCARD); | ||
| 269 | # endif | 351 | # endif |
| 270 | # endif | 352 | # endif |
| 271 | _GL_CXXALIAS_SYS (aligned_alloc, void *, (size_t alignment, size_t size)); | 353 | _GL_CXXALIAS_SYS (aligned_alloc, void *, (size_t alignment, size_t size)); |
| @@ -275,16 +357,17 @@ _GL_CXXALIAS_SYS (aligned_alloc, void *, (size_t alignment, size_t size)); | |||
| 275 | _GL_CXXALIASWARN (aligned_alloc); | 357 | _GL_CXXALIASWARN (aligned_alloc); |
| 276 | # endif | 358 | # endif |
| 277 | #else | 359 | #else |
| 278 | # if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined aligned_alloc | 360 | # if @GNULIB_FREE_POSIX@ \ |
| 361 | && (__GNUC__ >= 11 && !defined __clang__) && !defined aligned_alloc | ||
| 279 | /* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */ | 362 | /* For -Wmismatched-dealloc: Associate aligned_alloc with free or rpl_free. */ |
| 280 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 | 363 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 |
| 281 | _GL_FUNCDECL_SYS (aligned_alloc, void *, | 364 | _GL_FUNCDECL_SYS (aligned_alloc, void *, |
| 282 | (size_t alignment, size_t size) | 365 | (size_t alignment, size_t size), |
| 283 | _GL_ATTRIBUTE_NOTHROW | 366 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 284 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 367 | _GL_ATTRIBUTE_NOTHROW; |
| 285 | # else | 368 | # else |
| 286 | _GL_FUNCDECL_SYS (aligned_alloc, void *, | 369 | _GL_FUNCDECL_SYS (aligned_alloc, void *, |
| 287 | (size_t alignment, size_t size) | 370 | (size_t alignment, size_t size), |
| 288 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 371 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 289 | # endif | 372 | # endif |
| 290 | # endif | 373 | # endif |
| @@ -301,9 +384,10 @@ _GL_WARN_ON_USE (aligned_alloc, "aligned_alloc is not portable - " | |||
| 301 | /* Parse a signed decimal integer. | 384 | /* Parse a signed decimal integer. |
| 302 | Returns the value of the integer. Errors are not detected. */ | 385 | Returns the value of the integer. Errors are not detected. */ |
| 303 | # if !@HAVE_ATOLL@ | 386 | # if !@HAVE_ATOLL@ |
| 304 | _GL_FUNCDECL_SYS (atoll, long long, (const char *string) | 387 | _GL_FUNCDECL_SYS (atoll, long long, |
| 305 | _GL_ATTRIBUTE_PURE | 388 | (const char *string), |
| 306 | _GL_ARG_NONNULL ((1))); | 389 | _GL_ATTRIBUTE_PURE |
| 390 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 307 | # endif | 391 | # endif |
| 308 | _GL_CXXALIAS_SYS (atoll, long long, (const char *string)); | 392 | _GL_CXXALIAS_SYS (atoll, long long, (const char *string)); |
| 309 | _GL_CXXALIASWARN (atoll); | 393 | _GL_CXXALIASWARN (atoll); |
| @@ -316,28 +400,32 @@ _GL_WARN_ON_USE (atoll, "atoll is unportable - " | |||
| 316 | #endif | 400 | #endif |
| 317 | 401 | ||
| 318 | #if @GNULIB_CALLOC_POSIX@ | 402 | #if @GNULIB_CALLOC_POSIX@ |
| 319 | # if (@GNULIB_CALLOC_POSIX@ && @REPLACE_CALLOC_FOR_CALLOC_POSIX@) \ | 403 | # if @REPLACE_CALLOC_FOR_CALLOC_POSIX@ \ |
| 320 | || (@GNULIB_CALLOC_GNU@ && @REPLACE_CALLOC_FOR_CALLOC_GNU@) | 404 | || (@GNULIB_CALLOC_GNU@ && @REPLACE_CALLOC_FOR_CALLOC_GNU@) |
| 321 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 405 | # if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ |
| 406 | || _GL_USE_STDLIB_ALLOC) | ||
| 322 | # undef calloc | 407 | # undef calloc |
| 323 | # define calloc rpl_calloc | 408 | # define calloc rpl_calloc |
| 324 | # endif | 409 | # endif |
| 325 | _GL_FUNCDECL_RPL (calloc, void *, | 410 | _GL_FUNCDECL_RPL (calloc, void *, |
| 326 | (size_t nmemb, size_t size) | 411 | (size_t nmemb, size_t size), |
| 327 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 412 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 413 | _GL_ATTRIBUTE_NODISCARD); | ||
| 328 | _GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size)); | 414 | _GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size)); |
| 329 | # else | 415 | # else |
| 330 | # if __GNUC__ >= 11 | 416 | # if __GNUC__ >= 11 && !defined __clang__ |
| 331 | /* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */ | 417 | /* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */ |
| 332 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 | 418 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 |
| 333 | _GL_FUNCDECL_SYS (calloc, void *, | 419 | _GL_FUNCDECL_SYS (calloc, void *, |
| 334 | (size_t nmemb, size_t size) | 420 | (size_t nmemb, size_t size), |
| 335 | _GL_ATTRIBUTE_NOTHROW | 421 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 336 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 422 | _GL_ATTRIBUTE_NODISCARD) |
| 423 | _GL_ATTRIBUTE_NOTHROW; | ||
| 337 | # else | 424 | # else |
| 338 | _GL_FUNCDECL_SYS (calloc, void *, | 425 | _GL_FUNCDECL_SYS (calloc, void *, |
| 339 | (size_t nmemb, size_t size) | 426 | (size_t nmemb, size_t size), |
| 340 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 427 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 428 | _GL_ATTRIBUTE_NODISCARD); | ||
| 341 | # endif | 429 | # endif |
| 342 | # endif | 430 | # endif |
| 343 | _GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size)); | 431 | _GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size)); |
| @@ -346,16 +434,17 @@ _GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size)); | |||
| 346 | _GL_CXXALIASWARN (calloc); | 434 | _GL_CXXALIASWARN (calloc); |
| 347 | # endif | 435 | # endif |
| 348 | #else | 436 | #else |
| 349 | # if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined calloc | 437 | # if @GNULIB_FREE_POSIX@ \ |
| 438 | && (__GNUC__ >= 11 && !defined __clang__) && !defined calloc | ||
| 350 | /* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */ | 439 | /* For -Wmismatched-dealloc: Associate calloc with free or rpl_free. */ |
| 351 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 | 440 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 |
| 352 | _GL_FUNCDECL_SYS (calloc, void *, | 441 | _GL_FUNCDECL_SYS (calloc, void *, |
| 353 | (size_t nmemb, size_t size) | 442 | (size_t nmemb, size_t size), |
| 354 | _GL_ATTRIBUTE_NOTHROW | 443 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 355 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 444 | _GL_ATTRIBUTE_NOTHROW; |
| 356 | # else | 445 | # else |
| 357 | _GL_FUNCDECL_SYS (calloc, void *, | 446 | _GL_FUNCDECL_SYS (calloc, void *, |
| 358 | (size_t nmemb, size_t size) | 447 | (size_t nmemb, size_t size), |
| 359 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 448 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 360 | # endif | 449 | # endif |
| 361 | # endif | 450 | # endif |
| @@ -373,23 +462,26 @@ _GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - " | |||
| 373 | # define canonicalize_file_name rpl_canonicalize_file_name | 462 | # define canonicalize_file_name rpl_canonicalize_file_name |
| 374 | # endif | 463 | # endif |
| 375 | _GL_FUNCDECL_RPL (canonicalize_file_name, char *, | 464 | _GL_FUNCDECL_RPL (canonicalize_file_name, char *, |
| 376 | (const char *name) | 465 | (const char *name), |
| 377 | _GL_ARG_NONNULL ((1)) | 466 | _GL_ARG_NONNULL ((1)) |
| 378 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 467 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 468 | _GL_ATTRIBUTE_NODISCARD); | ||
| 379 | _GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name)); | 469 | _GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name)); |
| 380 | # else | 470 | # else |
| 381 | # if !@HAVE_CANONICALIZE_FILE_NAME@ || __GNUC__ >= 11 | 471 | # if !@HAVE_CANONICALIZE_FILE_NAME@ || (__GNUC__ >= 11 && !defined __clang__) |
| 382 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 472 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 383 | _GL_FUNCDECL_SYS (canonicalize_file_name, char *, | 473 | _GL_FUNCDECL_SYS (canonicalize_file_name, char *, |
| 384 | (const char *name) | 474 | (const char *name), |
| 385 | _GL_ATTRIBUTE_NOTHROW | ||
| 386 | _GL_ARG_NONNULL ((1)) | 475 | _GL_ARG_NONNULL ((1)) |
| 387 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 476 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 477 | _GL_ATTRIBUTE_NODISCARD) | ||
| 478 | _GL_ATTRIBUTE_NOTHROW; | ||
| 388 | # else | 479 | # else |
| 389 | _GL_FUNCDECL_SYS (canonicalize_file_name, char *, | 480 | _GL_FUNCDECL_SYS (canonicalize_file_name, char *, |
| 390 | (const char *name) | 481 | (const char *name), |
| 391 | _GL_ARG_NONNULL ((1)) | 482 | _GL_ARG_NONNULL ((1)) |
| 392 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 483 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 484 | _GL_ATTRIBUTE_NODISCARD); | ||
| 393 | # endif | 485 | # endif |
| 394 | # endif | 486 | # endif |
| 395 | _GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name)); | 487 | _GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name)); |
| @@ -400,18 +492,19 @@ _GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name)); | |||
| 400 | # endif | 492 | # endif |
| 401 | _GL_CXXALIASWARN (canonicalize_file_name); | 493 | _GL_CXXALIASWARN (canonicalize_file_name); |
| 402 | #else | 494 | #else |
| 403 | # if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined canonicalize_file_name | 495 | # if @GNULIB_FREE_POSIX@ \ |
| 496 | && (__GNUC__ >= 11 && !defined __clang__) && !defined canonicalize_file_name | ||
| 404 | /* For -Wmismatched-dealloc: Associate canonicalize_file_name with free or | 497 | /* For -Wmismatched-dealloc: Associate canonicalize_file_name with free or |
| 405 | rpl_free. */ | 498 | rpl_free. */ |
| 406 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 499 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 407 | _GL_FUNCDECL_SYS (canonicalize_file_name, char *, | 500 | _GL_FUNCDECL_SYS (canonicalize_file_name, char *, |
| 408 | (const char *name) | 501 | (const char *name), |
| 409 | _GL_ATTRIBUTE_NOTHROW | ||
| 410 | _GL_ARG_NONNULL ((1)) | 502 | _GL_ARG_NONNULL ((1)) |
| 411 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 503 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 504 | _GL_ATTRIBUTE_NOTHROW; | ||
| 412 | # else | 505 | # else |
| 413 | _GL_FUNCDECL_SYS (canonicalize_file_name, char *, | 506 | _GL_FUNCDECL_SYS (canonicalize_file_name, char *, |
| 414 | (const char *name) | 507 | (const char *name), |
| 415 | _GL_ARG_NONNULL ((1)) | 508 | _GL_ARG_NONNULL ((1)) |
| 416 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 509 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 417 | # endif | 510 | # endif |
| @@ -503,12 +596,12 @@ _GL_CXXALIASWARN (gcvt); | |||
| 503 | # undef getloadavg | 596 | # undef getloadavg |
| 504 | # define getloadavg rpl_getloadavg | 597 | # define getloadavg rpl_getloadavg |
| 505 | # endif | 598 | # endif |
| 506 | _GL_FUNCDECL_RPL (getloadavg, int, (double loadavg[], int nelem) | 599 | _GL_FUNCDECL_RPL (getloadavg, int, (double loadavg[], int nelem), |
| 507 | _GL_ARG_NONNULL ((1))); | 600 | _GL_ARG_NONNULL ((1))); |
| 508 | _GL_CXXALIAS_RPL (getloadavg, int, (double loadavg[], int nelem)); | 601 | _GL_CXXALIAS_RPL (getloadavg, int, (double loadavg[], int nelem)); |
| 509 | # else | 602 | # else |
| 510 | # if !@HAVE_DECL_GETLOADAVG@ | 603 | # if !@HAVE_DECL_GETLOADAVG@ |
| 511 | _GL_FUNCDECL_SYS (getloadavg, int, (double loadavg[], int nelem) | 604 | _GL_FUNCDECL_SYS (getloadavg, int, (double loadavg[], int nelem), |
| 512 | _GL_ARG_NONNULL ((1))); | 605 | _GL_ARG_NONNULL ((1))); |
| 513 | # endif | 606 | # endif |
| 514 | _GL_CXXALIAS_SYS (getloadavg, int, (double loadavg[], int nelem)); | 607 | _GL_CXXALIAS_SYS (getloadavg, int, (double loadavg[], int nelem)); |
| @@ -533,17 +626,17 @@ _GL_WARN_ON_USE (getloadavg, "getloadavg is not portable - " | |||
| 533 | # define getprogname rpl_getprogname | 626 | # define getprogname rpl_getprogname |
| 534 | # endif | 627 | # endif |
| 535 | # if @HAVE_DECL_PROGRAM_INVOCATION_NAME@ | 628 | # if @HAVE_DECL_PROGRAM_INVOCATION_NAME@ |
| 536 | _GL_FUNCDECL_RPL (getprogname, const char *, (void) _GL_ATTRIBUTE_PURE); | 629 | _GL_FUNCDECL_RPL (getprogname, const char *, (void), _GL_ATTRIBUTE_PURE); |
| 537 | # else | 630 | # else |
| 538 | _GL_FUNCDECL_RPL (getprogname, const char *, (void)); | 631 | _GL_FUNCDECL_RPL (getprogname, const char *, (void), ); |
| 539 | # endif | 632 | # endif |
| 540 | _GL_CXXALIAS_RPL (getprogname, const char *, (void)); | 633 | _GL_CXXALIAS_RPL (getprogname, const char *, (void)); |
| 541 | # else | 634 | # else |
| 542 | # if !@HAVE_GETPROGNAME@ | 635 | # if !@HAVE_GETPROGNAME@ |
| 543 | # if @HAVE_DECL_PROGRAM_INVOCATION_NAME@ | 636 | # if @HAVE_DECL_PROGRAM_INVOCATION_NAME@ |
| 544 | _GL_FUNCDECL_SYS (getprogname, const char *, (void) _GL_ATTRIBUTE_PURE); | 637 | _GL_FUNCDECL_SYS (getprogname, const char *, (void), _GL_ATTRIBUTE_PURE); |
| 545 | # else | 638 | # else |
| 546 | _GL_FUNCDECL_SYS (getprogname, const char *, (void)); | 639 | _GL_FUNCDECL_SYS (getprogname, const char *, (void), ); |
| 547 | # endif | 640 | # endif |
| 548 | # endif | 641 | # endif |
| 549 | _GL_CXXALIAS_SYS (getprogname, const char *, (void)); | 642 | _GL_CXXALIAS_SYS (getprogname, const char *, (void)); |
| @@ -577,15 +670,15 @@ _GL_WARN_ON_USE (getprogname, "getprogname is unportable - " | |||
| 577 | # define getsubopt rpl_getsubopt | 670 | # define getsubopt rpl_getsubopt |
| 578 | # endif | 671 | # endif |
| 579 | _GL_FUNCDECL_RPL (getsubopt, int, | 672 | _GL_FUNCDECL_RPL (getsubopt, int, |
| 580 | (char **optionp, char *const *tokens, char **valuep) | 673 | (char **optionp, char *const *tokens, char **valuep), |
| 581 | _GL_ARG_NONNULL ((1, 2, 3))); | 674 | _GL_ARG_NONNULL ((1, 2, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 582 | _GL_CXXALIAS_RPL (getsubopt, int, | 675 | _GL_CXXALIAS_RPL (getsubopt, int, |
| 583 | (char **optionp, char *const *tokens, char **valuep)); | 676 | (char **optionp, char *const *tokens, char **valuep)); |
| 584 | # else | 677 | # else |
| 585 | # if !@HAVE_GETSUBOPT@ | 678 | # if !@HAVE_GETSUBOPT@ |
| 586 | _GL_FUNCDECL_SYS (getsubopt, int, | 679 | _GL_FUNCDECL_SYS (getsubopt, int, |
| 587 | (char **optionp, char *const *tokens, char **valuep) | 680 | (char **optionp, char *const *tokens, char **valuep), |
| 588 | _GL_ARG_NONNULL ((1, 2, 3))); | 681 | _GL_ARG_NONNULL ((1, 2, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 589 | # endif | 682 | # endif |
| 590 | _GL_CXXALIAS_SYS (getsubopt, int, | 683 | _GL_CXXALIAS_SYS (getsubopt, int, |
| 591 | (char **optionp, char *const *tokens, char **valuep)); | 684 | (char **optionp, char *const *tokens, char **valuep)); |
| @@ -605,7 +698,7 @@ _GL_WARN_ON_USE (getsubopt, "getsubopt is unportable - " | |||
| 605 | /* Change the ownership and access permission of the slave side of the | 698 | /* Change the ownership and access permission of the slave side of the |
| 606 | pseudo-terminal whose master side is specified by FD. */ | 699 | pseudo-terminal whose master side is specified by FD. */ |
| 607 | # if !@HAVE_GRANTPT@ | 700 | # if !@HAVE_GRANTPT@ |
| 608 | _GL_FUNCDECL_SYS (grantpt, int, (int fd)); | 701 | _GL_FUNCDECL_SYS (grantpt, int, (int fd), ); |
| 609 | # endif | 702 | # endif |
| 610 | _GL_CXXALIAS_SYS (grantpt, int, (int fd)); | 703 | _GL_CXXALIAS_SYS (grantpt, int, (int fd)); |
| 611 | _GL_CXXALIASWARN (grantpt); | 704 | _GL_CXXALIASWARN (grantpt); |
| @@ -622,7 +715,7 @@ _GL_WARN_ON_USE (grantpt, "grantpt is not portable - " | |||
| 622 | by never specifying a zero size), so it does not need malloc or | 715 | by never specifying a zero size), so it does not need malloc or |
| 623 | realloc to be redefined. */ | 716 | realloc to be redefined. */ |
| 624 | #if @GNULIB_MALLOC_POSIX@ | 717 | #if @GNULIB_MALLOC_POSIX@ |
| 625 | # if (@GNULIB_MALLOC_POSIX@ && @REPLACE_MALLOC_FOR_MALLOC_POSIX@) \ | 718 | # if @REPLACE_MALLOC_FOR_MALLOC_POSIX@ \ |
| 626 | || (@GNULIB_MALLOC_GNU@ && @REPLACE_MALLOC_FOR_MALLOC_GNU@) | 719 | || (@GNULIB_MALLOC_GNU@ && @REPLACE_MALLOC_FOR_MALLOC_GNU@) |
| 627 | # if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ | 720 | # if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ |
| 628 | || _GL_USE_STDLIB_ALLOC) | 721 | || _GL_USE_STDLIB_ALLOC) |
| @@ -630,21 +723,24 @@ _GL_WARN_ON_USE (grantpt, "grantpt is not portable - " | |||
| 630 | # define malloc rpl_malloc | 723 | # define malloc rpl_malloc |
| 631 | # endif | 724 | # endif |
| 632 | _GL_FUNCDECL_RPL (malloc, void *, | 725 | _GL_FUNCDECL_RPL (malloc, void *, |
| 633 | (size_t size) | 726 | (size_t size), |
| 634 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 727 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 728 | _GL_ATTRIBUTE_NODISCARD); | ||
| 635 | _GL_CXXALIAS_RPL (malloc, void *, (size_t size)); | 729 | _GL_CXXALIAS_RPL (malloc, void *, (size_t size)); |
| 636 | # else | 730 | # else |
| 637 | # if __GNUC__ >= 11 | 731 | # if __GNUC__ >= 11 && !defined __clang__ |
| 638 | /* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */ | 732 | /* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */ |
| 639 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 | 733 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 |
| 640 | _GL_FUNCDECL_SYS (malloc, void *, | 734 | _GL_FUNCDECL_SYS (malloc, void *, |
| 641 | (size_t size) | 735 | (size_t size), |
| 642 | _GL_ATTRIBUTE_NOTHROW | 736 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 643 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 737 | _GL_ATTRIBUTE_NODISCARD) |
| 738 | _GL_ATTRIBUTE_NOTHROW; | ||
| 644 | # else | 739 | # else |
| 645 | _GL_FUNCDECL_SYS (malloc, void *, | 740 | _GL_FUNCDECL_SYS (malloc, void *, |
| 646 | (size_t size) | 741 | (size_t size), |
| 647 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 742 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE |
| 743 | _GL_ATTRIBUTE_NODISCARD); | ||
| 648 | # endif | 744 | # endif |
| 649 | # endif | 745 | # endif |
| 650 | _GL_CXXALIAS_SYS (malloc, void *, (size_t size)); | 746 | _GL_CXXALIAS_SYS (malloc, void *, (size_t size)); |
| @@ -653,16 +749,17 @@ _GL_CXXALIAS_SYS (malloc, void *, (size_t size)); | |||
| 653 | _GL_CXXALIASWARN (malloc); | 749 | _GL_CXXALIASWARN (malloc); |
| 654 | # endif | 750 | # endif |
| 655 | #else | 751 | #else |
| 656 | # if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined malloc | 752 | # if @GNULIB_FREE_POSIX@ \ |
| 753 | && (__GNUC__ >= 11 && !defined __clang__) && !defined malloc | ||
| 657 | /* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */ | 754 | /* For -Wmismatched-dealloc: Associate malloc with free or rpl_free. */ |
| 658 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 | 755 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 |
| 659 | _GL_FUNCDECL_SYS (malloc, void *, | 756 | _GL_FUNCDECL_SYS (malloc, void *, |
| 660 | (size_t size) | 757 | (size_t size), |
| 661 | _GL_ATTRIBUTE_NOTHROW | 758 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 662 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 759 | _GL_ATTRIBUTE_NOTHROW; |
| 663 | # else | 760 | # else |
| 664 | _GL_FUNCDECL_SYS (malloc, void *, | 761 | _GL_FUNCDECL_SYS (malloc, void *, |
| 665 | (size_t size) | 762 | (size_t size), |
| 666 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 763 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 667 | # endif | 764 | # endif |
| 668 | # endif | 765 | # endif |
| @@ -674,14 +771,20 @@ _GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - " | |||
| 674 | # endif | 771 | # endif |
| 675 | #endif | 772 | #endif |
| 676 | 773 | ||
| 677 | /* Return maximum number of bytes of a multibyte character. */ | 774 | /* Return maximum number of bytes in a multibyte character in the |
| 775 | current locale. */ | ||
| 678 | #if @REPLACE_MB_CUR_MAX@ | 776 | #if @REPLACE_MB_CUR_MAX@ |
| 679 | # if !GNULIB_defined_MB_CUR_MAX | 777 | # if !GNULIB_defined_MB_CUR_MAX |
| 680 | static inline | 778 | _GL_STDLIB_INLINE size_t |
| 681 | int gl_MB_CUR_MAX (void) | 779 | gl_MB_CUR_MAX (void) |
| 682 | { | 780 | { |
| 781 | # if 0 < @REPLACE_MB_CUR_MAX@ | ||
| 782 | return @REPLACE_MB_CUR_MAX@; | ||
| 783 | # else | ||
| 683 | /* Turn the value 3 to the value 4, as needed for the UTF-8 encoding. */ | 784 | /* Turn the value 3 to the value 4, as needed for the UTF-8 encoding. */ |
| 684 | return MB_CUR_MAX + (MB_CUR_MAX == 3); | 785 | int gl_mb_cur_max = MB_CUR_MAX; |
| 786 | return gl_mb_cur_max == 3 ? 4 : gl_mb_cur_max; | ||
| 787 | # endif | ||
| 685 | } | 788 | } |
| 686 | # undef MB_CUR_MAX | 789 | # undef MB_CUR_MAX |
| 687 | # define MB_CUR_MAX gl_MB_CUR_MAX () | 790 | # define MB_CUR_MAX gl_MB_CUR_MAX () |
| @@ -698,7 +801,7 @@ int gl_MB_CUR_MAX (void) | |||
| 698 | # endif | 801 | # endif |
| 699 | _GL_FUNCDECL_RPL (mbstowcs, size_t, | 802 | _GL_FUNCDECL_RPL (mbstowcs, size_t, |
| 700 | (wchar_t *restrict dest, const char *restrict src, | 803 | (wchar_t *restrict dest, const char *restrict src, |
| 701 | size_t len) | 804 | size_t len), |
| 702 | _GL_ARG_NONNULL ((2))); | 805 | _GL_ARG_NONNULL ((2))); |
| 703 | _GL_CXXALIAS_RPL (mbstowcs, size_t, | 806 | _GL_CXXALIAS_RPL (mbstowcs, size_t, |
| 704 | (wchar_t *restrict dest, const char *restrict src, | 807 | (wchar_t *restrict dest, const char *restrict src, |
| @@ -727,13 +830,13 @@ _GL_WARN_ON_USE (mbstowcs, "mbstowcs is unportable - " | |||
| 727 | # define mbtowc rpl_mbtowc | 830 | # define mbtowc rpl_mbtowc |
| 728 | # endif | 831 | # endif |
| 729 | _GL_FUNCDECL_RPL (mbtowc, int, | 832 | _GL_FUNCDECL_RPL (mbtowc, int, |
| 730 | (wchar_t *restrict pwc, const char *restrict s, size_t n)); | 833 | (wchar_t *restrict pwc, const char *restrict s, size_t n), ); |
| 731 | _GL_CXXALIAS_RPL (mbtowc, int, | 834 | _GL_CXXALIAS_RPL (mbtowc, int, |
| 732 | (wchar_t *restrict pwc, const char *restrict s, size_t n)); | 835 | (wchar_t *restrict pwc, const char *restrict s, size_t n)); |
| 733 | # else | 836 | # else |
| 734 | # if !@HAVE_MBTOWC@ | 837 | # if !@HAVE_MBTOWC@ |
| 735 | _GL_FUNCDECL_SYS (mbtowc, int, | 838 | _GL_FUNCDECL_SYS (mbtowc, int, |
| 736 | (wchar_t *restrict pwc, const char *restrict s, size_t n)); | 839 | (wchar_t *restrict pwc, const char *restrict s, size_t n), ); |
| 737 | # endif | 840 | # endif |
| 738 | _GL_CXXALIAS_SYS (mbtowc, int, | 841 | _GL_CXXALIAS_SYS (mbtowc, int, |
| 739 | (wchar_t *restrict pwc, const char *restrict s, size_t n)); | 842 | (wchar_t *restrict pwc, const char *restrict s, size_t n)); |
| @@ -756,7 +859,9 @@ _GL_WARN_ON_USE (mbtowc, "mbtowc is not portable - " | |||
| 756 | Returns TEMPLATE, or a null pointer if it cannot get a unique name. | 859 | Returns TEMPLATE, or a null pointer if it cannot get a unique name. |
| 757 | The directory is created mode 700. */ | 860 | The directory is created mode 700. */ |
| 758 | # if !@HAVE_MKDTEMP@ | 861 | # if !@HAVE_MKDTEMP@ |
| 759 | _GL_FUNCDECL_SYS (mkdtemp, char *, (char * /*template*/) _GL_ARG_NONNULL ((1))); | 862 | _GL_FUNCDECL_SYS (mkdtemp, char *, |
| 863 | (char * /*template*/), | ||
| 864 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 760 | # endif | 865 | # endif |
| 761 | _GL_CXXALIAS_SYS (mkdtemp, char *, (char * /*template*/)); | 866 | _GL_CXXALIAS_SYS (mkdtemp, char *, (char * /*template*/)); |
| 762 | _GL_CXXALIASWARN (mkdtemp); | 867 | _GL_CXXALIASWARN (mkdtemp); |
| @@ -786,13 +891,13 @@ _GL_WARN_ON_USE (mkdtemp, "mkdtemp is unportable - " | |||
| 786 | # undef mkostemp | 891 | # undef mkostemp |
| 787 | # define mkostemp rpl_mkostemp | 892 | # define mkostemp rpl_mkostemp |
| 788 | # endif | 893 | # endif |
| 789 | _GL_FUNCDECL_RPL (mkostemp, int, (char * /*template*/, int /*flags*/) | 894 | _GL_FUNCDECL_RPL (mkostemp, int, (char * /*template*/, int /*flags*/), |
| 790 | _GL_ARG_NONNULL ((1))); | 895 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 791 | _GL_CXXALIAS_RPL (mkostemp, int, (char * /*template*/, int /*flags*/)); | 896 | _GL_CXXALIAS_RPL (mkostemp, int, (char * /*template*/, int /*flags*/)); |
| 792 | # else | 897 | # else |
| 793 | # if !@HAVE_MKOSTEMP@ | 898 | # if !@HAVE_MKOSTEMP@ |
| 794 | _GL_FUNCDECL_SYS (mkostemp, int, (char * /*template*/, int /*flags*/) | 899 | _GL_FUNCDECL_SYS (mkostemp, int, (char * /*template*/, int /*flags*/), |
| 795 | _GL_ARG_NONNULL ((1))); | 900 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 796 | # endif | 901 | # endif |
| 797 | _GL_CXXALIAS_SYS (mkostemp, int, (char * /*template*/, int /*flags*/)); | 902 | _GL_CXXALIAS_SYS (mkostemp, int, (char * /*template*/, int /*flags*/)); |
| 798 | # endif | 903 | # endif |
| @@ -827,15 +932,15 @@ _GL_WARN_ON_USE (mkostemp, "mkostemp is unportable - " | |||
| 827 | # define mkostemps rpl_mkostemps | 932 | # define mkostemps rpl_mkostemps |
| 828 | # endif | 933 | # endif |
| 829 | _GL_FUNCDECL_RPL (mkostemps, int, | 934 | _GL_FUNCDECL_RPL (mkostemps, int, |
| 830 | (char * /*template*/, int /*suffixlen*/, int /*flags*/) | 935 | (char * /*template*/, int /*suffixlen*/, int /*flags*/), |
| 831 | _GL_ARG_NONNULL ((1))); | 936 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 832 | _GL_CXXALIAS_RPL (mkostemps, int, | 937 | _GL_CXXALIAS_RPL (mkostemps, int, |
| 833 | (char * /*template*/, int /*suffixlen*/, int /*flags*/)); | 938 | (char * /*template*/, int /*suffixlen*/, int /*flags*/)); |
| 834 | # else | 939 | # else |
| 835 | # if !@HAVE_MKOSTEMPS@ | 940 | # if !@HAVE_MKOSTEMPS@ |
| 836 | _GL_FUNCDECL_SYS (mkostemps, int, | 941 | _GL_FUNCDECL_SYS (mkostemps, int, |
| 837 | (char * /*template*/, int /*suffixlen*/, int /*flags*/) | 942 | (char * /*template*/, int /*suffixlen*/, int /*flags*/), |
| 838 | _GL_ARG_NONNULL ((1))); | 943 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 839 | # endif | 944 | # endif |
| 840 | _GL_CXXALIAS_SYS (mkostemps, int, | 945 | _GL_CXXALIAS_SYS (mkostemps, int, |
| 841 | (char * /*template*/, int /*suffixlen*/, int /*flags*/)); | 946 | (char * /*template*/, int /*suffixlen*/, int /*flags*/)); |
| @@ -865,11 +970,13 @@ _GL_WARN_ON_USE (mkostemps, "mkostemps is unportable - " | |||
| 865 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 970 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 866 | # define mkstemp rpl_mkstemp | 971 | # define mkstemp rpl_mkstemp |
| 867 | # endif | 972 | # endif |
| 868 | _GL_FUNCDECL_RPL (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1))); | 973 | _GL_FUNCDECL_RPL (mkstemp, int, (char * /*template*/), |
| 974 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 869 | _GL_CXXALIAS_RPL (mkstemp, int, (char * /*template*/)); | 975 | _GL_CXXALIAS_RPL (mkstemp, int, (char * /*template*/)); |
| 870 | # else | 976 | # else |
| 871 | # if ! @HAVE_MKSTEMP@ | 977 | # if ! @HAVE_MKSTEMP@ |
| 872 | _GL_FUNCDECL_SYS (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1))); | 978 | _GL_FUNCDECL_SYS (mkstemp, int, (char * /*template*/), |
| 979 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 873 | # endif | 980 | # endif |
| 874 | _GL_CXXALIAS_SYS (mkstemp, int, (char * /*template*/)); | 981 | _GL_CXXALIAS_SYS (mkstemp, int, (char * /*template*/)); |
| 875 | # endif | 982 | # endif |
| @@ -894,8 +1001,8 @@ _GL_WARN_ON_USE (mkstemp, "mkstemp is unportable - " | |||
| 894 | Returns the open file descriptor if successful, otherwise -1 and errno | 1001 | Returns the open file descriptor if successful, otherwise -1 and errno |
| 895 | set. */ | 1002 | set. */ |
| 896 | # if !@HAVE_MKSTEMPS@ | 1003 | # if !@HAVE_MKSTEMPS@ |
| 897 | _GL_FUNCDECL_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/) | 1004 | _GL_FUNCDECL_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/), |
| 898 | _GL_ARG_NONNULL ((1))); | 1005 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 899 | # endif | 1006 | # endif |
| 900 | _GL_CXXALIAS_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/)); | 1007 | _GL_CXXALIAS_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/)); |
| 901 | _GL_CXXALIASWARN (mkstemps); | 1008 | _GL_CXXALIASWARN (mkstemps); |
| @@ -931,8 +1038,8 @@ _GL_CXXALIASWARN (mktemp); | |||
| 931 | # define posix_memalign rpl_posix_memalign | 1038 | # define posix_memalign rpl_posix_memalign |
| 932 | # endif | 1039 | # endif |
| 933 | _GL_FUNCDECL_RPL (posix_memalign, int, | 1040 | _GL_FUNCDECL_RPL (posix_memalign, int, |
| 934 | (void **memptr, size_t alignment, size_t size) | 1041 | (void **memptr, size_t alignment, size_t size), |
| 935 | _GL_ARG_NONNULL ((1))); | 1042 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 936 | _GL_CXXALIAS_RPL (posix_memalign, int, | 1043 | _GL_CXXALIAS_RPL (posix_memalign, int, |
| 937 | (void **memptr, size_t alignment, size_t size)); | 1044 | (void **memptr, size_t alignment, size_t size)); |
| 938 | # else | 1045 | # else |
| @@ -960,11 +1067,11 @@ _GL_WARN_ON_USE (posix_memalign, "posix_memalign is not portable - " | |||
| 960 | # undef posix_openpt | 1067 | # undef posix_openpt |
| 961 | # define posix_openpt rpl_posix_openpt | 1068 | # define posix_openpt rpl_posix_openpt |
| 962 | # endif | 1069 | # endif |
| 963 | _GL_FUNCDECL_RPL (posix_openpt, int, (int flags)); | 1070 | _GL_FUNCDECL_RPL (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD); |
| 964 | _GL_CXXALIAS_RPL (posix_openpt, int, (int flags)); | 1071 | _GL_CXXALIAS_RPL (posix_openpt, int, (int flags)); |
| 965 | # else | 1072 | # else |
| 966 | # if !@HAVE_POSIX_OPENPT@ | 1073 | # if !@HAVE_POSIX_OPENPT@ |
| 967 | _GL_FUNCDECL_SYS (posix_openpt, int, (int flags)); | 1074 | _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD); |
| 968 | # endif | 1075 | # endif |
| 969 | _GL_CXXALIAS_SYS (posix_openpt, int, (int flags)); | 1076 | _GL_CXXALIAS_SYS (posix_openpt, int, (int flags)); |
| 970 | # endif | 1077 | # endif |
| @@ -987,11 +1094,11 @@ _GL_WARN_ON_USE (posix_openpt, "posix_openpt is not portable - " | |||
| 987 | # undef ptsname | 1094 | # undef ptsname |
| 988 | # define ptsname rpl_ptsname | 1095 | # define ptsname rpl_ptsname |
| 989 | # endif | 1096 | # endif |
| 990 | _GL_FUNCDECL_RPL (ptsname, char *, (int fd)); | 1097 | _GL_FUNCDECL_RPL (ptsname, char *, (int fd), _GL_ATTRIBUTE_NODISCARD); |
| 991 | _GL_CXXALIAS_RPL (ptsname, char *, (int fd)); | 1098 | _GL_CXXALIAS_RPL (ptsname, char *, (int fd)); |
| 992 | # else | 1099 | # else |
| 993 | # if !@HAVE_PTSNAME@ | 1100 | # if !@HAVE_PTSNAME@ |
| 994 | _GL_FUNCDECL_SYS (ptsname, char *, (int fd)); | 1101 | _GL_FUNCDECL_SYS (ptsname, char *, (int fd), _GL_ATTRIBUTE_NODISCARD); |
| 995 | # endif | 1102 | # endif |
| 996 | _GL_CXXALIAS_SYS (ptsname, char *, (int fd)); | 1103 | _GL_CXXALIAS_SYS (ptsname, char *, (int fd)); |
| 997 | # endif | 1104 | # endif |
| @@ -1013,11 +1120,11 @@ _GL_WARN_ON_USE (ptsname, "ptsname is not portable - " | |||
| 1013 | # undef ptsname_r | 1120 | # undef ptsname_r |
| 1014 | # define ptsname_r rpl_ptsname_r | 1121 | # define ptsname_r rpl_ptsname_r |
| 1015 | # endif | 1122 | # endif |
| 1016 | _GL_FUNCDECL_RPL (ptsname_r, int, (int fd, char *buf, size_t len)); | 1123 | _GL_FUNCDECL_RPL (ptsname_r, int, (int fd, char *buf, size_t len), ); |
| 1017 | _GL_CXXALIAS_RPL (ptsname_r, int, (int fd, char *buf, size_t len)); | 1124 | _GL_CXXALIAS_RPL (ptsname_r, int, (int fd, char *buf, size_t len)); |
| 1018 | # else | 1125 | # else |
| 1019 | # if !@HAVE_PTSNAME_R@ | 1126 | # if !@HAVE_PTSNAME_R@ |
| 1020 | _GL_FUNCDECL_SYS (ptsname_r, int, (int fd, char *buf, size_t len)); | 1127 | _GL_FUNCDECL_SYS (ptsname_r, int, (int fd, char *buf, size_t len), ); |
| 1021 | # endif | 1128 | # endif |
| 1022 | _GL_CXXALIAS_SYS (ptsname_r, int, (int fd, char *buf, size_t len)); | 1129 | _GL_CXXALIAS_SYS (ptsname_r, int, (int fd, char *buf, size_t len)); |
| 1023 | # endif | 1130 | # endif |
| @@ -1039,7 +1146,7 @@ _GL_WARN_ON_USE (ptsname_r, "ptsname_r is not portable - " | |||
| 1039 | # undef putenv | 1146 | # undef putenv |
| 1040 | # define putenv rpl_putenv | 1147 | # define putenv rpl_putenv |
| 1041 | # endif | 1148 | # endif |
| 1042 | _GL_FUNCDECL_RPL (putenv, int, (char *string) _GL_ARG_NONNULL ((1))); | 1149 | _GL_FUNCDECL_RPL (putenv, int, (char *string), _GL_ARG_NONNULL ((1))); |
| 1043 | _GL_CXXALIAS_RPL (putenv, int, (char *string)); | 1150 | _GL_CXXALIAS_RPL (putenv, int, (char *string)); |
| 1044 | # elif defined _WIN32 && !defined __CYGWIN__ | 1151 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 1045 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1152 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -1098,7 +1205,9 @@ typedef int (*_gl_qsort_r_compar_fn) (void const *, void const *, void *); | |||
| 1098 | # endif | 1205 | # endif |
| 1099 | _GL_FUNCDECL_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, | 1206 | _GL_FUNCDECL_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, |
| 1100 | _gl_qsort_r_compar_fn compare, | 1207 | _gl_qsort_r_compar_fn compare, |
| 1101 | void *arg) _GL_ARG_NONNULL ((1, 4))); | 1208 | void *arg), |
| 1209 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) | ||
| 1210 | _GL_ARG_NONNULL ((4))); | ||
| 1102 | _GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, | 1211 | _GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, |
| 1103 | _gl_qsort_r_compar_fn compare, | 1212 | _gl_qsort_r_compar_fn compare, |
| 1104 | void *arg)); | 1213 | void *arg)); |
| @@ -1106,7 +1215,9 @@ _GL_CXXALIAS_RPL (qsort_r, void, (void *base, size_t nmemb, size_t size, | |||
| 1106 | # if !@HAVE_QSORT_R@ | 1215 | # if !@HAVE_QSORT_R@ |
| 1107 | _GL_FUNCDECL_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, | 1216 | _GL_FUNCDECL_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, |
| 1108 | _gl_qsort_r_compar_fn compare, | 1217 | _gl_qsort_r_compar_fn compare, |
| 1109 | void *arg) _GL_ARG_NONNULL ((1, 4))); | 1218 | void *arg), |
| 1219 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) | ||
| 1220 | _GL_ARG_NONNULL ((4))); | ||
| 1110 | # endif | 1221 | # endif |
| 1111 | _GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, | 1222 | _GL_CXXALIAS_SYS (qsort_r, void, (void *base, size_t nmemb, size_t size, |
| 1112 | _gl_qsort_r_compar_fn compare, | 1223 | _gl_qsort_r_compar_fn compare, |
| @@ -1137,7 +1248,7 @@ _GL_WARN_ON_USE (qsort_r, "qsort_r is not portable - " | |||
| 1137 | # undef rand | 1248 | # undef rand |
| 1138 | # define rand rpl_rand | 1249 | # define rand rpl_rand |
| 1139 | # endif | 1250 | # endif |
| 1140 | _GL_FUNCDECL_RPL (rand, int, (void)); | 1251 | _GL_FUNCDECL_RPL (rand, int, (void), ); |
| 1141 | _GL_CXXALIAS_RPL (rand, int, (void)); | 1252 | _GL_CXXALIAS_RPL (rand, int, (void)); |
| 1142 | # else | 1253 | # else |
| 1143 | _GL_CXXALIAS_SYS (rand, int, (void)); | 1254 | _GL_CXXALIAS_SYS (rand, int, (void)); |
| @@ -1154,11 +1265,11 @@ _GL_CXXALIASWARN (rand); | |||
| 1154 | # undef random | 1265 | # undef random |
| 1155 | # define random rpl_random | 1266 | # define random rpl_random |
| 1156 | # endif | 1267 | # endif |
| 1157 | _GL_FUNCDECL_RPL (random, long, (void)); | 1268 | _GL_FUNCDECL_RPL (random, long, (void), ); |
| 1158 | _GL_CXXALIAS_RPL (random, long, (void)); | 1269 | _GL_CXXALIAS_RPL (random, long, (void)); |
| 1159 | # else | 1270 | # else |
| 1160 | # if !@HAVE_RANDOM@ | 1271 | # if !@HAVE_RANDOM@ |
| 1161 | _GL_FUNCDECL_SYS (random, long, (void)); | 1272 | _GL_FUNCDECL_SYS (random, long, (void), ); |
| 1162 | # endif | 1273 | # endif |
| 1163 | /* Need to cast, because on Haiku, the return type is | 1274 | /* Need to cast, because on Haiku, the return type is |
| 1164 | int. */ | 1275 | int. */ |
| @@ -1181,11 +1292,11 @@ _GL_WARN_ON_USE (random, "random is unportable - " | |||
| 1181 | # undef srandom | 1292 | # undef srandom |
| 1182 | # define srandom rpl_srandom | 1293 | # define srandom rpl_srandom |
| 1183 | # endif | 1294 | # endif |
| 1184 | _GL_FUNCDECL_RPL (srandom, void, (unsigned int seed)); | 1295 | _GL_FUNCDECL_RPL (srandom, void, (unsigned int seed), ); |
| 1185 | _GL_CXXALIAS_RPL (srandom, void, (unsigned int seed)); | 1296 | _GL_CXXALIAS_RPL (srandom, void, (unsigned int seed)); |
| 1186 | # else | 1297 | # else |
| 1187 | # if !@HAVE_RANDOM@ | 1298 | # if !@HAVE_RANDOM@ |
| 1188 | _GL_FUNCDECL_SYS (srandom, void, (unsigned int seed)); | 1299 | _GL_FUNCDECL_SYS (srandom, void, (unsigned int seed), ); |
| 1189 | # endif | 1300 | # endif |
| 1190 | /* Need to cast, because on FreeBSD, the first parameter is | 1301 | /* Need to cast, because on FreeBSD, the first parameter is |
| 1191 | unsigned long seed. */ | 1302 | unsigned long seed. */ |
| @@ -1209,14 +1320,14 @@ _GL_WARN_ON_USE (srandom, "srandom is unportable - " | |||
| 1209 | # define initstate rpl_initstate | 1320 | # define initstate rpl_initstate |
| 1210 | # endif | 1321 | # endif |
| 1211 | _GL_FUNCDECL_RPL (initstate, char *, | 1322 | _GL_FUNCDECL_RPL (initstate, char *, |
| 1212 | (unsigned int seed, char *buf, size_t buf_size) | 1323 | (unsigned int seed, char *buf, size_t buf_size), |
| 1213 | _GL_ARG_NONNULL ((2))); | 1324 | _GL_ARG_NONNULL ((2))); |
| 1214 | _GL_CXXALIAS_RPL (initstate, char *, | 1325 | _GL_CXXALIAS_RPL (initstate, char *, |
| 1215 | (unsigned int seed, char *buf, size_t buf_size)); | 1326 | (unsigned int seed, char *buf, size_t buf_size)); |
| 1216 | # else | 1327 | # else |
| 1217 | # if !@HAVE_INITSTATE@ || !@HAVE_DECL_INITSTATE@ | 1328 | # if !@HAVE_INITSTATE@ || !@HAVE_DECL_INITSTATE@ |
| 1218 | _GL_FUNCDECL_SYS (initstate, char *, | 1329 | _GL_FUNCDECL_SYS (initstate, char *, |
| 1219 | (unsigned int seed, char *buf, size_t buf_size) | 1330 | (unsigned int seed, char *buf, size_t buf_size), |
| 1220 | _GL_ARG_NONNULL ((2))); | 1331 | _GL_ARG_NONNULL ((2))); |
| 1221 | # endif | 1332 | # endif |
| 1222 | /* Need to cast, because on FreeBSD, the first parameter is | 1333 | /* Need to cast, because on FreeBSD, the first parameter is |
| @@ -1241,11 +1352,11 @@ _GL_WARN_ON_USE (initstate, "initstate is unportable - " | |||
| 1241 | # undef setstate | 1352 | # undef setstate |
| 1242 | # define setstate rpl_setstate | 1353 | # define setstate rpl_setstate |
| 1243 | # endif | 1354 | # endif |
| 1244 | _GL_FUNCDECL_RPL (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1))); | 1355 | _GL_FUNCDECL_RPL (setstate, char *, (char *arg_state), _GL_ARG_NONNULL ((1))); |
| 1245 | _GL_CXXALIAS_RPL (setstate, char *, (char *arg_state)); | 1356 | _GL_CXXALIAS_RPL (setstate, char *, (char *arg_state)); |
| 1246 | # else | 1357 | # else |
| 1247 | # if !@HAVE_SETSTATE@ || !@HAVE_DECL_SETSTATE@ | 1358 | # if !@HAVE_SETSTATE@ || !@HAVE_DECL_SETSTATE@ |
| 1248 | _GL_FUNCDECL_SYS (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1))); | 1359 | _GL_FUNCDECL_SYS (setstate, char *, (char *arg_state), _GL_ARG_NONNULL ((1))); |
| 1249 | # endif | 1360 | # endif |
| 1250 | /* Need to cast, because on Mac OS X 10.13, HP-UX, Solaris the first parameter | 1361 | /* Need to cast, because on Mac OS X 10.13, HP-UX, Solaris the first parameter |
| 1251 | is const char *arg_state. */ | 1362 | is const char *arg_state. */ |
| @@ -1269,12 +1380,12 @@ _GL_WARN_ON_USE (setstate, "setstate is unportable - " | |||
| 1269 | # undef random_r | 1380 | # undef random_r |
| 1270 | # define random_r rpl_random_r | 1381 | # define random_r rpl_random_r |
| 1271 | # endif | 1382 | # endif |
| 1272 | _GL_FUNCDECL_RPL (random_r, int, (struct random_data *buf, int32_t *result) | 1383 | _GL_FUNCDECL_RPL (random_r, int, (struct random_data *buf, int32_t *result), |
| 1273 | _GL_ARG_NONNULL ((1, 2))); | 1384 | _GL_ARG_NONNULL ((1, 2))); |
| 1274 | _GL_CXXALIAS_RPL (random_r, int, (struct random_data *buf, int32_t *result)); | 1385 | _GL_CXXALIAS_RPL (random_r, int, (struct random_data *buf, int32_t *result)); |
| 1275 | # else | 1386 | # else |
| 1276 | # if !@HAVE_RANDOM_R@ | 1387 | # if !@HAVE_RANDOM_R@ |
| 1277 | _GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result) | 1388 | _GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result), |
| 1278 | _GL_ARG_NONNULL ((1, 2))); | 1389 | _GL_ARG_NONNULL ((1, 2))); |
| 1279 | # endif | 1390 | # endif |
| 1280 | _GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result)); | 1391 | _GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result)); |
| @@ -1295,14 +1406,14 @@ _GL_WARN_ON_USE (random_r, "random_r is unportable - " | |||
| 1295 | # define srandom_r rpl_srandom_r | 1406 | # define srandom_r rpl_srandom_r |
| 1296 | # endif | 1407 | # endif |
| 1297 | _GL_FUNCDECL_RPL (srandom_r, int, | 1408 | _GL_FUNCDECL_RPL (srandom_r, int, |
| 1298 | (unsigned int seed, struct random_data *rand_state) | 1409 | (unsigned int seed, struct random_data *rand_state), |
| 1299 | _GL_ARG_NONNULL ((2))); | 1410 | _GL_ARG_NONNULL ((2))); |
| 1300 | _GL_CXXALIAS_RPL (srandom_r, int, | 1411 | _GL_CXXALIAS_RPL (srandom_r, int, |
| 1301 | (unsigned int seed, struct random_data *rand_state)); | 1412 | (unsigned int seed, struct random_data *rand_state)); |
| 1302 | # else | 1413 | # else |
| 1303 | # if !@HAVE_RANDOM_R@ | 1414 | # if !@HAVE_RANDOM_R@ |
| 1304 | _GL_FUNCDECL_SYS (srandom_r, int, | 1415 | _GL_FUNCDECL_SYS (srandom_r, int, |
| 1305 | (unsigned int seed, struct random_data *rand_state) | 1416 | (unsigned int seed, struct random_data *rand_state), |
| 1306 | _GL_ARG_NONNULL ((2))); | 1417 | _GL_ARG_NONNULL ((2))); |
| 1307 | # endif | 1418 | # endif |
| 1308 | _GL_CXXALIAS_SYS (srandom_r, int, | 1419 | _GL_CXXALIAS_SYS (srandom_r, int, |
| @@ -1325,7 +1436,7 @@ _GL_WARN_ON_USE (srandom_r, "srandom_r is unportable - " | |||
| 1325 | # endif | 1436 | # endif |
| 1326 | _GL_FUNCDECL_RPL (initstate_r, int, | 1437 | _GL_FUNCDECL_RPL (initstate_r, int, |
| 1327 | (unsigned int seed, char *buf, size_t buf_size, | 1438 | (unsigned int seed, char *buf, size_t buf_size, |
| 1328 | struct random_data *rand_state) | 1439 | struct random_data *rand_state), |
| 1329 | _GL_ARG_NONNULL ((2, 4))); | 1440 | _GL_ARG_NONNULL ((2, 4))); |
| 1330 | _GL_CXXALIAS_RPL (initstate_r, int, | 1441 | _GL_CXXALIAS_RPL (initstate_r, int, |
| 1331 | (unsigned int seed, char *buf, size_t buf_size, | 1442 | (unsigned int seed, char *buf, size_t buf_size, |
| @@ -1334,7 +1445,7 @@ _GL_CXXALIAS_RPL (initstate_r, int, | |||
| 1334 | # if !@HAVE_RANDOM_R@ | 1445 | # if !@HAVE_RANDOM_R@ |
| 1335 | _GL_FUNCDECL_SYS (initstate_r, int, | 1446 | _GL_FUNCDECL_SYS (initstate_r, int, |
| 1336 | (unsigned int seed, char *buf, size_t buf_size, | 1447 | (unsigned int seed, char *buf, size_t buf_size, |
| 1337 | struct random_data *rand_state) | 1448 | struct random_data *rand_state), |
| 1338 | _GL_ARG_NONNULL ((2, 4))); | 1449 | _GL_ARG_NONNULL ((2, 4))); |
| 1339 | # endif | 1450 | # endif |
| 1340 | /* Need to cast, because on Haiku, the third parameter is | 1451 | /* Need to cast, because on Haiku, the third parameter is |
| @@ -1359,14 +1470,14 @@ _GL_WARN_ON_USE (initstate_r, "initstate_r is unportable - " | |||
| 1359 | # define setstate_r rpl_setstate_r | 1470 | # define setstate_r rpl_setstate_r |
| 1360 | # endif | 1471 | # endif |
| 1361 | _GL_FUNCDECL_RPL (setstate_r, int, | 1472 | _GL_FUNCDECL_RPL (setstate_r, int, |
| 1362 | (char *arg_state, struct random_data *rand_state) | 1473 | (char *arg_state, struct random_data *rand_state), |
| 1363 | _GL_ARG_NONNULL ((1, 2))); | 1474 | _GL_ARG_NONNULL ((1, 2))); |
| 1364 | _GL_CXXALIAS_RPL (setstate_r, int, | 1475 | _GL_CXXALIAS_RPL (setstate_r, int, |
| 1365 | (char *arg_state, struct random_data *rand_state)); | 1476 | (char *arg_state, struct random_data *rand_state)); |
| 1366 | # else | 1477 | # else |
| 1367 | # if !@HAVE_RANDOM_R@ | 1478 | # if !@HAVE_RANDOM_R@ |
| 1368 | _GL_FUNCDECL_SYS (setstate_r, int, | 1479 | _GL_FUNCDECL_SYS (setstate_r, int, |
| 1369 | (char *arg_state, struct random_data *rand_state) | 1480 | (char *arg_state, struct random_data *rand_state), |
| 1370 | _GL_ARG_NONNULL ((1, 2))); | 1481 | _GL_ARG_NONNULL ((1, 2))); |
| 1371 | # endif | 1482 | # endif |
| 1372 | /* Need to cast, because on Haiku, the first parameter is | 1483 | /* Need to cast, because on Haiku, the first parameter is |
| @@ -1385,28 +1496,44 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - " | |||
| 1385 | 1496 | ||
| 1386 | 1497 | ||
| 1387 | #if @GNULIB_REALLOC_POSIX@ | 1498 | #if @GNULIB_REALLOC_POSIX@ |
| 1388 | # if (@GNULIB_REALLOC_POSIX@ && @REPLACE_REALLOC_FOR_REALLOC_POSIX@) \ | 1499 | # if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ |
| 1389 | || (@GNULIB_REALLOC_GNU@ && @REPLACE_REALLOC_FOR_REALLOC_GNU@) | 1500 | # if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ == 2 |
| 1501 | # define _GL_INLINE_RPL_REALLOC 1 | ||
| 1502 | # ifdef __cplusplus | ||
| 1503 | extern "C" { | ||
| 1504 | # endif | ||
| 1505 | _GL_REALLOC_INLINE void * | ||
| 1506 | rpl_realloc (void *ptr, size_t size) | ||
| 1507 | { | ||
| 1508 | return realloc (ptr, size ? size : 1); | ||
| 1509 | } | ||
| 1510 | # ifdef __cplusplus | ||
| 1511 | } | ||
| 1512 | # endif | ||
| 1513 | # endif | ||
| 1390 | # if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ | 1514 | # if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ |
| 1391 | || _GL_USE_STDLIB_ALLOC) | 1515 | || _GL_USE_STDLIB_ALLOC) |
| 1392 | # undef realloc | 1516 | # undef realloc |
| 1393 | # define realloc rpl_realloc | 1517 | # define realloc rpl_realloc |
| 1394 | # endif | 1518 | # endif |
| 1395 | _GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size) | 1519 | # if !defined _GL_INLINE_RPL_REALLOC |
| 1396 | _GL_ATTRIBUTE_DEALLOC_FREE); | 1520 | _GL_FUNCDECL_RPL (realloc, void *, |
| 1521 | (void *ptr, size_t size), | ||
| 1522 | _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_NODISCARD); | ||
| 1523 | # endif | ||
| 1397 | _GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size)); | 1524 | _GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size)); |
| 1398 | # else | 1525 | # else |
| 1399 | # if __GNUC__ >= 11 | 1526 | # if __GNUC__ >= 11 && !defined __clang__ |
| 1400 | /* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */ | 1527 | /* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */ |
| 1401 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 | 1528 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 |
| 1402 | _GL_FUNCDECL_SYS (realloc, void *, | 1529 | _GL_FUNCDECL_SYS (realloc, void *, |
| 1403 | (void *ptr, size_t size) | 1530 | (void *ptr, size_t size), |
| 1404 | _GL_ATTRIBUTE_NOTHROW | 1531 | _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_NODISCARD) |
| 1405 | _GL_ATTRIBUTE_DEALLOC_FREE); | 1532 | _GL_ATTRIBUTE_NOTHROW; |
| 1406 | # else | 1533 | # else |
| 1407 | _GL_FUNCDECL_SYS (realloc, void *, | 1534 | _GL_FUNCDECL_SYS (realloc, void *, |
| 1408 | (void *ptr, size_t size) | 1535 | (void *ptr, size_t size), |
| 1409 | _GL_ATTRIBUTE_DEALLOC_FREE); | 1536 | _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_NODISCARD); |
| 1410 | # endif | 1537 | # endif |
| 1411 | # endif | 1538 | # endif |
| 1412 | _GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size)); | 1539 | _GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size)); |
| @@ -1415,16 +1542,17 @@ _GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size)); | |||
| 1415 | _GL_CXXALIASWARN (realloc); | 1542 | _GL_CXXALIASWARN (realloc); |
| 1416 | # endif | 1543 | # endif |
| 1417 | #else | 1544 | #else |
| 1418 | # if @GNULIB_FREE_POSIX@ && __GNUC__ >= 11 && !defined realloc | 1545 | # if @GNULIB_FREE_POSIX@ \ |
| 1546 | && (__GNUC__ >= 11 && !defined __clang__) && !defined realloc | ||
| 1419 | /* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */ | 1547 | /* For -Wmismatched-dealloc: Associate realloc with free or rpl_free. */ |
| 1420 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 | 1548 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 14) > 2 |
| 1421 | _GL_FUNCDECL_SYS (realloc, void *, | 1549 | _GL_FUNCDECL_SYS (realloc, void *, |
| 1422 | (void *ptr, size_t size) | 1550 | (void *ptr, size_t size), |
| 1423 | _GL_ATTRIBUTE_NOTHROW | 1551 | _GL_ATTRIBUTE_DEALLOC_FREE) |
| 1424 | _GL_ATTRIBUTE_DEALLOC_FREE); | 1552 | _GL_ATTRIBUTE_NOTHROW; |
| 1425 | # else | 1553 | # else |
| 1426 | _GL_FUNCDECL_SYS (realloc, void *, | 1554 | _GL_FUNCDECL_SYS (realloc, void *, |
| 1427 | (void *ptr, size_t size) | 1555 | (void *ptr, size_t size), |
| 1428 | _GL_ATTRIBUTE_DEALLOC_FREE); | 1556 | _GL_ATTRIBUTE_DEALLOC_FREE); |
| 1429 | # endif | 1557 | # endif |
| 1430 | # endif | 1558 | # endif |
| @@ -1444,13 +1572,15 @@ _GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - " | |||
| 1444 | # define reallocarray rpl_reallocarray | 1572 | # define reallocarray rpl_reallocarray |
| 1445 | # endif | 1573 | # endif |
| 1446 | _GL_FUNCDECL_RPL (reallocarray, void *, | 1574 | _GL_FUNCDECL_RPL (reallocarray, void *, |
| 1447 | (void *ptr, size_t nmemb, size_t size)); | 1575 | (void *ptr, size_t nmemb, size_t size), |
| 1576 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1448 | _GL_CXXALIAS_RPL (reallocarray, void *, | 1577 | _GL_CXXALIAS_RPL (reallocarray, void *, |
| 1449 | (void *ptr, size_t nmemb, size_t size)); | 1578 | (void *ptr, size_t nmemb, size_t size)); |
| 1450 | # else | 1579 | # else |
| 1451 | # if ! @HAVE_REALLOCARRAY@ | 1580 | # if ! @HAVE_REALLOCARRAY@ |
| 1452 | _GL_FUNCDECL_SYS (reallocarray, void *, | 1581 | _GL_FUNCDECL_SYS (reallocarray, void *, |
| 1453 | (void *ptr, size_t nmemb, size_t size)); | 1582 | (void *ptr, size_t nmemb, size_t size), |
| 1583 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1454 | # endif | 1584 | # endif |
| 1455 | _GL_CXXALIAS_SYS (reallocarray, void *, | 1585 | _GL_CXXALIAS_SYS (reallocarray, void *, |
| 1456 | (void *ptr, size_t nmemb, size_t size)); | 1586 | (void *ptr, size_t nmemb, size_t size)); |
| @@ -1472,15 +1602,15 @@ _GL_WARN_ON_USE (reallocarray, "reallocarray is not portable - " | |||
| 1472 | # define realpath rpl_realpath | 1602 | # define realpath rpl_realpath |
| 1473 | # endif | 1603 | # endif |
| 1474 | _GL_FUNCDECL_RPL (realpath, char *, | 1604 | _GL_FUNCDECL_RPL (realpath, char *, |
| 1475 | (const char *restrict name, char *restrict resolved) | 1605 | (const char *restrict name, char *restrict resolved), |
| 1476 | _GL_ARG_NONNULL ((1))); | 1606 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 1477 | _GL_CXXALIAS_RPL (realpath, char *, | 1607 | _GL_CXXALIAS_RPL (realpath, char *, |
| 1478 | (const char *restrict name, char *restrict resolved)); | 1608 | (const char *restrict name, char *restrict resolved)); |
| 1479 | # else | 1609 | # else |
| 1480 | # if !@HAVE_REALPATH@ | 1610 | # if !@HAVE_REALPATH@ |
| 1481 | _GL_FUNCDECL_SYS (realpath, char *, | 1611 | _GL_FUNCDECL_SYS (realpath, char *, |
| 1482 | (const char *restrict name, char *restrict resolved) | 1612 | (const char *restrict name, char *restrict resolved), |
| 1483 | _GL_ARG_NONNULL ((1))); | 1613 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 1484 | # endif | 1614 | # endif |
| 1485 | _GL_CXXALIAS_SYS (realpath, char *, | 1615 | _GL_CXXALIAS_SYS (realpath, char *, |
| 1486 | (const char *restrict name, char *restrict resolved)); | 1616 | (const char *restrict name, char *restrict resolved)); |
| @@ -1498,7 +1628,8 @@ _GL_WARN_ON_USE (realpath, "realpath is unportable - use gnulib module " | |||
| 1498 | /* Test a user response to a question. | 1628 | /* Test a user response to a question. |
| 1499 | Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear. */ | 1629 | Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear. */ |
| 1500 | # if !@HAVE_RPMATCH@ | 1630 | # if !@HAVE_RPMATCH@ |
| 1501 | _GL_FUNCDECL_SYS (rpmatch, int, (const char *response) _GL_ARG_NONNULL ((1))); | 1631 | _GL_FUNCDECL_SYS (rpmatch, int, (const char *response), |
| 1632 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 1502 | # endif | 1633 | # endif |
| 1503 | _GL_CXXALIAS_SYS (rpmatch, int, (const char *response)); | 1634 | _GL_CXXALIAS_SYS (rpmatch, int, (const char *response)); |
| 1504 | _GL_CXXALIASWARN (rpmatch); | 1635 | _GL_CXXALIASWARN (rpmatch); |
| @@ -1514,7 +1645,8 @@ _GL_WARN_ON_USE (rpmatch, "rpmatch is unportable - " | |||
| 1514 | /* Look up NAME in the environment, returning 0 in insecure situations. */ | 1645 | /* Look up NAME in the environment, returning 0 in insecure situations. */ |
| 1515 | # if !@HAVE_SECURE_GETENV@ | 1646 | # if !@HAVE_SECURE_GETENV@ |
| 1516 | _GL_FUNCDECL_SYS (secure_getenv, char *, | 1647 | _GL_FUNCDECL_SYS (secure_getenv, char *, |
| 1517 | (char const *name) _GL_ARG_NONNULL ((1))); | 1648 | (char const *name), |
| 1649 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 1518 | # endif | 1650 | # endif |
| 1519 | _GL_CXXALIAS_SYS (secure_getenv, char *, (char const *name)); | 1651 | _GL_CXXALIAS_SYS (secure_getenv, char *, (char const *name)); |
| 1520 | _GL_CXXALIASWARN (secure_getenv); | 1652 | _GL_CXXALIASWARN (secure_getenv); |
| @@ -1535,14 +1667,14 @@ _GL_WARN_ON_USE (secure_getenv, "secure_getenv is unportable - " | |||
| 1535 | # define setenv rpl_setenv | 1667 | # define setenv rpl_setenv |
| 1536 | # endif | 1668 | # endif |
| 1537 | _GL_FUNCDECL_RPL (setenv, int, | 1669 | _GL_FUNCDECL_RPL (setenv, int, |
| 1538 | (const char *name, const char *value, int replace) | 1670 | (const char *name, const char *value, int replace), |
| 1539 | _GL_ARG_NONNULL ((1))); | 1671 | _GL_ARG_NONNULL ((1))); |
| 1540 | _GL_CXXALIAS_RPL (setenv, int, | 1672 | _GL_CXXALIAS_RPL (setenv, int, |
| 1541 | (const char *name, const char *value, int replace)); | 1673 | (const char *name, const char *value, int replace)); |
| 1542 | # else | 1674 | # else |
| 1543 | # if !@HAVE_DECL_SETENV@ | 1675 | # if !@HAVE_DECL_SETENV@ |
| 1544 | _GL_FUNCDECL_SYS (setenv, int, | 1676 | _GL_FUNCDECL_SYS (setenv, int, |
| 1545 | (const char *name, const char *value, int replace) | 1677 | (const char *name, const char *value, int replace), |
| 1546 | _GL_ARG_NONNULL ((1))); | 1678 | _GL_ARG_NONNULL ((1))); |
| 1547 | # endif | 1679 | # endif |
| 1548 | _GL_CXXALIAS_SYS (setenv, int, | 1680 | _GL_CXXALIAS_SYS (setenv, int, |
| @@ -1559,6 +1691,19 @@ _GL_WARN_ON_USE (setenv, "setenv is unportable - " | |||
| 1559 | # endif | 1691 | # endif |
| 1560 | #endif | 1692 | #endif |
| 1561 | 1693 | ||
| 1694 | #if @GNULIB_STACK_TRACE@ | ||
| 1695 | /* Prints a stack trace of the current thread to standard error, | ||
| 1696 | if possible. */ | ||
| 1697 | # if @CAN_PRINT_STACK_TRACE@ | ||
| 1698 | _GL_EXTERN_C void print_stack_trace (void); | ||
| 1699 | # else | ||
| 1700 | # if !GNULIB_defined_print_stack_trace | ||
| 1701 | # define print_stack_trace() /* nothing */ | ||
| 1702 | # define GNULIB_defined_print_stack_trace 1 | ||
| 1703 | # endif | ||
| 1704 | # endif | ||
| 1705 | #endif | ||
| 1706 | |||
| 1562 | #if @GNULIB_STRTOD@ | 1707 | #if @GNULIB_STRTOD@ |
| 1563 | /* Parse a double from STRING, updating ENDP if appropriate. */ | 1708 | /* Parse a double from STRING, updating ENDP if appropriate. */ |
| 1564 | # if @REPLACE_STRTOD@ | 1709 | # if @REPLACE_STRTOD@ |
| @@ -1567,14 +1712,14 @@ _GL_WARN_ON_USE (setenv, "setenv is unportable - " | |||
| 1567 | # endif | 1712 | # endif |
| 1568 | # define GNULIB_defined_strtod_function 1 | 1713 | # define GNULIB_defined_strtod_function 1 |
| 1569 | _GL_FUNCDECL_RPL (strtod, double, | 1714 | _GL_FUNCDECL_RPL (strtod, double, |
| 1570 | (const char *restrict str, char **restrict endp) | 1715 | (const char *restrict str, char **restrict endp), |
| 1571 | _GL_ARG_NONNULL ((1))); | 1716 | _GL_ARG_NONNULL ((1))); |
| 1572 | _GL_CXXALIAS_RPL (strtod, double, | 1717 | _GL_CXXALIAS_RPL (strtod, double, |
| 1573 | (const char *restrict str, char **restrict endp)); | 1718 | (const char *restrict str, char **restrict endp)); |
| 1574 | # else | 1719 | # else |
| 1575 | # if !@HAVE_STRTOD@ | 1720 | # if !@HAVE_STRTOD@ |
| 1576 | _GL_FUNCDECL_SYS (strtod, double, | 1721 | _GL_FUNCDECL_SYS (strtod, double, |
| 1577 | (const char *restrict str, char **restrict endp) | 1722 | (const char *restrict str, char **restrict endp), |
| 1578 | _GL_ARG_NONNULL ((1))); | 1723 | _GL_ARG_NONNULL ((1))); |
| 1579 | # endif | 1724 | # endif |
| 1580 | _GL_CXXALIAS_SYS (strtod, double, | 1725 | _GL_CXXALIAS_SYS (strtod, double, |
| @@ -1599,14 +1744,14 @@ _GL_WARN_ON_USE (strtod, "strtod is unportable - " | |||
| 1599 | # endif | 1744 | # endif |
| 1600 | # define GNULIB_defined_strtof_function 1 | 1745 | # define GNULIB_defined_strtof_function 1 |
| 1601 | _GL_FUNCDECL_RPL (strtof, float, | 1746 | _GL_FUNCDECL_RPL (strtof, float, |
| 1602 | (const char *restrict str, char **restrict endp) | 1747 | (const char *restrict str, char **restrict endp), |
| 1603 | _GL_ARG_NONNULL ((1))); | 1748 | _GL_ARG_NONNULL ((1))); |
| 1604 | _GL_CXXALIAS_RPL (strtof, float, | 1749 | _GL_CXXALIAS_RPL (strtof, float, |
| 1605 | (const char *restrict str, char **restrict endp)); | 1750 | (const char *restrict str, char **restrict endp)); |
| 1606 | # else | 1751 | # else |
| 1607 | # if !@HAVE_STRTOF@ | 1752 | # if !@HAVE_STRTOF@ |
| 1608 | _GL_FUNCDECL_SYS (strtof, float, | 1753 | _GL_FUNCDECL_SYS (strtof, float, |
| 1609 | (const char *restrict str, char **restrict endp) | 1754 | (const char *restrict str, char **restrict endp), |
| 1610 | _GL_ARG_NONNULL ((1))); | 1755 | _GL_ARG_NONNULL ((1))); |
| 1611 | # endif | 1756 | # endif |
| 1612 | _GL_CXXALIAS_SYS (strtof, float, | 1757 | _GL_CXXALIAS_SYS (strtof, float, |
| @@ -1631,14 +1776,14 @@ _GL_WARN_ON_USE (strtof, "strtof is unportable - " | |||
| 1631 | # endif | 1776 | # endif |
| 1632 | # define GNULIB_defined_strtold_function 1 | 1777 | # define GNULIB_defined_strtold_function 1 |
| 1633 | _GL_FUNCDECL_RPL (strtold, long double, | 1778 | _GL_FUNCDECL_RPL (strtold, long double, |
| 1634 | (const char *restrict str, char **restrict endp) | 1779 | (const char *restrict str, char **restrict endp), |
| 1635 | _GL_ARG_NONNULL ((1))); | 1780 | _GL_ARG_NONNULL ((1))); |
| 1636 | _GL_CXXALIAS_RPL (strtold, long double, | 1781 | _GL_CXXALIAS_RPL (strtold, long double, |
| 1637 | (const char *restrict str, char **restrict endp)); | 1782 | (const char *restrict str, char **restrict endp)); |
| 1638 | # else | 1783 | # else |
| 1639 | # if !@HAVE_STRTOLD@ | 1784 | # if !@HAVE_STRTOLD@ |
| 1640 | _GL_FUNCDECL_SYS (strtold, long double, | 1785 | _GL_FUNCDECL_SYS (strtold, long double, |
| 1641 | (const char *restrict str, char **restrict endp) | 1786 | (const char *restrict str, char **restrict endp), |
| 1642 | _GL_ARG_NONNULL ((1))); | 1787 | _GL_ARG_NONNULL ((1))); |
| 1643 | # endif | 1788 | # endif |
| 1644 | _GL_CXXALIAS_SYS (strtold, long double, | 1789 | _GL_CXXALIAS_SYS (strtold, long double, |
| @@ -1669,7 +1814,7 @@ _GL_WARN_ON_USE (strtold, "strtold is unportable - " | |||
| 1669 | # define GNULIB_defined_strtol_function 1 | 1814 | # define GNULIB_defined_strtol_function 1 |
| 1670 | _GL_FUNCDECL_RPL (strtol, long, | 1815 | _GL_FUNCDECL_RPL (strtol, long, |
| 1671 | (const char *restrict string, char **restrict endptr, | 1816 | (const char *restrict string, char **restrict endptr, |
| 1672 | int base) | 1817 | int base), |
| 1673 | _GL_ARG_NONNULL ((1))); | 1818 | _GL_ARG_NONNULL ((1))); |
| 1674 | _GL_CXXALIAS_RPL (strtol, long, | 1819 | _GL_CXXALIAS_RPL (strtol, long, |
| 1675 | (const char *restrict string, char **restrict endptr, | 1820 | (const char *restrict string, char **restrict endptr, |
| @@ -1678,7 +1823,7 @@ _GL_CXXALIAS_RPL (strtol, long, | |||
| 1678 | # if !@HAVE_STRTOL@ | 1823 | # if !@HAVE_STRTOL@ |
| 1679 | _GL_FUNCDECL_SYS (strtol, long, | 1824 | _GL_FUNCDECL_SYS (strtol, long, |
| 1680 | (const char *restrict string, char **restrict endptr, | 1825 | (const char *restrict string, char **restrict endptr, |
| 1681 | int base) | 1826 | int base), |
| 1682 | _GL_ARG_NONNULL ((1))); | 1827 | _GL_ARG_NONNULL ((1))); |
| 1683 | # endif | 1828 | # endif |
| 1684 | _GL_CXXALIAS_SYS (strtol, long, | 1829 | _GL_CXXALIAS_SYS (strtol, long, |
| @@ -1712,7 +1857,7 @@ _GL_WARN_ON_USE (strtol, "strtol is unportable - " | |||
| 1712 | # define GNULIB_defined_strtoll_function 1 | 1857 | # define GNULIB_defined_strtoll_function 1 |
| 1713 | _GL_FUNCDECL_RPL (strtoll, long long, | 1858 | _GL_FUNCDECL_RPL (strtoll, long long, |
| 1714 | (const char *restrict string, char **restrict endptr, | 1859 | (const char *restrict string, char **restrict endptr, |
| 1715 | int base) | 1860 | int base), |
| 1716 | _GL_ARG_NONNULL ((1))); | 1861 | _GL_ARG_NONNULL ((1))); |
| 1717 | _GL_CXXALIAS_RPL (strtoll, long long, | 1862 | _GL_CXXALIAS_RPL (strtoll, long long, |
| 1718 | (const char *restrict string, char **restrict endptr, | 1863 | (const char *restrict string, char **restrict endptr, |
| @@ -1721,7 +1866,7 @@ _GL_CXXALIAS_RPL (strtoll, long long, | |||
| 1721 | # if !@HAVE_STRTOLL@ | 1866 | # if !@HAVE_STRTOLL@ |
| 1722 | _GL_FUNCDECL_SYS (strtoll, long long, | 1867 | _GL_FUNCDECL_SYS (strtoll, long long, |
| 1723 | (const char *restrict string, char **restrict endptr, | 1868 | (const char *restrict string, char **restrict endptr, |
| 1724 | int base) | 1869 | int base), |
| 1725 | _GL_ARG_NONNULL ((1))); | 1870 | _GL_ARG_NONNULL ((1))); |
| 1726 | # endif | 1871 | # endif |
| 1727 | _GL_CXXALIAS_SYS (strtoll, long long, | 1872 | _GL_CXXALIAS_SYS (strtoll, long long, |
| @@ -1752,7 +1897,7 @@ _GL_WARN_ON_USE (strtoll, "strtoll is unportable - " | |||
| 1752 | # define GNULIB_defined_strtoul_function 1 | 1897 | # define GNULIB_defined_strtoul_function 1 |
| 1753 | _GL_FUNCDECL_RPL (strtoul, unsigned long, | 1898 | _GL_FUNCDECL_RPL (strtoul, unsigned long, |
| 1754 | (const char *restrict string, char **restrict endptr, | 1899 | (const char *restrict string, char **restrict endptr, |
| 1755 | int base) | 1900 | int base), |
| 1756 | _GL_ARG_NONNULL ((1))); | 1901 | _GL_ARG_NONNULL ((1))); |
| 1757 | _GL_CXXALIAS_RPL (strtoul, unsigned long, | 1902 | _GL_CXXALIAS_RPL (strtoul, unsigned long, |
| 1758 | (const char *restrict string, char **restrict endptr, | 1903 | (const char *restrict string, char **restrict endptr, |
| @@ -1761,7 +1906,7 @@ _GL_CXXALIAS_RPL (strtoul, unsigned long, | |||
| 1761 | # if !@HAVE_STRTOUL@ | 1906 | # if !@HAVE_STRTOUL@ |
| 1762 | _GL_FUNCDECL_SYS (strtoul, unsigned long, | 1907 | _GL_FUNCDECL_SYS (strtoul, unsigned long, |
| 1763 | (const char *restrict string, char **restrict endptr, | 1908 | (const char *restrict string, char **restrict endptr, |
| 1764 | int base) | 1909 | int base), |
| 1765 | _GL_ARG_NONNULL ((1))); | 1910 | _GL_ARG_NONNULL ((1))); |
| 1766 | # endif | 1911 | # endif |
| 1767 | _GL_CXXALIAS_SYS (strtoul, unsigned long, | 1912 | _GL_CXXALIAS_SYS (strtoul, unsigned long, |
| @@ -1795,7 +1940,7 @@ _GL_WARN_ON_USE (strtoul, "strtoul is unportable - " | |||
| 1795 | # define GNULIB_defined_strtoull_function 1 | 1940 | # define GNULIB_defined_strtoull_function 1 |
| 1796 | _GL_FUNCDECL_RPL (strtoull, unsigned long long, | 1941 | _GL_FUNCDECL_RPL (strtoull, unsigned long long, |
| 1797 | (const char *restrict string, char **restrict endptr, | 1942 | (const char *restrict string, char **restrict endptr, |
| 1798 | int base) | 1943 | int base), |
| 1799 | _GL_ARG_NONNULL ((1))); | 1944 | _GL_ARG_NONNULL ((1))); |
| 1800 | _GL_CXXALIAS_RPL (strtoull, unsigned long long, | 1945 | _GL_CXXALIAS_RPL (strtoull, unsigned long long, |
| 1801 | (const char *restrict string, char **restrict endptr, | 1946 | (const char *restrict string, char **restrict endptr, |
| @@ -1804,7 +1949,7 @@ _GL_CXXALIAS_RPL (strtoull, unsigned long long, | |||
| 1804 | # if !@HAVE_STRTOULL@ | 1949 | # if !@HAVE_STRTOULL@ |
| 1805 | _GL_FUNCDECL_SYS (strtoull, unsigned long long, | 1950 | _GL_FUNCDECL_SYS (strtoull, unsigned long long, |
| 1806 | (const char *restrict string, char **restrict endptr, | 1951 | (const char *restrict string, char **restrict endptr, |
| 1807 | int base) | 1952 | int base), |
| 1808 | _GL_ARG_NONNULL ((1))); | 1953 | _GL_ARG_NONNULL ((1))); |
| 1809 | # endif | 1954 | # endif |
| 1810 | _GL_CXXALIAS_SYS (strtoull, unsigned long long, | 1955 | _GL_CXXALIAS_SYS (strtoull, unsigned long long, |
| @@ -1824,7 +1969,7 @@ _GL_WARN_ON_USE (strtoull, "strtoull is unportable - " | |||
| 1824 | /* Unlock the slave side of the pseudo-terminal whose master side is specified | 1969 | /* Unlock the slave side of the pseudo-terminal whose master side is specified |
| 1825 | by FD, so that it can be opened. */ | 1970 | by FD, so that it can be opened. */ |
| 1826 | # if !@HAVE_UNLOCKPT@ | 1971 | # if !@HAVE_UNLOCKPT@ |
| 1827 | _GL_FUNCDECL_SYS (unlockpt, int, (int fd)); | 1972 | _GL_FUNCDECL_SYS (unlockpt, int, (int fd), ); |
| 1828 | # endif | 1973 | # endif |
| 1829 | _GL_CXXALIAS_SYS (unlockpt, int, (int fd)); | 1974 | _GL_CXXALIAS_SYS (unlockpt, int, (int fd)); |
| 1830 | _GL_CXXALIASWARN (unlockpt); | 1975 | _GL_CXXALIASWARN (unlockpt); |
| @@ -1843,11 +1988,11 @@ _GL_WARN_ON_USE (unlockpt, "unlockpt is not portable - " | |||
| 1843 | # undef unsetenv | 1988 | # undef unsetenv |
| 1844 | # define unsetenv rpl_unsetenv | 1989 | # define unsetenv rpl_unsetenv |
| 1845 | # endif | 1990 | # endif |
| 1846 | _GL_FUNCDECL_RPL (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); | 1991 | _GL_FUNCDECL_RPL (unsetenv, int, (const char *name), _GL_ARG_NONNULL ((1))); |
| 1847 | _GL_CXXALIAS_RPL (unsetenv, int, (const char *name)); | 1992 | _GL_CXXALIAS_RPL (unsetenv, int, (const char *name)); |
| 1848 | # else | 1993 | # else |
| 1849 | # if !@HAVE_DECL_UNSETENV@ | 1994 | # if !@HAVE_DECL_UNSETENV@ |
| 1850 | _GL_FUNCDECL_SYS (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); | 1995 | _GL_FUNCDECL_SYS (unsetenv, int, (const char *name), _GL_ARG_NONNULL ((1))); |
| 1851 | # endif | 1996 | # endif |
| 1852 | _GL_CXXALIAS_SYS (unsetenv, int, (const char *name)); | 1997 | _GL_CXXALIAS_SYS (unsetenv, int, (const char *name)); |
| 1853 | # endif | 1998 | # endif |
| @@ -1869,7 +2014,7 @@ _GL_WARN_ON_USE (unsetenv, "unsetenv is unportable - " | |||
| 1869 | # undef wctomb | 2014 | # undef wctomb |
| 1870 | # define wctomb rpl_wctomb | 2015 | # define wctomb rpl_wctomb |
| 1871 | # endif | 2016 | # endif |
| 1872 | _GL_FUNCDECL_RPL (wctomb, int, (char *s, wchar_t wc)); | 2017 | _GL_FUNCDECL_RPL (wctomb, int, (char *s, wchar_t wc), ); |
| 1873 | _GL_CXXALIAS_RPL (wctomb, int, (char *s, wchar_t wc)); | 2018 | _GL_CXXALIAS_RPL (wctomb, int, (char *s, wchar_t wc)); |
| 1874 | # else | 2019 | # else |
| 1875 | _GL_CXXALIAS_SYS (wctomb, int, (char *s, wchar_t wc)); | 2020 | _GL_CXXALIAS_SYS (wctomb, int, (char *s, wchar_t wc)); |
| @@ -1880,6 +2025,8 @@ _GL_CXXALIASWARN (wctomb); | |||
| 1880 | #endif | 2025 | #endif |
| 1881 | 2026 | ||
| 1882 | 2027 | ||
| 2028 | _GL_INLINE_HEADER_END | ||
| 2029 | |||
| 1883 | #endif /* _@GUARD_PREFIX@_STDLIB_H */ | 2030 | #endif /* _@GUARD_PREFIX@_STDLIB_H */ |
| 1884 | #endif /* _@GUARD_PREFIX@_STDLIB_H */ | 2031 | #endif /* _@GUARD_PREFIX@_STDLIB_H */ |
| 1885 | #endif | 2032 | #endif |
diff --git a/gl/str-two-way.h b/gl/str-two-way.h index cf85e268..d13fb298 100644 --- a/gl/str-two-way.h +++ b/gl/str-two-way.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Byte-wise substring search, using the Two-Way algorithm. | 1 | /* Byte-wise substring search, using the Two-Way algorithm. |
| 2 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | Written by Eric Blake <ebb9@byu.net>, 2008. | 4 | Written by Eric Blake <ebb9@byu.net>, 2008. |
| 5 | 5 | ||
diff --git a/gl/strcasecmp.c b/gl/strcasecmp.c index 7939b404..16626d4d 100644 --- a/gl/strcasecmp.c +++ b/gl/strcasecmp.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Case-insensitive string comparison function. | 1 | /* Case-insensitive string comparison function for unibyte locales. |
| 2 | Copyright (C) 1998-1999, 2005-2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1998-1999, 2005-2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <config.h> | 17 | #include <config.h> |
| 18 | 18 | ||
| 19 | /* Specification. */ | 19 | /* Specification. */ |
| 20 | #include <string.h> | 20 | #include <strings.h> |
| 21 | 21 | ||
| 22 | #include <ctype.h> | 22 | #include <ctype.h> |
| 23 | #include <limits.h> | 23 | #include <limits.h> |
diff --git a/gl/strcasestr.c b/gl/strcasestr.c index b8c0479d..fd0e2c3e 100644 --- a/gl/strcasestr.c +++ b/gl/strcasestr.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Case-insensitive searching in a string. | 1 | /* Case-insensitive searching in a string. |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2005. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2005. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Optimized string comparison. | 1 | /* Optimized string comparison. |
| 2 | Copyright (C) 2001-2002, 2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2001-2002, 2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -26,7 +26,7 @@ extern "C" { | |||
| 26 | #endif | 26 | #endif |
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | /* STREQ_OPT allows to optimize string comparison with a small literal string. | 29 | /* STREQ_OPT optimizes string comparison with a small literal string. |
| 30 | STREQ_OPT (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) | 30 | STREQ_OPT (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) |
| 31 | is semantically equivalent to | 31 | is semantically equivalent to |
| 32 | strcmp (s, "EUC-KR") == 0 | 32 | strcmp (s, "EUC-KR") == 0 |
diff --git a/gl/strerror-override.c b/gl/strerror-override.c index b9c1c7ab..3cc25905 100644 --- a/gl/strerror-override.c +++ b/gl/strerror-override.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* strerror-override.c --- POSIX compatible system error routine | 1 | /* strerror-override.c --- POSIX compatible system error routine |
| 2 | 2 | ||
| 3 | Copyright (C) 2010-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2010-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -298,6 +298,11 @@ strerror_override (int errnum) | |||
| 298 | return "Invalid or incomplete multibyte or wide character"; | 298 | return "Invalid or incomplete multibyte or wide character"; |
| 299 | # endif | 299 | # endif |
| 300 | 300 | ||
| 301 | # if GNULIB_defined_ESOCKTNOSUPPORT | ||
| 302 | case ESOCKTNOSUPPORT: | ||
| 303 | return "Socket type not supported"; | ||
| 304 | # endif | ||
| 305 | |||
| 301 | default: | 306 | default: |
| 302 | return NULL; | 307 | return NULL; |
| 303 | } | 308 | } |
diff --git a/gl/strerror-override.h b/gl/strerror-override.h index a1734a24..653ea0ad 100644 --- a/gl/strerror-override.h +++ b/gl/strerror-override.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* strerror-override.h --- POSIX compatible system error routine | 1 | /* strerror-override.h --- POSIX compatible system error routine |
| 2 | 2 | ||
| 3 | Copyright (C) 2010-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2010-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -57,7 +57,8 @@ extern "C" { | |||
| 57 | || GNULIB_defined_ECANCELED \ | 57 | || GNULIB_defined_ECANCELED \ |
| 58 | || GNULIB_defined_EOWNERDEAD \ | 58 | || GNULIB_defined_EOWNERDEAD \ |
| 59 | || GNULIB_defined_ENOTRECOVERABLE \ | 59 | || GNULIB_defined_ENOTRECOVERABLE \ |
| 60 | || GNULIB_defined_EILSEQ | 60 | || GNULIB_defined_EILSEQ \ |
| 61 | || GNULIB_defined_ESOCKTNOSUPPORT | ||
| 61 | extern const char *strerror_override (int errnum) _GL_ATTRIBUTE_CONST; | 62 | extern const char *strerror_override (int errnum) _GL_ATTRIBUTE_CONST; |
| 62 | #else | 63 | #else |
| 63 | # define strerror_override(ignored) NULL | 64 | # define strerror_override(ignored) NULL |
diff --git a/gl/strerror.c b/gl/strerror.c index 6b760ff4..72572ae4 100644 --- a/gl/strerror.c +++ b/gl/strerror.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* strerror.c --- POSIX compatible system error routine | 1 | /* strerror.c --- POSIX compatible system error routine |
| 2 | 2 | ||
| 3 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -31,6 +31,12 @@ | |||
| 31 | /* Use the system functions, not the gnulib overrides in this file. */ | 31 | /* Use the system functions, not the gnulib overrides in this file. */ |
| 32 | #undef sprintf | 32 | #undef sprintf |
| 33 | 33 | ||
| 34 | /* macOS 12's "warning: 'sprintf' is deprecated" is pointless, | ||
| 35 | as sprintf is used safely here. */ | ||
| 36 | #if defined __APPLE__ && defined __MACH__ && _GL_GNUC_PREREQ (4, 2) | ||
| 37 | # pragma GCC diagnostic ignored "-Wdeprecated-declarations" | ||
| 38 | #endif | ||
| 39 | |||
| 34 | char * | 40 | char * |
| 35 | strerror (int n) | 41 | strerror (int n) |
| 36 | #undef strerror | 42 | #undef strerror |
diff --git a/gl/string.in.h b/gl/string.in.h index 44ec2e7e..25e6a087 100644 --- a/gl/string.in.h +++ b/gl/string.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A GNU-like <string.h>. | 1 | /* A GNU-like <string.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 1995-1996, 2001-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1995-1996, 2001-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -20,7 +20,7 @@ | |||
| 20 | #endif | 20 | #endif |
| 21 | @PRAGMA_COLUMNS@ | 21 | @PRAGMA_COLUMNS@ |
| 22 | 22 | ||
| 23 | #if defined _GL_ALREADY_INCLUDING_STRING_H | 23 | #if defined _@GUARD_PREFIX@_ALREADY_INCLUDING_STRING_H |
| 24 | /* Special invocation convention: | 24 | /* Special invocation convention: |
| 25 | - On OS X/NetBSD we have a sequence of nested includes | 25 | - On OS X/NetBSD we have a sequence of nested includes |
| 26 | <string.h> -> <strings.h> -> "string.h" | 26 | <string.h> -> <strings.h> -> "string.h" |
| @@ -34,12 +34,12 @@ | |||
| 34 | 34 | ||
| 35 | #ifndef _@GUARD_PREFIX@_STRING_H | 35 | #ifndef _@GUARD_PREFIX@_STRING_H |
| 36 | 36 | ||
| 37 | #define _GL_ALREADY_INCLUDING_STRING_H | 37 | #define _@GUARD_PREFIX@_ALREADY_INCLUDING_STRING_H |
| 38 | 38 | ||
| 39 | /* The include_next requires a split double-inclusion guard. */ | 39 | /* The include_next requires a split double-inclusion guard. */ |
| 40 | #@INCLUDE_NEXT@ @NEXT_STRING_H@ | 40 | #@INCLUDE_NEXT@ @NEXT_STRING_H@ |
| 41 | 41 | ||
| 42 | #undef _GL_ALREADY_INCLUDING_STRING_H | 42 | #undef _@GUARD_PREFIX@_ALREADY_INCLUDING_STRING_H |
| 43 | 43 | ||
| 44 | #ifndef _@GUARD_PREFIX@_STRING_H | 44 | #ifndef _@GUARD_PREFIX@_STRING_H |
| 45 | #define _@GUARD_PREFIX@_STRING_H | 45 | #define _@GUARD_PREFIX@_STRING_H |
| @@ -54,6 +54,11 @@ | |||
| 54 | /* NetBSD 5.0 mis-defines NULL. */ | 54 | /* NetBSD 5.0 mis-defines NULL. */ |
| 55 | #include <stddef.h> | 55 | #include <stddef.h> |
| 56 | 56 | ||
| 57 | #if @GNULIB_STRERROR_L@ | ||
| 58 | /* Get locale_t. */ | ||
| 59 | # include <locale.h> | ||
| 60 | #endif | ||
| 61 | |||
| 57 | /* MirBSD defines mbslen as a macro. */ | 62 | /* MirBSD defines mbslen as a macro. */ |
| 58 | #if @GNULIB_MBSLEN@ && defined __MirBSD__ | 63 | #if @GNULIB_MBSLEN@ && defined __MirBSD__ |
| 59 | # include <wchar.h> | 64 | # include <wchar.h> |
| @@ -79,7 +84,7 @@ | |||
| 79 | that can be freed by passing them as the Ith argument to the | 84 | that can be freed by passing them as the Ith argument to the |
| 80 | function F. */ | 85 | function F. */ |
| 81 | #ifndef _GL_ATTRIBUTE_DEALLOC | 86 | #ifndef _GL_ATTRIBUTE_DEALLOC |
| 82 | # if __GNUC__ >= 11 | 87 | # if __GNUC__ >= 11 && !defined __clang__ |
| 83 | # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) | 88 | # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) |
| 84 | # else | 89 | # else |
| 85 | # define _GL_ATTRIBUTE_DEALLOC(f, i) | 90 | # define _GL_ATTRIBUTE_DEALLOC(f, i) |
| @@ -111,11 +116,23 @@ | |||
| 111 | # endif | 116 | # endif |
| 112 | #endif | 117 | #endif |
| 113 | 118 | ||
| 119 | /* _GL_ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) declares that the argument NP | ||
| 120 | (a pointer) must not be NULL if the argument NI (an integer) is != 0. */ | ||
| 121 | /* Applies to: functions. */ | ||
| 122 | #ifndef _GL_ATTRIBUTE_NONNULL_IF_NONZERO | ||
| 123 | # if __GNUC__ >= 15 && !defined __clang__ | ||
| 124 | # define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) \ | ||
| 125 | __attribute__ ((__nonnull_if_nonzero__ (np, ni))) | ||
| 126 | # else | ||
| 127 | # define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) | ||
| 128 | # endif | ||
| 129 | #endif | ||
| 130 | |||
| 114 | /* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. | 131 | /* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. |
| 115 | */ | 132 | */ |
| 116 | #ifndef _GL_ATTRIBUTE_NOTHROW | 133 | #ifndef _GL_ATTRIBUTE_NOTHROW |
| 117 | # if defined __cplusplus | 134 | # if defined __cplusplus |
| 118 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major >= 4 | 135 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major__ >= 4 |
| 119 | # if __cplusplus >= 201103L | 136 | # if __cplusplus >= 201103L |
| 120 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) | 137 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) |
| 121 | # else | 138 | # else |
| @@ -149,6 +166,7 @@ | |||
| 149 | 166 | ||
| 150 | /* The definition of _GL_WARN_ON_USE is copied here. */ | 167 | /* The definition of _GL_WARN_ON_USE is copied here. */ |
| 151 | 168 | ||
| 169 | |||
| 152 | /* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though <stdlib.h> may not have | 170 | /* Make _GL_ATTRIBUTE_DEALLOC_FREE work, even though <stdlib.h> may not have |
| 153 | been included yet. */ | 171 | been included yet. */ |
| 154 | #if @GNULIB_FREE_POSIX@ | 172 | #if @GNULIB_FREE_POSIX@ |
| @@ -193,12 +211,97 @@ _GL_EXTERN_C void free (void *); | |||
| 193 | # endif | 211 | # endif |
| 194 | #endif | 212 | #endif |
| 195 | 213 | ||
| 214 | |||
| 215 | /* Declarations for ISO C N3322. */ | ||
| 216 | #if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ | ||
| 217 | # ifndef memcpy | ||
| 218 | _GL_EXTERN_C void *memcpy (void *__dest, const void *__src, size_t __n) | ||
| 219 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 220 | _GL_ATTRIBUTE_NOTHROW | ||
| 221 | # endif | ||
| 222 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 223 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 224 | # endif | ||
| 225 | # ifndef memccpy | ||
| 226 | _GL_EXTERN_C void *memccpy (void *__dest, const void *__src, int __c, size_t __n) | ||
| 227 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 228 | _GL_ATTRIBUTE_NOTHROW | ||
| 229 | # endif | ||
| 230 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 4) | ||
| 231 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 4); | ||
| 232 | # endif | ||
| 233 | # ifndef memmove | ||
| 234 | _GL_EXTERN_C void *memmove (void *__dest, const void *__src, size_t __n) | ||
| 235 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 236 | _GL_ATTRIBUTE_NOTHROW | ||
| 237 | # endif | ||
| 238 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 239 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 240 | # endif | ||
| 241 | # ifndef strncpy | ||
| 242 | _GL_EXTERN_C char *strncpy (char *__dest, const char *__src, size_t __n) | ||
| 243 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 244 | _GL_ATTRIBUTE_NOTHROW | ||
| 245 | # endif | ||
| 246 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 247 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 248 | # endif | ||
| 249 | # ifndef strndup | ||
| 250 | _GL_EXTERN_C char *strndup (const char *__s, size_t __n) | ||
| 251 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 252 | _GL_ATTRIBUTE_NOTHROW | ||
| 253 | # endif | ||
| 254 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2); | ||
| 255 | # endif | ||
| 256 | # ifndef strncat | ||
| 257 | _GL_EXTERN_C char *strncat (char *__dest, const char *__src, size_t __n) | ||
| 258 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 259 | _GL_ATTRIBUTE_NOTHROW | ||
| 260 | # endif | ||
| 261 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 262 | # endif | ||
| 263 | # ifndef memcmp | ||
| 264 | _GL_EXTERN_C int memcmp (const void *__s1, const void *__s2, size_t __n) | ||
| 265 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 266 | _GL_ATTRIBUTE_NOTHROW | ||
| 267 | # endif | ||
| 268 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 269 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 270 | # endif | ||
| 271 | # ifndef strncmp | ||
| 272 | _GL_EXTERN_C int strncmp (const char *__s1, const char *__s2, size_t __n) | ||
| 273 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 274 | _GL_ATTRIBUTE_NOTHROW | ||
| 275 | # endif | ||
| 276 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 277 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 278 | # endif | ||
| 279 | # if !defined memchr && !defined __cplusplus | ||
| 280 | _GL_EXTERN_C void *memchr (const void *__s, int __c, size_t __n) | ||
| 281 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); | ||
| 282 | _GL_EXTERN_C void *memrchr (const void *__s, int __c, size_t __n) | ||
| 283 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); | ||
| 284 | # endif | ||
| 285 | # ifndef memset | ||
| 286 | _GL_EXTERN_C void *memset (void *__s, int __c, size_t __n) | ||
| 287 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 288 | _GL_ATTRIBUTE_NOTHROW | ||
| 289 | # endif | ||
| 290 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); | ||
| 291 | # endif | ||
| 292 | # ifndef memset_explicit | ||
| 293 | _GL_EXTERN_C void *memset_explicit (void *__s, int __c, size_t __n) | ||
| 294 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); | ||
| 295 | # endif | ||
| 296 | #endif | ||
| 297 | |||
| 298 | |||
| 196 | /* Clear a block of memory. The compiler will not delete a call to | 299 | /* Clear a block of memory. The compiler will not delete a call to |
| 197 | this function, even if the block is dead after the call. */ | 300 | this function, even if the block is dead after the call. */ |
| 198 | #if @GNULIB_EXPLICIT_BZERO@ | 301 | #if @GNULIB_EXPLICIT_BZERO@ |
| 199 | # if ! @HAVE_EXPLICIT_BZERO@ | 302 | # if ! @HAVE_EXPLICIT_BZERO@ |
| 200 | _GL_FUNCDECL_SYS (explicit_bzero, void, | 303 | _GL_FUNCDECL_SYS (explicit_bzero, void, |
| 201 | (void *__dest, size_t __n) _GL_ARG_NONNULL ((1))); | 304 | (void *__dest, size_t __n), _GL_ARG_NONNULL ((1))); |
| 202 | # endif | 305 | # endif |
| 203 | _GL_CXXALIAS_SYS (explicit_bzero, void, (void *__dest, size_t __n)); | 306 | _GL_CXXALIAS_SYS (explicit_bzero, void, (void *__dest, size_t __n)); |
| 204 | _GL_CXXALIASWARN (explicit_bzero); | 307 | _GL_CXXALIASWARN (explicit_bzero); |
| @@ -210,10 +313,11 @@ _GL_WARN_ON_USE (explicit_bzero, "explicit_bzero is unportable - " | |||
| 210 | # endif | 313 | # endif |
| 211 | #endif | 314 | #endif |
| 212 | 315 | ||
| 316 | |||
| 213 | /* Find the index of the least-significant set bit. */ | 317 | /* Find the index of the least-significant set bit. */ |
| 214 | #if @GNULIB_FFSL@ | 318 | #if @GNULIB_FFSL@ |
| 215 | # if !@HAVE_FFSL@ | 319 | # if !@HAVE_FFSL@ |
| 216 | _GL_FUNCDECL_SYS (ffsl, int, (long int i)); | 320 | _GL_FUNCDECL_SYS (ffsl, int, (long int i), ); |
| 217 | # endif | 321 | # endif |
| 218 | _GL_CXXALIAS_SYS (ffsl, int, (long int i)); | 322 | _GL_CXXALIAS_SYS (ffsl, int, (long int i)); |
| 219 | _GL_CXXALIASWARN (ffsl); | 323 | _GL_CXXALIASWARN (ffsl); |
| @@ -231,11 +335,11 @@ _GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the ffsl module"); | |||
| 231 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 335 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 232 | # define ffsll rpl_ffsll | 336 | # define ffsll rpl_ffsll |
| 233 | # endif | 337 | # endif |
| 234 | _GL_FUNCDECL_RPL (ffsll, int, (long long int i)); | 338 | _GL_FUNCDECL_RPL (ffsll, int, (long long int i), ); |
| 235 | _GL_CXXALIAS_RPL (ffsll, int, (long long int i)); | 339 | _GL_CXXALIAS_RPL (ffsll, int, (long long int i)); |
| 236 | # else | 340 | # else |
| 237 | # if !@HAVE_FFSLL@ | 341 | # if !@HAVE_FFSLL@ |
| 238 | _GL_FUNCDECL_SYS (ffsll, int, (long long int i)); | 342 | _GL_FUNCDECL_SYS (ffsll, int, (long long int i), ); |
| 239 | # endif | 343 | # endif |
| 240 | _GL_CXXALIAS_SYS (ffsll, int, (long long int i)); | 344 | _GL_CXXALIAS_SYS (ffsll, int, (long long int i)); |
| 241 | # endif | 345 | # endif |
| @@ -274,9 +378,9 @@ _GL_CXXALIASWARN (memccpy); | |||
| 274 | # undef memchr | 378 | # undef memchr |
| 275 | # define memchr rpl_memchr | 379 | # define memchr rpl_memchr |
| 276 | # endif | 380 | # endif |
| 277 | _GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n) | 381 | _GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n), |
| 278 | _GL_ATTRIBUTE_PURE | 382 | _GL_ATTRIBUTE_PURE |
| 279 | _GL_ARG_NONNULL ((1))); | 383 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); |
| 280 | _GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n)); | 384 | _GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n)); |
| 281 | # else | 385 | # else |
| 282 | /* On some systems, this function is defined as an overloaded function: | 386 | /* On some systems, this function is defined as an overloaded function: |
| @@ -301,8 +405,10 @@ _GL_CXXALIASWARN (memchr); | |||
| 301 | #elif defined GNULIB_POSIXCHECK | 405 | #elif defined GNULIB_POSIXCHECK |
| 302 | # undef memchr | 406 | # undef memchr |
| 303 | /* Assume memchr is always declared. */ | 407 | /* Assume memchr is always declared. */ |
| 304 | _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " | 408 | _GL_WARN_ON_USE_CXX (memchr, |
| 305 | "use gnulib module memchr for portability" ); | 409 | const void *, void *, (void const *, int, size_t), |
| 410 | "memchr has platform-specific bugs - " | ||
| 411 | "use gnulib module memchr for portability" ); | ||
| 306 | #endif | 412 | #endif |
| 307 | 413 | ||
| 308 | /* Return the first occurrence of NEEDLE in HAYSTACK. */ | 414 | /* Return the first occurrence of NEEDLE in HAYSTACK. */ |
| @@ -313,7 +419,7 @@ _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " | |||
| 313 | # endif | 419 | # endif |
| 314 | _GL_FUNCDECL_RPL (memmem, void *, | 420 | _GL_FUNCDECL_RPL (memmem, void *, |
| 315 | (void const *__haystack, size_t __haystack_len, | 421 | (void const *__haystack, size_t __haystack_len, |
| 316 | void const *__needle, size_t __needle_len) | 422 | void const *__needle, size_t __needle_len), |
| 317 | _GL_ATTRIBUTE_PURE | 423 | _GL_ATTRIBUTE_PURE |
| 318 | _GL_ARG_NONNULL ((1, 3))); | 424 | _GL_ARG_NONNULL ((1, 3))); |
| 319 | _GL_CXXALIAS_RPL (memmem, void *, | 425 | _GL_CXXALIAS_RPL (memmem, void *, |
| @@ -323,7 +429,7 @@ _GL_CXXALIAS_RPL (memmem, void *, | |||
| 323 | # if ! @HAVE_DECL_MEMMEM@ | 429 | # if ! @HAVE_DECL_MEMMEM@ |
| 324 | _GL_FUNCDECL_SYS (memmem, void *, | 430 | _GL_FUNCDECL_SYS (memmem, void *, |
| 325 | (void const *__haystack, size_t __haystack_len, | 431 | (void const *__haystack, size_t __haystack_len, |
| 326 | void const *__needle, size_t __needle_len) | 432 | void const *__needle, size_t __needle_len), |
| 327 | _GL_ATTRIBUTE_PURE | 433 | _GL_ATTRIBUTE_PURE |
| 328 | _GL_ARG_NONNULL ((1, 3))); | 434 | _GL_ARG_NONNULL ((1, 3))); |
| 329 | # endif | 435 | # endif |
| @@ -351,7 +457,7 @@ _GL_WARN_ON_USE (memmem, "memmem is unportable and often quadratic - " | |||
| 351 | # endif | 457 | # endif |
| 352 | _GL_FUNCDECL_RPL (mempcpy, void *, | 458 | _GL_FUNCDECL_RPL (mempcpy, void *, |
| 353 | (void *restrict __dest, void const *restrict __src, | 459 | (void *restrict __dest, void const *restrict __src, |
| 354 | size_t __n) | 460 | size_t __n), |
| 355 | _GL_ARG_NONNULL ((1, 2))); | 461 | _GL_ARG_NONNULL ((1, 2))); |
| 356 | _GL_CXXALIAS_RPL (mempcpy, void *, | 462 | _GL_CXXALIAS_RPL (mempcpy, void *, |
| 357 | (void *restrict __dest, void const *restrict __src, | 463 | (void *restrict __dest, void const *restrict __src, |
| @@ -360,7 +466,7 @@ _GL_CXXALIAS_RPL (mempcpy, void *, | |||
| 360 | # if !@HAVE_MEMPCPY@ | 466 | # if !@HAVE_MEMPCPY@ |
| 361 | _GL_FUNCDECL_SYS (mempcpy, void *, | 467 | _GL_FUNCDECL_SYS (mempcpy, void *, |
| 362 | (void *restrict __dest, void const *restrict __src, | 468 | (void *restrict __dest, void const *restrict __src, |
| 363 | size_t __n) | 469 | size_t __n), |
| 364 | _GL_ARG_NONNULL ((1, 2))); | 470 | _GL_ARG_NONNULL ((1, 2))); |
| 365 | # endif | 471 | # endif |
| 366 | _GL_CXXALIAS_SYS (mempcpy, void *, | 472 | _GL_CXXALIAS_SYS (mempcpy, void *, |
| @@ -381,9 +487,9 @@ _GL_WARN_ON_USE (mempcpy, "mempcpy is unportable - " | |||
| 381 | /* Search backwards through a block for a byte (specified as an int). */ | 487 | /* Search backwards through a block for a byte (specified as an int). */ |
| 382 | #if @GNULIB_MEMRCHR@ | 488 | #if @GNULIB_MEMRCHR@ |
| 383 | # if ! @HAVE_DECL_MEMRCHR@ | 489 | # if ! @HAVE_DECL_MEMRCHR@ |
| 384 | _GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t) | 490 | _GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t), |
| 385 | _GL_ATTRIBUTE_PURE | 491 | _GL_ATTRIBUTE_PURE |
| 386 | _GL_ARG_NONNULL ((1))); | 492 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); |
| 387 | # endif | 493 | # endif |
| 388 | /* On some systems, this function is defined as an overloaded function: | 494 | /* On some systems, this function is defined as an overloaded function: |
| 389 | extern "C++" { const void * std::memrchr (const void *, int, size_t); } | 495 | extern "C++" { const void * std::memrchr (const void *, int, size_t); } |
| @@ -420,16 +526,20 @@ _GL_WARN_ON_USE (memrchr, "memrchr is unportable - " | |||
| 420 | # define memset_explicit rpl_memset_explicit | 526 | # define memset_explicit rpl_memset_explicit |
| 421 | # endif | 527 | # endif |
| 422 | _GL_FUNCDECL_RPL (memset_explicit, void *, | 528 | _GL_FUNCDECL_RPL (memset_explicit, void *, |
| 423 | (void *__dest, int __c, size_t __n) _GL_ARG_NONNULL ((1))); | 529 | (void *__dest, int __c, size_t __n), |
| 530 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); | ||
| 424 | _GL_CXXALIAS_RPL (memset_explicit, void *, (void *__dest, int __c, size_t __n)); | 531 | _GL_CXXALIAS_RPL (memset_explicit, void *, (void *__dest, int __c, size_t __n)); |
| 425 | # else | 532 | # else |
| 426 | # if !@HAVE_MEMSET_EXPLICIT@ | 533 | # if !@HAVE_MEMSET_EXPLICIT@ |
| 427 | _GL_FUNCDECL_SYS (memset_explicit, void *, | 534 | _GL_FUNCDECL_SYS (memset_explicit, void *, |
| 428 | (void *__dest, int __c, size_t __n) _GL_ARG_NONNULL ((1))); | 535 | (void *__dest, int __c, size_t __n), |
| 536 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); | ||
| 429 | # endif | 537 | # endif |
| 430 | _GL_CXXALIAS_SYS (memset_explicit, void *, (void *__dest, int __c, size_t __n)); | 538 | _GL_CXXALIAS_SYS (memset_explicit, void *, (void *__dest, int __c, size_t __n)); |
| 431 | # endif | 539 | # endif |
| 540 | # if __GLIBC__ >= 2 | ||
| 432 | _GL_CXXALIASWARN (memset_explicit); | 541 | _GL_CXXALIASWARN (memset_explicit); |
| 542 | # endif | ||
| 433 | #elif defined GNULIB_POSIXCHECK | 543 | #elif defined GNULIB_POSIXCHECK |
| 434 | # undef memset_explicit | 544 | # undef memset_explicit |
| 435 | # if HAVE_RAW_DECL_MEMSET_EXPLICIT | 545 | # if HAVE_RAW_DECL_MEMSET_EXPLICIT |
| @@ -443,7 +553,7 @@ _GL_WARN_ON_USE (memset_explicit, "memset_explicit is unportable - " | |||
| 443 | occur within N bytes. */ | 553 | occur within N bytes. */ |
| 444 | #if @GNULIB_RAWMEMCHR@ | 554 | #if @GNULIB_RAWMEMCHR@ |
| 445 | # if ! @HAVE_RAWMEMCHR@ | 555 | # if ! @HAVE_RAWMEMCHR@ |
| 446 | _GL_FUNCDECL_SYS (rawmemchr, void *, (void const *__s, int __c_in) | 556 | _GL_FUNCDECL_SYS (rawmemchr, void *, (void const *__s, int __c_in), |
| 447 | _GL_ATTRIBUTE_PURE | 557 | _GL_ATTRIBUTE_PURE |
| 448 | _GL_ARG_NONNULL ((1))); | 558 | _GL_ARG_NONNULL ((1))); |
| 449 | # endif | 559 | # endif |
| @@ -481,14 +591,14 @@ _GL_WARN_ON_USE (rawmemchr, "rawmemchr is unportable - " | |||
| 481 | # define stpcpy rpl_stpcpy | 591 | # define stpcpy rpl_stpcpy |
| 482 | # endif | 592 | # endif |
| 483 | _GL_FUNCDECL_RPL (stpcpy, char *, | 593 | _GL_FUNCDECL_RPL (stpcpy, char *, |
| 484 | (char *restrict __dst, char const *restrict __src) | 594 | (char *restrict __dst, char const *restrict __src), |
| 485 | _GL_ARG_NONNULL ((1, 2))); | 595 | _GL_ARG_NONNULL ((1, 2))); |
| 486 | _GL_CXXALIAS_RPL (stpcpy, char *, | 596 | _GL_CXXALIAS_RPL (stpcpy, char *, |
| 487 | (char *restrict __dst, char const *restrict __src)); | 597 | (char *restrict __dst, char const *restrict __src)); |
| 488 | # else | 598 | # else |
| 489 | # if !@HAVE_STPCPY@ | 599 | # if !@HAVE_STPCPY@ |
| 490 | _GL_FUNCDECL_SYS (stpcpy, char *, | 600 | _GL_FUNCDECL_SYS (stpcpy, char *, |
| 491 | (char *restrict __dst, char const *restrict __src) | 601 | (char *restrict __dst, char const *restrict __src), |
| 492 | _GL_ARG_NONNULL ((1, 2))); | 602 | _GL_ARG_NONNULL ((1, 2))); |
| 493 | # endif | 603 | # endif |
| 494 | _GL_CXXALIAS_SYS (stpcpy, char *, | 604 | _GL_CXXALIAS_SYS (stpcpy, char *, |
| @@ -515,7 +625,7 @@ _GL_WARN_ON_USE (stpcpy, "stpcpy is unportable - " | |||
| 515 | # endif | 625 | # endif |
| 516 | _GL_FUNCDECL_RPL (stpncpy, char *, | 626 | _GL_FUNCDECL_RPL (stpncpy, char *, |
| 517 | (char *restrict __dst, char const *restrict __src, | 627 | (char *restrict __dst, char const *restrict __src, |
| 518 | size_t __n) | 628 | size_t __n), |
| 519 | _GL_ARG_NONNULL ((1, 2))); | 629 | _GL_ARG_NONNULL ((1, 2))); |
| 520 | _GL_CXXALIAS_RPL (stpncpy, char *, | 630 | _GL_CXXALIAS_RPL (stpncpy, char *, |
| 521 | (char *restrict __dst, char const *restrict __src, | 631 | (char *restrict __dst, char const *restrict __src, |
| @@ -524,7 +634,7 @@ _GL_CXXALIAS_RPL (stpncpy, char *, | |||
| 524 | # if ! @HAVE_STPNCPY@ | 634 | # if ! @HAVE_STPNCPY@ |
| 525 | _GL_FUNCDECL_SYS (stpncpy, char *, | 635 | _GL_FUNCDECL_SYS (stpncpy, char *, |
| 526 | (char *restrict __dst, char const *restrict __src, | 636 | (char *restrict __dst, char const *restrict __src, |
| 527 | size_t __n) | 637 | size_t __n), |
| 528 | _GL_ARG_NONNULL ((1, 2))); | 638 | _GL_ARG_NONNULL ((1, 2))); |
| 529 | # endif | 639 | # endif |
| 530 | _GL_CXXALIAS_SYS (stpncpy, char *, | 640 | _GL_CXXALIAS_SYS (stpncpy, char *, |
| @@ -560,14 +670,14 @@ _GL_WARN_ON_USE_CXX (strchr, | |||
| 560 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 670 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 561 | # define strchrnul rpl_strchrnul | 671 | # define strchrnul rpl_strchrnul |
| 562 | # endif | 672 | # endif |
| 563 | _GL_FUNCDECL_RPL (strchrnul, char *, (const char *__s, int __c_in) | 673 | _GL_FUNCDECL_RPL (strchrnul, char *, (const char *__s, int __c_in), |
| 564 | _GL_ATTRIBUTE_PURE | 674 | _GL_ATTRIBUTE_PURE |
| 565 | _GL_ARG_NONNULL ((1))); | 675 | _GL_ARG_NONNULL ((1))); |
| 566 | _GL_CXXALIAS_RPL (strchrnul, char *, | 676 | _GL_CXXALIAS_RPL (strchrnul, char *, |
| 567 | (const char *str, int ch)); | 677 | (const char *str, int ch)); |
| 568 | # else | 678 | # else |
| 569 | # if ! @HAVE_STRCHRNUL@ | 679 | # if ! @HAVE_STRCHRNUL@ |
| 570 | _GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in) | 680 | _GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in), |
| 571 | _GL_ATTRIBUTE_PURE | 681 | _GL_ATTRIBUTE_PURE |
| 572 | _GL_ARG_NONNULL ((1))); | 682 | _GL_ARG_NONNULL ((1))); |
| 573 | # endif | 683 | # endif |
| @@ -606,7 +716,7 @@ _GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - " | |||
| 606 | # define strdup rpl_strdup | 716 | # define strdup rpl_strdup |
| 607 | # endif | 717 | # endif |
| 608 | _GL_FUNCDECL_RPL (strdup, char *, | 718 | _GL_FUNCDECL_RPL (strdup, char *, |
| 609 | (char const *__s) | 719 | (char const *__s), |
| 610 | _GL_ARG_NONNULL ((1)) | 720 | _GL_ARG_NONNULL ((1)) |
| 611 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 721 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 612 | _GL_CXXALIAS_RPL (strdup, char *, (char const *__s)); | 722 | _GL_CXXALIAS_RPL (strdup, char *, (char const *__s)); |
| @@ -621,16 +731,17 @@ _GL_CXXALIAS_MDA (strdup, char *, (char const *__s)); | |||
| 621 | /* strdup exists as a function and as a macro. Get rid of the macro. */ | 731 | /* strdup exists as a function and as a macro. Get rid of the macro. */ |
| 622 | # undef strdup | 732 | # undef strdup |
| 623 | # endif | 733 | # endif |
| 624 | # if (!@HAVE_DECL_STRDUP@ || __GNUC__ >= 11) && !defined strdup | 734 | # if (!@HAVE_DECL_STRDUP@ || (__GNUC__ >= 11 && !defined __clang__)) \ |
| 735 | && !defined strdup | ||
| 625 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 736 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 626 | _GL_FUNCDECL_SYS (strdup, char *, | 737 | _GL_FUNCDECL_SYS (strdup, char *, |
| 627 | (char const *__s) | 738 | (char const *__s), |
| 628 | _GL_ATTRIBUTE_NOTHROW | ||
| 629 | _GL_ARG_NONNULL ((1)) | 739 | _GL_ARG_NONNULL ((1)) |
| 630 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 740 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 741 | _GL_ATTRIBUTE_NOTHROW; | ||
| 631 | # else | 742 | # else |
| 632 | _GL_FUNCDECL_SYS (strdup, char *, | 743 | _GL_FUNCDECL_SYS (strdup, char *, |
| 633 | (char const *__s) | 744 | (char const *__s), |
| 634 | _GL_ARG_NONNULL ((1)) | 745 | _GL_ARG_NONNULL ((1)) |
| 635 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 746 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 636 | # endif | 747 | # endif |
| @@ -639,17 +750,17 @@ _GL_CXXALIAS_SYS (strdup, char *, (char const *__s)); | |||
| 639 | # endif | 750 | # endif |
| 640 | _GL_CXXALIASWARN (strdup); | 751 | _GL_CXXALIASWARN (strdup); |
| 641 | #else | 752 | #else |
| 642 | # if __GNUC__ >= 11 && !defined strdup | 753 | # if (__GNUC__ >= 11 && !defined __clang__) && !defined strdup |
| 643 | /* For -Wmismatched-dealloc: Associate strdup with free or rpl_free. */ | 754 | /* For -Wmismatched-dealloc: Associate strdup with free or rpl_free. */ |
| 644 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 755 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 645 | _GL_FUNCDECL_SYS (strdup, char *, | 756 | _GL_FUNCDECL_SYS (strdup, char *, |
| 646 | (char const *__s) | 757 | (char const *__s), |
| 647 | _GL_ATTRIBUTE_NOTHROW | ||
| 648 | _GL_ARG_NONNULL ((1)) | 758 | _GL_ARG_NONNULL ((1)) |
| 649 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 759 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 760 | _GL_ATTRIBUTE_NOTHROW; | ||
| 650 | # else | 761 | # else |
| 651 | _GL_FUNCDECL_SYS (strdup, char *, | 762 | _GL_FUNCDECL_SYS (strdup, char *, |
| 652 | (char const *__s) | 763 | (char const *__s), |
| 653 | _GL_ARG_NONNULL ((1)) | 764 | _GL_ARG_NONNULL ((1)) |
| 654 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 765 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 655 | # endif | 766 | # endif |
| @@ -688,8 +799,9 @@ _GL_CXXALIASWARN (strdup); | |||
| 688 | # define strncat rpl_strncat | 799 | # define strncat rpl_strncat |
| 689 | # endif | 800 | # endif |
| 690 | _GL_FUNCDECL_RPL (strncat, char *, | 801 | _GL_FUNCDECL_RPL (strncat, char *, |
| 691 | (char *restrict dest, const char *restrict src, size_t n) | 802 | (char *restrict dest, const char *restrict src, size_t n), |
| 692 | _GL_ARG_NONNULL ((1, 2))); | 803 | _GL_ARG_NONNULL ((1)) |
| 804 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 693 | _GL_CXXALIAS_RPL (strncat, char *, | 805 | _GL_CXXALIAS_RPL (strncat, char *, |
| 694 | (char *restrict dest, const char *restrict src, size_t n)); | 806 | (char *restrict dest, const char *restrict src, size_t n)); |
| 695 | # else | 807 | # else |
| @@ -707,6 +819,35 @@ _GL_WARN_ON_USE (strncat, "strncat is unportable - " | |||
| 707 | # endif | 819 | # endif |
| 708 | #endif | 820 | #endif |
| 709 | 821 | ||
| 822 | /* Copy no more than N bytes of SRC to DST, returning DST. */ | ||
| 823 | #if @GNULIB_STRNCPY@ | ||
| 824 | # if @REPLACE_STRNCPY@ | ||
| 825 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 826 | # undef strncpy | ||
| 827 | # define strncpy rpl_strncpy | ||
| 828 | # endif | ||
| 829 | _GL_FUNCDECL_RPL (strncpy, char *, | ||
| 830 | (char *restrict __dst, char const *restrict __src, | ||
| 831 | size_t __n), | ||
| 832 | _GL_ARG_NONNULL ((1, 2))); | ||
| 833 | _GL_CXXALIAS_RPL (strncpy, char *, | ||
| 834 | (char *restrict __dst, char const *restrict __src, | ||
| 835 | size_t __n)); | ||
| 836 | # else | ||
| 837 | _GL_CXXALIAS_SYS (strncpy, char *, | ||
| 838 | (char *restrict __dst, char const *restrict __src, | ||
| 839 | size_t __n)); | ||
| 840 | # endif | ||
| 841 | # if __GLIBC__ >= 2 | ||
| 842 | _GL_CXXALIASWARN (strncpy); | ||
| 843 | # endif | ||
| 844 | #elif defined GNULIB_POSIXCHECK | ||
| 845 | # if HAVE_RAW_DECL_STRNCPY | ||
| 846 | _GL_WARN_ON_USE (strncpy, "strncpy is unportable - " | ||
| 847 | "use gnulib module strncpy for portability"); | ||
| 848 | # endif | ||
| 849 | #endif | ||
| 850 | |||
| 710 | /* Return a newly allocated copy of at most N bytes of STRING. */ | 851 | /* Return a newly allocated copy of at most N bytes of STRING. */ |
| 711 | #if @GNULIB_STRNDUP@ | 852 | #if @GNULIB_STRNDUP@ |
| 712 | # if @REPLACE_STRNDUP@ | 853 | # if @REPLACE_STRNDUP@ |
| @@ -715,22 +856,23 @@ _GL_WARN_ON_USE (strncat, "strncat is unportable - " | |||
| 715 | # define strndup rpl_strndup | 856 | # define strndup rpl_strndup |
| 716 | # endif | 857 | # endif |
| 717 | _GL_FUNCDECL_RPL (strndup, char *, | 858 | _GL_FUNCDECL_RPL (strndup, char *, |
| 718 | (char const *__s, size_t __n) | 859 | (char const *__s, size_t __n), |
| 719 | _GL_ARG_NONNULL ((1)) | 860 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) |
| 720 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 861 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 721 | _GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n)); | 862 | _GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n)); |
| 722 | # else | 863 | # else |
| 723 | # if !@HAVE_DECL_STRNDUP@ || (__GNUC__ >= 11 && !defined strndup) | 864 | # if !@HAVE_DECL_STRNDUP@ \ |
| 865 | || ((__GNUC__ >= 11 && !defined __clang__) && !defined strndup) | ||
| 724 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 866 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 725 | _GL_FUNCDECL_SYS (strndup, char *, | 867 | _GL_FUNCDECL_SYS (strndup, char *, |
| 726 | (char const *__s, size_t __n) | 868 | (char const *__s, size_t __n), |
| 727 | _GL_ATTRIBUTE_NOTHROW | 869 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) |
| 728 | _GL_ARG_NONNULL ((1)) | 870 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 729 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 871 | _GL_ATTRIBUTE_NOTHROW; |
| 730 | # else | 872 | # else |
| 731 | _GL_FUNCDECL_SYS (strndup, char *, | 873 | _GL_FUNCDECL_SYS (strndup, char *, |
| 732 | (char const *__s, size_t __n) | 874 | (char const *__s, size_t __n), |
| 733 | _GL_ARG_NONNULL ((1)) | 875 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) |
| 734 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 876 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 735 | # endif | 877 | # endif |
| 736 | # endif | 878 | # endif |
| @@ -738,18 +880,18 @@ _GL_CXXALIAS_SYS (strndup, char *, (char const *__s, size_t __n)); | |||
| 738 | # endif | 880 | # endif |
| 739 | _GL_CXXALIASWARN (strndup); | 881 | _GL_CXXALIASWARN (strndup); |
| 740 | #else | 882 | #else |
| 741 | # if __GNUC__ >= 11 && !defined strndup | 883 | # if (__GNUC__ >= 11 && !defined __clang__) && !defined strndup |
| 742 | /* For -Wmismatched-dealloc: Associate strndup with free or rpl_free. */ | 884 | /* For -Wmismatched-dealloc: Associate strndup with free or rpl_free. */ |
| 743 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 885 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 744 | _GL_FUNCDECL_SYS (strndup, char *, | 886 | _GL_FUNCDECL_SYS (strndup, char *, |
| 745 | (char const *__s, size_t __n) | 887 | (char const *__s, size_t __n), |
| 746 | _GL_ATTRIBUTE_NOTHROW | 888 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) |
| 747 | _GL_ARG_NONNULL ((1)) | 889 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 748 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 890 | _GL_ATTRIBUTE_NOTHROW; |
| 749 | # else | 891 | # else |
| 750 | _GL_FUNCDECL_SYS (strndup, char *, | 892 | _GL_FUNCDECL_SYS (strndup, char *, |
| 751 | (char const *__s, size_t __n) | 893 | (char const *__s, size_t __n), |
| 752 | _GL_ARG_NONNULL ((1)) | 894 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 2) |
| 753 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 895 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 754 | # endif | 896 | # endif |
| 755 | # endif | 897 | # endif |
| @@ -771,13 +913,13 @@ _GL_WARN_ON_USE (strndup, "strndup is unportable - " | |||
| 771 | # undef strnlen | 913 | # undef strnlen |
| 772 | # define strnlen rpl_strnlen | 914 | # define strnlen rpl_strnlen |
| 773 | # endif | 915 | # endif |
| 774 | _GL_FUNCDECL_RPL (strnlen, size_t, (char const *__s, size_t __maxlen) | 916 | _GL_FUNCDECL_RPL (strnlen, size_t, (char const *__s, size_t __maxlen), |
| 775 | _GL_ATTRIBUTE_PURE | 917 | _GL_ATTRIBUTE_PURE |
| 776 | _GL_ARG_NONNULL ((1))); | 918 | _GL_ARG_NONNULL ((1))); |
| 777 | _GL_CXXALIAS_RPL (strnlen, size_t, (char const *__s, size_t __maxlen)); | 919 | _GL_CXXALIAS_RPL (strnlen, size_t, (char const *__s, size_t __maxlen)); |
| 778 | # else | 920 | # else |
| 779 | # if ! @HAVE_DECL_STRNLEN@ | 921 | # if ! @HAVE_DECL_STRNLEN@ |
| 780 | _GL_FUNCDECL_SYS (strnlen, size_t, (char const *__s, size_t __maxlen) | 922 | _GL_FUNCDECL_SYS (strnlen, size_t, (char const *__s, size_t __maxlen), |
| 781 | _GL_ATTRIBUTE_PURE | 923 | _GL_ATTRIBUTE_PURE |
| 782 | _GL_ARG_NONNULL ((1))); | 924 | _GL_ARG_NONNULL ((1))); |
| 783 | # endif | 925 | # endif |
| @@ -807,7 +949,7 @@ _GL_WARN_ON_USE (strcspn, "strcspn cannot work correctly on character strings " | |||
| 807 | /* Find the first occurrence in S of any character in ACCEPT. */ | 949 | /* Find the first occurrence in S of any character in ACCEPT. */ |
| 808 | #if @GNULIB_STRPBRK@ | 950 | #if @GNULIB_STRPBRK@ |
| 809 | # if ! @HAVE_STRPBRK@ | 951 | # if ! @HAVE_STRPBRK@ |
| 810 | _GL_FUNCDECL_SYS (strpbrk, char *, (char const *__s, char const *__accept) | 952 | _GL_FUNCDECL_SYS (strpbrk, char *, (char const *__s, char const *__accept), |
| 811 | _GL_ATTRIBUTE_PURE | 953 | _GL_ATTRIBUTE_PURE |
| 812 | _GL_ARG_NONNULL ((1, 2))); | 954 | _GL_ARG_NONNULL ((1, 2))); |
| 813 | # endif | 955 | # endif |
| @@ -892,7 +1034,7 @@ _GL_WARN_ON_USE_CXX (strrchr, | |||
| 892 | #if @GNULIB_STRSEP@ | 1034 | #if @GNULIB_STRSEP@ |
| 893 | # if ! @HAVE_STRSEP@ | 1035 | # if ! @HAVE_STRSEP@ |
| 894 | _GL_FUNCDECL_SYS (strsep, char *, | 1036 | _GL_FUNCDECL_SYS (strsep, char *, |
| 895 | (char **restrict __stringp, char const *restrict __delim) | 1037 | (char **restrict __stringp, char const *restrict __delim), |
| 896 | _GL_ARG_NONNULL ((1, 2))); | 1038 | _GL_ARG_NONNULL ((1, 2))); |
| 897 | # endif | 1039 | # endif |
| 898 | _GL_CXXALIAS_SYS (strsep, char *, | 1040 | _GL_CXXALIAS_SYS (strsep, char *, |
| @@ -917,7 +1059,7 @@ _GL_WARN_ON_USE (strsep, "strsep is unportable - " | |||
| 917 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1059 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 918 | # define strstr rpl_strstr | 1060 | # define strstr rpl_strstr |
| 919 | # endif | 1061 | # endif |
| 920 | _GL_FUNCDECL_RPL (strstr, char *, (const char *haystack, const char *needle) | 1062 | _GL_FUNCDECL_RPL (strstr, char *, (const char *haystack, const char *needle), |
| 921 | _GL_ATTRIBUTE_PURE | 1063 | _GL_ATTRIBUTE_PURE |
| 922 | _GL_ARG_NONNULL ((1, 2))); | 1064 | _GL_ARG_NONNULL ((1, 2))); |
| 923 | _GL_CXXALIAS_RPL (strstr, char *, (const char *haystack, const char *needle)); | 1065 | _GL_CXXALIAS_RPL (strstr, char *, (const char *haystack, const char *needle)); |
| @@ -948,11 +1090,13 @@ _GL_CXXALIASWARN (strstr); | |||
| 948 | as a sequence of bytes, not of characters. */ | 1090 | as a sequence of bytes, not of characters. */ |
| 949 | # undef strstr | 1091 | # undef strstr |
| 950 | /* Assume strstr is always declared. */ | 1092 | /* Assume strstr is always declared. */ |
| 951 | _GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and cannot " | 1093 | _GL_WARN_ON_USE_CXX (strstr, |
| 952 | "work correctly on character strings in most " | 1094 | const char *, char *, (const char *, const char *), |
| 953 | "multibyte locales - " | 1095 | "strstr is quadratic on many systems, and cannot " |
| 954 | "use mbsstr if you care about internationalization, " | 1096 | "work correctly on character strings in most " |
| 955 | "or use strstr if you care about speed"); | 1097 | "multibyte locales - " |
| 1098 | "use mbsstr if you care about internationalization, " | ||
| 1099 | "or use strstr if you care about speed"); | ||
| 956 | #endif | 1100 | #endif |
| 957 | 1101 | ||
| 958 | /* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive | 1102 | /* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive |
| @@ -963,7 +1107,7 @@ _GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and cannot " | |||
| 963 | # define strcasestr rpl_strcasestr | 1107 | # define strcasestr rpl_strcasestr |
| 964 | # endif | 1108 | # endif |
| 965 | _GL_FUNCDECL_RPL (strcasestr, char *, | 1109 | _GL_FUNCDECL_RPL (strcasestr, char *, |
| 966 | (const char *haystack, const char *needle) | 1110 | (const char *haystack, const char *needle), |
| 967 | _GL_ATTRIBUTE_PURE | 1111 | _GL_ATTRIBUTE_PURE |
| 968 | _GL_ARG_NONNULL ((1, 2))); | 1112 | _GL_ARG_NONNULL ((1, 2))); |
| 969 | _GL_CXXALIAS_RPL (strcasestr, char *, | 1113 | _GL_CXXALIAS_RPL (strcasestr, char *, |
| @@ -971,7 +1115,7 @@ _GL_CXXALIAS_RPL (strcasestr, char *, | |||
| 971 | # else | 1115 | # else |
| 972 | # if ! @HAVE_STRCASESTR@ | 1116 | # if ! @HAVE_STRCASESTR@ |
| 973 | _GL_FUNCDECL_SYS (strcasestr, char *, | 1117 | _GL_FUNCDECL_SYS (strcasestr, char *, |
| 974 | (const char *haystack, const char *needle) | 1118 | (const char *haystack, const char *needle), |
| 975 | _GL_ATTRIBUTE_PURE | 1119 | _GL_ATTRIBUTE_PURE |
| 976 | _GL_ARG_NONNULL ((1, 2))); | 1120 | _GL_ARG_NONNULL ((1, 2))); |
| 977 | # endif | 1121 | # endif |
| @@ -1038,7 +1182,7 @@ _GL_WARN_ON_USE (strcasestr, "strcasestr does work correctly on character " | |||
| 1038 | # endif | 1182 | # endif |
| 1039 | _GL_FUNCDECL_RPL (strtok_r, char *, | 1183 | _GL_FUNCDECL_RPL (strtok_r, char *, |
| 1040 | (char *restrict s, char const *restrict delim, | 1184 | (char *restrict s, char const *restrict delim, |
| 1041 | char **restrict save_ptr) | 1185 | char **restrict save_ptr), |
| 1042 | _GL_ARG_NONNULL ((2, 3))); | 1186 | _GL_ARG_NONNULL ((2, 3))); |
| 1043 | _GL_CXXALIAS_RPL (strtok_r, char *, | 1187 | _GL_CXXALIAS_RPL (strtok_r, char *, |
| 1044 | (char *restrict s, char const *restrict delim, | 1188 | (char *restrict s, char const *restrict delim, |
| @@ -1050,7 +1194,7 @@ _GL_CXXALIAS_RPL (strtok_r, char *, | |||
| 1050 | # if ! @HAVE_DECL_STRTOK_R@ | 1194 | # if ! @HAVE_DECL_STRTOK_R@ |
| 1051 | _GL_FUNCDECL_SYS (strtok_r, char *, | 1195 | _GL_FUNCDECL_SYS (strtok_r, char *, |
| 1052 | (char *restrict s, char const *restrict delim, | 1196 | (char *restrict s, char const *restrict delim, |
| 1053 | char **restrict save_ptr) | 1197 | char **restrict save_ptr), |
| 1054 | _GL_ARG_NONNULL ((2, 3))); | 1198 | _GL_ARG_NONNULL ((2, 3))); |
| 1055 | # endif | 1199 | # endif |
| 1056 | _GL_CXXALIAS_SYS (strtok_r, char *, | 1200 | _GL_CXXALIAS_SYS (strtok_r, char *, |
| @@ -1075,6 +1219,22 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " | |||
| 1075 | /* The following functions are not specified by POSIX. They are gnulib | 1219 | /* The following functions are not specified by POSIX. They are gnulib |
| 1076 | extensions. */ | 1220 | extensions. */ |
| 1077 | 1221 | ||
| 1222 | #if @GNULIB_STR_STARTSWITH@ | ||
| 1223 | /* Returns true if STRING starts with PREFIX. | ||
| 1224 | Returns false otherwise. */ | ||
| 1225 | _GL_EXTERN_C bool str_startswith (const char *string, const char *prefix) | ||
| 1226 | _GL_ATTRIBUTE_PURE | ||
| 1227 | _GL_ARG_NONNULL ((1, 2)); | ||
| 1228 | #endif | ||
| 1229 | |||
| 1230 | #if @GNULIB_STR_ENDSWITH@ | ||
| 1231 | /* Returns true if STRING ends with SUFFIX. | ||
| 1232 | Returns false otherwise. */ | ||
| 1233 | _GL_EXTERN_C bool str_endswith (const char *string, const char *prefix) | ||
| 1234 | _GL_ATTRIBUTE_PURE | ||
| 1235 | _GL_ARG_NONNULL ((1, 2)); | ||
| 1236 | #endif | ||
| 1237 | |||
| 1078 | #if @GNULIB_MBSLEN@ | 1238 | #if @GNULIB_MBSLEN@ |
| 1079 | /* Return the number of multibyte characters in the character string STRING. | 1239 | /* Return the number of multibyte characters in the character string STRING. |
| 1080 | This considers multibyte characters, unlike strlen, which counts bytes. */ | 1240 | This considers multibyte characters, unlike strlen, which counts bytes. */ |
| @@ -1085,12 +1245,12 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " | |||
| 1085 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1245 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1086 | # define mbslen rpl_mbslen | 1246 | # define mbslen rpl_mbslen |
| 1087 | # endif | 1247 | # endif |
| 1088 | _GL_FUNCDECL_RPL (mbslen, size_t, (const char *string) | 1248 | _GL_FUNCDECL_RPL (mbslen, size_t, (const char *string), |
| 1089 | _GL_ATTRIBUTE_PURE | 1249 | _GL_ATTRIBUTE_PURE |
| 1090 | _GL_ARG_NONNULL ((1))); | 1250 | _GL_ARG_NONNULL ((1))); |
| 1091 | _GL_CXXALIAS_RPL (mbslen, size_t, (const char *string)); | 1251 | _GL_CXXALIAS_RPL (mbslen, size_t, (const char *string)); |
| 1092 | # else | 1252 | # else |
| 1093 | _GL_FUNCDECL_SYS (mbslen, size_t, (const char *string) | 1253 | _GL_FUNCDECL_SYS (mbslen, size_t, (const char *string), |
| 1094 | _GL_ATTRIBUTE_PURE | 1254 | _GL_ATTRIBUTE_PURE |
| 1095 | _GL_ARG_NONNULL ((1))); | 1255 | _GL_ARG_NONNULL ((1))); |
| 1096 | _GL_CXXALIAS_SYS (mbslen, size_t, (const char *string)); | 1256 | _GL_CXXALIAS_SYS (mbslen, size_t, (const char *string)); |
| @@ -1117,12 +1277,12 @@ _GL_EXTERN_C size_t mbsnlen (const char *string, size_t len) | |||
| 1117 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1277 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1118 | # define mbschr rpl_mbschr /* avoid collision with HP-UX function */ | 1278 | # define mbschr rpl_mbschr /* avoid collision with HP-UX function */ |
| 1119 | # endif | 1279 | # endif |
| 1120 | _GL_FUNCDECL_RPL (mbschr, char *, (const char *string, int c) | 1280 | _GL_FUNCDECL_RPL (mbschr, char *, (const char *string, int c), |
| 1121 | _GL_ATTRIBUTE_PURE | 1281 | _GL_ATTRIBUTE_PURE |
| 1122 | _GL_ARG_NONNULL ((1))); | 1282 | _GL_ARG_NONNULL ((1))); |
| 1123 | _GL_CXXALIAS_RPL (mbschr, char *, (const char *string, int c)); | 1283 | _GL_CXXALIAS_RPL (mbschr, char *, (const char *string, int c)); |
| 1124 | # else | 1284 | # else |
| 1125 | _GL_FUNCDECL_SYS (mbschr, char *, (const char *string, int c) | 1285 | _GL_FUNCDECL_SYS (mbschr, char *, (const char *string, int c), |
| 1126 | _GL_ATTRIBUTE_PURE | 1286 | _GL_ATTRIBUTE_PURE |
| 1127 | _GL_ARG_NONNULL ((1))); | 1287 | _GL_ARG_NONNULL ((1))); |
| 1128 | _GL_CXXALIAS_SYS (mbschr, char *, (const char *string, int c)); | 1288 | _GL_CXXALIAS_SYS (mbschr, char *, (const char *string, int c)); |
| @@ -1139,12 +1299,12 @@ _GL_CXXALIASWARN (mbschr); | |||
| 1139 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1299 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1140 | # define mbsrchr rpl_mbsrchr /* avoid collision with system function */ | 1300 | # define mbsrchr rpl_mbsrchr /* avoid collision with system function */ |
| 1141 | # endif | 1301 | # endif |
| 1142 | _GL_FUNCDECL_RPL (mbsrchr, char *, (const char *string, int c) | 1302 | _GL_FUNCDECL_RPL (mbsrchr, char *, (const char *string, int c), |
| 1143 | _GL_ATTRIBUTE_PURE | 1303 | _GL_ATTRIBUTE_PURE |
| 1144 | _GL_ARG_NONNULL ((1))); | 1304 | _GL_ARG_NONNULL ((1))); |
| 1145 | _GL_CXXALIAS_RPL (mbsrchr, char *, (const char *string, int c)); | 1305 | _GL_CXXALIAS_RPL (mbsrchr, char *, (const char *string, int c)); |
| 1146 | # else | 1306 | # else |
| 1147 | _GL_FUNCDECL_SYS (mbsrchr, char *, (const char *string, int c) | 1307 | _GL_FUNCDECL_SYS (mbsrchr, char *, (const char *string, int c), |
| 1148 | _GL_ATTRIBUTE_PURE | 1308 | _GL_ATTRIBUTE_PURE |
| 1149 | _GL_ARG_NONNULL ((1))); | 1309 | _GL_ARG_NONNULL ((1))); |
| 1150 | _GL_CXXALIAS_SYS (mbsrchr, char *, (const char *string, int c)); | 1310 | _GL_CXXALIAS_SYS (mbsrchr, char *, (const char *string, int c)); |
| @@ -1160,6 +1320,33 @@ _GL_CXXALIASWARN (mbsrchr); | |||
| 1160 | _GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) | 1320 | _GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) |
| 1161 | _GL_ATTRIBUTE_PURE | 1321 | _GL_ATTRIBUTE_PURE |
| 1162 | _GL_ARG_NONNULL ((1, 2)); | 1322 | _GL_ARG_NONNULL ((1, 2)); |
| 1323 | # ifndef _GL_NO_CONST_GENERICS | ||
| 1324 | /* Don't silently convert a 'const char *' to a 'char *'. Programmers want | ||
| 1325 | compiler warnings for 'const' related mistakes. */ | ||
| 1326 | # ifdef __cplusplus | ||
| 1327 | extern "C++" { /* needed for AIX */ | ||
| 1328 | template <typename T> | ||
| 1329 | T * mbsstr_template (T* haystack, const char *needle); | ||
| 1330 | template <> | ||
| 1331 | inline char * mbsstr_template (char *haystack, const char *needle) | ||
| 1332 | { return mbsstr (haystack, needle); } | ||
| 1333 | template <> | ||
| 1334 | inline const char * mbsstr_template (const char *haystack, const char *needle) | ||
| 1335 | { return mbsstr (haystack, needle); } | ||
| 1336 | } | ||
| 1337 | # undef mbsstr | ||
| 1338 | # define mbsstr mbsstr_template | ||
| 1339 | # elif !defined mbsstr | ||
| 1340 | # if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ | ||
| 1341 | || defined __ICC || defined __TINYC__ \ | ||
| 1342 | || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__))) | ||
| 1343 | # define mbsstr(h,n) \ | ||
| 1344 | _Generic ((h), \ | ||
| 1345 | char const *: (char const *) mbsstr ((h), (n)), \ | ||
| 1346 | default : mbsstr ((h), (n))) | ||
| 1347 | # endif | ||
| 1348 | # endif | ||
| 1349 | # endif | ||
| 1163 | #endif | 1350 | #endif |
| 1164 | 1351 | ||
| 1165 | #if @GNULIB_MBSCASECMP@ | 1352 | #if @GNULIB_MBSCASECMP@ |
| @@ -1201,6 +1388,33 @@ _GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n) | |||
| 1201 | _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) | 1388 | _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) |
| 1202 | _GL_ATTRIBUTE_PURE | 1389 | _GL_ATTRIBUTE_PURE |
| 1203 | _GL_ARG_NONNULL ((1, 2)); | 1390 | _GL_ARG_NONNULL ((1, 2)); |
| 1391 | # ifndef _GL_NO_CONST_GENERICS | ||
| 1392 | /* Don't silently convert a 'const char *' to a 'char *'. Programmers want | ||
| 1393 | compiler warnings for 'const' related mistakes. */ | ||
| 1394 | # ifdef __cplusplus | ||
| 1395 | extern "C++" { /* needed for AIX */ | ||
| 1396 | template <typename T> | ||
| 1397 | T * mbspcasecmp_template (T* string, const char *prefix); | ||
| 1398 | template <> | ||
| 1399 | inline char * mbspcasecmp_template (char *string, const char *prefix) | ||
| 1400 | { return mbspcasecmp (string, prefix); } | ||
| 1401 | template <> | ||
| 1402 | inline const char * mbspcasecmp_template (const char *string, const char *prefix) | ||
| 1403 | { return mbspcasecmp (string, prefix); } | ||
| 1404 | } | ||
| 1405 | # undef mbspcasecmp | ||
| 1406 | # define mbspcasecmp mbspcasecmp_template | ||
| 1407 | # elif !defined mbspcasecmp | ||
| 1408 | # if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ | ||
| 1409 | || defined __ICC || defined __TINYC__ \ | ||
| 1410 | || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__))) | ||
| 1411 | # define mbspcasecmp(s,p) \ | ||
| 1412 | _Generic ((s), \ | ||
| 1413 | char const *: (char const *) mbspcasecmp ((s), (p)), \ | ||
| 1414 | default : mbspcasecmp ((s), (p))) | ||
| 1415 | # endif | ||
| 1416 | # endif | ||
| 1417 | # endif | ||
| 1204 | #endif | 1418 | #endif |
| 1205 | 1419 | ||
| 1206 | #if @GNULIB_MBSCASESTR@ | 1420 | #if @GNULIB_MBSCASESTR@ |
| @@ -1212,6 +1426,33 @@ _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) | |||
| 1212 | _GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) | 1426 | _GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) |
| 1213 | _GL_ATTRIBUTE_PURE | 1427 | _GL_ATTRIBUTE_PURE |
| 1214 | _GL_ARG_NONNULL ((1, 2)); | 1428 | _GL_ARG_NONNULL ((1, 2)); |
| 1429 | # ifndef _GL_NO_CONST_GENERICS | ||
| 1430 | /* Don't silently convert a 'const char *' to a 'char *'. Programmers want | ||
| 1431 | compiler warnings for 'const' related mistakes. */ | ||
| 1432 | # ifdef __cplusplus | ||
| 1433 | extern "C++" { /* needed for AIX */ | ||
| 1434 | template <typename T> | ||
| 1435 | T * mbscasestr_template (T* haystack, const char *needle); | ||
| 1436 | template <> | ||
| 1437 | inline char * mbscasestr_template (char *haystack, const char *needle) | ||
| 1438 | { return mbscasestr (haystack, needle); } | ||
| 1439 | template <> | ||
| 1440 | inline const char * mbscasestr_template (const char *haystack, const char *needle) | ||
| 1441 | { return mbscasestr (haystack, needle); } | ||
| 1442 | } | ||
| 1443 | # undef mbscasestr | ||
| 1444 | # define mbscasestr mbscasestr_template | ||
| 1445 | # elif !defined mbscasestr | ||
| 1446 | # if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ | ||
| 1447 | || defined __ICC || defined __TINYC__ \ | ||
| 1448 | || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__))) | ||
| 1449 | # define mbscasestr(h,n) \ | ||
| 1450 | _Generic ((h), \ | ||
| 1451 | char const *: (char const *) mbscasestr ((h), (n)), \ | ||
| 1452 | default : mbscasestr ((h), (n))) | ||
| 1453 | # endif | ||
| 1454 | # endif | ||
| 1455 | # endif | ||
| 1215 | #endif | 1456 | #endif |
| 1216 | 1457 | ||
| 1217 | #if @GNULIB_MBSCSPN@ | 1458 | #if @GNULIB_MBSCSPN@ |
| @@ -1234,12 +1475,12 @@ _GL_EXTERN_C size_t mbscspn (const char *string, const char *accept) | |||
| 1234 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1475 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1235 | # define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */ | 1476 | # define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */ |
| 1236 | # endif | 1477 | # endif |
| 1237 | _GL_FUNCDECL_RPL (mbspbrk, char *, (const char *string, const char *accept) | 1478 | _GL_FUNCDECL_RPL (mbspbrk, char *, (const char *string, const char *accept), |
| 1238 | _GL_ATTRIBUTE_PURE | 1479 | _GL_ATTRIBUTE_PURE |
| 1239 | _GL_ARG_NONNULL ((1, 2))); | 1480 | _GL_ARG_NONNULL ((1, 2))); |
| 1240 | _GL_CXXALIAS_RPL (mbspbrk, char *, (const char *string, const char *accept)); | 1481 | _GL_CXXALIAS_RPL (mbspbrk, char *, (const char *string, const char *accept)); |
| 1241 | # else | 1482 | # else |
| 1242 | _GL_FUNCDECL_SYS (mbspbrk, char *, (const char *string, const char *accept) | 1483 | _GL_FUNCDECL_SYS (mbspbrk, char *, (const char *string, const char *accept), |
| 1243 | _GL_ATTRIBUTE_PURE | 1484 | _GL_ATTRIBUTE_PURE |
| 1244 | _GL_ARG_NONNULL ((1, 2))); | 1485 | _GL_ARG_NONNULL ((1, 2))); |
| 1245 | _GL_CXXALIAS_SYS (mbspbrk, char *, (const char *string, const char *accept)); | 1486 | _GL_CXXALIAS_SYS (mbspbrk, char *, (const char *string, const char *accept)); |
| @@ -1299,6 +1540,26 @@ _GL_EXTERN_C char * mbstok_r (char *restrict string, const char *delim, | |||
| 1299 | _GL_ARG_NONNULL ((2, 3)); | 1540 | _GL_ARG_NONNULL ((2, 3)); |
| 1300 | #endif | 1541 | #endif |
| 1301 | 1542 | ||
| 1543 | #if @GNULIB_MBS_STARTSWITH@ | ||
| 1544 | /* Returns true if STRING starts with PREFIX. | ||
| 1545 | Returns false otherwise. */ | ||
| 1546 | _GL_EXTERN_C bool mbs_startswith (const char *string, const char *prefix) | ||
| 1547 | _GL_ATTRIBUTE_PURE | ||
| 1548 | _GL_ARG_NONNULL ((1, 2)); | ||
| 1549 | /* No extra code is needed for multibyte locales for this function. */ | ||
| 1550 | # define mbs_startswith str_startswith | ||
| 1551 | #endif | ||
| 1552 | |||
| 1553 | #if @GNULIB_MBS_ENDSWITH@ | ||
| 1554 | /* Returns true if STRING ends with SUFFIX. | ||
| 1555 | Returns false otherwise. | ||
| 1556 | Unlike str_endswith(), this function works correctly in multibyte locales. | ||
| 1557 | */ | ||
| 1558 | _GL_EXTERN_C bool mbs_endswith (const char *string, const char *suffix) | ||
| 1559 | _GL_ATTRIBUTE_PURE | ||
| 1560 | _GL_ARG_NONNULL ((1, 2)); | ||
| 1561 | #endif | ||
| 1562 | |||
| 1302 | /* Map any int, typically from errno, into an error message. */ | 1563 | /* Map any int, typically from errno, into an error message. */ |
| 1303 | #if @GNULIB_STRERROR@ | 1564 | #if @GNULIB_STRERROR@ |
| 1304 | # if @REPLACE_STRERROR@ | 1565 | # if @REPLACE_STRERROR@ |
| @@ -1306,7 +1567,7 @@ _GL_EXTERN_C char * mbstok_r (char *restrict string, const char *delim, | |||
| 1306 | # undef strerror | 1567 | # undef strerror |
| 1307 | # define strerror rpl_strerror | 1568 | # define strerror rpl_strerror |
| 1308 | # endif | 1569 | # endif |
| 1309 | _GL_FUNCDECL_RPL (strerror, char *, (int)); | 1570 | _GL_FUNCDECL_RPL (strerror, char *, (int), ); |
| 1310 | _GL_CXXALIAS_RPL (strerror, char *, (int)); | 1571 | _GL_CXXALIAS_RPL (strerror, char *, (int)); |
| 1311 | # else | 1572 | # else |
| 1312 | _GL_CXXALIAS_SYS (strerror, char *, (int)); | 1573 | _GL_CXXALIAS_SYS (strerror, char *, (int)); |
| @@ -1329,12 +1590,12 @@ _GL_WARN_ON_USE (strerror, "strerror is unportable - " | |||
| 1329 | # undef strerror_r | 1590 | # undef strerror_r |
| 1330 | # define strerror_r rpl_strerror_r | 1591 | # define strerror_r rpl_strerror_r |
| 1331 | # endif | 1592 | # endif |
| 1332 | _GL_FUNCDECL_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen) | 1593 | _GL_FUNCDECL_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen), |
| 1333 | _GL_ARG_NONNULL ((2))); | 1594 | _GL_ARG_NONNULL ((2))); |
| 1334 | _GL_CXXALIAS_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen)); | 1595 | _GL_CXXALIAS_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen)); |
| 1335 | # else | 1596 | # else |
| 1336 | # if !@HAVE_DECL_STRERROR_R@ | 1597 | # if !@HAVE_DECL_STRERROR_R@ |
| 1337 | _GL_FUNCDECL_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen) | 1598 | _GL_FUNCDECL_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen), |
| 1338 | _GL_ARG_NONNULL ((2))); | 1599 | _GL_ARG_NONNULL ((2))); |
| 1339 | # endif | 1600 | # endif |
| 1340 | _GL_CXXALIAS_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen)); | 1601 | _GL_CXXALIAS_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen)); |
| @@ -1350,6 +1611,44 @@ _GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - " | |||
| 1350 | # endif | 1611 | # endif |
| 1351 | #endif | 1612 | #endif |
| 1352 | 1613 | ||
| 1614 | /* Map any int, typically from errno, into an error message. | ||
| 1615 | With locale_t argument. */ | ||
| 1616 | #if @GNULIB_STRERROR_L@ | ||
| 1617 | # if @REPLACE_STRERROR_L@ | ||
| 1618 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1619 | # undef strerror_l | ||
| 1620 | # define strerror_l rpl_strerror_l | ||
| 1621 | # endif | ||
| 1622 | _GL_FUNCDECL_RPL (strerror_l, char *, (int errnum, locale_t locale), | ||
| 1623 | _GL_ARG_NONNULL ((2))); | ||
| 1624 | _GL_CXXALIAS_RPL (strerror_l, char *, (int errnum, locale_t locale)); | ||
| 1625 | # else | ||
| 1626 | # if !@HAVE_STRERROR_L@ | ||
| 1627 | _GL_FUNCDECL_SYS (strerror_l, char *, (int errnum, locale_t locale), | ||
| 1628 | _GL_ARG_NONNULL ((2))); | ||
| 1629 | # endif | ||
| 1630 | _GL_CXXALIAS_SYS (strerror_l, char *, (int errnum, locale_t locale)); | ||
| 1631 | # endif | ||
| 1632 | # if __GLIBC__ >= 2 | ||
| 1633 | _GL_CXXALIASWARN (strerror_l); | ||
| 1634 | # endif | ||
| 1635 | #elif defined GNULIB_POSIXCHECK | ||
| 1636 | # undef strerror_l | ||
| 1637 | # if HAVE_RAW_DECL_STRERROR_L | ||
| 1638 | _GL_WARN_ON_USE (strerror_l, "strerror_l is unportable - " | ||
| 1639 | "use gnulib module strerror_l for portability"); | ||
| 1640 | # endif | ||
| 1641 | #endif | ||
| 1642 | |||
| 1643 | /* Map any int, typically from errno, into an error message. Multithread-safe, | ||
| 1644 | with locale_t argument. | ||
| 1645 | Not portable! Only provided by gnulib. */ | ||
| 1646 | #if @GNULIB_STRERROR_L@ | ||
| 1647 | _GL_FUNCDECL_SYS (strerror_l_r, int, | ||
| 1648 | (int errnum, char *buf, size_t buflen, locale_t locale), | ||
| 1649 | _GL_ARG_NONNULL ((2, 4))); | ||
| 1650 | #endif | ||
| 1651 | |||
| 1353 | /* Return the name of the system error code ERRNUM. */ | 1652 | /* Return the name of the system error code ERRNUM. */ |
| 1354 | #if @GNULIB_STRERRORNAME_NP@ | 1653 | #if @GNULIB_STRERRORNAME_NP@ |
| 1355 | # if @REPLACE_STRERRORNAME_NP@ | 1654 | # if @REPLACE_STRERRORNAME_NP@ |
| @@ -1357,15 +1656,17 @@ _GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - " | |||
| 1357 | # undef strerrorname_np | 1656 | # undef strerrorname_np |
| 1358 | # define strerrorname_np rpl_strerrorname_np | 1657 | # define strerrorname_np rpl_strerrorname_np |
| 1359 | # endif | 1658 | # endif |
| 1360 | _GL_FUNCDECL_RPL (strerrorname_np, const char *, (int errnum)); | 1659 | _GL_FUNCDECL_RPL (strerrorname_np, const char *, (int errnum), ); |
| 1361 | _GL_CXXALIAS_RPL (strerrorname_np, const char *, (int errnum)); | 1660 | _GL_CXXALIAS_RPL (strerrorname_np, const char *, (int errnum)); |
| 1362 | # else | 1661 | # else |
| 1363 | # if !@HAVE_STRERRORNAME_NP@ | 1662 | # if !@HAVE_STRERRORNAME_NP@ |
| 1364 | _GL_FUNCDECL_SYS (strerrorname_np, const char *, (int errnum)); | 1663 | _GL_FUNCDECL_SYS (strerrorname_np, const char *, (int errnum), ); |
| 1365 | # endif | 1664 | # endif |
| 1366 | _GL_CXXALIAS_SYS (strerrorname_np, const char *, (int errnum)); | 1665 | _GL_CXXALIAS_SYS (strerrorname_np, const char *, (int errnum)); |
| 1367 | # endif | 1666 | # endif |
| 1667 | # if __GLIBC__ >= 2 | ||
| 1368 | _GL_CXXALIASWARN (strerrorname_np); | 1668 | _GL_CXXALIASWARN (strerrorname_np); |
| 1669 | # endif | ||
| 1369 | #elif defined GNULIB_POSIXCHECK | 1670 | #elif defined GNULIB_POSIXCHECK |
| 1370 | # undef strerrorname_np | 1671 | # undef strerrorname_np |
| 1371 | # if HAVE_RAW_DECL_STRERRORNAME_NP | 1672 | # if HAVE_RAW_DECL_STRERRORNAME_NP |
| @@ -1377,7 +1678,7 @@ _GL_WARN_ON_USE (strerrorname_np, "strerrorname_np is unportable - " | |||
| 1377 | /* Return an abbreviation string for the signal number SIG. */ | 1678 | /* Return an abbreviation string for the signal number SIG. */ |
| 1378 | #if @GNULIB_SIGABBREV_NP@ | 1679 | #if @GNULIB_SIGABBREV_NP@ |
| 1379 | # if ! @HAVE_SIGABBREV_NP@ | 1680 | # if ! @HAVE_SIGABBREV_NP@ |
| 1380 | _GL_FUNCDECL_SYS (sigabbrev_np, const char *, (int sig)); | 1681 | _GL_FUNCDECL_SYS (sigabbrev_np, const char *, (int sig), ); |
| 1381 | # endif | 1682 | # endif |
| 1382 | _GL_CXXALIAS_SYS (sigabbrev_np, const char *, (int sig)); | 1683 | _GL_CXXALIAS_SYS (sigabbrev_np, const char *, (int sig)); |
| 1383 | _GL_CXXALIASWARN (sigabbrev_np); | 1684 | _GL_CXXALIASWARN (sigabbrev_np); |
| @@ -1392,7 +1693,7 @@ _GL_WARN_ON_USE (sigabbrev_np, "sigabbrev_np is unportable - " | |||
| 1392 | /* Return an English description string for the signal number SIG. */ | 1693 | /* Return an English description string for the signal number SIG. */ |
| 1393 | #if @GNULIB_SIGDESCR_NP@ | 1694 | #if @GNULIB_SIGDESCR_NP@ |
| 1394 | # if ! @HAVE_SIGDESCR_NP@ | 1695 | # if ! @HAVE_SIGDESCR_NP@ |
| 1395 | _GL_FUNCDECL_SYS (sigdescr_np, const char *, (int sig)); | 1696 | _GL_FUNCDECL_SYS (sigdescr_np, const char *, (int sig), ); |
| 1396 | # endif | 1697 | # endif |
| 1397 | _GL_CXXALIAS_SYS (sigdescr_np, const char *, (int sig)); | 1698 | _GL_CXXALIAS_SYS (sigdescr_np, const char *, (int sig)); |
| 1398 | _GL_CXXALIASWARN (sigdescr_np); | 1699 | _GL_CXXALIASWARN (sigdescr_np); |
| @@ -1409,11 +1710,11 @@ _GL_WARN_ON_USE (sigdescr_np, "sigdescr_np is unportable - " | |||
| 1409 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1710 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1410 | # define strsignal rpl_strsignal | 1711 | # define strsignal rpl_strsignal |
| 1411 | # endif | 1712 | # endif |
| 1412 | _GL_FUNCDECL_RPL (strsignal, char *, (int __sig)); | 1713 | _GL_FUNCDECL_RPL (strsignal, char *, (int __sig), ); |
| 1413 | _GL_CXXALIAS_RPL (strsignal, char *, (int __sig)); | 1714 | _GL_CXXALIAS_RPL (strsignal, char *, (int __sig)); |
| 1414 | # else | 1715 | # else |
| 1415 | # if ! @HAVE_DECL_STRSIGNAL@ | 1716 | # if ! @HAVE_DECL_STRSIGNAL@ |
| 1416 | _GL_FUNCDECL_SYS (strsignal, char *, (int __sig)); | 1717 | _GL_FUNCDECL_SYS (strsignal, char *, (int __sig), ); |
| 1417 | # endif | 1718 | # endif |
| 1418 | /* Need to cast, because on Cygwin 1.5.x systems, the return type is | 1719 | /* Need to cast, because on Cygwin 1.5.x systems, the return type is |
| 1419 | 'const char *'. */ | 1720 | 'const char *'. */ |
| @@ -1433,13 +1734,13 @@ _GL_WARN_ON_USE (strsignal, "strsignal is unportable - " | |||
| 1433 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1734 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1434 | # define strverscmp rpl_strverscmp | 1735 | # define strverscmp rpl_strverscmp |
| 1435 | # endif | 1736 | # endif |
| 1436 | _GL_FUNCDECL_RPL (strverscmp, int, (const char *, const char *) | 1737 | _GL_FUNCDECL_RPL (strverscmp, int, (const char *, const char *), |
| 1437 | _GL_ATTRIBUTE_PURE | 1738 | _GL_ATTRIBUTE_PURE |
| 1438 | _GL_ARG_NONNULL ((1, 2))); | 1739 | _GL_ARG_NONNULL ((1, 2))); |
| 1439 | _GL_CXXALIAS_RPL (strverscmp, int, (const char *, const char *)); | 1740 | _GL_CXXALIAS_RPL (strverscmp, int, (const char *, const char *)); |
| 1440 | # else | 1741 | # else |
| 1441 | # if !@HAVE_STRVERSCMP@ | 1742 | # if !@HAVE_STRVERSCMP@ |
| 1442 | _GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *) | 1743 | _GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *), |
| 1443 | _GL_ATTRIBUTE_PURE | 1744 | _GL_ATTRIBUTE_PURE |
| 1444 | _GL_ARG_NONNULL ((1, 2))); | 1745 | _GL_ARG_NONNULL ((1, 2))); |
| 1445 | # endif | 1746 | # endif |
diff --git a/gl/strings.in.h b/gl/strings.in.h index 2b3e062a..40c891d7 100644 --- a/gl/strings.in.h +++ b/gl/strings.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A substitute <strings.h>. | 1 | /* A substitute <strings.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -36,7 +36,7 @@ | |||
| 36 | #ifndef _@GUARD_PREFIX@_STRINGS_H | 36 | #ifndef _@GUARD_PREFIX@_STRINGS_H |
| 37 | #define _@GUARD_PREFIX@_STRINGS_H | 37 | #define _@GUARD_PREFIX@_STRINGS_H |
| 38 | 38 | ||
| 39 | /* This file uses GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ | 39 | /* This file uses _GL_ARG_NONNULL, GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ |
| 40 | #if !_GL_CONFIG_H_INCLUDED | 40 | #if !_GL_CONFIG_H_INCLUDED |
| 41 | #error "Please include config.h first." | 41 | #error "Please include config.h first." |
| 42 | #endif | 42 | #endif |
| @@ -46,6 +46,16 @@ | |||
| 46 | # include <stddef.h> | 46 | # include <stddef.h> |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #if @GNULIB_STRCASECMP_L@ || @GNULIB_STRNCASECMP_L@ | ||
| 50 | /* Get locale_t. */ | ||
| 51 | # include <locale.h> | ||
| 52 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ < 10) \ | ||
| 53 | || (defined __APPLE__ && defined __MACH__)) | ||
| 54 | /* Get the declaration of strcasecmp_l. */ | ||
| 55 | # include <string.h> | ||
| 56 | # endif | ||
| 57 | #endif | ||
| 58 | |||
| 49 | 59 | ||
| 50 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | 60 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ |
| 51 | 61 | ||
| @@ -58,10 +68,10 @@ extern "C" { | |||
| 58 | #endif | 68 | #endif |
| 59 | 69 | ||
| 60 | 70 | ||
| 61 | /* Find the index of the least-significant set bit. */ | ||
| 62 | #if @GNULIB_FFS@ | 71 | #if @GNULIB_FFS@ |
| 72 | /* Find the index of the least-significant set bit. */ | ||
| 63 | # if !@HAVE_FFS@ | 73 | # if !@HAVE_FFS@ |
| 64 | _GL_FUNCDECL_SYS (ffs, int, (int i)); | 74 | _GL_FUNCDECL_SYS (ffs, int, (int i), ); |
| 65 | # endif | 75 | # endif |
| 66 | _GL_CXXALIAS_SYS (ffs, int, (int i)); | 76 | _GL_CXXALIAS_SYS (ffs, int, (int i)); |
| 67 | _GL_CXXALIASWARN (ffs); | 77 | _GL_CXXALIASWARN (ffs); |
| @@ -72,52 +82,152 @@ _GL_WARN_ON_USE (ffs, "ffs is not portable - use the ffs module"); | |||
| 72 | # endif | 82 | # endif |
| 73 | #endif | 83 | #endif |
| 74 | 84 | ||
| 85 | #if @GNULIB_STRCASECMP@ | ||
| 75 | /* Compare strings S1 and S2, ignoring case, returning less than, equal to or | 86 | /* Compare strings S1 and S2, ignoring case, returning less than, equal to or |
| 76 | greater than zero if S1 is lexicographically less than, equal to or greater | 87 | greater than zero if S1 is lexicographically less than, equal to or greater |
| 77 | than S2. | 88 | than S2. |
| 78 | Note: This function does not work in multibyte locales. */ | 89 | Note: This function does not work in multibyte locales. */ |
| 79 | #if ! @HAVE_STRCASECMP@ | 90 | # if @REPLACE_STRCASECMP@ |
| 80 | extern int strcasecmp (char const *s1, char const *s2) | 91 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 81 | _GL_ARG_NONNULL ((1, 2)); | 92 | # undef strcasecmp |
| 82 | #endif | 93 | # define strcasecmp rpl_strcasecmp |
| 83 | #if defined GNULIB_POSIXCHECK | 94 | # endif |
| 95 | _GL_FUNCDECL_RPL (strcasecmp, int, (const char *, const char *), | ||
| 96 | _GL_ARG_NONNULL ((1, 2))); | ||
| 97 | _GL_CXXALIAS_RPL (strcasecmp, int, (const char *, const char *)); | ||
| 98 | # else | ||
| 99 | # if !@HAVE_STRCASECMP@ | ||
| 100 | _GL_FUNCDECL_SYS (strcasecmp, int, (const char *, const char *), | ||
| 101 | _GL_ARG_NONNULL ((1, 2))); | ||
| 102 | # endif | ||
| 103 | _GL_CXXALIAS_SYS (strcasecmp, int, (const char *, const char *)); | ||
| 104 | # endif | ||
| 105 | # if __GLIBC__ >= 2 | ||
| 106 | _GL_CXXALIASWARN (strcasecmp); | ||
| 107 | # endif | ||
| 108 | #elif defined GNULIB_POSIXCHECK | ||
| 84 | /* strcasecmp() does not work with multibyte strings: | 109 | /* strcasecmp() does not work with multibyte strings: |
| 85 | POSIX says that it operates on "strings", and "string" in POSIX is defined | 110 | POSIX says that it operates on "strings", and "string" in POSIX is defined |
| 86 | as a sequence of bytes, not of characters. */ | 111 | as a sequence of bytes, not of characters. */ |
| 87 | # undef strcasecmp | 112 | # undef strcasecmp |
| 88 | # if HAVE_RAW_DECL_STRCASECMP | 113 | # if HAVE_RAW_DECL_STRCASECMP |
| 89 | _GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character " | 114 | _GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character " |
| 90 | "strings in multibyte locales - " | 115 | "strings in multibyte locales and is unportable - " |
| 91 | "use mbscasecmp if you care about " | 116 | "use mbscasecmp if you care about " |
| 92 | "internationalization, or use c_strcasecmp , " | 117 | "internationalization, or use c_strcasecmp " |
| 93 | "gnulib module c-strcase) if you want a locale " | 118 | "(gnulib module c-strcasecmp) if you want a locale " |
| 94 | "independent function"); | 119 | "independent function"); |
| 95 | # endif | 120 | # endif |
| 96 | #endif | 121 | #endif |
| 97 | 122 | ||
| 123 | #if @GNULIB_STRCASECMP_L@ | ||
| 124 | # if @REPLACE_STRCASECMP_L@ | ||
| 125 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 126 | # undef strcasecmp_l | ||
| 127 | # define strcasecmp_l rpl_strcasecmp_l | ||
| 128 | # endif | ||
| 129 | _GL_FUNCDECL_RPL (strcasecmp_l, int, | ||
| 130 | (const char *s1, const char *s2, locale_t locale), | ||
| 131 | _GL_ARG_NONNULL ((1, 2, 3))); | ||
| 132 | _GL_CXXALIAS_RPL (strcasecmp_l, int, | ||
| 133 | (const char *s1, const char *s2, locale_t locale)); | ||
| 134 | # else | ||
| 135 | # if !@HAVE_STRCASECMP_L@ | ||
| 136 | _GL_FUNCDECL_SYS (strcasecmp_l, int, | ||
| 137 | (const char *s1, const char *s2, locale_t locale), | ||
| 138 | _GL_ARG_NONNULL ((1, 2, 3))); | ||
| 139 | # endif | ||
| 140 | _GL_CXXALIAS_SYS (strcasecmp_l, int, | ||
| 141 | (const char *s1, const char *s2, locale_t locale)); | ||
| 142 | # endif | ||
| 143 | # if __GLIBC__ >= 2 | ||
| 144 | _GL_CXXALIASWARN (strcasecmp_l); | ||
| 145 | # endif | ||
| 146 | #elif defined GNULIB_POSIXCHECK | ||
| 147 | /* strcasecmp_l() does not work with multibyte strings: | ||
| 148 | POSIX says that it operates on "strings", and "string" in POSIX is defined | ||
| 149 | as a sequence of bytes, not of characters. */ | ||
| 150 | # undef strcasecmp_l | ||
| 151 | # if HAVE_RAW_DECL_STRCASECMP_L | ||
| 152 | _GL_WARN_ON_USE (strcasecmp_l, "strcasecmp_l cannot work correctly on " | ||
| 153 | "character strings in multibyte locales and is unportable - " | ||
| 154 | "use gnulib module strcasecmp_l for portability"); | ||
| 155 | # endif | ||
| 156 | #endif | ||
| 157 | |||
| 158 | #if @GNULIB_STRNCASECMP@ | ||
| 98 | /* Compare no more than N bytes of strings S1 and S2, ignoring case, | 159 | /* Compare no more than N bytes of strings S1 and S2, ignoring case, |
| 99 | returning less than, equal to or greater than zero if S1 is | 160 | returning less than, equal to or greater than zero if S1 is |
| 100 | lexicographically less than, equal to or greater than S2. | 161 | lexicographically less than, equal to or greater than S2. |
| 101 | Note: This function cannot work correctly in multibyte locales. */ | 162 | Note: This function cannot work correctly in multibyte locales. */ |
| 102 | #if ! @HAVE_DECL_STRNCASECMP@ | 163 | # if @REPLACE_STRNCASECMP@ |
| 103 | extern int strncasecmp (char const *s1, char const *s2, size_t n) | 164 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 104 | _GL_ARG_NONNULL ((1, 2)); | 165 | # undef strncasecmp |
| 105 | #endif | 166 | # define strncasecmp rpl_strncasecmp |
| 106 | #if defined GNULIB_POSIXCHECK | 167 | # endif |
| 168 | _GL_FUNCDECL_RPL (strncasecmp, int, (const char *, const char *, size_t), | ||
| 169 | _GL_ARG_NONNULL ((1, 2))); | ||
| 170 | _GL_CXXALIAS_RPL (strncasecmp, int, (const char *, const char *, size_t)); | ||
| 171 | # else | ||
| 172 | # if !@HAVE_DECL_STRNCASECMP@ | ||
| 173 | _GL_FUNCDECL_SYS (strncasecmp, int, (const char *, const char *, size_t), | ||
| 174 | _GL_ARG_NONNULL ((1, 2))); | ||
| 175 | # endif | ||
| 176 | _GL_CXXALIAS_SYS (strncasecmp, int, (const char *, const char *, size_t)); | ||
| 177 | # endif | ||
| 178 | # if __GLIBC__ >= 2 | ||
| 179 | _GL_CXXALIASWARN (strncasecmp); | ||
| 180 | # endif | ||
| 181 | #elif defined GNULIB_POSIXCHECK | ||
| 107 | /* strncasecmp() does not work with multibyte strings: | 182 | /* strncasecmp() does not work with multibyte strings: |
| 108 | POSIX says that it operates on "strings", and "string" in POSIX is defined | 183 | POSIX says that it operates on "strings", and "string" in POSIX is defined |
| 109 | as a sequence of bytes, not of characters. */ | 184 | as a sequence of bytes, not of characters. */ |
| 110 | # undef strncasecmp | 185 | # undef strncasecmp |
| 111 | # if HAVE_RAW_DECL_STRNCASECMP | 186 | # if HAVE_RAW_DECL_STRNCASECMP |
| 112 | _GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character " | 187 | _GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character " |
| 113 | "strings in multibyte locales - " | 188 | "strings in multibyte locales and is unportable - " |
| 114 | "use mbsncasecmp or mbspcasecmp if you care about " | 189 | "use mbsncasecmp or mbspcasecmp if you care about " |
| 115 | "internationalization, or use c_strncasecmp , " | 190 | "internationalization, or use c_strncasecmp " |
| 116 | "gnulib module c-strcase) if you want a locale " | 191 | "(gnulib module c-strncasecmp) if you want a locale " |
| 117 | "independent function"); | 192 | "independent function"); |
| 118 | # endif | 193 | # endif |
| 119 | #endif | 194 | #endif |
| 120 | 195 | ||
| 196 | #if @GNULIB_STRNCASECMP_L@ | ||
| 197 | # if @REPLACE_STRNCASECMP_L@ | ||
| 198 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 199 | # undef strncasecmp_l | ||
| 200 | # define strncasecmp_l rpl_strncasecmp_l | ||
| 201 | # endif | ||
| 202 | _GL_FUNCDECL_RPL (strncasecmp_l, int, | ||
| 203 | (const char *s1, const char *s2, size_t n, locale_t locale), | ||
| 204 | _GL_ARG_NONNULL ((1, 2, 4))); | ||
| 205 | _GL_CXXALIAS_RPL (strncasecmp_l, int, | ||
| 206 | (const char *s1, const char *s2, size_t n, locale_t locale)); | ||
| 207 | # else | ||
| 208 | # if !@HAVE_STRNCASECMP_L@ | ||
| 209 | _GL_FUNCDECL_SYS (strncasecmp_l, int, | ||
| 210 | (const char *s1, const char *s2, size_t n, locale_t locale), | ||
| 211 | _GL_ARG_NONNULL ((1, 2, 4))); | ||
| 212 | # endif | ||
| 213 | _GL_CXXALIAS_SYS (strncasecmp_l, int, | ||
| 214 | (const char *s1, const char *s2, size_t n, locale_t locale)); | ||
| 215 | # endif | ||
| 216 | # if __GLIBC__ >= 2 | ||
| 217 | _GL_CXXALIASWARN (strncasecmp_l); | ||
| 218 | # endif | ||
| 219 | #elif defined GNULIB_POSIXCHECK | ||
| 220 | /* strncasecmp_l() does not work with multibyte strings: | ||
| 221 | POSIX says that it operates on "strings", and "string" in POSIX is defined | ||
| 222 | as a sequence of bytes, not of characters. */ | ||
| 223 | # undef strncasecmp_l | ||
| 224 | # if HAVE_RAW_DECL_STRNCASECMP_L | ||
| 225 | _GL_WARN_ON_USE (strncasecmp_l, "strncasecmp_l cannot work correctly on " | ||
| 226 | "character strings in multibyte locales and is unportable - " | ||
| 227 | "use gnulib module strncasecmp_l for portability"); | ||
| 228 | # endif | ||
| 229 | #endif | ||
| 230 | |||
| 121 | 231 | ||
| 122 | #ifdef __cplusplus | 232 | #ifdef __cplusplus |
| 123 | } | 233 | } |
diff --git a/gl/stripslash.c b/gl/stripslash.c index c127ce7e..d5b07bca 100644 --- a/gl/stripslash.c +++ b/gl/stripslash.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* stripslash.c -- remove redundant trailing slashes from a file name | 1 | /* stripslash.c -- remove redundant trailing slashes from a file name |
| 2 | 2 | ||
| 3 | Copyright (C) 1990, 2001, 2003-2006, 2009-2024 Free Software Foundation, | 3 | Copyright (C) 1990, 2001, 2003-2006, 2009-2025 Free Software Foundation, |
| 4 | Inc. | 4 | Inc. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/strncasecmp.c b/gl/strncasecmp.c index c79161f3..7d7c5b7f 100644 --- a/gl/strncasecmp.c +++ b/gl/strncasecmp.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* strncasecmp.c -- case insensitive string comparator | 1 | /* Case-insensitive string comparison function for unibyte locales. |
| 2 | Copyright (C) 1998-1999, 2005-2007, 2009-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1998-1999, 2005-2007, 2009-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <config.h> | 17 | #include <config.h> |
| 18 | 18 | ||
| 19 | /* Specification. */ | 19 | /* Specification. */ |
| 20 | #include <string.h> | 20 | #include <strings.h> |
| 21 | 21 | ||
| 22 | #include <ctype.h> | 22 | #include <ctype.h> |
| 23 | #include <limits.h> | 23 | #include <limits.h> |
diff --git a/gl/strncpy.c b/gl/strncpy.c new file mode 100644 index 00000000..1b680046 --- /dev/null +++ b/gl/strncpy.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* Copy a size-bounded string. | ||
| 2 | Copyright (C) 1999, 2011-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation, either version 3 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, 1999. */ | ||
| 18 | |||
| 19 | #include <config.h> | ||
| 20 | |||
| 21 | /* Specification. */ | ||
| 22 | #include <string.h> | ||
| 23 | |||
| 24 | char * | ||
| 25 | strncpy (char *dest, const char *src, size_t n) | ||
| 26 | { | ||
| 27 | char *destptr = dest; | ||
| 28 | |||
| 29 | for (; n > 0 && (*destptr = *src) != '\0'; src++, destptr++, n--) | ||
| 30 | ; | ||
| 31 | |||
| 32 | /* This behavior is rarely useful, but it is specified by the ISO C | ||
| 33 | standard. */ | ||
| 34 | for (; n > 0; n--) | ||
| 35 | *destptr++ = '\0'; | ||
| 36 | |||
| 37 | return dest; | ||
| 38 | } | ||
diff --git a/gl/strsep.c b/gl/strsep.c index eefd85e2..5a489d11 100644 --- a/gl/strsep.c +++ b/gl/strsep.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 2004, 2007, 2009-2024 Free Software Foundation, Inc. | 1 | /* Copyright (C) 2004, 2007, 2009-2025 Free Software Foundation, Inc. |
| 2 | 2 | ||
| 3 | Written by Yoann Vandoorselaere <yoann@prelude-ids.org>. | 3 | Written by Yoann Vandoorselaere <yoann@prelude-ids.org>. |
| 4 | 4 | ||
diff --git a/gl/strstr.c b/gl/strstr.c index 7ea28603..d6953f90 100644 --- a/gl/strstr.c +++ b/gl/strstr.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 1991-1994, 1996-1998, 2000, 2004, 2007-2024 Free Software | 1 | /* Copyright (C) 1991-1994, 1996-1998, 2000, 2004, 2007-2025 Free Software |
| 2 | Foundation, Inc. | 2 | Foundation, Inc. |
| 3 | This file is part of the GNU C Library. | 3 | This file is part of the GNU C Library. |
| 4 | 4 | ||
diff --git a/gl/sys-limits.h b/gl/sys-limits.h index d2f29d80..a556dfeb 100644 --- a/gl/sys-limits.h +++ b/gl/sys-limits.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* System call limits | 1 | /* System call limits |
| 2 | 2 | ||
| 3 | Copyright 2018-2024 Free Software Foundation, Inc. | 3 | Copyright 2018-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/sys_socket.c b/gl/sys_socket.c index 672d3aac..efd36610 100644 --- a/gl/sys_socket.c +++ b/gl/sys_socket.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Inline functions for <sys/socket.h>. | 1 | /* Inline functions for <sys/socket.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2012-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -15,8 +15,8 @@ | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | 15 | You should have received a copy of the GNU Lesser General Public License |
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
| 17 | 17 | ||
| 18 | #define _GL_SYS_SOCKET_INLINE _GL_EXTERN_INLINE | ||
| 18 | #include <config.h> | 19 | #include <config.h> |
| 19 | 20 | ||
| 20 | #define _GL_SYS_SOCKET_INLINE _GL_EXTERN_INLINE | ||
| 21 | #include <sys/socket.h> | 21 | #include <sys/socket.h> |
| 22 | typedef int dummy; | 22 | typedef int dummy; |
diff --git a/gl/sys_socket.in.h b/gl/sys_socket.in.h index 13833c0f..8632c66d 100644 --- a/gl/sys_socket.in.h +++ b/gl/sys_socket.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Provide a sys/socket header file for systems lacking it (read: MinGW) | 1 | /* Provide a sys/socket header file for systems lacking it (read: MinGW) |
| 2 | and for systems where it is incomplete. | 2 | and for systems where it is incomplete. |
| 3 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 4 | Written by Simon Josefsson. | 4 | Written by Simon Josefsson. |
| 5 | 5 | ||
| 6 | This file is free software: you can redistribute it and/or modify | 6 | This file is free software: you can redistribute it and/or modify |
| @@ -27,7 +27,7 @@ | |||
| 27 | #endif | 27 | #endif |
| 28 | @PRAGMA_COLUMNS@ | 28 | @PRAGMA_COLUMNS@ |
| 29 | 29 | ||
| 30 | #if defined _GL_ALREADY_INCLUDING_SYS_SOCKET_H | 30 | #if defined _@GUARD_PREFIX@_ALREADY_INCLUDING_SYS_SOCKET_H |
| 31 | /* Special invocation convention: | 31 | /* Special invocation convention: |
| 32 | - On Cygwin 1.5.x we have a sequence of nested includes | 32 | - On Cygwin 1.5.x we have a sequence of nested includes |
| 33 | <sys/socket.h> -> <cygwin/socket.h> -> <asm/socket.h> -> <cygwin/if.h>, | 33 | <sys/socket.h> -> <cygwin/socket.h> -> <asm/socket.h> -> <cygwin/if.h>, |
| @@ -43,7 +43,7 @@ | |||
| 43 | 43 | ||
| 44 | #if @HAVE_SYS_SOCKET_H@ | 44 | #if @HAVE_SYS_SOCKET_H@ |
| 45 | 45 | ||
| 46 | # define _GL_ALREADY_INCLUDING_SYS_SOCKET_H | 46 | # define _@GUARD_PREFIX@_ALREADY_INCLUDING_SYS_SOCKET_H |
| 47 | 47 | ||
| 48 | /* On many platforms, <sys/socket.h> assumes prior inclusion of | 48 | /* On many platforms, <sys/socket.h> assumes prior inclusion of |
| 49 | <sys/types.h>. */ | 49 | <sys/types.h>. */ |
| @@ -56,7 +56,7 @@ | |||
| 56 | /* The include_next requires a split double-inclusion guard. */ | 56 | /* The include_next requires a split double-inclusion guard. */ |
| 57 | # @INCLUDE_NEXT@ @NEXT_SYS_SOCKET_H@ | 57 | # @INCLUDE_NEXT@ @NEXT_SYS_SOCKET_H@ |
| 58 | 58 | ||
| 59 | # undef _GL_ALREADY_INCLUDING_SYS_SOCKET_H | 59 | # undef _@GUARD_PREFIX@_ALREADY_INCLUDING_SYS_SOCKET_H |
| 60 | 60 | ||
| 61 | #endif | 61 | #endif |
| 62 | 62 | ||
| @@ -202,6 +202,7 @@ struct sockaddr_storage | |||
| 202 | 202 | ||
| 203 | /* Rudimentary 'struct msghdr'; this works as long as you don't try to | 203 | /* Rudimentary 'struct msghdr'; this works as long as you don't try to |
| 204 | access msg_control or msg_controllen. */ | 204 | access msg_control or msg_controllen. */ |
| 205 | # if !defined GNULIB_defined_struct_msghdr | ||
| 205 | struct msghdr { | 206 | struct msghdr { |
| 206 | void *msg_name; | 207 | void *msg_name; |
| 207 | socklen_t msg_namelen; | 208 | socklen_t msg_namelen; |
| @@ -209,6 +210,8 @@ struct msghdr { | |||
| 209 | int msg_iovlen; | 210 | int msg_iovlen; |
| 210 | int msg_flags; | 211 | int msg_flags; |
| 211 | }; | 212 | }; |
| 213 | # define GNULIB_defined_struct_msghdr 1 | ||
| 214 | # endif | ||
| 212 | 215 | ||
| 213 | #endif | 216 | #endif |
| 214 | 217 | ||
| @@ -289,15 +292,17 @@ rpl_fd_isset (SOCKET fd, fd_set * set) | |||
| 289 | # undef socket | 292 | # undef socket |
| 290 | # define socket rpl_socket | 293 | # define socket rpl_socket |
| 291 | # endif | 294 | # endif |
| 292 | _GL_FUNCDECL_RPL (socket, int, (int domain, int type, int protocol)); | 295 | _GL_FUNCDECL_RPL (socket, int, (int domain, int type, int protocol), ); |
| 293 | _GL_CXXALIAS_RPL (socket, int, (int domain, int type, int protocol)); | 296 | _GL_CXXALIAS_RPL (socket, int, (int domain, int type, int protocol)); |
| 294 | # else | 297 | # else |
| 295 | _GL_CXXALIAS_SYS (socket, int, (int domain, int type, int protocol)); | 298 | _GL_CXXALIAS_SYS (socket, int, (int domain, int type, int protocol)); |
| 296 | # endif | 299 | # endif |
| 297 | _GL_CXXALIASWARN (socket); | 300 | _GL_CXXALIASWARN (socket); |
| 298 | #elif @HAVE_WINSOCK2_H@ | 301 | #elif @HAVE_WINSOCK2_H@ |
| 299 | # undef socket | 302 | # if !GNULIB_SOCKET |
| 300 | # define socket socket_used_without_requesting_gnulib_module_socket | 303 | # undef socket |
| 304 | # define socket socket_used_without_requesting_gnulib_module_socket | ||
| 305 | # endif | ||
| 301 | #elif defined GNULIB_POSIXCHECK | 306 | #elif defined GNULIB_POSIXCHECK |
| 302 | # undef socket | 307 | # undef socket |
| 303 | # if HAVE_RAW_DECL_SOCKET | 308 | # if HAVE_RAW_DECL_SOCKET |
| @@ -313,7 +318,7 @@ _GL_WARN_ON_USE (socket, "socket is not always POSIX compliant - " | |||
| 313 | # define connect rpl_connect | 318 | # define connect rpl_connect |
| 314 | # endif | 319 | # endif |
| 315 | _GL_FUNCDECL_RPL (connect, int, | 320 | _GL_FUNCDECL_RPL (connect, int, |
| 316 | (int fd, const struct sockaddr *addr, socklen_t addrlen) | 321 | (int fd, const struct sockaddr *addr, socklen_t addrlen), |
| 317 | _GL_ARG_NONNULL ((2))); | 322 | _GL_ARG_NONNULL ((2))); |
| 318 | _GL_CXXALIAS_RPL (connect, int, | 323 | _GL_CXXALIAS_RPL (connect, int, |
| 319 | (int fd, const struct sockaddr *addr, socklen_t addrlen)); | 324 | (int fd, const struct sockaddr *addr, socklen_t addrlen)); |
| @@ -326,8 +331,10 @@ _GL_CXXALIAS_SYS_CAST (connect, int, | |||
| 326 | # endif | 331 | # endif |
| 327 | _GL_CXXALIASWARN (connect); | 332 | _GL_CXXALIASWARN (connect); |
| 328 | #elif @HAVE_WINSOCK2_H@ | 333 | #elif @HAVE_WINSOCK2_H@ |
| 329 | # undef connect | 334 | # if !GNULIB_CONNECT |
| 330 | # define connect socket_used_without_requesting_gnulib_module_connect | 335 | # undef connect |
| 336 | # define connect connect_used_without_requesting_gnulib_module_connect | ||
| 337 | # endif | ||
| 331 | #elif defined GNULIB_POSIXCHECK | 338 | #elif defined GNULIB_POSIXCHECK |
| 332 | # undef connect | 339 | # undef connect |
| 333 | # if HAVE_RAW_DECL_CONNECT | 340 | # if HAVE_RAW_DECL_CONNECT |
| @@ -345,7 +352,7 @@ _GL_WARN_ON_USE (connect, "connect is not always POSIX compliant - " | |||
| 345 | _GL_FUNCDECL_RPL (accept, int, | 352 | _GL_FUNCDECL_RPL (accept, int, |
| 346 | (int fd, | 353 | (int fd, |
| 347 | struct sockaddr *restrict addr, | 354 | struct sockaddr *restrict addr, |
| 348 | socklen_t *restrict addrlen)); | 355 | socklen_t *restrict addrlen), ); |
| 349 | _GL_CXXALIAS_RPL (accept, int, | 356 | _GL_CXXALIAS_RPL (accept, int, |
| 350 | (int fd, | 357 | (int fd, |
| 351 | struct sockaddr *restrict addr, | 358 | struct sockaddr *restrict addr, |
| @@ -362,8 +369,10 @@ _GL_CXXALIAS_SYS_CAST (accept, int, | |||
| 362 | _GL_CXXALIASWARN (accept); | 369 | _GL_CXXALIASWARN (accept); |
| 363 | # endif | 370 | # endif |
| 364 | #elif @HAVE_WINSOCK2_H@ | 371 | #elif @HAVE_WINSOCK2_H@ |
| 365 | # undef accept | 372 | # if !GNULIB_ACCEPT |
| 366 | # define accept accept_used_without_requesting_gnulib_module_accept | 373 | # undef accept |
| 374 | # define accept accept_used_without_requesting_gnulib_module_accept | ||
| 375 | # endif | ||
| 367 | #elif defined GNULIB_POSIXCHECK | 376 | #elif defined GNULIB_POSIXCHECK |
| 368 | # undef accept | 377 | # undef accept |
| 369 | # if HAVE_RAW_DECL_ACCEPT | 378 | # if HAVE_RAW_DECL_ACCEPT |
| @@ -379,7 +388,7 @@ _GL_WARN_ON_USE (accept, "accept is not always POSIX compliant - " | |||
| 379 | # define bind rpl_bind | 388 | # define bind rpl_bind |
| 380 | # endif | 389 | # endif |
| 381 | _GL_FUNCDECL_RPL (bind, int, | 390 | _GL_FUNCDECL_RPL (bind, int, |
| 382 | (int fd, const struct sockaddr *addr, socklen_t addrlen) | 391 | (int fd, const struct sockaddr *addr, socklen_t addrlen), |
| 383 | _GL_ARG_NONNULL ((2))); | 392 | _GL_ARG_NONNULL ((2))); |
| 384 | _GL_CXXALIAS_RPL (bind, int, | 393 | _GL_CXXALIAS_RPL (bind, int, |
| 385 | (int fd, const struct sockaddr *addr, socklen_t addrlen)); | 394 | (int fd, const struct sockaddr *addr, socklen_t addrlen)); |
| @@ -392,8 +401,10 @@ _GL_CXXALIAS_SYS_CAST (bind, int, | |||
| 392 | # endif | 401 | # endif |
| 393 | _GL_CXXALIASWARN (bind); | 402 | _GL_CXXALIASWARN (bind); |
| 394 | #elif @HAVE_WINSOCK2_H@ | 403 | #elif @HAVE_WINSOCK2_H@ |
| 395 | # undef bind | 404 | # if !GNULIB_BIND |
| 396 | # define bind bind_used_without_requesting_gnulib_module_bind | 405 | # undef bind |
| 406 | # define bind bind_used_without_requesting_gnulib_module_bind | ||
| 407 | # endif | ||
| 397 | #elif defined GNULIB_POSIXCHECK | 408 | #elif defined GNULIB_POSIXCHECK |
| 398 | # undef bind | 409 | # undef bind |
| 399 | # if HAVE_RAW_DECL_BIND | 410 | # if HAVE_RAW_DECL_BIND |
| @@ -410,7 +421,7 @@ _GL_WARN_ON_USE (bind, "bind is not always POSIX compliant - " | |||
| 410 | # endif | 421 | # endif |
| 411 | _GL_FUNCDECL_RPL (getpeername, int, | 422 | _GL_FUNCDECL_RPL (getpeername, int, |
| 412 | (int fd, struct sockaddr *restrict addr, | 423 | (int fd, struct sockaddr *restrict addr, |
| 413 | socklen_t *restrict addrlen) | 424 | socklen_t *restrict addrlen), |
| 414 | _GL_ARG_NONNULL ((2, 3))); | 425 | _GL_ARG_NONNULL ((2, 3))); |
| 415 | _GL_CXXALIAS_RPL (getpeername, int, | 426 | _GL_CXXALIAS_RPL (getpeername, int, |
| 416 | (int fd, struct sockaddr *restrict addr, | 427 | (int fd, struct sockaddr *restrict addr, |
| @@ -426,8 +437,10 @@ _GL_CXXALIAS_SYS_CAST (getpeername, int, | |||
| 426 | _GL_CXXALIASWARN (getpeername); | 437 | _GL_CXXALIASWARN (getpeername); |
| 427 | # endif | 438 | # endif |
| 428 | #elif @HAVE_WINSOCK2_H@ | 439 | #elif @HAVE_WINSOCK2_H@ |
| 429 | # undef getpeername | 440 | # if !GNULIB_GETPEERNAME |
| 430 | # define getpeername getpeername_used_without_requesting_gnulib_module_getpeername | 441 | # undef getpeername |
| 442 | # define getpeername getpeername_used_without_requesting_gnulib_module_getpeername | ||
| 443 | # endif | ||
| 431 | #elif defined GNULIB_POSIXCHECK | 444 | #elif defined GNULIB_POSIXCHECK |
| 432 | # undef getpeername | 445 | # undef getpeername |
| 433 | # if HAVE_RAW_DECL_GETPEERNAME | 446 | # if HAVE_RAW_DECL_GETPEERNAME |
| @@ -444,7 +457,7 @@ _GL_WARN_ON_USE (getpeername, "getpeername is not always POSIX compliant - " | |||
| 444 | # endif | 457 | # endif |
| 445 | _GL_FUNCDECL_RPL (getsockname, int, | 458 | _GL_FUNCDECL_RPL (getsockname, int, |
| 446 | (int fd, struct sockaddr *restrict addr, | 459 | (int fd, struct sockaddr *restrict addr, |
| 447 | socklen_t *restrict addrlen) | 460 | socklen_t *restrict addrlen), |
| 448 | _GL_ARG_NONNULL ((2, 3))); | 461 | _GL_ARG_NONNULL ((2, 3))); |
| 449 | _GL_CXXALIAS_RPL (getsockname, int, | 462 | _GL_CXXALIAS_RPL (getsockname, int, |
| 450 | (int fd, struct sockaddr *restrict addr, | 463 | (int fd, struct sockaddr *restrict addr, |
| @@ -460,8 +473,10 @@ _GL_CXXALIAS_SYS_CAST (getsockname, int, | |||
| 460 | _GL_CXXALIASWARN (getsockname); | 473 | _GL_CXXALIASWARN (getsockname); |
| 461 | # endif | 474 | # endif |
| 462 | #elif @HAVE_WINSOCK2_H@ | 475 | #elif @HAVE_WINSOCK2_H@ |
| 463 | # undef getsockname | 476 | # if !GNULIB_GETSOCKNAME |
| 464 | # define getsockname getsockname_used_without_requesting_gnulib_module_getsockname | 477 | # undef getsockname |
| 478 | # define getsockname getsockname_used_without_requesting_gnulib_module_getsockname | ||
| 479 | # endif | ||
| 465 | #elif defined GNULIB_POSIXCHECK | 480 | #elif defined GNULIB_POSIXCHECK |
| 466 | # undef getsockname | 481 | # undef getsockname |
| 467 | # if HAVE_RAW_DECL_GETSOCKNAME | 482 | # if HAVE_RAW_DECL_GETSOCKNAME |
| @@ -478,7 +493,7 @@ _GL_WARN_ON_USE (getsockname, "getsockname is not always POSIX compliant - " | |||
| 478 | # endif | 493 | # endif |
| 479 | _GL_FUNCDECL_RPL (getsockopt, int, | 494 | _GL_FUNCDECL_RPL (getsockopt, int, |
| 480 | (int fd, int level, int optname, | 495 | (int fd, int level, int optname, |
| 481 | void *restrict optval, socklen_t *restrict optlen) | 496 | void *restrict optval, socklen_t *restrict optlen), |
| 482 | _GL_ARG_NONNULL ((4, 5))); | 497 | _GL_ARG_NONNULL ((4, 5))); |
| 483 | _GL_CXXALIAS_RPL (getsockopt, int, | 498 | _GL_CXXALIAS_RPL (getsockopt, int, |
| 484 | (int fd, int level, int optname, | 499 | (int fd, int level, int optname, |
| @@ -492,8 +507,10 @@ _GL_CXXALIAS_SYS_CAST (getsockopt, int, | |||
| 492 | # endif | 507 | # endif |
| 493 | _GL_CXXALIASWARN (getsockopt); | 508 | _GL_CXXALIASWARN (getsockopt); |
| 494 | #elif @HAVE_WINSOCK2_H@ | 509 | #elif @HAVE_WINSOCK2_H@ |
| 495 | # undef getsockopt | 510 | # if !GNULIB_GETSOCKOPT |
| 496 | # define getsockopt getsockopt_used_without_requesting_gnulib_module_getsockopt | 511 | # undef getsockopt |
| 512 | # define getsockopt getsockopt_used_without_requesting_gnulib_module_getsockopt | ||
| 513 | # endif | ||
| 497 | #elif defined GNULIB_POSIXCHECK | 514 | #elif defined GNULIB_POSIXCHECK |
| 498 | # undef getsockopt | 515 | # undef getsockopt |
| 499 | # if HAVE_RAW_DECL_GETSOCKOPT | 516 | # if HAVE_RAW_DECL_GETSOCKOPT |
| @@ -508,15 +525,17 @@ _GL_WARN_ON_USE (getsockopt, "getsockopt is not always POSIX compliant - " | |||
| 508 | # undef listen | 525 | # undef listen |
| 509 | # define listen rpl_listen | 526 | # define listen rpl_listen |
| 510 | # endif | 527 | # endif |
| 511 | _GL_FUNCDECL_RPL (listen, int, (int fd, int backlog)); | 528 | _GL_FUNCDECL_RPL (listen, int, (int fd, int backlog), ); |
| 512 | _GL_CXXALIAS_RPL (listen, int, (int fd, int backlog)); | 529 | _GL_CXXALIAS_RPL (listen, int, (int fd, int backlog)); |
| 513 | # else | 530 | # else |
| 514 | _GL_CXXALIAS_SYS (listen, int, (int fd, int backlog)); | 531 | _GL_CXXALIAS_SYS (listen, int, (int fd, int backlog)); |
| 515 | # endif | 532 | # endif |
| 516 | _GL_CXXALIASWARN (listen); | 533 | _GL_CXXALIASWARN (listen); |
| 517 | #elif @HAVE_WINSOCK2_H@ | 534 | #elif @HAVE_WINSOCK2_H@ |
| 518 | # undef listen | 535 | # if !GNULIB_LISTEN |
| 519 | # define listen listen_used_without_requesting_gnulib_module_listen | 536 | # undef listen |
| 537 | # define listen listen_used_without_requesting_gnulib_module_listen | ||
| 538 | # endif | ||
| 520 | #elif defined GNULIB_POSIXCHECK | 539 | #elif defined GNULIB_POSIXCHECK |
| 521 | # undef listen | 540 | # undef listen |
| 522 | # if HAVE_RAW_DECL_LISTEN | 541 | # if HAVE_RAW_DECL_LISTEN |
| @@ -531,7 +550,7 @@ _GL_WARN_ON_USE (listen, "listen is not always POSIX compliant - " | |||
| 531 | # undef recv | 550 | # undef recv |
| 532 | # define recv rpl_recv | 551 | # define recv rpl_recv |
| 533 | # endif | 552 | # endif |
| 534 | _GL_FUNCDECL_RPL (recv, ssize_t, (int fd, void *buf, size_t len, int flags) | 553 | _GL_FUNCDECL_RPL (recv, ssize_t, (int fd, void *buf, size_t len, int flags), |
| 535 | _GL_ARG_NONNULL ((2))); | 554 | _GL_ARG_NONNULL ((2))); |
| 536 | _GL_CXXALIAS_RPL (recv, ssize_t, (int fd, void *buf, size_t len, int flags)); | 555 | _GL_CXXALIAS_RPL (recv, ssize_t, (int fd, void *buf, size_t len, int flags)); |
| 537 | # else | 556 | # else |
| @@ -542,8 +561,10 @@ _GL_CXXALIAS_SYS_CAST (recv, ssize_t, (int fd, void *buf, size_t len, int flags) | |||
| 542 | # endif | 561 | # endif |
| 543 | _GL_CXXALIASWARN (recv); | 562 | _GL_CXXALIASWARN (recv); |
| 544 | #elif @HAVE_WINSOCK2_H@ | 563 | #elif @HAVE_WINSOCK2_H@ |
| 545 | # undef recv | 564 | # if !GNULIB_RECV |
| 546 | # define recv recv_used_without_requesting_gnulib_module_recv | 565 | # undef recv |
| 566 | # define recv recv_used_without_requesting_gnulib_module_recv | ||
| 567 | # endif | ||
| 547 | #elif defined GNULIB_POSIXCHECK | 568 | #elif defined GNULIB_POSIXCHECK |
| 548 | # undef recv | 569 | # undef recv |
| 549 | # if HAVE_RAW_DECL_RECV | 570 | # if HAVE_RAW_DECL_RECV |
| @@ -559,7 +580,7 @@ _GL_WARN_ON_USE (recv, "recv is not always POSIX compliant - " | |||
| 559 | # define send rpl_send | 580 | # define send rpl_send |
| 560 | # endif | 581 | # endif |
| 561 | _GL_FUNCDECL_RPL (send, ssize_t, | 582 | _GL_FUNCDECL_RPL (send, ssize_t, |
| 562 | (int fd, const void *buf, size_t len, int flags) | 583 | (int fd, const void *buf, size_t len, int flags), |
| 563 | _GL_ARG_NONNULL ((2))); | 584 | _GL_ARG_NONNULL ((2))); |
| 564 | _GL_CXXALIAS_RPL (send, ssize_t, | 585 | _GL_CXXALIAS_RPL (send, ssize_t, |
| 565 | (int fd, const void *buf, size_t len, int flags)); | 586 | (int fd, const void *buf, size_t len, int flags)); |
| @@ -572,8 +593,10 @@ _GL_CXXALIAS_SYS_CAST (send, ssize_t, | |||
| 572 | # endif | 593 | # endif |
| 573 | _GL_CXXALIASWARN (send); | 594 | _GL_CXXALIASWARN (send); |
| 574 | #elif @HAVE_WINSOCK2_H@ | 595 | #elif @HAVE_WINSOCK2_H@ |
| 575 | # undef send | 596 | # if !GNULIB_SEND |
| 576 | # define send send_used_without_requesting_gnulib_module_send | 597 | # undef send |
| 598 | # define send send_used_without_requesting_gnulib_module_send | ||
| 599 | # endif | ||
| 577 | #elif defined GNULIB_POSIXCHECK | 600 | #elif defined GNULIB_POSIXCHECK |
| 578 | # undef send | 601 | # undef send |
| 579 | # if HAVE_RAW_DECL_SEND | 602 | # if HAVE_RAW_DECL_SEND |
| @@ -591,7 +614,7 @@ _GL_WARN_ON_USE (send, "send is not always POSIX compliant - " | |||
| 591 | _GL_FUNCDECL_RPL (recvfrom, ssize_t, | 614 | _GL_FUNCDECL_RPL (recvfrom, ssize_t, |
| 592 | (int fd, void *restrict buf, size_t len, int flags, | 615 | (int fd, void *restrict buf, size_t len, int flags, |
| 593 | struct sockaddr *restrict from, | 616 | struct sockaddr *restrict from, |
| 594 | socklen_t *restrict fromlen) | 617 | socklen_t *restrict fromlen), |
| 595 | _GL_ARG_NONNULL ((2))); | 618 | _GL_ARG_NONNULL ((2))); |
| 596 | _GL_CXXALIAS_RPL (recvfrom, ssize_t, | 619 | _GL_CXXALIAS_RPL (recvfrom, ssize_t, |
| 597 | (int fd, void *restrict buf, size_t len, int flags, | 620 | (int fd, void *restrict buf, size_t len, int flags, |
| @@ -609,8 +632,10 @@ _GL_CXXALIAS_SYS_CAST (recvfrom, ssize_t, | |||
| 609 | _GL_CXXALIASWARN (recvfrom); | 632 | _GL_CXXALIASWARN (recvfrom); |
| 610 | # endif | 633 | # endif |
| 611 | #elif @HAVE_WINSOCK2_H@ | 634 | #elif @HAVE_WINSOCK2_H@ |
| 612 | # undef recvfrom | 635 | # if !GNULIB_RECVFROM |
| 613 | # define recvfrom recvfrom_used_without_requesting_gnulib_module_recvfrom | 636 | # undef recvfrom |
| 637 | # define recvfrom recvfrom_used_without_requesting_gnulib_module_recvfrom | ||
| 638 | # endif | ||
| 614 | #elif defined GNULIB_POSIXCHECK | 639 | #elif defined GNULIB_POSIXCHECK |
| 615 | # undef recvfrom | 640 | # undef recvfrom |
| 616 | # if HAVE_RAW_DECL_RECVFROM | 641 | # if HAVE_RAW_DECL_RECVFROM |
| @@ -627,7 +652,7 @@ _GL_WARN_ON_USE (recvfrom, "recvfrom is not always POSIX compliant - " | |||
| 627 | # endif | 652 | # endif |
| 628 | _GL_FUNCDECL_RPL (sendto, ssize_t, | 653 | _GL_FUNCDECL_RPL (sendto, ssize_t, |
| 629 | (int fd, const void *buf, size_t len, int flags, | 654 | (int fd, const void *buf, size_t len, int flags, |
| 630 | const struct sockaddr *to, socklen_t tolen) | 655 | const struct sockaddr *to, socklen_t tolen), |
| 631 | _GL_ARG_NONNULL ((2))); | 656 | _GL_ARG_NONNULL ((2))); |
| 632 | _GL_CXXALIAS_RPL (sendto, ssize_t, | 657 | _GL_CXXALIAS_RPL (sendto, ssize_t, |
| 633 | (int fd, const void *buf, size_t len, int flags, | 658 | (int fd, const void *buf, size_t len, int flags, |
| @@ -641,8 +666,10 @@ _GL_CXXALIAS_SYS_CAST (sendto, ssize_t, | |||
| 641 | # endif | 666 | # endif |
| 642 | _GL_CXXALIASWARN (sendto); | 667 | _GL_CXXALIASWARN (sendto); |
| 643 | #elif @HAVE_WINSOCK2_H@ | 668 | #elif @HAVE_WINSOCK2_H@ |
| 644 | # undef sendto | 669 | # if !GNULIB_SENDTO |
| 645 | # define sendto sendto_used_without_requesting_gnulib_module_sendto | 670 | # undef sendto |
| 671 | # define sendto sendto_used_without_requesting_gnulib_module_sendto | ||
| 672 | # endif | ||
| 646 | #elif defined GNULIB_POSIXCHECK | 673 | #elif defined GNULIB_POSIXCHECK |
| 647 | # undef sendto | 674 | # undef sendto |
| 648 | # if HAVE_RAW_DECL_SENDTO | 675 | # if HAVE_RAW_DECL_SENDTO |
| @@ -658,7 +685,7 @@ _GL_WARN_ON_USE (sendto, "sendto is not always POSIX compliant - " | |||
| 658 | # define setsockopt rpl_setsockopt | 685 | # define setsockopt rpl_setsockopt |
| 659 | # endif | 686 | # endif |
| 660 | _GL_FUNCDECL_RPL (setsockopt, int, (int fd, int level, int optname, | 687 | _GL_FUNCDECL_RPL (setsockopt, int, (int fd, int level, int optname, |
| 661 | const void * optval, socklen_t optlen) | 688 | const void * optval, socklen_t optlen), |
| 662 | _GL_ARG_NONNULL ((4))); | 689 | _GL_ARG_NONNULL ((4))); |
| 663 | _GL_CXXALIAS_RPL (setsockopt, int, (int fd, int level, int optname, | 690 | _GL_CXXALIAS_RPL (setsockopt, int, (int fd, int level, int optname, |
| 664 | const void * optval, socklen_t optlen)); | 691 | const void * optval, socklen_t optlen)); |
| @@ -671,8 +698,10 @@ _GL_CXXALIAS_SYS_CAST (setsockopt, int, | |||
| 671 | # endif | 698 | # endif |
| 672 | _GL_CXXALIASWARN (setsockopt); | 699 | _GL_CXXALIASWARN (setsockopt); |
| 673 | #elif @HAVE_WINSOCK2_H@ | 700 | #elif @HAVE_WINSOCK2_H@ |
| 674 | # undef setsockopt | 701 | # if !GNULIB_SETSOCKOPT |
| 675 | # define setsockopt setsockopt_used_without_requesting_gnulib_module_setsockopt | 702 | # undef setsockopt |
| 703 | # define setsockopt setsockopt_used_without_requesting_gnulib_module_setsockopt | ||
| 704 | # endif | ||
| 676 | #elif defined GNULIB_POSIXCHECK | 705 | #elif defined GNULIB_POSIXCHECK |
| 677 | # undef setsockopt | 706 | # undef setsockopt |
| 678 | # if HAVE_RAW_DECL_SETSOCKOPT | 707 | # if HAVE_RAW_DECL_SETSOCKOPT |
| @@ -687,15 +716,17 @@ _GL_WARN_ON_USE (setsockopt, "setsockopt is not always POSIX compliant - " | |||
| 687 | # undef shutdown | 716 | # undef shutdown |
| 688 | # define shutdown rpl_shutdown | 717 | # define shutdown rpl_shutdown |
| 689 | # endif | 718 | # endif |
| 690 | _GL_FUNCDECL_RPL (shutdown, int, (int fd, int how)); | 719 | _GL_FUNCDECL_RPL (shutdown, int, (int fd, int how), ); |
| 691 | _GL_CXXALIAS_RPL (shutdown, int, (int fd, int how)); | 720 | _GL_CXXALIAS_RPL (shutdown, int, (int fd, int how)); |
| 692 | # else | 721 | # else |
| 693 | _GL_CXXALIAS_SYS (shutdown, int, (int fd, int how)); | 722 | _GL_CXXALIAS_SYS (shutdown, int, (int fd, int how)); |
| 694 | # endif | 723 | # endif |
| 695 | _GL_CXXALIASWARN (shutdown); | 724 | _GL_CXXALIASWARN (shutdown); |
| 696 | #elif @HAVE_WINSOCK2_H@ | 725 | #elif @HAVE_WINSOCK2_H@ |
| 697 | # undef shutdown | 726 | # if !GNULIB_SHUTDOWN |
| 698 | # define shutdown shutdown_used_without_requesting_gnulib_module_shutdown | 727 | # undef shutdown |
| 728 | # define shutdown shutdown_used_without_requesting_gnulib_module_shutdown | ||
| 729 | # endif | ||
| 699 | #elif defined GNULIB_POSIXCHECK | 730 | #elif defined GNULIB_POSIXCHECK |
| 700 | # undef shutdown | 731 | # undef shutdown |
| 701 | # if HAVE_RAW_DECL_SHUTDOWN | 732 | # if HAVE_RAW_DECL_SHUTDOWN |
| @@ -716,14 +747,14 @@ _GL_WARN_ON_USE (shutdown, "shutdown is not always POSIX compliant - " | |||
| 716 | # endif | 747 | # endif |
| 717 | _GL_FUNCDECL_RPL (accept4, int, | 748 | _GL_FUNCDECL_RPL (accept4, int, |
| 718 | (int sockfd, struct sockaddr *addr, socklen_t *addrlen, | 749 | (int sockfd, struct sockaddr *addr, socklen_t *addrlen, |
| 719 | int flags)); | 750 | int flags), ); |
| 720 | _GL_CXXALIAS_RPL (accept4, int, | 751 | _GL_CXXALIAS_RPL (accept4, int, |
| 721 | (int sockfd, struct sockaddr *addr, socklen_t *addrlen, | 752 | (int sockfd, struct sockaddr *addr, socklen_t *addrlen, |
| 722 | int flags)); | 753 | int flags)); |
| 723 | # else | 754 | # else |
| 724 | _GL_FUNCDECL_SYS (accept4, int, | 755 | _GL_FUNCDECL_SYS (accept4, int, |
| 725 | (int sockfd, struct sockaddr *addr, socklen_t *addrlen, | 756 | (int sockfd, struct sockaddr *addr, socklen_t *addrlen, |
| 726 | int flags)); | 757 | int flags), ); |
| 727 | _GL_CXXALIAS_SYS (accept4, int, | 758 | _GL_CXXALIAS_SYS (accept4, int, |
| 728 | (int sockfd, struct sockaddr *addr, socklen_t *addrlen, | 759 | (int sockfd, struct sockaddr *addr, socklen_t *addrlen, |
| 729 | int flags)); | 760 | int flags)); |
diff --git a/gl/sys_stat.in.h b/gl/sys_stat.in.h index bf08f335..c3c38fd6 100644 --- a/gl/sys_stat.in.h +++ b/gl/sys_stat.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Provide a more complete sys/stat.h header file. | 1 | /* Provide a more complete sys/stat.h header file. |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -55,7 +55,8 @@ | |||
| 55 | #ifndef _@GUARD_PREFIX@_SYS_STAT_H | 55 | #ifndef _@GUARD_PREFIX@_SYS_STAT_H |
| 56 | #define _@GUARD_PREFIX@_SYS_STAT_H | 56 | #define _@GUARD_PREFIX@_SYS_STAT_H |
| 57 | 57 | ||
| 58 | /* This file uses _GL_ATTRIBUTE_NOTHROW, GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ | 58 | /* This file uses _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOTHROW, |
| 59 | GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ | ||
| 59 | #if !_GL_CONFIG_H_INCLUDED | 60 | #if !_GL_CONFIG_H_INCLUDED |
| 60 | #error "Please include config.h first." | 61 | #error "Please include config.h first." |
| 61 | #endif | 62 | #endif |
| @@ -65,7 +66,7 @@ | |||
| 65 | */ | 66 | */ |
| 66 | #ifndef _GL_ATTRIBUTE_NOTHROW | 67 | #ifndef _GL_ATTRIBUTE_NOTHROW |
| 67 | # if defined __cplusplus | 68 | # if defined __cplusplus |
| 68 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major >= 4 | 69 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major__ >= 4 |
| 69 | # if __cplusplus >= 201103L | 70 | # if __cplusplus >= 201103L |
| 70 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) | 71 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) |
| 71 | # else | 72 | # else |
| @@ -122,9 +123,11 @@ | |||
| 122 | # if @GNULIB_STAT@ | 123 | # if @GNULIB_STAT@ |
| 123 | # define stat rpl_stat | 124 | # define stat rpl_stat |
| 124 | # else | 125 | # else |
| 125 | /* Provoke a clear link error if stat() is used as a function and | 126 | # if !GNULIB_STAT |
| 126 | module 'stat' is not in use. */ | 127 | /* Provoke a clear link error if stat() is used as a function and |
| 127 | # define stat stat_used_without_requesting_gnulib_module_stat | 128 | module 'stat' is not in use. */ |
| 129 | # define stat stat_used_without_requesting_gnulib_module_stat | ||
| 130 | # endif | ||
| 128 | # endif | 131 | # endif |
| 129 | 132 | ||
| 130 | # if !GNULIB_defined_struct_stat | 133 | # if !GNULIB_defined_struct_stat |
| @@ -433,7 +436,7 @@ struct stat | |||
| 433 | # undef chmod | 436 | # undef chmod |
| 434 | # define chmod rpl_chmod | 437 | # define chmod rpl_chmod |
| 435 | # endif | 438 | # endif |
| 436 | _GL_FUNCDECL_RPL (chmod, int, (const char *filename, mode_t mode) | 439 | _GL_FUNCDECL_RPL (chmod, int, (const char *filename, mode_t mode), |
| 437 | _GL_ARG_NONNULL ((1))); | 440 | _GL_ARG_NONNULL ((1))); |
| 438 | _GL_CXXALIAS_RPL (chmod, int, (const char *filename, mode_t mode)); | 441 | _GL_CXXALIAS_RPL (chmod, int, (const char *filename, mode_t mode)); |
| 439 | # elif defined _WIN32 && !defined __CYGWIN__ | 442 | # elif defined _WIN32 && !defined __CYGWIN__ |
| @@ -478,15 +481,15 @@ _GL_CXXALIASWARN (chmod); | |||
| 478 | # define fchmodat rpl_fchmodat | 481 | # define fchmodat rpl_fchmodat |
| 479 | # endif | 482 | # endif |
| 480 | _GL_FUNCDECL_RPL (fchmodat, int, | 483 | _GL_FUNCDECL_RPL (fchmodat, int, |
| 481 | (int fd, char const *file, mode_t mode, int flag) | 484 | (int fd, char const *file, mode_t mode, int flag), |
| 482 | _GL_ARG_NONNULL ((2))); | 485 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 483 | _GL_CXXALIAS_RPL (fchmodat, int, | 486 | _GL_CXXALIAS_RPL (fchmodat, int, |
| 484 | (int fd, char const *file, mode_t mode, int flag)); | 487 | (int fd, char const *file, mode_t mode, int flag)); |
| 485 | # else | 488 | # else |
| 486 | # if !@HAVE_FCHMODAT@ | 489 | # if !@HAVE_FCHMODAT@ |
| 487 | _GL_FUNCDECL_SYS (fchmodat, int, | 490 | _GL_FUNCDECL_SYS (fchmodat, int, |
| 488 | (int fd, char const *file, mode_t mode, int flag) | 491 | (int fd, char const *file, mode_t mode, int flag), |
| 489 | _GL_ARG_NONNULL ((2))); | 492 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 490 | # endif | 493 | # endif |
| 491 | _GL_CXXALIAS_SYS (fchmodat, int, | 494 | _GL_CXXALIAS_SYS (fchmodat, int, |
| 492 | (int fd, char const *file, mode_t mode, int flag)); | 495 | (int fd, char const *file, mode_t mode, int flag)); |
| @@ -507,7 +510,8 @@ _GL_WARN_ON_USE (fchmodat, "fchmodat is not portable - " | |||
| 507 | # undef fstat | 510 | # undef fstat |
| 508 | # define fstat rpl_fstat | 511 | # define fstat rpl_fstat |
| 509 | # endif | 512 | # endif |
| 510 | _GL_FUNCDECL_RPL (fstat, int, (int fd, struct stat *buf) _GL_ARG_NONNULL ((2))); | 513 | _GL_FUNCDECL_RPL (fstat, int, (int fd, struct stat *buf), |
| 514 | _GL_ARG_NONNULL ((2))); | ||
| 511 | _GL_CXXALIAS_RPL (fstat, int, (int fd, struct stat *buf)); | 515 | _GL_CXXALIAS_RPL (fstat, int, (int fd, struct stat *buf)); |
| 512 | # else | 516 | # else |
| 513 | _GL_CXXALIAS_SYS (fstat, int, (int fd, struct stat *buf)); | 517 | _GL_CXXALIAS_SYS (fstat, int, (int fd, struct stat *buf)); |
| @@ -516,8 +520,10 @@ _GL_CXXALIAS_SYS (fstat, int, (int fd, struct stat *buf)); | |||
| 516 | _GL_CXXALIASWARN (fstat); | 520 | _GL_CXXALIASWARN (fstat); |
| 517 | # endif | 521 | # endif |
| 518 | #elif @GNULIB_OVERRIDES_STRUCT_STAT@ | 522 | #elif @GNULIB_OVERRIDES_STRUCT_STAT@ |
| 519 | # undef fstat | 523 | # if !GNULIB_FSTAT |
| 520 | # define fstat fstat_used_without_requesting_gnulib_module_fstat | 524 | # undef fstat |
| 525 | # define fstat fstat_used_without_requesting_gnulib_module_fstat | ||
| 526 | # endif | ||
| 521 | #elif @WINDOWS_64_BIT_ST_SIZE@ | 527 | #elif @WINDOWS_64_BIT_ST_SIZE@ |
| 522 | /* Above, we define stat to _stati64. */ | 528 | /* Above, we define stat to _stati64. */ |
| 523 | # define fstat _fstati64 | 529 | # define fstat _fstati64 |
| @@ -538,7 +544,7 @@ _GL_WARN_ON_USE (fstat, "fstat has portability problems - " | |||
| 538 | # endif | 544 | # endif |
| 539 | _GL_FUNCDECL_RPL (fstatat, int, | 545 | _GL_FUNCDECL_RPL (fstatat, int, |
| 540 | (int fd, char const *restrict name, struct stat *restrict st, | 546 | (int fd, char const *restrict name, struct stat *restrict st, |
| 541 | int flags) | 547 | int flags), |
| 542 | _GL_ARG_NONNULL ((2, 3))); | 548 | _GL_ARG_NONNULL ((2, 3))); |
| 543 | _GL_CXXALIAS_RPL (fstatat, int, | 549 | _GL_CXXALIAS_RPL (fstatat, int, |
| 544 | (int fd, char const *restrict name, struct stat *restrict st, | 550 | (int fd, char const *restrict name, struct stat *restrict st, |
| @@ -547,7 +553,7 @@ _GL_CXXALIAS_RPL (fstatat, int, | |||
| 547 | # if !@HAVE_FSTATAT@ | 553 | # if !@HAVE_FSTATAT@ |
| 548 | _GL_FUNCDECL_SYS (fstatat, int, | 554 | _GL_FUNCDECL_SYS (fstatat, int, |
| 549 | (int fd, char const *restrict name, struct stat *restrict st, | 555 | (int fd, char const *restrict name, struct stat *restrict st, |
| 550 | int flags) | 556 | int flags), |
| 551 | _GL_ARG_NONNULL ((2, 3))); | 557 | _GL_ARG_NONNULL ((2, 3))); |
| 552 | # endif | 558 | # endif |
| 553 | _GL_CXXALIAS_SYS (fstatat, int, | 559 | _GL_CXXALIAS_SYS (fstatat, int, |
| @@ -556,8 +562,10 @@ _GL_CXXALIAS_SYS (fstatat, int, | |||
| 556 | # endif | 562 | # endif |
| 557 | _GL_CXXALIASWARN (fstatat); | 563 | _GL_CXXALIASWARN (fstatat); |
| 558 | #elif @GNULIB_OVERRIDES_STRUCT_STAT@ | 564 | #elif @GNULIB_OVERRIDES_STRUCT_STAT@ |
| 559 | # undef fstatat | 565 | # if !GNULIB_FSTATAT |
| 560 | # define fstatat fstatat_used_without_requesting_gnulib_module_fstatat | 566 | # undef fstatat |
| 567 | # define fstatat fstatat_used_without_requesting_gnulib_module_fstatat | ||
| 568 | # endif | ||
| 561 | #elif defined GNULIB_POSIXCHECK | 569 | #elif defined GNULIB_POSIXCHECK |
| 562 | # undef fstatat | 570 | # undef fstatat |
| 563 | # if HAVE_RAW_DECL_FSTATAT | 571 | # if HAVE_RAW_DECL_FSTATAT |
| @@ -577,11 +585,11 @@ _GL_WARN_ON_USE (fstatat, "fstatat is not portable - " | |||
| 577 | # undef futimens | 585 | # undef futimens |
| 578 | # define futimens rpl_futimens | 586 | # define futimens rpl_futimens |
| 579 | # endif | 587 | # endif |
| 580 | _GL_FUNCDECL_RPL (futimens, int, (int fd, struct timespec const times[2])); | 588 | _GL_FUNCDECL_RPL (futimens, int, (int fd, struct timespec const times[2]), ); |
| 581 | _GL_CXXALIAS_RPL (futimens, int, (int fd, struct timespec const times[2])); | 589 | _GL_CXXALIAS_RPL (futimens, int, (int fd, struct timespec const times[2])); |
| 582 | # else | 590 | # else |
| 583 | # if !@HAVE_FUTIMENS@ | 591 | # if !@HAVE_FUTIMENS@ |
| 584 | _GL_FUNCDECL_SYS (futimens, int, (int fd, struct timespec const times[2])); | 592 | _GL_FUNCDECL_SYS (futimens, int, (int fd, struct timespec const times[2]), ); |
| 585 | # endif | 593 | # endif |
| 586 | _GL_CXXALIAS_SYS (futimens, int, (int fd, struct timespec const times[2])); | 594 | _GL_CXXALIAS_SYS (futimens, int, (int fd, struct timespec const times[2])); |
| 587 | # endif | 595 | # endif |
| @@ -600,9 +608,9 @@ _GL_WARN_ON_USE (futimens, "futimens is not portable - " | |||
| 600 | #if @GNULIB_GETUMASK@ | 608 | #if @GNULIB_GETUMASK@ |
| 601 | # if !@HAVE_GETUMASK@ | 609 | # if !@HAVE_GETUMASK@ |
| 602 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 610 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 603 | _GL_FUNCDECL_SYS (getumask, mode_t, (void) _GL_ATTRIBUTE_NOTHROW); | 611 | _GL_FUNCDECL_SYS (getumask, mode_t, (void), ) _GL_ATTRIBUTE_NOTHROW; |
| 604 | # else | 612 | # else |
| 605 | _GL_FUNCDECL_SYS (getumask, mode_t, (void)); | 613 | _GL_FUNCDECL_SYS (getumask, mode_t, (void), ); |
| 606 | # endif | 614 | # endif |
| 607 | # endif | 615 | # endif |
| 608 | _GL_CXXALIAS_SYS (getumask, mode_t, (void)); | 616 | _GL_CXXALIAS_SYS (getumask, mode_t, (void)); |
| @@ -622,7 +630,7 @@ _GL_WARN_ON_USE (getumask, "getumask is not portable - " | |||
| 622 | /* Change the mode of FILENAME to MODE, without dereferencing it if FILENAME | 630 | /* Change the mode of FILENAME to MODE, without dereferencing it if FILENAME |
| 623 | denotes a symbolic link. */ | 631 | denotes a symbolic link. */ |
| 624 | # if !@HAVE_LCHMOD@ || defined __hpux | 632 | # if !@HAVE_LCHMOD@ || defined __hpux |
| 625 | _GL_FUNCDECL_SYS (lchmod, int, (const char *filename, mode_t mode) | 633 | _GL_FUNCDECL_SYS (lchmod, int, (const char *filename, mode_t mode), |
| 626 | _GL_ARG_NONNULL ((1))); | 634 | _GL_ARG_NONNULL ((1))); |
| 627 | # endif | 635 | # endif |
| 628 | _GL_CXXALIAS_SYS (lchmod, int, (const char *filename, mode_t mode)); | 636 | _GL_CXXALIAS_SYS (lchmod, int, (const char *filename, mode_t mode)); |
| @@ -642,7 +650,7 @@ _GL_WARN_ON_USE (lchmod, "lchmod is unportable - " | |||
| 642 | # undef mkdir | 650 | # undef mkdir |
| 643 | # define mkdir rpl_mkdir | 651 | # define mkdir rpl_mkdir |
| 644 | # endif | 652 | # endif |
| 645 | _GL_FUNCDECL_RPL (mkdir, int, (char const *name, mode_t mode) | 653 | _GL_FUNCDECL_RPL (mkdir, int, (char const *name, mode_t mode), |
| 646 | _GL_ARG_NONNULL ((1))); | 654 | _GL_ARG_NONNULL ((1))); |
| 647 | _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); | 655 | _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); |
| 648 | # elif defined _WIN32 && !defined __CYGWIN__ | 656 | # elif defined _WIN32 && !defined __CYGWIN__ |
| @@ -667,12 +675,6 @@ _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); | |||
| 667 | _GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); | 675 | _GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); |
| 668 | # endif | 676 | # endif |
| 669 | _GL_CXXALIASWARN (mkdir); | 677 | _GL_CXXALIASWARN (mkdir); |
| 670 | #elif defined GNULIB_POSIXCHECK | ||
| 671 | # undef mkdir | ||
| 672 | # if HAVE_RAW_DECL_MKDIR | ||
| 673 | _GL_WARN_ON_USE (mkdir, "mkdir does not always support two parameters - " | ||
| 674 | "use gnulib module mkdir for portability"); | ||
| 675 | # endif | ||
| 676 | #elif @GNULIB_MDA_MKDIR@ | 678 | #elif @GNULIB_MDA_MKDIR@ |
| 677 | /* On native Windows, map 'mkdir' to '_mkdir', so that -loldnames is not | 679 | /* On native Windows, map 'mkdir' to '_mkdir', so that -loldnames is not |
| 678 | required. In C++ with GNULIB_NAMESPACE, avoid differences between | 680 | required. In C++ with GNULIB_NAMESPACE, avoid differences between |
| @@ -695,12 +697,18 @@ _GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode)); | |||
| 695 | _GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); | 697 | _GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode)); |
| 696 | # endif | 698 | # endif |
| 697 | _GL_CXXALIASWARN (mkdir); | 699 | _GL_CXXALIASWARN (mkdir); |
| 700 | #elif defined GNULIB_POSIXCHECK | ||
| 701 | # undef mkdir | ||
| 702 | # if HAVE_RAW_DECL_MKDIR | ||
| 703 | _GL_WARN_ON_USE (mkdir, "mkdir does not always support two parameters - " | ||
| 704 | "use gnulib module mkdir for portability"); | ||
| 705 | # endif | ||
| 698 | #endif | 706 | #endif |
| 699 | 707 | ||
| 700 | 708 | ||
| 701 | #if @GNULIB_MKDIRAT@ | 709 | #if @GNULIB_MKDIRAT@ |
| 702 | # if !@HAVE_MKDIRAT@ | 710 | # if !@HAVE_MKDIRAT@ |
| 703 | _GL_FUNCDECL_SYS (mkdirat, int, (int fd, char const *file, mode_t mode) | 711 | _GL_FUNCDECL_SYS (mkdirat, int, (int fd, char const *file, mode_t mode), |
| 704 | _GL_ARG_NONNULL ((2))); | 712 | _GL_ARG_NONNULL ((2))); |
| 705 | # endif | 713 | # endif |
| 706 | _GL_CXXALIAS_SYS (mkdirat, int, (int fd, char const *file, mode_t mode)); | 714 | _GL_CXXALIAS_SYS (mkdirat, int, (int fd, char const *file, mode_t mode)); |
| @@ -720,12 +728,12 @@ _GL_WARN_ON_USE (mkdirat, "mkdirat is not portable - " | |||
| 720 | # undef mkfifo | 728 | # undef mkfifo |
| 721 | # define mkfifo rpl_mkfifo | 729 | # define mkfifo rpl_mkfifo |
| 722 | # endif | 730 | # endif |
| 723 | _GL_FUNCDECL_RPL (mkfifo, int, (char const *file, mode_t mode) | 731 | _GL_FUNCDECL_RPL (mkfifo, int, (char const *file, mode_t mode), |
| 724 | _GL_ARG_NONNULL ((1))); | 732 | _GL_ARG_NONNULL ((1))); |
| 725 | _GL_CXXALIAS_RPL (mkfifo, int, (char const *file, mode_t mode)); | 733 | _GL_CXXALIAS_RPL (mkfifo, int, (char const *file, mode_t mode)); |
| 726 | # else | 734 | # else |
| 727 | # if !@HAVE_MKFIFO@ | 735 | # if !@HAVE_MKFIFO@ |
| 728 | _GL_FUNCDECL_SYS (mkfifo, int, (char const *file, mode_t mode) | 736 | _GL_FUNCDECL_SYS (mkfifo, int, (char const *file, mode_t mode), |
| 729 | _GL_ARG_NONNULL ((1))); | 737 | _GL_ARG_NONNULL ((1))); |
| 730 | # endif | 738 | # endif |
| 731 | _GL_CXXALIAS_SYS (mkfifo, int, (char const *file, mode_t mode)); | 739 | _GL_CXXALIAS_SYS (mkfifo, int, (char const *file, mode_t mode)); |
| @@ -746,12 +754,12 @@ _GL_WARN_ON_USE (mkfifo, "mkfifo is not portable - " | |||
| 746 | # undef mkfifoat | 754 | # undef mkfifoat |
| 747 | # define mkfifoat rpl_mkfifoat | 755 | # define mkfifoat rpl_mkfifoat |
| 748 | # endif | 756 | # endif |
| 749 | _GL_FUNCDECL_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode) | 757 | _GL_FUNCDECL_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode), |
| 750 | _GL_ARG_NONNULL ((2))); | 758 | _GL_ARG_NONNULL ((2))); |
| 751 | _GL_CXXALIAS_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode)); | 759 | _GL_CXXALIAS_RPL (mkfifoat, int, (int fd, char const *file, mode_t mode)); |
| 752 | # else | 760 | # else |
| 753 | # if !@HAVE_MKFIFOAT@ | 761 | # if !@HAVE_MKFIFOAT@ |
| 754 | _GL_FUNCDECL_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode) | 762 | _GL_FUNCDECL_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode), |
| 755 | _GL_ARG_NONNULL ((2))); | 763 | _GL_ARG_NONNULL ((2))); |
| 756 | # endif | 764 | # endif |
| 757 | _GL_CXXALIAS_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode)); | 765 | _GL_CXXALIAS_SYS (mkfifoat, int, (int fd, char const *file, mode_t mode)); |
| @@ -774,12 +782,12 @@ _GL_WARN_ON_USE (mkfifoat, "mkfifoat is not portable - " | |||
| 774 | # undef mknod | 782 | # undef mknod |
| 775 | # define mknod rpl_mknod | 783 | # define mknod rpl_mknod |
| 776 | # endif | 784 | # endif |
| 777 | _GL_FUNCDECL_RPL (mknod, int, (char const *file, mode_t mode, dev_t dev) | 785 | _GL_FUNCDECL_RPL (mknod, int, (char const *file, mode_t mode, dev_t dev), |
| 778 | _GL_ARG_NONNULL ((1))); | 786 | _GL_ARG_NONNULL ((1))); |
| 779 | _GL_CXXALIAS_RPL (mknod, int, (char const *file, mode_t mode, dev_t dev)); | 787 | _GL_CXXALIAS_RPL (mknod, int, (char const *file, mode_t mode, dev_t dev)); |
| 780 | # else | 788 | # else |
| 781 | # if !@HAVE_MKNOD@ | 789 | # if !@HAVE_MKNOD@ |
| 782 | _GL_FUNCDECL_SYS (mknod, int, (char const *file, mode_t mode, dev_t dev) | 790 | _GL_FUNCDECL_SYS (mknod, int, (char const *file, mode_t mode, dev_t dev), |
| 783 | _GL_ARG_NONNULL ((1))); | 791 | _GL_ARG_NONNULL ((1))); |
| 784 | # endif | 792 | # endif |
| 785 | /* Need to cast, because on OSF/1 5.1, the third parameter is '...'. */ | 793 | /* Need to cast, because on OSF/1 5.1, the third parameter is '...'. */ |
| @@ -802,14 +810,14 @@ _GL_WARN_ON_USE (mknod, "mknod is not portable - " | |||
| 802 | # define mknodat rpl_mknodat | 810 | # define mknodat rpl_mknodat |
| 803 | # endif | 811 | # endif |
| 804 | _GL_FUNCDECL_RPL (mknodat, int, | 812 | _GL_FUNCDECL_RPL (mknodat, int, |
| 805 | (int fd, char const *file, mode_t mode, dev_t dev) | 813 | (int fd, char const *file, mode_t mode, dev_t dev), |
| 806 | _GL_ARG_NONNULL ((2))); | 814 | _GL_ARG_NONNULL ((2))); |
| 807 | _GL_CXXALIAS_RPL (mknodat, int, | 815 | _GL_CXXALIAS_RPL (mknodat, int, |
| 808 | (int fd, char const *file, mode_t mode, dev_t dev)); | 816 | (int fd, char const *file, mode_t mode, dev_t dev)); |
| 809 | # else | 817 | # else |
| 810 | # if !@HAVE_MKNODAT@ | 818 | # if !@HAVE_MKNODAT@ |
| 811 | _GL_FUNCDECL_SYS (mknodat, int, | 819 | _GL_FUNCDECL_SYS (mknodat, int, |
| 812 | (int fd, char const *file, mode_t mode, dev_t dev) | 820 | (int fd, char const *file, mode_t mode, dev_t dev), |
| 813 | _GL_ARG_NONNULL ((2))); | 821 | _GL_ARG_NONNULL ((2))); |
| 814 | # endif | 822 | # endif |
| 815 | _GL_CXXALIAS_SYS (mknodat, int, | 823 | _GL_CXXALIAS_SYS (mknodat, int, |
| @@ -841,7 +849,11 @@ _GL_WARN_ON_USE (mknodat, "mknodat is not portable - " | |||
| 841 | # elif @WINDOWS_64_BIT_ST_SIZE@ | 849 | # elif @WINDOWS_64_BIT_ST_SIZE@ |
| 842 | /* Above, we define stat to _stati64. */ | 850 | /* Above, we define stat to _stati64. */ |
| 843 | # if defined __MINGW32__ && defined _stati64 | 851 | # if defined __MINGW32__ && defined _stati64 |
| 844 | # ifndef _USE_32BIT_TIME_T | 852 | # ifdef _USE_32BIT_TIME_T |
| 853 | /* The system headers possibly define _stati64 to _stat32i64. */ | ||
| 854 | # undef _stat32i64 | ||
| 855 | # define _stat32i64(name, st) rpl_stat (name, st) | ||
| 856 | # else | ||
| 845 | /* The system headers define _stati64 to _stat64. */ | 857 | /* The system headers define _stati64 to _stat64. */ |
| 846 | # undef _stat64 | 858 | # undef _stat64 |
| 847 | # define _stat64(name, st) rpl_stat (name, st) | 859 | # define _stat64(name, st) rpl_stat (name, st) |
| @@ -916,7 +928,7 @@ _GL_CXXALIAS_RPL_1 (lstat, stat, int, | |||
| 916 | # define lstat rpl_lstat | 928 | # define lstat rpl_lstat |
| 917 | # endif | 929 | # endif |
| 918 | _GL_FUNCDECL_RPL (lstat, int, | 930 | _GL_FUNCDECL_RPL (lstat, int, |
| 919 | (const char *restrict name, struct stat *restrict buf) | 931 | (const char *restrict name, struct stat *restrict buf), |
| 920 | _GL_ARG_NONNULL ((1, 2))); | 932 | _GL_ARG_NONNULL ((1, 2))); |
| 921 | _GL_CXXALIAS_RPL (lstat, int, | 933 | _GL_CXXALIAS_RPL (lstat, int, |
| 922 | (const char *restrict name, struct stat *restrict buf)); | 934 | (const char *restrict name, struct stat *restrict buf)); |
| @@ -928,8 +940,10 @@ _GL_CXXALIAS_SYS (lstat, int, | |||
| 928 | _GL_CXXALIASWARN (lstat); | 940 | _GL_CXXALIASWARN (lstat); |
| 929 | # endif | 941 | # endif |
| 930 | #elif @GNULIB_OVERRIDES_STRUCT_STAT@ | 942 | #elif @GNULIB_OVERRIDES_STRUCT_STAT@ |
| 931 | # undef lstat | 943 | # if !GNULIB_LSTAT |
| 932 | # define lstat lstat_used_without_requesting_gnulib_module_lstat | 944 | # undef lstat |
| 945 | # define lstat lstat_used_without_requesting_gnulib_module_lstat | ||
| 946 | # endif | ||
| 933 | #elif defined GNULIB_POSIXCHECK | 947 | #elif defined GNULIB_POSIXCHECK |
| 934 | # undef lstat | 948 | # undef lstat |
| 935 | # if HAVE_RAW_DECL_LSTAT | 949 | # if HAVE_RAW_DECL_LSTAT |
| @@ -968,14 +982,14 @@ _GL_CXXALIASWARN (umask); | |||
| 968 | # define utimensat rpl_utimensat | 982 | # define utimensat rpl_utimensat |
| 969 | # endif | 983 | # endif |
| 970 | _GL_FUNCDECL_RPL (utimensat, int, (int fd, char const *name, | 984 | _GL_FUNCDECL_RPL (utimensat, int, (int fd, char const *name, |
| 971 | struct timespec const times[2], int flag) | 985 | struct timespec const times[2], int flag), |
| 972 | _GL_ARG_NONNULL ((2))); | 986 | _GL_ARG_NONNULL ((2))); |
| 973 | _GL_CXXALIAS_RPL (utimensat, int, (int fd, char const *name, | 987 | _GL_CXXALIAS_RPL (utimensat, int, (int fd, char const *name, |
| 974 | struct timespec const times[2], int flag)); | 988 | struct timespec const times[2], int flag)); |
| 975 | # else | 989 | # else |
| 976 | # if !@HAVE_UTIMENSAT@ | 990 | # if !@HAVE_UTIMENSAT@ |
| 977 | _GL_FUNCDECL_SYS (utimensat, int, (int fd, char const *name, | 991 | _GL_FUNCDECL_SYS (utimensat, int, (int fd, char const *name, |
| 978 | struct timespec const times[2], int flag) | 992 | struct timespec const times[2], int flag), |
| 979 | _GL_ARG_NONNULL ((2))); | 993 | _GL_ARG_NONNULL ((2))); |
| 980 | # endif | 994 | # endif |
| 981 | _GL_CXXALIAS_SYS (utimensat, int, (int fd, char const *name, | 995 | _GL_CXXALIAS_SYS (utimensat, int, (int fd, char const *name, |
diff --git a/gl/sys_types.in.h b/gl/sys_types.in.h index 0a0ccc3c..acf9b2f7 100644 --- a/gl/sys_types.in.h +++ b/gl/sys_types.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Provide a more complete sys/types.h. | 1 | /* Provide a more complete sys/types.h. |
| 2 | 2 | ||
| 3 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -60,6 +60,15 @@ | |||
| 60 | # define _GL_WINDOWS_64_BIT_OFF_T 1 | 60 | # define _GL_WINDOWS_64_BIT_OFF_T 1 |
| 61 | #endif | 61 | #endif |
| 62 | 62 | ||
| 63 | /* Define the off64_t type. */ | ||
| 64 | #if !@HAVE_OFF64_T@ | ||
| 65 | # if !GNULIB_defined_off64_t | ||
| 66 | /* Define off64_t to int64_t always. */ | ||
| 67 | typedef long long off64_t; | ||
| 68 | # define GNULIB_defined_off64_t 1 | ||
| 69 | # endif | ||
| 70 | #endif | ||
| 71 | |||
| 63 | /* Override dev_t and ino_t if distinguishable inodes support is requested | 72 | /* Override dev_t and ino_t if distinguishable inodes support is requested |
| 64 | on native Windows. */ | 73 | on native Windows. */ |
| 65 | #if @WINDOWS_STAT_INODES@ | 74 | #if @WINDOWS_STAT_INODES@ |
| @@ -108,6 +117,22 @@ typedef unsigned long long int rpl_ino_t; | |||
| 108 | # include <stddef.h> | 117 | # include <stddef.h> |
| 109 | #endif | 118 | #endif |
| 110 | 119 | ||
| 120 | /* Define blksize_t, required by POSIX:2024. */ | ||
| 121 | #if !@HAVE_BLKSIZE_T@ | ||
| 122 | # if !defined GNULIB_defined_blksize_t | ||
| 123 | typedef int blksize_t; | ||
| 124 | # define GNULIB_defined_blksize_t 1 | ||
| 125 | # endif | ||
| 126 | #endif | ||
| 127 | |||
| 128 | /* Define blkcnt_t, required by POSIX:2024. */ | ||
| 129 | #if !@HAVE_BLKCNT_T@ | ||
| 130 | # if !defined GNULIB_defined_blkcnt_t | ||
| 131 | typedef long long blkcnt_t; | ||
| 132 | # define GNULIB_defined_blkcnt_t 1 | ||
| 133 | # endif | ||
| 134 | #endif | ||
| 135 | |||
| 111 | #endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ | 136 | #endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ |
| 112 | #endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ | 137 | #endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ |
| 113 | #endif /* __need_XXX */ | 138 | #endif /* __need_XXX */ |
diff --git a/gl/sys_uio.in.h b/gl/sys_uio.in.h index 5e71859d..fec3a70a 100644 --- a/gl/sys_uio.in.h +++ b/gl/sys_uio.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Substitute for <sys/uio.h>. | 1 | /* Substitute for <sys/uio.h>. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/time.in.h b/gl/time.in.h index df99c8ab..3ff16e3b 100644 --- a/gl/time.in.h +++ b/gl/time.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A more-standard <time.h>. | 1 | /* A more-standard <time.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -122,6 +122,23 @@ struct __time_t_must_be_integral { | |||
| 122 | # endif | 122 | # endif |
| 123 | # endif | 123 | # endif |
| 124 | 124 | ||
| 125 | # if @GNULIB_TZNAME@ | ||
| 126 | /* tzname[0..1]: Abbreviated time zone names, set by the tzset() function. */ | ||
| 127 | # if NEED_DECL_TZNAME | ||
| 128 | extern | ||
| 129 | # ifdef __cplusplus | ||
| 130 | "C" | ||
| 131 | # endif | ||
| 132 | char *tzname[]; | ||
| 133 | # endif | ||
| 134 | # if defined _WIN32 && !defined __CYGWIN__ | ||
| 135 | /* On native Windows, map 'tzname' to '_tzname' etc., so that -loldnames is not | ||
| 136 | required. */ | ||
| 137 | # undef tzname | ||
| 138 | # define tzname _tzname | ||
| 139 | # endif | ||
| 140 | # endif | ||
| 141 | |||
| 125 | /* Set *TS to the current time, and return BASE. | 142 | /* Set *TS to the current time, and return BASE. |
| 126 | Upon failure, return 0. */ | 143 | Upon failure, return 0. */ |
| 127 | # if @GNULIB_TIMESPEC_GET@ | 144 | # if @GNULIB_TIMESPEC_GET@ |
| @@ -130,12 +147,12 @@ struct __time_t_must_be_integral { | |||
| 130 | # undef timespec_get | 147 | # undef timespec_get |
| 131 | # define timespec_get rpl_timespec_get | 148 | # define timespec_get rpl_timespec_get |
| 132 | # endif | 149 | # endif |
| 133 | _GL_FUNCDECL_RPL (timespec_get, int, (struct timespec *ts, int base) | 150 | _GL_FUNCDECL_RPL (timespec_get, int, (struct timespec *ts, int base), |
| 134 | _GL_ARG_NONNULL ((1))); | 151 | _GL_ARG_NONNULL ((1))); |
| 135 | _GL_CXXALIAS_RPL (timespec_get, int, (struct timespec *ts, int base)); | 152 | _GL_CXXALIAS_RPL (timespec_get, int, (struct timespec *ts, int base)); |
| 136 | # else | 153 | # else |
| 137 | # if !@HAVE_TIMESPEC_GET@ | 154 | # if !@HAVE_TIMESPEC_GET@ |
| 138 | _GL_FUNCDECL_SYS (timespec_get, int, (struct timespec *ts, int base) | 155 | _GL_FUNCDECL_SYS (timespec_get, int, (struct timespec *ts, int base), |
| 139 | _GL_ARG_NONNULL ((1))); | 156 | _GL_ARG_NONNULL ((1))); |
| 140 | # endif | 157 | # endif |
| 141 | _GL_CXXALIAS_SYS (timespec_get, int, (struct timespec *ts, int base)); | 158 | _GL_CXXALIAS_SYS (timespec_get, int, (struct timespec *ts, int base)); |
| @@ -159,17 +176,19 @@ _GL_WARN_ON_USE (timespec_get, "timespec_get is unportable - " | |||
| 159 | # undef timespec_getres | 176 | # undef timespec_getres |
| 160 | # define timespec_getres rpl_timespec_getres | 177 | # define timespec_getres rpl_timespec_getres |
| 161 | # endif | 178 | # endif |
| 162 | _GL_FUNCDECL_RPL (timespec_getres, int, (struct timespec *ts, int base) | 179 | _GL_FUNCDECL_RPL (timespec_getres, int, (struct timespec *ts, int base), |
| 163 | _GL_ARG_NONNULL ((1))); | 180 | _GL_ARG_NONNULL ((1))); |
| 164 | _GL_CXXALIAS_RPL (timespec_getres, int, (struct timespec *ts, int base)); | 181 | _GL_CXXALIAS_RPL (timespec_getres, int, (struct timespec *ts, int base)); |
| 165 | # else | 182 | # else |
| 166 | # if !@HAVE_TIMESPEC_GETRES@ | 183 | # if !@HAVE_TIMESPEC_GETRES@ |
| 167 | _GL_FUNCDECL_SYS (timespec_getres, int, (struct timespec *ts, int base) | 184 | _GL_FUNCDECL_SYS (timespec_getres, int, (struct timespec *ts, int base), |
| 168 | _GL_ARG_NONNULL ((1))); | 185 | _GL_ARG_NONNULL ((1))); |
| 169 | # endif | 186 | # endif |
| 170 | _GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base)); | 187 | _GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base)); |
| 171 | # endif | 188 | # endif |
| 189 | # if __GLIBC__ >= 2 | ||
| 172 | _GL_CXXALIASWARN (timespec_getres); | 190 | _GL_CXXALIASWARN (timespec_getres); |
| 191 | # endif | ||
| 173 | # elif defined GNULIB_POSIXCHECK | 192 | # elif defined GNULIB_POSIXCHECK |
| 174 | # undef timespec_getres | 193 | # undef timespec_getres |
| 175 | # if HAVE_RAW_DECL_TIMESPEC_GETRES | 194 | # if HAVE_RAW_DECL_TIMESPEC_GETRES |
| @@ -184,7 +203,7 @@ _GL_WARN_ON_USE (timespec_getres, "timespec_getres is unportable - " | |||
| 184 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 203 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 185 | # define time rpl_time | 204 | # define time rpl_time |
| 186 | # endif | 205 | # endif |
| 187 | _GL_FUNCDECL_RPL (time, time_t, (time_t *__tp)); | 206 | _GL_FUNCDECL_RPL (time, time_t, (time_t *__tp), ); |
| 188 | _GL_CXXALIAS_RPL (time, time_t, (time_t *__tp)); | 207 | _GL_CXXALIAS_RPL (time, time_t, (time_t *__tp)); |
| 189 | # else | 208 | # else |
| 190 | _GL_CXXALIAS_SYS (time, time_t, (time_t *__tp)); | 209 | _GL_CXXALIAS_SYS (time, time_t, (time_t *__tp)); |
| @@ -209,14 +228,14 @@ _GL_WARN_ON_USE (time, "time has consistency problems - " | |||
| 209 | # define nanosleep rpl_nanosleep | 228 | # define nanosleep rpl_nanosleep |
| 210 | # endif | 229 | # endif |
| 211 | _GL_FUNCDECL_RPL (nanosleep, int, | 230 | _GL_FUNCDECL_RPL (nanosleep, int, |
| 212 | (struct timespec const *__rqtp, struct timespec *__rmtp) | 231 | (struct timespec const *__rqtp, struct timespec *__rmtp), |
| 213 | _GL_ARG_NONNULL ((1))); | 232 | _GL_ARG_NONNULL ((1))); |
| 214 | _GL_CXXALIAS_RPL (nanosleep, int, | 233 | _GL_CXXALIAS_RPL (nanosleep, int, |
| 215 | (struct timespec const *__rqtp, struct timespec *__rmtp)); | 234 | (struct timespec const *__rqtp, struct timespec *__rmtp)); |
| 216 | # else | 235 | # else |
| 217 | # if ! @HAVE_NANOSLEEP@ | 236 | # if ! @HAVE_NANOSLEEP@ |
| 218 | _GL_FUNCDECL_SYS (nanosleep, int, | 237 | _GL_FUNCDECL_SYS (nanosleep, int, |
| 219 | (struct timespec const *__rqtp, struct timespec *__rmtp) | 238 | (struct timespec const *__rqtp, struct timespec *__rmtp), |
| 220 | _GL_ARG_NONNULL ((1))); | 239 | _GL_ARG_NONNULL ((1))); |
| 221 | # endif | 240 | # endif |
| 222 | _GL_CXXALIAS_SYS (nanosleep, int, | 241 | _GL_CXXALIAS_SYS (nanosleep, int, |
| @@ -238,7 +257,7 @@ _GL_WARN_ON_USE (nanosleep, "nanosleep is unportable - " | |||
| 238 | # undef tzset | 257 | # undef tzset |
| 239 | # define tzset rpl_tzset | 258 | # define tzset rpl_tzset |
| 240 | # endif | 259 | # endif |
| 241 | _GL_FUNCDECL_RPL (tzset, void, (void)); | 260 | _GL_FUNCDECL_RPL (tzset, void, (void), ); |
| 242 | _GL_CXXALIAS_RPL (tzset, void, (void)); | 261 | _GL_CXXALIAS_RPL (tzset, void, (void)); |
| 243 | # elif defined _WIN32 && !defined __CYGWIN__ | 262 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 244 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 263 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -278,7 +297,7 @@ _GL_WARN_ON_USE (tzset, "tzset has portability problems - " | |||
| 278 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 297 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 279 | # define mktime rpl_mktime | 298 | # define mktime rpl_mktime |
| 280 | # endif | 299 | # endif |
| 281 | _GL_FUNCDECL_RPL (mktime, time_t, (struct tm *__tp) _GL_ARG_NONNULL ((1))); | 300 | _GL_FUNCDECL_RPL (mktime, time_t, (struct tm *__tp), _GL_ARG_NONNULL ((1))); |
| 282 | _GL_CXXALIAS_RPL (mktime, time_t, (struct tm *__tp)); | 301 | _GL_CXXALIAS_RPL (mktime, time_t, (struct tm *__tp)); |
| 283 | # else | 302 | # else |
| 284 | _GL_CXXALIAS_SYS (mktime, time_t, (struct tm *__tp)); | 303 | _GL_CXXALIAS_SYS (mktime, time_t, (struct tm *__tp)); |
| @@ -304,14 +323,14 @@ _GL_WARN_ON_USE (mktime, "mktime has portability problems - " | |||
| 304 | # define localtime_r rpl_localtime_r | 323 | # define localtime_r rpl_localtime_r |
| 305 | # endif | 324 | # endif |
| 306 | _GL_FUNCDECL_RPL (localtime_r, struct tm *, (time_t const *restrict __timer, | 325 | _GL_FUNCDECL_RPL (localtime_r, struct tm *, (time_t const *restrict __timer, |
| 307 | struct tm *restrict __result) | 326 | struct tm *restrict __result), |
| 308 | _GL_ARG_NONNULL ((1, 2))); | 327 | _GL_ARG_NONNULL ((1, 2))); |
| 309 | _GL_CXXALIAS_RPL (localtime_r, struct tm *, (time_t const *restrict __timer, | 328 | _GL_CXXALIAS_RPL (localtime_r, struct tm *, (time_t const *restrict __timer, |
| 310 | struct tm *restrict __result)); | 329 | struct tm *restrict __result)); |
| 311 | # else | 330 | # else |
| 312 | # if ! @HAVE_DECL_LOCALTIME_R@ | 331 | # if ! @HAVE_DECL_LOCALTIME_R@ |
| 313 | _GL_FUNCDECL_SYS (localtime_r, struct tm *, (time_t const *restrict __timer, | 332 | _GL_FUNCDECL_SYS (localtime_r, struct tm *, (time_t const *restrict __timer, |
| 314 | struct tm *restrict __result) | 333 | struct tm *restrict __result), |
| 315 | _GL_ARG_NONNULL ((1, 2))); | 334 | _GL_ARG_NONNULL ((1, 2))); |
| 316 | # endif | 335 | # endif |
| 317 | _GL_CXXALIAS_SYS (localtime_r, struct tm *, (time_t const *restrict __timer, | 336 | _GL_CXXALIAS_SYS (localtime_r, struct tm *, (time_t const *restrict __timer, |
| @@ -326,14 +345,14 @@ _GL_CXXALIASWARN (localtime_r); | |||
| 326 | # define gmtime_r rpl_gmtime_r | 345 | # define gmtime_r rpl_gmtime_r |
| 327 | # endif | 346 | # endif |
| 328 | _GL_FUNCDECL_RPL (gmtime_r, struct tm *, (time_t const *restrict __timer, | 347 | _GL_FUNCDECL_RPL (gmtime_r, struct tm *, (time_t const *restrict __timer, |
| 329 | struct tm *restrict __result) | 348 | struct tm *restrict __result), |
| 330 | _GL_ARG_NONNULL ((1, 2))); | 349 | _GL_ARG_NONNULL ((1, 2))); |
| 331 | _GL_CXXALIAS_RPL (gmtime_r, struct tm *, (time_t const *restrict __timer, | 350 | _GL_CXXALIAS_RPL (gmtime_r, struct tm *, (time_t const *restrict __timer, |
| 332 | struct tm *restrict __result)); | 351 | struct tm *restrict __result)); |
| 333 | # else | 352 | # else |
| 334 | # if ! @HAVE_DECL_LOCALTIME_R@ | 353 | # if ! @HAVE_DECL_LOCALTIME_R@ |
| 335 | _GL_FUNCDECL_SYS (gmtime_r, struct tm *, (time_t const *restrict __timer, | 354 | _GL_FUNCDECL_SYS (gmtime_r, struct tm *, (time_t const *restrict __timer, |
| 336 | struct tm *restrict __result) | 355 | struct tm *restrict __result), |
| 337 | _GL_ARG_NONNULL ((1, 2))); | 356 | _GL_ARG_NONNULL ((1, 2))); |
| 338 | # endif | 357 | # endif |
| 339 | _GL_CXXALIAS_SYS (gmtime_r, struct tm *, (time_t const *restrict __timer, | 358 | _GL_CXXALIAS_SYS (gmtime_r, struct tm *, (time_t const *restrict __timer, |
| @@ -364,7 +383,7 @@ _GL_WARN_ON_USE (gmtime_r, "gmtime_r is unportable - " | |||
| 364 | # undef localtime | 383 | # undef localtime |
| 365 | # define localtime rpl_localtime | 384 | # define localtime rpl_localtime |
| 366 | # endif | 385 | # endif |
| 367 | _GL_FUNCDECL_RPL (localtime, struct tm *, (time_t const *__timer) | 386 | _GL_FUNCDECL_RPL (localtime, struct tm *, (time_t const *__timer), |
| 368 | _GL_ARG_NONNULL ((1))); | 387 | _GL_ARG_NONNULL ((1))); |
| 369 | _GL_CXXALIAS_RPL (localtime, struct tm *, (time_t const *__timer)); | 388 | _GL_CXXALIAS_RPL (localtime, struct tm *, (time_t const *__timer)); |
| 370 | # else | 389 | # else |
| @@ -387,7 +406,7 @@ _GL_WARN_ON_USE (localtime, "localtime has portability problems - " | |||
| 387 | # undef gmtime | 406 | # undef gmtime |
| 388 | # define gmtime rpl_gmtime | 407 | # define gmtime rpl_gmtime |
| 389 | # endif | 408 | # endif |
| 390 | _GL_FUNCDECL_RPL (gmtime, struct tm *, (time_t const *__timer) | 409 | _GL_FUNCDECL_RPL (gmtime, struct tm *, (time_t const *__timer), |
| 391 | _GL_ARG_NONNULL ((1))); | 410 | _GL_ARG_NONNULL ((1))); |
| 392 | _GL_CXXALIAS_RPL (gmtime, struct tm *, (time_t const *__timer)); | 411 | _GL_CXXALIAS_RPL (gmtime, struct tm *, (time_t const *__timer)); |
| 393 | # else | 412 | # else |
| @@ -403,7 +422,7 @@ _GL_CXXALIASWARN (gmtime); | |||
| 403 | # if ! @HAVE_STRPTIME@ | 422 | # if ! @HAVE_STRPTIME@ |
| 404 | _GL_FUNCDECL_SYS (strptime, char *, (char const *restrict __buf, | 423 | _GL_FUNCDECL_SYS (strptime, char *, (char const *restrict __buf, |
| 405 | char const *restrict __format, | 424 | char const *restrict __format, |
| 406 | struct tm *restrict __tm) | 425 | struct tm *restrict __tm), |
| 407 | _GL_ARG_NONNULL ((1, 2, 3))); | 426 | _GL_ARG_NONNULL ((1, 2, 3))); |
| 408 | # endif | 427 | # endif |
| 409 | _GL_CXXALIAS_SYS (strptime, char *, (char const *restrict __buf, | 428 | _GL_CXXALIAS_SYS (strptime, char *, (char const *restrict __buf, |
| @@ -428,7 +447,7 @@ _GL_WARN_ON_USE (strptime, "strptime is unportable - " | |||
| 428 | # ifndef __cplusplus | 447 | # ifndef __cplusplus |
| 429 | _GL_ATTRIBUTE_DEPRECATED | 448 | _GL_ATTRIBUTE_DEPRECATED |
| 430 | # endif | 449 | # endif |
| 431 | _GL_FUNCDECL_RPL (ctime, char *, (time_t const *__tp) | 450 | _GL_FUNCDECL_RPL (ctime, char *, (time_t const *__tp), |
| 432 | _GL_ARG_NONNULL ((1))); | 451 | _GL_ARG_NONNULL ((1))); |
| 433 | _GL_CXXALIAS_RPL (ctime, char *, (time_t const *__tp)); | 452 | _GL_CXXALIAS_RPL (ctime, char *, (time_t const *__tp)); |
| 434 | # else | 453 | # else |
| @@ -450,7 +469,7 @@ _GL_CXXALIASWARN (ctime); | |||
| 450 | # endif | 469 | # endif |
| 451 | _GL_FUNCDECL_RPL (strftime, size_t, | 470 | _GL_FUNCDECL_RPL (strftime, size_t, |
| 452 | (char *restrict __buf, size_t __bufsize, | 471 | (char *restrict __buf, size_t __bufsize, |
| 453 | const char *restrict __fmt, const struct tm *restrict __tp) | 472 | const char *restrict __fmt, const struct tm *restrict __tp), |
| 454 | _GL_ARG_NONNULL ((1, 3, 4))); | 473 | _GL_ARG_NONNULL ((1, 3, 4))); |
| 455 | _GL_CXXALIAS_RPL (strftime, size_t, | 474 | _GL_CXXALIAS_RPL (strftime, size_t, |
| 456 | (char *restrict __buf, size_t __bufsize, | 475 | (char *restrict __buf, size_t __bufsize, |
| @@ -471,14 +490,24 @@ _GL_WARN_ON_USE (strftime, "strftime has portability problems - " | |||
| 471 | # endif | 490 | # endif |
| 472 | # endif | 491 | # endif |
| 473 | 492 | ||
| 474 | # if defined _GNU_SOURCE && @GNULIB_TIME_RZ@ && ! @HAVE_TIMEZONE_T@ | 493 | # if @GNULIB_TIME_RZ@ |
| 475 | /* Functions that use a first-class time zone data type, instead of | 494 | /* Functions that use a first-class time zone data type, instead of |
| 476 | relying on an implicit global time zone. | 495 | relying on an implicit global time zone. |
| 477 | Inspired by NetBSD. */ | 496 | Inspired by NetBSD. */ |
| 478 | 497 | ||
| 479 | /* Represents a time zone. | 498 | /* Represents a time zone. |
| 480 | (timezone_t) NULL stands for UTC. */ | 499 | (timezone_t) NULL stands for UTC. */ |
| 500 | # if !@HAVE_TZALLOC@ | ||
| 501 | # if !GNULIB_defined_timezone_t | ||
| 502 | # if !@HAVE_TIMEZONE_T@ | ||
| 481 | typedef struct tm_zone *timezone_t; | 503 | typedef struct tm_zone *timezone_t; |
| 504 | # else | ||
| 505 | typedef struct tm_zone *rpl_timezone_t; | ||
| 506 | # define timezone_t rpl_timezone_t | ||
| 507 | # endif | ||
| 508 | # define GNULIB_defined_timezone_t 1 | ||
| 509 | # endif | ||
| 510 | # endif | ||
| 482 | 511 | ||
| 483 | /* tzalloc (name) | 512 | /* tzalloc (name) |
| 484 | Returns a time zone object for the given time zone NAME. This object | 513 | Returns a time zone object for the given time zone NAME. This object |
| @@ -488,37 +517,72 @@ typedef struct tm_zone *timezone_t; | |||
| 488 | would use it the TZ environment variable was unset. | 517 | would use it the TZ environment variable was unset. |
| 489 | May return NULL if NAME is invalid (this is platform dependent) or | 518 | May return NULL if NAME is invalid (this is platform dependent) or |
| 490 | upon memory allocation failure. */ | 519 | upon memory allocation failure. */ |
| 491 | _GL_FUNCDECL_SYS (tzalloc, timezone_t, (char const *__name)); | 520 | # if !@HAVE_TZALLOC@ |
| 521 | _GL_FUNCDECL_SYS (tzalloc, timezone_t, (char const *__name), ); | ||
| 492 | _GL_CXXALIAS_SYS (tzalloc, timezone_t, (char const *__name)); | 522 | _GL_CXXALIAS_SYS (tzalloc, timezone_t, (char const *__name)); |
| 523 | # endif | ||
| 493 | 524 | ||
| 494 | /* tzfree (tz) | 525 | /* tzfree (tz) |
| 495 | Frees a time zone object. | 526 | Frees a time zone object. |
| 496 | The argument must have been returned by tzalloc(). */ | 527 | The argument must have been returned by tzalloc(). */ |
| 497 | _GL_FUNCDECL_SYS (tzfree, void, (timezone_t __tz)); | 528 | # if !@HAVE_TZALLOC@ |
| 529 | _GL_FUNCDECL_SYS (tzfree, void, (timezone_t __tz), ); | ||
| 498 | _GL_CXXALIAS_SYS (tzfree, void, (timezone_t __tz)); | 530 | _GL_CXXALIAS_SYS (tzfree, void, (timezone_t __tz)); |
| 531 | # endif | ||
| 499 | 532 | ||
| 500 | /* localtime_rz (tz, &t, &result) | 533 | /* localtime_rz (tz, &t, &result) |
| 501 | Converts an absolute time T to a broken-down time RESULT, assuming the | 534 | Converts an absolute time T to a broken-down time RESULT, assuming the |
| 502 | time zone TZ. | 535 | time zone TZ. |
| 503 | This function is like 'localtime_r', but relies on the argument TZ instead | 536 | This function is like 'localtime_r', but relies on the argument TZ instead |
| 504 | of an implicit global time zone. */ | 537 | of an implicit global time zone. */ |
| 538 | # if @REPLACE_LOCALTIME_RZ@ | ||
| 539 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 540 | # undef localtime_rz | ||
| 541 | # define localtime_rz rpl_localtime_rz | ||
| 542 | # endif | ||
| 543 | _GL_FUNCDECL_RPL (localtime_rz, struct tm *, | ||
| 544 | (timezone_t __tz, time_t const *restrict __timer, | ||
| 545 | struct tm *restrict __result), | ||
| 546 | _GL_ARG_NONNULL ((2, 3))); | ||
| 547 | _GL_CXXALIAS_RPL (localtime_rz, struct tm *, | ||
| 548 | (timezone_t __tz, time_t const *restrict __timer, | ||
| 549 | struct tm *restrict __result)); | ||
| 550 | # else | ||
| 551 | # if !@HAVE_TZALLOC@ | ||
| 505 | _GL_FUNCDECL_SYS (localtime_rz, struct tm *, | 552 | _GL_FUNCDECL_SYS (localtime_rz, struct tm *, |
| 506 | (timezone_t __tz, time_t const *restrict __timer, | 553 | (timezone_t __tz, time_t const *restrict __timer, |
| 507 | struct tm *restrict __result) _GL_ARG_NONNULL ((2, 3))); | 554 | struct tm *restrict __result), |
| 555 | _GL_ARG_NONNULL ((2, 3))); | ||
| 556 | # endif | ||
| 508 | _GL_CXXALIAS_SYS (localtime_rz, struct tm *, | 557 | _GL_CXXALIAS_SYS (localtime_rz, struct tm *, |
| 509 | (timezone_t __tz, time_t const *restrict __timer, | 558 | (timezone_t __tz, time_t const *restrict __timer, |
| 510 | struct tm *restrict __result)); | 559 | struct tm *restrict __result)); |
| 560 | # endif | ||
| 511 | 561 | ||
| 512 | /* mktime_z (tz, &tm) | 562 | /* mktime_z (tz, &tm) |
| 513 | Normalizes the broken-down time TM and converts it to an absolute time, | 563 | Normalizes the broken-down time TM and converts it to an absolute time, |
| 514 | assuming the time zone TZ. Returns the absolute time. | 564 | assuming the time zone TZ. Returns the absolute time. |
| 515 | This function is like 'mktime', but relies on the argument TZ instead | 565 | This function is like 'mktime', but relies on the argument TZ instead |
| 516 | of an implicit global time zone. */ | 566 | of an implicit global time zone. */ |
| 567 | # if @REPLACE_MKTIME_Z@ | ||
| 568 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 569 | # undef mktime_z | ||
| 570 | # define mktime_z rpl_mktime_z | ||
| 571 | # endif | ||
| 572 | _GL_FUNCDECL_RPL (mktime_z, time_t, | ||
| 573 | (timezone_t __tz, struct tm *restrict __tm), | ||
| 574 | _GL_ARG_NONNULL ((2))); | ||
| 575 | _GL_CXXALIAS_RPL (mktime_z, time_t, | ||
| 576 | (timezone_t __tz, struct tm *restrict __tm)); | ||
| 577 | # else | ||
| 578 | # if !@HAVE_TZALLOC@ | ||
| 517 | _GL_FUNCDECL_SYS (mktime_z, time_t, | 579 | _GL_FUNCDECL_SYS (mktime_z, time_t, |
| 518 | (timezone_t __tz, struct tm *restrict __tm) | 580 | (timezone_t __tz, struct tm *restrict __tm), |
| 519 | _GL_ARG_NONNULL ((2))); | 581 | _GL_ARG_NONNULL ((2))); |
| 582 | # endif | ||
| 520 | _GL_CXXALIAS_SYS (mktime_z, time_t, | 583 | _GL_CXXALIAS_SYS (mktime_z, time_t, |
| 521 | (timezone_t __tz, struct tm *restrict __tm)); | 584 | (timezone_t __tz, struct tm *restrict __tm)); |
| 585 | # endif | ||
| 522 | 586 | ||
| 523 | /* Time zone abbreviation strings (returned by 'localtime_rz' or 'mktime_z' | 587 | /* Time zone abbreviation strings (returned by 'localtime_rz' or 'mktime_z' |
| 524 | in the 'tm_zone' member of 'struct tm') are valid as long as | 588 | in the 'tm_zone' member of 'struct tm') are valid as long as |
| @@ -535,11 +599,11 @@ _GL_CXXALIAS_SYS (mktime_z, time_t, | |||
| 535 | # undef timegm | 599 | # undef timegm |
| 536 | # define timegm rpl_timegm | 600 | # define timegm rpl_timegm |
| 537 | # endif | 601 | # endif |
| 538 | _GL_FUNCDECL_RPL (timegm, time_t, (struct tm *__tm) _GL_ARG_NONNULL ((1))); | 602 | _GL_FUNCDECL_RPL (timegm, time_t, (struct tm *__tm), _GL_ARG_NONNULL ((1))); |
| 539 | _GL_CXXALIAS_RPL (timegm, time_t, (struct tm *__tm)); | 603 | _GL_CXXALIAS_RPL (timegm, time_t, (struct tm *__tm)); |
| 540 | # else | 604 | # else |
| 541 | # if ! @HAVE_TIMEGM@ | 605 | # if ! @HAVE_TIMEGM@ |
| 542 | _GL_FUNCDECL_SYS (timegm, time_t, (struct tm *__tm) _GL_ARG_NONNULL ((1))); | 606 | _GL_FUNCDECL_SYS (timegm, time_t, (struct tm *__tm), _GL_ARG_NONNULL ((1))); |
| 543 | # endif | 607 | # endif |
| 544 | _GL_CXXALIAS_SYS (timegm, time_t, (struct tm *__tm)); | 608 | _GL_CXXALIAS_SYS (timegm, time_t, (struct tm *__tm)); |
| 545 | # endif | 609 | # endif |
diff --git a/gl/time_r.c b/gl/time_r.c index b724f3b3..15d65d59 100644 --- a/gl/time_r.c +++ b/gl/time_r.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Reentrant time functions like localtime_r. | 1 | /* Reentrant time functions like localtime_r. |
| 2 | 2 | ||
| 3 | Copyright (C) 2003, 2006-2007, 2010-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2003, 2006-2007, 2010-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/timegm.c b/gl/timegm.c index e5cf30c0..4c2615b9 100644 --- a/gl/timegm.c +++ b/gl/timegm.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Convert UTC calendar time to simple time. Like mktime but assumes UTC. | 1 | /* Convert UTC calendar time to simple time. Like mktime but assumes UTC. |
| 2 | 2 | ||
| 3 | Copyright (C) 1994-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1994-2025 Free Software Foundation, Inc. |
| 4 | This file is part of the GNU C Library. | 4 | This file is part of the GNU C Library. |
| 5 | 5 | ||
| 6 | The GNU C Library is free software; you can redistribute it and/or | 6 | The GNU C Library is free software; you can redistribute it and/or |
| @@ -30,8 +30,7 @@ __time64_t | |||
| 30 | __timegm64 (struct tm *tmp) | 30 | __timegm64 (struct tm *tmp) |
| 31 | { | 31 | { |
| 32 | static mktime_offset_t gmtime_offset; | 32 | static mktime_offset_t gmtime_offset; |
| 33 | tmp->tm_isdst = 0; | 33 | return __mktime_internal (tmp, false, &gmtime_offset); |
| 34 | return __mktime_internal (tmp, __gmtime64_r, &gmtime_offset); | ||
| 35 | } | 34 | } |
| 36 | 35 | ||
| 37 | #if defined _LIBC && __TIMESIZE != 64 | 36 | #if defined _LIBC && __TIMESIZE != 64 |
diff --git a/gl/uchar.h b/gl/uchar.h new file mode 100644 index 00000000..abc636c5 --- /dev/null +++ b/gl/uchar.h | |||
| @@ -0,0 +1,1456 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* <uchar.h> substitute - 16-bit and 32-bit wide character types. | ||
| 3 | Copyright (C) 2019-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | /* Written by Bruno Haible <bruno@clisp.org>, 2019. */ | ||
| 19 | |||
| 20 | /* | ||
| 21 | * ISO C 23 <uchar.h> for platforms that lack it. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef _GL_UCHAR_H | ||
| 25 | |||
| 26 | #if __GNUC__ >= 3 | ||
| 27 | #pragma GCC system_header | ||
| 28 | #endif | ||
| 29 | |||
| 30 | |||
| 31 | /* The include_next requires a split double-inclusion guard. */ | ||
| 32 | #if (defined __cplusplus ? 0 : 1) | ||
| 33 | # if defined __HAIKU__ | ||
| 34 | /* Work around <https://dev.haiku-os.org/ticket/17040>. */ | ||
| 35 | # include <stdint.h> | ||
| 36 | # endif | ||
| 37 | /* On AIX 7.2 with xlclang++, /usr/include/uchar.h produces compilation errors | ||
| 38 | because it contains typedef definitions of char16_t and char32_t, however | ||
| 39 | char16_t and char32_t are keywords in this situation. To work around it, | ||
| 40 | define char16_t and char32_t as macros. */ | ||
| 41 | # if defined __cplusplus && defined _AIX && defined __ibmxl__ && defined __clang__ | ||
| 42 | # define char16_t gl_char16_t | ||
| 43 | # define char32_t gl_char32_t | ||
| 44 | # endif | ||
| 45 | # include_next <uchar.h> | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #ifndef _GL_UCHAR_H | ||
| 49 | #define _GL_UCHAR_H | ||
| 50 | |||
| 51 | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, _GL_BEGIN_C_LINKAGE, | ||
| 52 | _GL_ATTRIBUTE_PURE, GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ | ||
| 53 | #if !_GL_CONFIG_H_INCLUDED | ||
| 54 | #error "Please include config.h first." | ||
| 55 | #endif | ||
| 56 | |||
| 57 | /* Get uint_least16_t, uint_least32_t. */ | ||
| 58 | #include <stdint.h> | ||
| 59 | |||
| 60 | /* Get mbstate_t, size_t. */ | ||
| 61 | #include <wchar.h> | ||
| 62 | |||
| 63 | /* For the inline functions. */ | ||
| 64 | #include <string.h> | ||
| 65 | #include <wctype.h> | ||
| 66 | |||
| 67 | /* The __attribute__ feature is available in gcc versions 2.5 and later. | ||
| 68 | The attribute __pure__ was added in gcc 2.96. */ | ||
| 69 | #ifndef _GL_ATTRIBUTE_PURE | ||
| 70 | # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ | ||
| 71 | # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) | ||
| 72 | # else | ||
| 73 | # define _GL_ATTRIBUTE_PURE /* empty */ | ||
| 74 | # endif | ||
| 75 | #endif | ||
| 76 | |||
| 77 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | ||
| 78 | /* C++ compatible function declaration macros. | ||
| 79 | Copyright (C) 2010-2025 Free Software Foundation, Inc. | ||
| 80 | |||
| 81 | This program is free software: you can redistribute it and/or modify it | ||
| 82 | under the terms of the GNU Lesser General Public License as published | ||
| 83 | by the Free Software Foundation; either version 2 of the License, or | ||
| 84 | (at your option) any later version. | ||
| 85 | |||
| 86 | This program is distributed in the hope that it will be useful, | ||
| 87 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 88 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 89 | Lesser General Public License for more details. | ||
| 90 | |||
| 91 | You should have received a copy of the GNU Lesser General Public License | ||
| 92 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 93 | |||
| 94 | #ifndef _GL_CXXDEFS_H | ||
| 95 | #define _GL_CXXDEFS_H | ||
| 96 | |||
| 97 | /* Begin/end the GNULIB_NAMESPACE namespace. */ | ||
| 98 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 99 | # define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE { | ||
| 100 | # define _GL_END_NAMESPACE } | ||
| 101 | #else | ||
| 102 | # define _GL_BEGIN_NAMESPACE | ||
| 103 | # define _GL_END_NAMESPACE | ||
| 104 | #endif | ||
| 105 | |||
| 106 | /* The three most frequent use cases of these macros are: | ||
| 107 | |||
| 108 | * For providing a substitute for a function that is missing on some | ||
| 109 | platforms, but is declared and works fine on the platforms on which | ||
| 110 | it exists: | ||
| 111 | |||
| 112 | #if @GNULIB_FOO@ | ||
| 113 | # if !@HAVE_FOO@ | ||
| 114 | _GL_FUNCDECL_SYS (foo, ...); | ||
| 115 | # endif | ||
| 116 | _GL_CXXALIAS_SYS (foo, ...); | ||
| 117 | _GL_CXXALIASWARN (foo); | ||
| 118 | #elif defined GNULIB_POSIXCHECK | ||
| 119 | ... | ||
| 120 | #endif | ||
| 121 | |||
| 122 | * For providing a replacement for a function that exists on all platforms, | ||
| 123 | but is broken/insufficient and needs to be replaced on some platforms: | ||
| 124 | |||
| 125 | #if @GNULIB_FOO@ | ||
| 126 | # if @REPLACE_FOO@ | ||
| 127 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 128 | # undef foo | ||
| 129 | # define foo rpl_foo | ||
| 130 | # endif | ||
| 131 | _GL_FUNCDECL_RPL (foo, ...); | ||
| 132 | _GL_CXXALIAS_RPL (foo, ...); | ||
| 133 | # else | ||
| 134 | _GL_CXXALIAS_SYS (foo, ...); | ||
| 135 | # endif | ||
| 136 | _GL_CXXALIASWARN (foo); | ||
| 137 | #elif defined GNULIB_POSIXCHECK | ||
| 138 | ... | ||
| 139 | #endif | ||
| 140 | |||
| 141 | * For providing a replacement for a function that exists on some platforms | ||
| 142 | but is broken/insufficient and needs to be replaced on some of them and | ||
| 143 | is additionally either missing or undeclared on some other platforms: | ||
| 144 | |||
| 145 | #if @GNULIB_FOO@ | ||
| 146 | # if @REPLACE_FOO@ | ||
| 147 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 148 | # undef foo | ||
| 149 | # define foo rpl_foo | ||
| 150 | # endif | ||
| 151 | _GL_FUNCDECL_RPL (foo, ...); | ||
| 152 | _GL_CXXALIAS_RPL (foo, ...); | ||
| 153 | # else | ||
| 154 | # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ | ||
| 155 | _GL_FUNCDECL_SYS (foo, ...); | ||
| 156 | # endif | ||
| 157 | _GL_CXXALIAS_SYS (foo, ...); | ||
| 158 | # endif | ||
| 159 | _GL_CXXALIASWARN (foo); | ||
| 160 | #elif defined GNULIB_POSIXCHECK | ||
| 161 | ... | ||
| 162 | #endif | ||
| 163 | */ | ||
| 164 | |||
| 165 | /* _GL_EXTERN_C declaration; | ||
| 166 | performs the declaration with C linkage. */ | ||
| 167 | #if defined __cplusplus | ||
| 168 | # define _GL_EXTERN_C extern "C" | ||
| 169 | #else | ||
| 170 | # define _GL_EXTERN_C extern | ||
| 171 | #endif | ||
| 172 | |||
| 173 | /* _GL_EXTERN_C_FUNC declaration; | ||
| 174 | performs the declaration of a function with C linkage. */ | ||
| 175 | #if defined __cplusplus | ||
| 176 | # define _GL_EXTERN_C_FUNC extern "C" | ||
| 177 | #else | ||
| 178 | /* In C mode, omit the 'extern' keyword, because attributes in bracket syntax | ||
| 179 | are not allowed between 'extern' and the return type (see gnulib-common.m4). | ||
| 180 | */ | ||
| 181 | # define _GL_EXTERN_C_FUNC | ||
| 182 | #endif | ||
| 183 | |||
| 184 | /* _GL_FUNCDECL_RPL (func, rettype, parameters, [attributes]); | ||
| 185 | declares a replacement function, named rpl_func, with the given prototype, | ||
| 186 | consisting of return type, parameters, and attributes. | ||
| 187 | Although attributes are optional, the comma before them is required | ||
| 188 | for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW, | ||
| 189 | if needed, must be placed after the _GL_FUNCDECL_RPL invocation, | ||
| 190 | at the end of the declaration. | ||
| 191 | Examples: | ||
| 192 | _GL_FUNCDECL_RPL (free, void, (void *ptr), ) _GL_ATTRIBUTE_NOTHROW; | ||
| 193 | _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...), | ||
| 194 | _GL_ARG_NONNULL ((1))); | ||
| 195 | |||
| 196 | Note: Attributes, such as _GL_ATTRIBUTE_DEPRECATED, are supported in front | ||
| 197 | of a _GL_FUNCDECL_RPL invocation only in C mode, not in C++ mode. (That's | ||
| 198 | because | ||
| 199 | [[...]] extern "C" <declaration>; | ||
| 200 | is invalid syntax in C++.) | ||
| 201 | */ | ||
| 202 | #define _GL_FUNCDECL_RPL(func,rettype,parameters,...) \ | ||
| 203 | _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters, __VA_ARGS__) | ||
| 204 | #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \ | ||
| 205 | _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters | ||
| 206 | |||
| 207 | /* _GL_FUNCDECL_SYS_NAME (func) expands to plain func if C++, and to | ||
| 208 | parenthesized func otherwise. Parenthesization is needed in C23 if | ||
| 209 | the function is like strchr and so is a qualifier-generic macro | ||
| 210 | that expands to something more complicated. */ | ||
| 211 | #ifdef __cplusplus | ||
| 212 | # define _GL_FUNCDECL_SYS_NAME(func) func | ||
| 213 | #else | ||
| 214 | # define _GL_FUNCDECL_SYS_NAME(func) (func) | ||
| 215 | #endif | ||
| 216 | |||
| 217 | /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]); | ||
| 218 | declares the system function, named func, with the given prototype, | ||
| 219 | consisting of return type, parameters, and attributes. | ||
| 220 | Although attributes are optional, the comma before them is required | ||
| 221 | for portability to C17 and earlier. The attribute _GL_ATTRIBUTE_NOTHROW, | ||
| 222 | if needed, must be placed after the _GL_FUNCDECL_RPL invocation, | ||
| 223 | at the end of the declaration. | ||
| 224 | Examples: | ||
| 225 | _GL_FUNCDECL_SYS (getumask, mode_t, (void), ) _GL_ATTRIBUTE_NOTHROW; | ||
| 226 | _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD); | ||
| 227 | */ | ||
| 228 | #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \ | ||
| 229 | _GL_EXTERN_C_FUNC __VA_ARGS__ rettype _GL_FUNCDECL_SYS_NAME (func) parameters | ||
| 230 | |||
| 231 | /* _GL_CXXALIAS_RPL (func, rettype, parameters); | ||
| 232 | declares a C++ alias called GNULIB_NAMESPACE::func | ||
| 233 | that redirects to rpl_func, if GNULIB_NAMESPACE is defined. | ||
| 234 | Example: | ||
| 235 | _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); | ||
| 236 | |||
| 237 | Wrapping rpl_func in an object with an inline conversion operator | ||
| 238 | avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is | ||
| 239 | actually used in the program. */ | ||
| 240 | #define _GL_CXXALIAS_RPL(func,rettype,parameters) \ | ||
| 241 | _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) | ||
| 242 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 243 | # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ | ||
| 244 | namespace GNULIB_NAMESPACE \ | ||
| 245 | { \ | ||
| 246 | static const struct _gl_ ## func ## _wrapper \ | ||
| 247 | { \ | ||
| 248 | typedef rettype (*type) parameters; \ | ||
| 249 | \ | ||
| 250 | inline operator type () const \ | ||
| 251 | { \ | ||
| 252 | return ::rpl_func; \ | ||
| 253 | } \ | ||
| 254 | } func = {}; \ | ||
| 255 | } \ | ||
| 256 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 257 | #else | ||
| 258 | # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ | ||
| 259 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 260 | #endif | ||
| 261 | |||
| 262 | /* _GL_CXXALIAS_MDA (func, rettype, parameters); | ||
| 263 | is to be used when func is a Microsoft deprecated alias, on native Windows. | ||
| 264 | It declares a C++ alias called GNULIB_NAMESPACE::func | ||
| 265 | that redirects to _func, if GNULIB_NAMESPACE is defined. | ||
| 266 | Example: | ||
| 267 | _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...)); | ||
| 268 | */ | ||
| 269 | #define _GL_CXXALIAS_MDA(func,rettype,parameters) \ | ||
| 270 | _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters) | ||
| 271 | |||
| 272 | /* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); | ||
| 273 | is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); | ||
| 274 | except that the C function rpl_func may have a slightly different | ||
| 275 | declaration. A cast is used to silence the "invalid conversion" error | ||
| 276 | that would otherwise occur. */ | ||
| 277 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 278 | # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ | ||
| 279 | namespace GNULIB_NAMESPACE \ | ||
| 280 | { \ | ||
| 281 | static const struct _gl_ ## func ## _wrapper \ | ||
| 282 | { \ | ||
| 283 | typedef rettype (*type) parameters; \ | ||
| 284 | \ | ||
| 285 | inline operator type () const \ | ||
| 286 | { \ | ||
| 287 | return reinterpret_cast<type>(::rpl_func); \ | ||
| 288 | } \ | ||
| 289 | } func = {}; \ | ||
| 290 | } \ | ||
| 291 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 292 | #else | ||
| 293 | # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ | ||
| 294 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 295 | #endif | ||
| 296 | |||
| 297 | /* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters); | ||
| 298 | is like _GL_CXXALIAS_MDA (func, rettype, parameters); | ||
| 299 | except that the C function func may have a slightly different declaration. | ||
| 300 | A cast is used to silence the "invalid conversion" error that would | ||
| 301 | otherwise occur. */ | ||
| 302 | #define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \ | ||
| 303 | _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters) | ||
| 304 | |||
| 305 | /* _GL_CXXALIAS_SYS (func, rettype, parameters); | ||
| 306 | declares a C++ alias called GNULIB_NAMESPACE::func | ||
| 307 | that redirects to the system provided function func, if GNULIB_NAMESPACE | ||
| 308 | is defined. | ||
| 309 | Example: | ||
| 310 | _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); | ||
| 311 | |||
| 312 | Wrapping func in an object with an inline conversion operator | ||
| 313 | avoids a reference to func unless GNULIB_NAMESPACE::func is | ||
| 314 | actually used in the program. */ | ||
| 315 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 316 | # define _GL_CXXALIAS_SYS(func,rettype,parameters) \ | ||
| 317 | namespace GNULIB_NAMESPACE \ | ||
| 318 | { \ | ||
| 319 | static const struct _gl_ ## func ## _wrapper \ | ||
| 320 | { \ | ||
| 321 | typedef rettype (*type) parameters; \ | ||
| 322 | \ | ||
| 323 | inline operator type () const \ | ||
| 324 | { \ | ||
| 325 | return ::func; \ | ||
| 326 | } \ | ||
| 327 | } func = {}; \ | ||
| 328 | } \ | ||
| 329 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 330 | #else | ||
| 331 | # define _GL_CXXALIAS_SYS(func,rettype,parameters) \ | ||
| 332 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 333 | #endif | ||
| 334 | |||
| 335 | /* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); | ||
| 336 | is like _GL_CXXALIAS_SYS (func, rettype, parameters); | ||
| 337 | except that the C function func may have a slightly different declaration. | ||
| 338 | A cast is used to silence the "invalid conversion" error that would | ||
| 339 | otherwise occur. */ | ||
| 340 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 341 | # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ | ||
| 342 | namespace GNULIB_NAMESPACE \ | ||
| 343 | { \ | ||
| 344 | static const struct _gl_ ## func ## _wrapper \ | ||
| 345 | { \ | ||
| 346 | typedef rettype (*type) parameters; \ | ||
| 347 | \ | ||
| 348 | inline operator type () const \ | ||
| 349 | { \ | ||
| 350 | return reinterpret_cast<type>(::func); \ | ||
| 351 | } \ | ||
| 352 | } func = {}; \ | ||
| 353 | } \ | ||
| 354 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 355 | #else | ||
| 356 | # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ | ||
| 357 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 358 | #endif | ||
| 359 | |||
| 360 | /* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); | ||
| 361 | is like _GL_CXXALIAS_SYS (func, rettype, parameters); | ||
| 362 | except that the C function is picked among a set of overloaded functions, | ||
| 363 | namely the one with rettype2 and parameters2. Two consecutive casts | ||
| 364 | are used to silence the "cannot find a match" and "invalid conversion" | ||
| 365 | errors that would otherwise occur. */ | ||
| 366 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 367 | /* The outer cast must be a reinterpret_cast. | ||
| 368 | The inner cast: When the function is defined as a set of overloaded | ||
| 369 | functions, it works as a static_cast<>, choosing the designated variant. | ||
| 370 | When the function is defined as a single variant, it works as a | ||
| 371 | reinterpret_cast<>. The parenthesized cast syntax works both ways. */ | ||
| 372 | # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ | ||
| 373 | namespace GNULIB_NAMESPACE \ | ||
| 374 | { \ | ||
| 375 | static const struct _gl_ ## func ## _wrapper \ | ||
| 376 | { \ | ||
| 377 | typedef rettype (*type) parameters; \ | ||
| 378 | \ | ||
| 379 | inline operator type () const \ | ||
| 380 | { \ | ||
| 381 | return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \ | ||
| 382 | } \ | ||
| 383 | } func = {}; \ | ||
| 384 | } \ | ||
| 385 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 386 | #else | ||
| 387 | # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ | ||
| 388 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 389 | #endif | ||
| 390 | |||
| 391 | /* _GL_CXXALIASWARN (func); | ||
| 392 | causes a warning to be emitted when ::func is used but not when | ||
| 393 | GNULIB_NAMESPACE::func is used. func must be defined without overloaded | ||
| 394 | variants. */ | ||
| 395 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 396 | # define _GL_CXXALIASWARN(func) \ | ||
| 397 | _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) | ||
| 398 | # define _GL_CXXALIASWARN_1(func,namespace) \ | ||
| 399 | _GL_CXXALIASWARN_2 (func, namespace) | ||
| 400 | /* To work around GCC bug <https://gcc.gnu.org/PR43881>, | ||
| 401 | we enable the warning only when not optimizing. */ | ||
| 402 | # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) | ||
| 403 | # define _GL_CXXALIASWARN_2(func,namespace) \ | ||
| 404 | _GL_WARN_ON_USE (func, \ | ||
| 405 | "The symbol ::" #func " refers to the system function. " \ | ||
| 406 | "Use " #namespace "::" #func " instead.") | ||
| 407 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING | ||
| 408 | # define _GL_CXXALIASWARN_2(func,namespace) \ | ||
| 409 | extern __typeof__ (func) func | ||
| 410 | # else | ||
| 411 | # define _GL_CXXALIASWARN_2(func,namespace) \ | ||
| 412 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 413 | # endif | ||
| 414 | #else | ||
| 415 | # define _GL_CXXALIASWARN(func) \ | ||
| 416 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 417 | #endif | ||
| 418 | |||
| 419 | /* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); | ||
| 420 | causes a warning to be emitted when the given overloaded variant of ::func | ||
| 421 | is used but not when GNULIB_NAMESPACE::func is used. */ | ||
| 422 | #if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 423 | # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ | ||
| 424 | _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ | ||
| 425 | GNULIB_NAMESPACE) | ||
| 426 | # define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ | ||
| 427 | _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) | ||
| 428 | /* To work around GCC bug <https://gcc.gnu.org/PR43881>, | ||
| 429 | we enable the warning only when not optimizing. */ | ||
| 430 | # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) | ||
| 431 | # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ | ||
| 432 | _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \ | ||
| 433 | "The symbol ::" #func " refers to the system function. " \ | ||
| 434 | "Use " #namespace "::" #func " instead.") | ||
| 435 | # else | ||
| 436 | # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ | ||
| 437 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 438 | # endif | ||
| 439 | #else | ||
| 440 | # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ | ||
| 441 | _GL_EXTERN_C int _gl_cxxalias_dummy | ||
| 442 | #endif | ||
| 443 | |||
| 444 | #endif /* _GL_CXXDEFS_H */ | ||
| 445 | |||
| 446 | /* The definition of _GL_ARG_NONNULL is copied here. */ | ||
| 447 | /* A C macro for declaring that specific arguments must not be NULL. | ||
| 448 | Copyright (C) 2009-2025 Free Software Foundation, Inc. | ||
| 449 | |||
| 450 | This program is free software: you can redistribute it and/or modify it | ||
| 451 | under the terms of the GNU Lesser General Public License as published | ||
| 452 | by the Free Software Foundation; either version 2 of the License, or | ||
| 453 | (at your option) any later version. | ||
| 454 | |||
| 455 | This program is distributed in the hope that it will be useful, | ||
| 456 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 457 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 458 | Lesser General Public License for more details. | ||
| 459 | |||
| 460 | You should have received a copy of the GNU Lesser General Public License | ||
| 461 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 462 | |||
| 463 | /* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools | ||
| 464 | that the values passed as arguments n, ..., m must be non-NULL pointers. | ||
| 465 | n = 1 stands for the first argument, n = 2 for the second argument etc. */ | ||
| 466 | #ifndef _GL_ARG_NONNULL | ||
| 467 | # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__ | ||
| 468 | # define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) | ||
| 469 | # else | ||
| 470 | # define _GL_ARG_NONNULL(params) | ||
| 471 | # endif | ||
| 472 | #endif | ||
| 473 | |||
| 474 | /* The definition of _GL_WARN_ON_USE is copied here. */ | ||
| 475 | /* A C macro for emitting warnings if a function is used. | ||
| 476 | Copyright (C) 2010-2025 Free Software Foundation, Inc. | ||
| 477 | |||
| 478 | This program is free software: you can redistribute it and/or modify it | ||
| 479 | under the terms of the GNU Lesser General Public License as published | ||
| 480 | by the Free Software Foundation; either version 2 of the License, or | ||
| 481 | (at your option) any later version. | ||
| 482 | |||
| 483 | This program is distributed in the hope that it will be useful, | ||
| 484 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 485 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 486 | Lesser General Public License for more details. | ||
| 487 | |||
| 488 | You should have received a copy of the GNU Lesser General Public License | ||
| 489 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 490 | |||
| 491 | /* _GL_WARN_ON_USE (function, "literal string") issues a declaration | ||
| 492 | for FUNCTION which will then trigger a compiler warning containing | ||
| 493 | the text of "literal string" anywhere that function is called, if | ||
| 494 | supported by the compiler. If the compiler does not support this | ||
| 495 | feature, the macro expands to an unused extern declaration. | ||
| 496 | |||
| 497 | _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the | ||
| 498 | attribute used in _GL_WARN_ON_USE. If the compiler does not support | ||
| 499 | this feature, it expands to empty. | ||
| 500 | |||
| 501 | These macros are useful for marking a function as a potential | ||
| 502 | portability trap, with the intent that "literal string" include | ||
| 503 | instructions on the replacement function that should be used | ||
| 504 | instead. | ||
| 505 | _GL_WARN_ON_USE is for functions with 'extern' linkage. | ||
| 506 | _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline' | ||
| 507 | linkage. | ||
| 508 | |||
| 509 | _GL_WARN_ON_USE should not be used more than once for a given function | ||
| 510 | in a given compilation unit (because this may generate a warning even | ||
| 511 | if the function is never called). | ||
| 512 | |||
| 513 | However, one of the reasons that a function is a portability trap is | ||
| 514 | if it has the wrong signature. Declaring FUNCTION with a different | ||
| 515 | signature in C is a compilation error, so this macro must use the | ||
| 516 | same type as any existing declaration so that programs that avoid | ||
| 517 | the problematic FUNCTION do not fail to compile merely because they | ||
| 518 | included a header that poisoned the function. But this implies that | ||
| 519 | _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already | ||
| 520 | have a declaration. Use of this macro implies that there must not | ||
| 521 | be any other macro hiding the declaration of FUNCTION; but | ||
| 522 | undefining FUNCTION first is part of the poisoning process anyway | ||
| 523 | (although for symbols that are provided only via a macro, the result | ||
| 524 | is a compilation error rather than a warning containing | ||
| 525 | "literal string"). Also note that in C++, it is only safe to use if | ||
| 526 | FUNCTION has no overloads. | ||
| 527 | |||
| 528 | For an example, it is possible to poison 'getline' by: | ||
| 529 | - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]], | ||
| 530 | [getline]) in configure.ac, which potentially defines | ||
| 531 | HAVE_RAW_DECL_GETLINE | ||
| 532 | - adding this code to a header that wraps the system <stdio.h>: | ||
| 533 | #undef getline | ||
| 534 | #if HAVE_RAW_DECL_GETLINE | ||
| 535 | _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but" | ||
| 536 | "not universally present; use the gnulib module getline"); | ||
| 537 | #endif | ||
| 538 | |||
| 539 | It is not possible to directly poison global variables. But it is | ||
| 540 | possible to write a wrapper accessor function, and poison that | ||
| 541 | (less common usage, like &environ, will cause a compilation error | ||
| 542 | rather than issue the nice warning, but the end result of informing | ||
| 543 | the developer about their portability problem is still achieved): | ||
| 544 | #if HAVE_RAW_DECL_ENVIRON | ||
| 545 | static char *** | ||
| 546 | rpl_environ (void) { return &environ; } | ||
| 547 | _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared"); | ||
| 548 | # undef environ | ||
| 549 | # define environ (*rpl_environ ()) | ||
| 550 | #endif | ||
| 551 | or better (avoiding contradictory use of 'static' and 'extern'): | ||
| 552 | #if HAVE_RAW_DECL_ENVIRON | ||
| 553 | static char *** | ||
| 554 | _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared") | ||
| 555 | rpl_environ (void) { return &environ; } | ||
| 556 | # undef environ | ||
| 557 | # define environ (*rpl_environ ()) | ||
| 558 | #endif | ||
| 559 | */ | ||
| 560 | #ifndef _GL_WARN_ON_USE | ||
| 561 | |||
| 562 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ | ||
| 563 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ | ||
| 564 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 565 | _GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message))) | ||
| 566 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) \ | ||
| 567 | __attribute__ ((__warning__ (message))) | ||
| 568 | # elif __clang_major__ >= 4 | ||
| 569 | /* Another compiler attribute is available in clang. */ | ||
| 570 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 571 | _GL_WARN_EXTERN_C __typeof__ (function) function \ | ||
| 572 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) | ||
| 573 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) \ | ||
| 574 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) | ||
| 575 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING | ||
| 576 | /* Verify the existence of the function. */ | ||
| 577 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 578 | _GL_WARN_EXTERN_C __typeof__ (function) function | ||
| 579 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) | ||
| 580 | # else /* Unsupported. */ | ||
| 581 | # define _GL_WARN_ON_USE(function, message) \ | ||
| 582 | _GL_WARN_EXTERN_C int _gl_warn_on_use | ||
| 583 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) | ||
| 584 | # endif | ||
| 585 | #endif | ||
| 586 | |||
| 587 | /* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message") | ||
| 588 | is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode the | ||
| 589 | function is declared with the given prototype, consisting of return type, | ||
| 590 | parameters, and attributes. | ||
| 591 | This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does | ||
| 592 | not work in this case. */ | ||
| 593 | #ifndef _GL_WARN_ON_USE_CXX | ||
| 594 | # if !defined __cplusplus | ||
| 595 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 596 | _GL_WARN_ON_USE (function, msg) | ||
| 597 | # else | ||
| 598 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ | ||
| 599 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ | ||
| 600 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 601 | extern rettype_gcc function parameters_and_attributes \ | ||
| 602 | __attribute__ ((__warning__ (msg))) | ||
| 603 | # elif __clang_major__ >= 4 | ||
| 604 | /* Another compiler attribute is available in clang. */ | ||
| 605 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 606 | extern rettype_clang function parameters_and_attributes \ | ||
| 607 | __attribute__ ((__diagnose_if__ (1, msg, "warning"))) | ||
| 608 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING | ||
| 609 | /* Verify the existence of the function. */ | ||
| 610 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 611 | extern rettype_gcc function parameters_and_attributes | ||
| 612 | # else /* Unsupported. */ | ||
| 613 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | ||
| 614 | _GL_WARN_EXTERN_C int _gl_warn_on_use | ||
| 615 | # endif | ||
| 616 | # endif | ||
| 617 | #endif | ||
| 618 | |||
| 619 | /* _GL_WARN_EXTERN_C declaration; | ||
| 620 | performs the declaration with C linkage. */ | ||
| 621 | #ifndef _GL_WARN_EXTERN_C | ||
| 622 | # if defined __cplusplus | ||
| 623 | # define _GL_WARN_EXTERN_C extern "C" | ||
| 624 | # else | ||
| 625 | # define _GL_WARN_EXTERN_C extern | ||
| 626 | # endif | ||
| 627 | #endif | ||
| 628 | |||
| 629 | |||
| 630 | _GL_INLINE_HEADER_BEGIN | ||
| 631 | |||
| 632 | |||
| 633 | #if !(defined __cplusplus ? 0 || 0 : 1) | ||
| 634 | |||
| 635 | /* An 8-bit variant of wchar_t. | ||
| 636 | Note: This type is only mandated by ISO C 23 or newer, and it does | ||
| 637 | denote UTF-8 units. */ | ||
| 638 | typedef unsigned char char8_t; | ||
| 639 | |||
| 640 | #elif 0 | ||
| 641 | |||
| 642 | typedef unsigned char gl_char8_t; | ||
| 643 | # define char8_t gl_char8_t | ||
| 644 | |||
| 645 | #endif | ||
| 646 | |||
| 647 | #if !(defined __cplusplus ? 0 || 0 : 1) | ||
| 648 | |||
| 649 | /* A 16-bit variant of wchar_t. | ||
| 650 | Note: This type is only mandated by ISO C 11 or newer. In ISO C 23 | ||
| 651 | and newer, it denotes UTF-16 units; in older versions of ISO C it did | ||
| 652 | so only on platforms on which __STDC_UTF_16__ was defined. */ | ||
| 653 | typedef uint_least16_t char16_t; | ||
| 654 | |||
| 655 | #elif 0 | ||
| 656 | |||
| 657 | typedef uint_least16_t gl_char16_t; | ||
| 658 | # define char16_t gl_char16_t | ||
| 659 | |||
| 660 | #endif | ||
| 661 | |||
| 662 | #if !(defined __cplusplus ? 0 || 0 : 1) | ||
| 663 | |||
| 664 | /* A 32-bit variant of wchar_t. | ||
| 665 | Note: This type is only mandated by ISO C 11 or newer. In ISO C 23 | ||
| 666 | and newer, it denotes UTF-32 code points; in older versions of ISO C | ||
| 667 | it did so only on platforms on which __STDC_UTF_32__ was defined. | ||
| 668 | In gnulib, we guarantee that it denotes UTF-32 code points if and | ||
| 669 | only if the module 'uchar-h-c23' is in use. */ | ||
| 670 | typedef uint_least32_t char32_t; | ||
| 671 | |||
| 672 | #elif 0 | ||
| 673 | |||
| 674 | typedef uint_least32_t gl_char32_t; | ||
| 675 | # define char32_t gl_char32_t | ||
| 676 | |||
| 677 | #endif | ||
| 678 | |||
| 679 | /* Define if a 'char32_t' can hold more characters than a 'wchar_t'. */ | ||
| 680 | #if 0 /* 32-bit AIX, Cygwin, native Windows */ | ||
| 681 | # define _GL_SMALL_WCHAR_T 1 | ||
| 682 | #endif | ||
| 683 | |||
| 684 | /* Define if 'wchar_t', like 'char32_t', | ||
| 685 | - is a 32-bit type, and | ||
| 686 | - represents Unicode code points. | ||
| 687 | For this test, we can use __STDC_ISO_10646__ (defined by glibc, musl libc, | ||
| 688 | Cygwin) but need to consider _GL_SMALL_WCHAR_T, so as to exclude Cygwin. | ||
| 689 | We cannot use __STDC_UTF_16__ or __STDC_UTF_32__ | ||
| 690 | - because these macros provide info about char16_t and char32_t (not | ||
| 691 | wchar_t!), and | ||
| 692 | - because GCC >= 4.9 defines these macros on all platforms, even on | ||
| 693 | FreeBSD and Solaris. | ||
| 694 | We should better not use __STD_UTF_16__, __STD_UTF_32__ either, because | ||
| 695 | these macros are misspellings, only defined by Android's <uchar.h>. */ | ||
| 696 | #if defined __STDC_ISO_10646__ && !_GL_SMALL_WCHAR_T | ||
| 697 | /* glibc, musl libc */ | ||
| 698 | # define _GL_WCHAR_T_IS_UCS4 1 | ||
| 699 | #endif | ||
| 700 | #if _GL_WCHAR_T_IS_UCS4 | ||
| 701 | static_assert (sizeof (char32_t) == sizeof (wchar_t)); | ||
| 702 | #endif | ||
| 703 | |||
| 704 | |||
| 705 | /* Convert a single-byte character to a 32-bit wide character. */ | ||
| 706 | #if 0 | ||
| 707 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_BTOC32 | ||
| 708 | _GL_BEGIN_C_LINKAGE | ||
| 709 | _GL_INLINE _GL_ATTRIBUTE_PURE wint_t | ||
| 710 | btoc32 (int c) | ||
| 711 | { | ||
| 712 | return | ||
| 713 | # if 1 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 714 | GNULIB_NAMESPACE:: | ||
| 715 | # endif | ||
| 716 | btowc (c); | ||
| 717 | } | ||
| 718 | _GL_END_C_LINKAGE | ||
| 719 | # else | ||
| 720 | _GL_FUNCDECL_SYS (btoc32, wint_t, (int c), _GL_ATTRIBUTE_PURE); | ||
| 721 | # endif | ||
| 722 | _GL_CXXALIAS_SYS (btoc32, wint_t, (int c)); | ||
| 723 | _GL_CXXALIASWARN (btoc32); | ||
| 724 | #endif | ||
| 725 | |||
| 726 | |||
| 727 | /* Test a specific property of a 32-bit wide character. */ | ||
| 728 | #if 1 | ||
| 729 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISALNUM | ||
| 730 | _GL_BEGIN_C_LINKAGE | ||
| 731 | _GL_INLINE int | ||
| 732 | c32isalnum (wint_t wc) | ||
| 733 | { | ||
| 734 | return | ||
| 735 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 736 | GNULIB_NAMESPACE:: | ||
| 737 | # endif | ||
| 738 | iswalnum (wc); | ||
| 739 | } | ||
| 740 | _GL_END_C_LINKAGE | ||
| 741 | # else | ||
| 742 | _GL_FUNCDECL_SYS (c32isalnum, int, (wint_t wc), ); | ||
| 743 | # endif | ||
| 744 | _GL_CXXALIAS_SYS (c32isalnum, int, (wint_t wc)); | ||
| 745 | _GL_CXXALIASWARN (c32isalnum); | ||
| 746 | #endif | ||
| 747 | #if 1 | ||
| 748 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISALPHA | ||
| 749 | _GL_BEGIN_C_LINKAGE | ||
| 750 | _GL_INLINE int | ||
| 751 | c32isalpha (wint_t wc) | ||
| 752 | { | ||
| 753 | return | ||
| 754 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 755 | GNULIB_NAMESPACE:: | ||
| 756 | # endif | ||
| 757 | iswalpha (wc); | ||
| 758 | } | ||
| 759 | _GL_END_C_LINKAGE | ||
| 760 | # else | ||
| 761 | _GL_FUNCDECL_SYS (c32isalpha, int, (wint_t wc), ); | ||
| 762 | # endif | ||
| 763 | _GL_CXXALIAS_SYS (c32isalpha, int, (wint_t wc)); | ||
| 764 | _GL_CXXALIASWARN (c32isalpha); | ||
| 765 | #endif | ||
| 766 | #if 1 | ||
| 767 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISBLANK | ||
| 768 | _GL_BEGIN_C_LINKAGE | ||
| 769 | _GL_INLINE int | ||
| 770 | c32isblank (wint_t wc) | ||
| 771 | { | ||
| 772 | return | ||
| 773 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 774 | GNULIB_NAMESPACE:: | ||
| 775 | # endif | ||
| 776 | iswblank (wc); | ||
| 777 | } | ||
| 778 | _GL_END_C_LINKAGE | ||
| 779 | # else | ||
| 780 | _GL_FUNCDECL_SYS (c32isblank, int, (wint_t wc), ); | ||
| 781 | # endif | ||
| 782 | _GL_CXXALIAS_SYS (c32isblank, int, (wint_t wc)); | ||
| 783 | _GL_CXXALIASWARN (c32isblank); | ||
| 784 | #endif | ||
| 785 | #if 1 | ||
| 786 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISCNTRL | ||
| 787 | _GL_BEGIN_C_LINKAGE | ||
| 788 | _GL_INLINE int | ||
| 789 | c32iscntrl (wint_t wc) | ||
| 790 | { | ||
| 791 | return | ||
| 792 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 793 | GNULIB_NAMESPACE:: | ||
| 794 | # endif | ||
| 795 | iswcntrl (wc); | ||
| 796 | } | ||
| 797 | _GL_END_C_LINKAGE | ||
| 798 | # else | ||
| 799 | _GL_FUNCDECL_SYS (c32iscntrl, int, (wint_t wc), ); | ||
| 800 | # endif | ||
| 801 | _GL_CXXALIAS_SYS (c32iscntrl, int, (wint_t wc)); | ||
| 802 | _GL_CXXALIASWARN (c32iscntrl); | ||
| 803 | #endif | ||
| 804 | #if 1 | ||
| 805 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISDIGIT | ||
| 806 | _GL_BEGIN_C_LINKAGE | ||
| 807 | _GL_INLINE int | ||
| 808 | c32isdigit (wint_t wc) | ||
| 809 | { | ||
| 810 | return | ||
| 811 | # if 1 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 812 | GNULIB_NAMESPACE:: | ||
| 813 | # endif | ||
| 814 | iswdigit (wc); | ||
| 815 | } | ||
| 816 | _GL_END_C_LINKAGE | ||
| 817 | # else | ||
| 818 | _GL_FUNCDECL_SYS (c32isdigit, int, (wint_t wc), ); | ||
| 819 | # endif | ||
| 820 | _GL_CXXALIAS_SYS (c32isdigit, int, (wint_t wc)); | ||
| 821 | _GL_CXXALIASWARN (c32isdigit); | ||
| 822 | #endif | ||
| 823 | #if 1 | ||
| 824 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISGRAPH | ||
| 825 | _GL_BEGIN_C_LINKAGE | ||
| 826 | _GL_INLINE int | ||
| 827 | c32isgraph (wint_t wc) | ||
| 828 | { | ||
| 829 | return | ||
| 830 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 831 | GNULIB_NAMESPACE:: | ||
| 832 | # endif | ||
| 833 | iswgraph (wc); | ||
| 834 | } | ||
| 835 | _GL_END_C_LINKAGE | ||
| 836 | # else | ||
| 837 | _GL_FUNCDECL_SYS (c32isgraph, int, (wint_t wc), ); | ||
| 838 | # endif | ||
| 839 | _GL_CXXALIAS_SYS (c32isgraph, int, (wint_t wc)); | ||
| 840 | _GL_CXXALIASWARN (c32isgraph); | ||
| 841 | #endif | ||
| 842 | #if 1 | ||
| 843 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISLOWER | ||
| 844 | _GL_BEGIN_C_LINKAGE | ||
| 845 | _GL_INLINE int | ||
| 846 | c32islower (wint_t wc) | ||
| 847 | { | ||
| 848 | return | ||
| 849 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 850 | GNULIB_NAMESPACE:: | ||
| 851 | # endif | ||
| 852 | iswlower (wc); | ||
| 853 | } | ||
| 854 | _GL_END_C_LINKAGE | ||
| 855 | # else | ||
| 856 | _GL_FUNCDECL_SYS (c32islower, int, (wint_t wc), ); | ||
| 857 | # endif | ||
| 858 | _GL_CXXALIAS_SYS (c32islower, int, (wint_t wc)); | ||
| 859 | _GL_CXXALIASWARN (c32islower); | ||
| 860 | #endif | ||
| 861 | #if 1 | ||
| 862 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISPRINT | ||
| 863 | _GL_BEGIN_C_LINKAGE | ||
| 864 | _GL_INLINE int | ||
| 865 | c32isprint (wint_t wc) | ||
| 866 | { | ||
| 867 | return | ||
| 868 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 869 | GNULIB_NAMESPACE:: | ||
| 870 | # endif | ||
| 871 | iswprint (wc); | ||
| 872 | } | ||
| 873 | _GL_END_C_LINKAGE | ||
| 874 | # else | ||
| 875 | _GL_FUNCDECL_SYS (c32isprint, int, (wint_t wc), ); | ||
| 876 | # endif | ||
| 877 | _GL_CXXALIAS_SYS (c32isprint, int, (wint_t wc)); | ||
| 878 | _GL_CXXALIASWARN (c32isprint); | ||
| 879 | #endif | ||
| 880 | #if 1 | ||
| 881 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISPUNCT | ||
| 882 | _GL_BEGIN_C_LINKAGE | ||
| 883 | _GL_INLINE int | ||
| 884 | c32ispunct (wint_t wc) | ||
| 885 | { | ||
| 886 | return | ||
| 887 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 888 | GNULIB_NAMESPACE:: | ||
| 889 | # endif | ||
| 890 | iswpunct (wc); | ||
| 891 | } | ||
| 892 | _GL_END_C_LINKAGE | ||
| 893 | # else | ||
| 894 | _GL_FUNCDECL_SYS (c32ispunct, int, (wint_t wc), ); | ||
| 895 | # endif | ||
| 896 | _GL_CXXALIAS_SYS (c32ispunct, int, (wint_t wc)); | ||
| 897 | _GL_CXXALIASWARN (c32ispunct); | ||
| 898 | #endif | ||
| 899 | #if 1 | ||
| 900 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISSPACE | ||
| 901 | _GL_BEGIN_C_LINKAGE | ||
| 902 | _GL_INLINE int | ||
| 903 | c32isspace (wint_t wc) | ||
| 904 | { | ||
| 905 | return | ||
| 906 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 907 | GNULIB_NAMESPACE:: | ||
| 908 | # endif | ||
| 909 | iswspace (wc); | ||
| 910 | } | ||
| 911 | _GL_END_C_LINKAGE | ||
| 912 | # else | ||
| 913 | _GL_FUNCDECL_SYS (c32isspace, int, (wint_t wc), ); | ||
| 914 | # endif | ||
| 915 | _GL_CXXALIAS_SYS (c32isspace, int, (wint_t wc)); | ||
| 916 | _GL_CXXALIASWARN (c32isspace); | ||
| 917 | #endif | ||
| 918 | #if 1 | ||
| 919 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISUPPER | ||
| 920 | _GL_BEGIN_C_LINKAGE | ||
| 921 | _GL_INLINE int | ||
| 922 | c32isupper (wint_t wc) | ||
| 923 | { | ||
| 924 | return | ||
| 925 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 926 | GNULIB_NAMESPACE:: | ||
| 927 | # endif | ||
| 928 | iswupper (wc); | ||
| 929 | } | ||
| 930 | _GL_END_C_LINKAGE | ||
| 931 | # else | ||
| 932 | _GL_FUNCDECL_SYS (c32isupper, int, (wint_t wc), ); | ||
| 933 | # endif | ||
| 934 | _GL_CXXALIAS_SYS (c32isupper, int, (wint_t wc)); | ||
| 935 | _GL_CXXALIASWARN (c32isupper); | ||
| 936 | #endif | ||
| 937 | #if 1 | ||
| 938 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISXDIGIT | ||
| 939 | _GL_BEGIN_C_LINKAGE | ||
| 940 | _GL_INLINE int | ||
| 941 | c32isxdigit (wint_t wc) | ||
| 942 | { | ||
| 943 | return | ||
| 944 | # if 1 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 945 | GNULIB_NAMESPACE:: | ||
| 946 | # endif | ||
| 947 | iswxdigit (wc); | ||
| 948 | } | ||
| 949 | _GL_END_C_LINKAGE | ||
| 950 | # else | ||
| 951 | _GL_FUNCDECL_SYS (c32isxdigit, int, (wint_t wc), ); | ||
| 952 | # endif | ||
| 953 | _GL_CXXALIAS_SYS (c32isxdigit, int, (wint_t wc)); | ||
| 954 | _GL_CXXALIASWARN (c32isxdigit); | ||
| 955 | #endif | ||
| 956 | |||
| 957 | |||
| 958 | /* Case mapping of a 32-bit wide character. */ | ||
| 959 | #if 1 | ||
| 960 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32TOLOWER | ||
| 961 | _GL_BEGIN_C_LINKAGE | ||
| 962 | _GL_INLINE wint_t | ||
| 963 | c32tolower (wint_t wc) | ||
| 964 | { | ||
| 965 | return | ||
| 966 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 967 | GNULIB_NAMESPACE:: | ||
| 968 | # endif | ||
| 969 | towlower (wc); | ||
| 970 | } | ||
| 971 | _GL_END_C_LINKAGE | ||
| 972 | # else | ||
| 973 | _GL_FUNCDECL_SYS (c32tolower, wint_t, (wint_t wc), ); | ||
| 974 | # endif | ||
| 975 | _GL_CXXALIAS_SYS (c32tolower, wint_t, (wint_t wc)); | ||
| 976 | _GL_CXXALIASWARN (c32tolower); | ||
| 977 | #endif | ||
| 978 | #if 0 | ||
| 979 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32TOUPPER | ||
| 980 | _GL_BEGIN_C_LINKAGE | ||
| 981 | _GL_INLINE wint_t | ||
| 982 | c32toupper (wint_t wc) | ||
| 983 | { | ||
| 984 | return | ||
| 985 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 986 | GNULIB_NAMESPACE:: | ||
| 987 | # endif | ||
| 988 | towupper (wc); | ||
| 989 | } | ||
| 990 | _GL_END_C_LINKAGE | ||
| 991 | # else | ||
| 992 | _GL_FUNCDECL_SYS (c32toupper, wint_t, (wint_t wc), ); | ||
| 993 | # endif | ||
| 994 | _GL_CXXALIAS_SYS (c32toupper, wint_t, (wint_t wc)); | ||
| 995 | _GL_CXXALIASWARN (c32toupper); | ||
| 996 | #endif | ||
| 997 | |||
| 998 | |||
| 999 | /* Number of screen columns needed for a 32-bit wide character. */ | ||
| 1000 | #if 1 | ||
| 1001 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32WIDTH | ||
| 1002 | _GL_BEGIN_C_LINKAGE | ||
| 1003 | _GL_INLINE int | ||
| 1004 | c32width (char32_t wc) | ||
| 1005 | { | ||
| 1006 | return | ||
| 1007 | # if 1 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1008 | GNULIB_NAMESPACE:: | ||
| 1009 | # endif | ||
| 1010 | wcwidth (wc); | ||
| 1011 | } | ||
| 1012 | _GL_END_C_LINKAGE | ||
| 1013 | # else | ||
| 1014 | _GL_FUNCDECL_SYS (c32width, int, (char32_t wc), ); | ||
| 1015 | # endif | ||
| 1016 | _GL_CXXALIAS_SYS (c32width, int, (char32_t wc)); | ||
| 1017 | _GL_CXXALIASWARN (c32width); | ||
| 1018 | #endif | ||
| 1019 | |||
| 1020 | |||
| 1021 | /* Converts a 32-bit wide character to a multibyte character. */ | ||
| 1022 | #if 0 | ||
| 1023 | # if 0 | ||
| 1024 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1025 | # undef c32rtomb | ||
| 1026 | # define c32rtomb rpl_c32rtomb | ||
| 1027 | # endif | ||
| 1028 | _GL_FUNCDECL_RPL (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps), ); | ||
| 1029 | _GL_CXXALIAS_RPL (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps)); | ||
| 1030 | # else | ||
| 1031 | # if !1 | ||
| 1032 | _GL_FUNCDECL_SYS (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps), ); | ||
| 1033 | # endif | ||
| 1034 | _GL_CXXALIAS_SYS (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps)); | ||
| 1035 | # endif | ||
| 1036 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 | ||
| 1037 | _GL_CXXALIASWARN (c32rtomb); | ||
| 1038 | # endif | ||
| 1039 | #elif defined GNULIB_POSIXCHECK | ||
| 1040 | # if HAVE_RAW_DECL_C32RTOMB | ||
| 1041 | _GL_WARN_ON_USE (c32rtomb, "c32rtomb is not portable - " | ||
| 1042 | "use gnulib module c32rtomb for portability"); | ||
| 1043 | # endif | ||
| 1044 | #endif | ||
| 1045 | |||
| 1046 | |||
| 1047 | /* Convert a 32-bit wide string to a string. */ | ||
| 1048 | #if 0 | ||
| 1049 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32SNRTOMBS | ||
| 1050 | _GL_BEGIN_C_LINKAGE | ||
| 1051 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 1052 | c32snrtombs (char *dest, const char32_t **srcp, size_t srclen, size_t len, | ||
| 1053 | mbstate_t *ps) | ||
| 1054 | { | ||
| 1055 | return | ||
| 1056 | # if 0 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1057 | GNULIB_NAMESPACE:: | ||
| 1058 | # endif | ||
| 1059 | wcsnrtombs (dest, (const wchar_t **) srcp, srclen, len, ps); | ||
| 1060 | } | ||
| 1061 | _GL_END_C_LINKAGE | ||
| 1062 | # else | ||
| 1063 | _GL_FUNCDECL_SYS (c32snrtombs, size_t, | ||
| 1064 | (char *dest, const char32_t **srcp, size_t srclen, size_t len, | ||
| 1065 | mbstate_t *ps), | ||
| 1066 | _GL_ARG_NONNULL ((2))); | ||
| 1067 | # endif | ||
| 1068 | _GL_CXXALIAS_SYS (c32snrtombs, size_t, | ||
| 1069 | (char *dest, const char32_t **srcp, size_t srclen, size_t len, | ||
| 1070 | mbstate_t *ps)); | ||
| 1071 | _GL_CXXALIASWARN (c32snrtombs); | ||
| 1072 | #endif | ||
| 1073 | |||
| 1074 | |||
| 1075 | /* Convert a 32-bit wide string to a string. */ | ||
| 1076 | #if 0 | ||
| 1077 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32SRTOMBS | ||
| 1078 | _GL_BEGIN_C_LINKAGE | ||
| 1079 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 1080 | c32srtombs (char *dest, const char32_t **srcp, size_t len, mbstate_t *ps) | ||
| 1081 | { | ||
| 1082 | return | ||
| 1083 | # if 0 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1084 | GNULIB_NAMESPACE:: | ||
| 1085 | # endif | ||
| 1086 | wcsrtombs (dest, (const wchar_t **) srcp, len, ps); | ||
| 1087 | } | ||
| 1088 | _GL_END_C_LINKAGE | ||
| 1089 | # else | ||
| 1090 | _GL_FUNCDECL_SYS (c32srtombs, size_t, | ||
| 1091 | (char *dest, const char32_t **srcp, size_t len, | ||
| 1092 | mbstate_t *ps), | ||
| 1093 | _GL_ARG_NONNULL ((2))); | ||
| 1094 | # endif | ||
| 1095 | _GL_CXXALIAS_SYS (c32srtombs, size_t, | ||
| 1096 | (char *dest, const char32_t **srcp, size_t len, | ||
| 1097 | mbstate_t *ps)); | ||
| 1098 | _GL_CXXALIASWARN (c32srtombs); | ||
| 1099 | #endif | ||
| 1100 | |||
| 1101 | |||
| 1102 | /* Convert a 32-bit wide string to a string. */ | ||
| 1103 | #if 0 | ||
| 1104 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32STOMBS | ||
| 1105 | _GL_BEGIN_C_LINKAGE | ||
| 1106 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 1107 | c32stombs (char *dest, const char32_t *src, size_t len) | ||
| 1108 | { | ||
| 1109 | mbstate_t state; | ||
| 1110 | |||
| 1111 | mbszero (&state); | ||
| 1112 | return c32srtombs (dest, &src, len, &state); | ||
| 1113 | } | ||
| 1114 | _GL_END_C_LINKAGE | ||
| 1115 | # else | ||
| 1116 | _GL_FUNCDECL_SYS (c32stombs, size_t, | ||
| 1117 | (char *dest, const char32_t *src, size_t len), | ||
| 1118 | _GL_ARG_NONNULL ((2))); | ||
| 1119 | # endif | ||
| 1120 | _GL_CXXALIAS_SYS (c32stombs, size_t, | ||
| 1121 | (char *dest, const char32_t *src, size_t len)); | ||
| 1122 | _GL_CXXALIASWARN (c32stombs); | ||
| 1123 | #endif | ||
| 1124 | |||
| 1125 | |||
| 1126 | /* Number of screen columns needed for a size-bounded 32-bit wide string. */ | ||
| 1127 | #if 0 | ||
| 1128 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32SWIDTH | ||
| 1129 | _GL_BEGIN_C_LINKAGE | ||
| 1130 | _GL_INLINE _GL_ARG_NONNULL ((1)) int | ||
| 1131 | c32swidth (const char32_t *s, size_t n) | ||
| 1132 | { | ||
| 1133 | return | ||
| 1134 | # if 0 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1135 | GNULIB_NAMESPACE:: | ||
| 1136 | # endif | ||
| 1137 | wcswidth ((const wchar_t *) s, n); | ||
| 1138 | } | ||
| 1139 | _GL_END_C_LINKAGE | ||
| 1140 | # else | ||
| 1141 | _GL_FUNCDECL_SYS (c32swidth, int, (const char32_t *s, size_t n), | ||
| 1142 | _GL_ARG_NONNULL ((1))); | ||
| 1143 | # endif | ||
| 1144 | _GL_CXXALIAS_SYS (c32swidth, int, (const char32_t *s, size_t n)); | ||
| 1145 | _GL_CXXALIASWARN (c32swidth); | ||
| 1146 | #endif | ||
| 1147 | |||
| 1148 | |||
| 1149 | /* Converts a 32-bit wide character to unibyte character. | ||
| 1150 | Returns the single-byte representation of WC if it exists, | ||
| 1151 | or EOF otherwise. */ | ||
| 1152 | #if 0 | ||
| 1153 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32TOB | ||
| 1154 | _GL_BEGIN_C_LINKAGE | ||
| 1155 | _GL_INLINE int | ||
| 1156 | c32tob (wint_t wc) | ||
| 1157 | { | ||
| 1158 | return | ||
| 1159 | # if 0 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1160 | GNULIB_NAMESPACE:: | ||
| 1161 | # endif | ||
| 1162 | wctob (wc); | ||
| 1163 | } | ||
| 1164 | _GL_END_C_LINKAGE | ||
| 1165 | # else | ||
| 1166 | _GL_FUNCDECL_SYS (c32tob, int, (wint_t wc), ); | ||
| 1167 | # endif | ||
| 1168 | _GL_CXXALIAS_SYS (c32tob, int, (wint_t wc)); | ||
| 1169 | _GL_CXXALIASWARN (c32tob); | ||
| 1170 | #endif | ||
| 1171 | |||
| 1172 | |||
| 1173 | /* Converts a multibyte character to a 32-bit wide character. */ | ||
| 1174 | #if 1 | ||
| 1175 | # if 1 | ||
| 1176 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1177 | # undef mbrtoc32 | ||
| 1178 | # define mbrtoc32 rpl_mbrtoc32 | ||
| 1179 | # endif | ||
| 1180 | _GL_FUNCDECL_RPL (mbrtoc32, size_t, | ||
| 1181 | (char32_t *pc, const char *s, size_t n, mbstate_t *ps), ); | ||
| 1182 | _GL_CXXALIAS_RPL (mbrtoc32, size_t, | ||
| 1183 | (char32_t *pc, const char *s, size_t n, mbstate_t *ps)); | ||
| 1184 | # else | ||
| 1185 | # if !1 | ||
| 1186 | _GL_FUNCDECL_SYS (mbrtoc32, size_t, | ||
| 1187 | (char32_t *pc, const char *s, size_t n, mbstate_t *ps), ); | ||
| 1188 | # endif | ||
| 1189 | _GL_CXXALIAS_SYS (mbrtoc32, size_t, | ||
| 1190 | (char32_t *pc, const char *s, size_t n, mbstate_t *ps)); | ||
| 1191 | # endif | ||
| 1192 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 | ||
| 1193 | _GL_CXXALIASWARN (mbrtoc32); | ||
| 1194 | # endif | ||
| 1195 | #elif defined GNULIB_POSIXCHECK | ||
| 1196 | # if HAVE_RAW_DECL_MBRTOC32 | ||
| 1197 | _GL_WARN_ON_USE (mbrtoc32, "mbrtoc32 is not portable - " | ||
| 1198 | "use gnulib module mbrtoc32 for portability"); | ||
| 1199 | # endif | ||
| 1200 | #endif | ||
| 1201 | |||
| 1202 | |||
| 1203 | /* Converts a multibyte character and returns the next 16-bit wide | ||
| 1204 | character. */ | ||
| 1205 | #if 0 | ||
| 1206 | # if 0 | ||
| 1207 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 1208 | # undef mbrtoc16 | ||
| 1209 | # define mbrtoc16 rpl_mbrtoc16 | ||
| 1210 | # endif | ||
| 1211 | _GL_FUNCDECL_RPL (mbrtoc16, size_t, | ||
| 1212 | (char16_t *pc, const char *s, size_t n, mbstate_t *ps), ); | ||
| 1213 | _GL_CXXALIAS_RPL (mbrtoc16, size_t, | ||
| 1214 | (char16_t *pc, const char *s, size_t n, mbstate_t *ps)); | ||
| 1215 | # else | ||
| 1216 | # if !1 | ||
| 1217 | _GL_FUNCDECL_SYS (mbrtoc16, size_t, | ||
| 1218 | (char16_t *pc, const char *s, size_t n, mbstate_t *ps), ); | ||
| 1219 | # endif | ||
| 1220 | _GL_CXXALIAS_SYS (mbrtoc16, size_t, | ||
| 1221 | (char16_t *pc, const char *s, size_t n, mbstate_t *ps)); | ||
| 1222 | # endif | ||
| 1223 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 | ||
| 1224 | _GL_CXXALIASWARN (mbrtoc16); | ||
| 1225 | # endif | ||
| 1226 | #elif defined GNULIB_POSIXCHECK | ||
| 1227 | # if HAVE_RAW_DECL_MBRTOC16 | ||
| 1228 | _GL_WARN_ON_USE (mbrtoc16, "mbrtoc16 is not portable - " | ||
| 1229 | "use gnulib module mbrtoc16 for portability"); | ||
| 1230 | # endif | ||
| 1231 | #endif | ||
| 1232 | |||
| 1233 | |||
| 1234 | /* Convert a string to a 32-bit wide string. */ | ||
| 1235 | #if 0 | ||
| 1236 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSNRTOC32S | ||
| 1237 | _GL_BEGIN_C_LINKAGE | ||
| 1238 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 1239 | mbsnrtoc32s (char32_t *dest, const char **srcp, size_t srclen, size_t len, | ||
| 1240 | mbstate_t *ps) | ||
| 1241 | { | ||
| 1242 | return | ||
| 1243 | # if 0 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1244 | GNULIB_NAMESPACE:: | ||
| 1245 | # endif | ||
| 1246 | mbsnrtowcs ((wchar_t *) dest, srcp, srclen, len, ps); | ||
| 1247 | } | ||
| 1248 | _GL_END_C_LINKAGE | ||
| 1249 | # else | ||
| 1250 | _GL_FUNCDECL_SYS (mbsnrtoc32s, size_t, | ||
| 1251 | (char32_t *dest, const char **srcp, size_t srclen, size_t len, | ||
| 1252 | mbstate_t *ps), | ||
| 1253 | _GL_ARG_NONNULL ((2))); | ||
| 1254 | # endif | ||
| 1255 | _GL_CXXALIAS_SYS (mbsnrtoc32s, size_t, | ||
| 1256 | (char32_t *dest, const char **srcp, size_t srclen, size_t len, | ||
| 1257 | mbstate_t *ps)); | ||
| 1258 | _GL_CXXALIASWARN (mbsnrtoc32s); | ||
| 1259 | #endif | ||
| 1260 | |||
| 1261 | |||
| 1262 | /* Convert a string to a 32-bit wide string. */ | ||
| 1263 | #if 0 | ||
| 1264 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSRTOC32S | ||
| 1265 | _GL_BEGIN_C_LINKAGE | ||
| 1266 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 1267 | mbsrtoc32s (char32_t *dest, const char **srcp, size_t len, mbstate_t *ps) | ||
| 1268 | { | ||
| 1269 | return | ||
| 1270 | # if 0 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1271 | GNULIB_NAMESPACE:: | ||
| 1272 | # endif | ||
| 1273 | mbsrtowcs ((wchar_t *) dest, srcp, len, ps); | ||
| 1274 | } | ||
| 1275 | _GL_END_C_LINKAGE | ||
| 1276 | # else | ||
| 1277 | _GL_FUNCDECL_SYS (mbsrtoc32s, size_t, | ||
| 1278 | (char32_t *dest, const char **srcp, size_t len, | ||
| 1279 | mbstate_t *ps), | ||
| 1280 | _GL_ARG_NONNULL ((2))); | ||
| 1281 | # endif | ||
| 1282 | _GL_CXXALIAS_SYS (mbsrtoc32s, size_t, | ||
| 1283 | (char32_t *dest, const char **srcp, size_t len, | ||
| 1284 | mbstate_t *ps)); | ||
| 1285 | _GL_CXXALIASWARN (mbsrtoc32s); | ||
| 1286 | #endif | ||
| 1287 | |||
| 1288 | |||
| 1289 | /* Convert a string to a 32-bit wide string. */ | ||
| 1290 | #if 0 | ||
| 1291 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSTOC32S | ||
| 1292 | _GL_BEGIN_C_LINKAGE | ||
| 1293 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 1294 | mbstoc32s (char32_t *dest, const char *src, size_t len) | ||
| 1295 | { | ||
| 1296 | mbstate_t state; | ||
| 1297 | |||
| 1298 | mbszero (&state); | ||
| 1299 | return mbsrtoc32s (dest, &src, len, &state); | ||
| 1300 | } | ||
| 1301 | _GL_END_C_LINKAGE | ||
| 1302 | # else | ||
| 1303 | _GL_FUNCDECL_SYS (mbstoc32s, size_t, | ||
| 1304 | (char32_t *dest, const char *src, size_t len), | ||
| 1305 | _GL_ARG_NONNULL ((2))); | ||
| 1306 | # endif | ||
| 1307 | _GL_CXXALIAS_SYS (mbstoc32s, size_t, | ||
| 1308 | (char32_t *dest, const char *src, size_t len)); | ||
| 1309 | _GL_CXXALIASWARN (mbstoc32s); | ||
| 1310 | #endif | ||
| 1311 | |||
| 1312 | |||
| 1313 | #if 0 || 0 | ||
| 1314 | /* A scalar type. Instances of this type, other than (c32_type_test_t) 0, | ||
| 1315 | represent a character property, sometimes also viewed as a "character class". | ||
| 1316 | It can be applied to 32-bit wide characters. It is the counterpart of | ||
| 1317 | type 'wctype_t' for wide characters. | ||
| 1318 | To test whether a given character has a certain property, use the function | ||
| 1319 | 'c32_apply_type_test'. */ | ||
| 1320 | # if _GL_WCHAR_T_IS_UCS4 | ||
| 1321 | typedef wctype_t c32_type_test_t; | ||
| 1322 | # else | ||
| 1323 | typedef /*bool*/int (*c32_type_test_t) (wint_t wc); | ||
| 1324 | # endif | ||
| 1325 | #endif | ||
| 1326 | |||
| 1327 | /* Return a character property with the given name, or (c32_type_test_t) 0 | ||
| 1328 | if the designated property does not exist. | ||
| 1329 | This function is the counterpart of function 'wctype' for wide characters. | ||
| 1330 | */ | ||
| 1331 | #if 0 | ||
| 1332 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32_GET_TYPE_TEST | ||
| 1333 | _GL_BEGIN_C_LINKAGE | ||
| 1334 | _GL_INLINE _GL_ARG_NONNULL ((1)) c32_type_test_t | ||
| 1335 | c32_get_type_test (const char *name) | ||
| 1336 | { | ||
| 1337 | return | ||
| 1338 | # if 1 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1339 | GNULIB_NAMESPACE:: | ||
| 1340 | # endif | ||
| 1341 | wctype (name); | ||
| 1342 | } | ||
| 1343 | _GL_END_C_LINKAGE | ||
| 1344 | # else | ||
| 1345 | _GL_FUNCDECL_SYS (c32_get_type_test, c32_type_test_t, (const char *name), | ||
| 1346 | _GL_ARG_NONNULL ((1))); | ||
| 1347 | # endif | ||
| 1348 | _GL_CXXALIAS_SYS (c32_get_type_test, c32_type_test_t, (const char *name)); | ||
| 1349 | _GL_CXXALIASWARN (c32_get_type_test); | ||
| 1350 | #endif | ||
| 1351 | |||
| 1352 | /* Test whether a given 32-bit wide character has the specified character | ||
| 1353 | property. | ||
| 1354 | Return non-zero if true, zero if false or if the argument is WEOF. | ||
| 1355 | This function is the counterpart of function 'iswctype' for wide characters. | ||
| 1356 | */ | ||
| 1357 | #if 0 | ||
| 1358 | # if _GL_WCHAR_T_IS_UCS4 | ||
| 1359 | # if !defined IN_C32_APPLY_TYPE_TEST | ||
| 1360 | _GL_BEGIN_C_LINKAGE | ||
| 1361 | _GL_INLINE int | ||
| 1362 | c32_apply_type_test (wint_t wc, c32_type_test_t property) | ||
| 1363 | { | ||
| 1364 | return | ||
| 1365 | # if 1 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1366 | GNULIB_NAMESPACE:: | ||
| 1367 | # endif | ||
| 1368 | iswctype (wc, property); | ||
| 1369 | } | ||
| 1370 | _GL_END_C_LINKAGE | ||
| 1371 | # else | ||
| 1372 | _GL_FUNCDECL_SYS (c32_apply_type_test, int, | ||
| 1373 | (wint_t wc, c32_type_test_t property), ); | ||
| 1374 | # endif | ||
| 1375 | # else | ||
| 1376 | _GL_FUNCDECL_SYS (c32_apply_type_test, int, | ||
| 1377 | (wint_t wc, c32_type_test_t property), | ||
| 1378 | _GL_ARG_NONNULL ((2))); | ||
| 1379 | # endif | ||
| 1380 | _GL_CXXALIAS_SYS (c32_apply_type_test, int, | ||
| 1381 | (wint_t wc, c32_type_test_t property)); | ||
| 1382 | _GL_CXXALIASWARN (c32_apply_type_test); | ||
| 1383 | #endif | ||
| 1384 | |||
| 1385 | |||
| 1386 | #if 0 || 0 | ||
| 1387 | /* A scalar type. Instances of this type, other than (c32_mapping_t) 0, | ||
| 1388 | represent a character mapping. It can be applied to 32-bit wide characters. | ||
| 1389 | It is the counterpart of type 'wctrans_t' for wide characters. | ||
| 1390 | To apply a certain mapping to a given character, use the function | ||
| 1391 | 'c32_apply_mapping'. */ | ||
| 1392 | # if _GL_WCHAR_T_IS_UCS4 | ||
| 1393 | typedef wctrans_t c32_mapping_t; | ||
| 1394 | # else | ||
| 1395 | typedef wint_t (*c32_mapping_t) (wint_t wc); | ||
| 1396 | # endif | ||
| 1397 | #endif | ||
| 1398 | |||
| 1399 | /* Return a character mapping with the given name, or (c32_mapping_t) 0 | ||
| 1400 | if the designated mapping does not exist. | ||
| 1401 | This function is the counterpart of function 'wctrans' for wide characters. | ||
| 1402 | */ | ||
| 1403 | #if 0 | ||
| 1404 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32_GET_MAPPING | ||
| 1405 | _GL_BEGIN_C_LINKAGE | ||
| 1406 | _GL_INLINE _GL_ARG_NONNULL ((1)) c32_mapping_t | ||
| 1407 | c32_get_mapping (const char *name) | ||
| 1408 | { | ||
| 1409 | return | ||
| 1410 | # if 0 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1411 | GNULIB_NAMESPACE:: | ||
| 1412 | # endif | ||
| 1413 | wctrans (name); | ||
| 1414 | } | ||
| 1415 | _GL_END_C_LINKAGE | ||
| 1416 | # else | ||
| 1417 | _GL_FUNCDECL_SYS (c32_get_mapping, c32_mapping_t, (const char *name), | ||
| 1418 | _GL_ARG_NONNULL ((1))); | ||
| 1419 | # endif | ||
| 1420 | _GL_CXXALIAS_SYS (c32_get_mapping, c32_mapping_t, (const char *name)); | ||
| 1421 | _GL_CXXALIASWARN (c32_get_mapping); | ||
| 1422 | #endif | ||
| 1423 | |||
| 1424 | /* Apply the specified character mapping to a given 32-bit wide character. | ||
| 1425 | Return the result of this mapping. Return the WC argument unchanged if it is | ||
| 1426 | WEOF. | ||
| 1427 | This function is the counterpart of function 'towctrans' for wide characters. | ||
| 1428 | */ | ||
| 1429 | #if 0 | ||
| 1430 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32_APPLY_MAPPING | ||
| 1431 | _GL_BEGIN_C_LINKAGE | ||
| 1432 | _GL_INLINE _GL_ARG_NONNULL ((2)) wint_t | ||
| 1433 | c32_apply_mapping (wint_t wc, c32_mapping_t mapping) | ||
| 1434 | { | ||
| 1435 | return | ||
| 1436 | # if 0 && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 1437 | GNULIB_NAMESPACE:: | ||
| 1438 | # endif | ||
| 1439 | towctrans (wc, mapping); | ||
| 1440 | } | ||
| 1441 | _GL_END_C_LINKAGE | ||
| 1442 | # else | ||
| 1443 | _GL_FUNCDECL_SYS (c32_apply_mapping, wint_t, | ||
| 1444 | (wint_t wc, c32_mapping_t mapping), | ||
| 1445 | _GL_ARG_NONNULL ((2))); | ||
| 1446 | # endif | ||
| 1447 | _GL_CXXALIAS_SYS (c32_apply_mapping, wint_t, | ||
| 1448 | (wint_t wc, c32_mapping_t mapping)); | ||
| 1449 | _GL_CXXALIASWARN (c32_apply_mapping); | ||
| 1450 | #endif | ||
| 1451 | |||
| 1452 | |||
| 1453 | _GL_INLINE_HEADER_END | ||
| 1454 | |||
| 1455 | #endif /* _GL_UCHAR_H */ | ||
| 1456 | #endif /* _GL_UCHAR_H */ | ||
diff --git a/gl/uchar.in.h b/gl/uchar.in.h new file mode 100644 index 00000000..9a65ac37 --- /dev/null +++ b/gl/uchar.in.h | |||
| @@ -0,0 +1,912 @@ | |||
| 1 | /* <uchar.h> substitute - 16-bit and 32-bit wide character types. | ||
| 2 | Copyright (C) 2019-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | /* Written by Bruno Haible <bruno@clisp.org>, 2019. */ | ||
| 18 | |||
| 19 | /* | ||
| 20 | * ISO C 23 <uchar.h> for platforms that lack it. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #ifndef _@GUARD_PREFIX@_UCHAR_H | ||
| 24 | |||
| 25 | #if __GNUC__ >= 3 | ||
| 26 | @PRAGMA_SYSTEM_HEADER@ | ||
| 27 | #endif | ||
| 28 | @PRAGMA_COLUMNS@ | ||
| 29 | |||
| 30 | /* The include_next requires a split double-inclusion guard. */ | ||
| 31 | #if (defined __cplusplus ? @CXX_HAVE_UCHAR_H@ : @HAVE_UCHAR_H@) | ||
| 32 | # if defined __HAIKU__ | ||
| 33 | /* Work around <https://dev.haiku-os.org/ticket/17040>. */ | ||
| 34 | # include <stdint.h> | ||
| 35 | # endif | ||
| 36 | /* On AIX 7.2 with xlclang++, /usr/include/uchar.h produces compilation errors | ||
| 37 | because it contains typedef definitions of char16_t and char32_t, however | ||
| 38 | char16_t and char32_t are keywords in this situation. To work around it, | ||
| 39 | define char16_t and char32_t as macros. */ | ||
| 40 | # if defined __cplusplus && defined _AIX && defined __ibmxl__ && defined __clang__ | ||
| 41 | # define char16_t gl_char16_t | ||
| 42 | # define char32_t gl_char32_t | ||
| 43 | # endif | ||
| 44 | # @INCLUDE_NEXT@ @NEXT_UCHAR_H@ | ||
| 45 | #endif | ||
| 46 | |||
| 47 | #ifndef _@GUARD_PREFIX@_UCHAR_H | ||
| 48 | #define _@GUARD_PREFIX@_UCHAR_H | ||
| 49 | |||
| 50 | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, _GL_BEGIN_C_LINKAGE, | ||
| 51 | _GL_ATTRIBUTE_PURE, GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ | ||
| 52 | #if !_GL_CONFIG_H_INCLUDED | ||
| 53 | #error "Please include config.h first." | ||
| 54 | #endif | ||
| 55 | |||
| 56 | /* Get uint_least16_t, uint_least32_t. */ | ||
| 57 | #include <stdint.h> | ||
| 58 | |||
| 59 | /* Get mbstate_t, size_t. */ | ||
| 60 | #include <wchar.h> | ||
| 61 | |||
| 62 | /* For the inline functions. */ | ||
| 63 | #include <string.h> | ||
| 64 | #include <wctype.h> | ||
| 65 | |||
| 66 | /* The __attribute__ feature is available in gcc versions 2.5 and later. | ||
| 67 | The attribute __pure__ was added in gcc 2.96. */ | ||
| 68 | #ifndef _GL_ATTRIBUTE_PURE | ||
| 69 | # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ | ||
| 70 | # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) | ||
| 71 | # else | ||
| 72 | # define _GL_ATTRIBUTE_PURE /* empty */ | ||
| 73 | # endif | ||
| 74 | #endif | ||
| 75 | |||
| 76 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | ||
| 77 | |||
| 78 | /* The definition of _GL_ARG_NONNULL is copied here. */ | ||
| 79 | |||
| 80 | /* The definition of _GL_WARN_ON_USE is copied here. */ | ||
| 81 | |||
| 82 | |||
| 83 | _GL_INLINE_HEADER_BEGIN | ||
| 84 | |||
| 85 | |||
| 86 | #if !(defined __cplusplus ? @CXX_HAVE_UCHAR_H@ || @CXX_HAS_CHAR8_TYPE@ : @HAVE_UCHAR_H@) | ||
| 87 | |||
| 88 | /* An 8-bit variant of wchar_t. | ||
| 89 | Note: This type is only mandated by ISO C 23 or newer, and it does | ||
| 90 | denote UTF-8 units. */ | ||
| 91 | typedef unsigned char char8_t; | ||
| 92 | |||
| 93 | #elif @GNULIBHEADERS_OVERRIDE_CHAR8_T@ | ||
| 94 | |||
| 95 | typedef unsigned char gl_char8_t; | ||
| 96 | # define char8_t gl_char8_t | ||
| 97 | |||
| 98 | #endif | ||
| 99 | |||
| 100 | #if !(defined __cplusplus ? @CXX_HAVE_UCHAR_H@ || @CXX_HAS_UCHAR_TYPES@ : @HAVE_UCHAR_H@) | ||
| 101 | |||
| 102 | /* A 16-bit variant of wchar_t. | ||
| 103 | Note: This type is only mandated by ISO C 11 or newer. In ISO C 23 | ||
| 104 | and newer, it denotes UTF-16 units; in older versions of ISO C it did | ||
| 105 | so only on platforms on which __STDC_UTF_16__ was defined. */ | ||
| 106 | typedef uint_least16_t char16_t; | ||
| 107 | |||
| 108 | #elif @GNULIBHEADERS_OVERRIDE_CHAR16_T@ | ||
| 109 | |||
| 110 | typedef uint_least16_t gl_char16_t; | ||
| 111 | # define char16_t gl_char16_t | ||
| 112 | |||
| 113 | #endif | ||
| 114 | |||
| 115 | #if !(defined __cplusplus ? @CXX_HAVE_UCHAR_H@ || @CXX_HAS_UCHAR_TYPES@ : @HAVE_UCHAR_H@) | ||
| 116 | |||
| 117 | /* A 32-bit variant of wchar_t. | ||
| 118 | Note: This type is only mandated by ISO C 11 or newer. In ISO C 23 | ||
| 119 | and newer, it denotes UTF-32 code points; in older versions of ISO C | ||
| 120 | it did so only on platforms on which __STDC_UTF_32__ was defined. | ||
| 121 | In gnulib, we guarantee that it denotes UTF-32 code points if and | ||
| 122 | only if the module 'uchar-h-c23' is in use. */ | ||
| 123 | typedef uint_least32_t char32_t; | ||
| 124 | |||
| 125 | #elif @GNULIBHEADERS_OVERRIDE_CHAR32_T@ | ||
| 126 | |||
| 127 | typedef uint_least32_t gl_char32_t; | ||
| 128 | # define char32_t gl_char32_t | ||
| 129 | |||
| 130 | #endif | ||
| 131 | |||
| 132 | /* Define if a 'char32_t' can hold more characters than a 'wchar_t'. */ | ||
| 133 | #if @SMALL_WCHAR_T@ /* 32-bit AIX, Cygwin, native Windows */ | ||
| 134 | # define _GL_SMALL_WCHAR_T 1 | ||
| 135 | #endif | ||
| 136 | |||
| 137 | /* Define if 'wchar_t', like 'char32_t', | ||
| 138 | - is a 32-bit type, and | ||
| 139 | - represents Unicode code points. | ||
| 140 | For this test, we can use __STDC_ISO_10646__ (defined by glibc, musl libc, | ||
| 141 | Cygwin) but need to consider _GL_SMALL_WCHAR_T, so as to exclude Cygwin. | ||
| 142 | We cannot use __STDC_UTF_16__ or __STDC_UTF_32__ | ||
| 143 | - because these macros provide info about char16_t and char32_t (not | ||
| 144 | wchar_t!), and | ||
| 145 | - because GCC >= 4.9 defines these macros on all platforms, even on | ||
| 146 | FreeBSD and Solaris. | ||
| 147 | We should better not use __STD_UTF_16__, __STD_UTF_32__ either, because | ||
| 148 | these macros are misspellings, only defined by Android's <uchar.h>. */ | ||
| 149 | #if defined __STDC_ISO_10646__ && !_GL_SMALL_WCHAR_T | ||
| 150 | /* glibc, musl libc */ | ||
| 151 | # define _GL_WCHAR_T_IS_UCS4 1 | ||
| 152 | #endif | ||
| 153 | #if _GL_WCHAR_T_IS_UCS4 | ||
| 154 | static_assert (sizeof (char32_t) == sizeof (wchar_t)); | ||
| 155 | #endif | ||
| 156 | |||
| 157 | |||
| 158 | /* Convert a single-byte character to a 32-bit wide character. */ | ||
| 159 | #if @GNULIB_BTOC32@ | ||
| 160 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_BTOC32 | ||
| 161 | _GL_BEGIN_C_LINKAGE | ||
| 162 | _GL_INLINE _GL_ATTRIBUTE_PURE wint_t | ||
| 163 | btoc32 (int c) | ||
| 164 | { | ||
| 165 | return | ||
| 166 | # if @GNULIB_BTOWC@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 167 | GNULIB_NAMESPACE:: | ||
| 168 | # endif | ||
| 169 | btowc (c); | ||
| 170 | } | ||
| 171 | _GL_END_C_LINKAGE | ||
| 172 | # else | ||
| 173 | _GL_FUNCDECL_SYS (btoc32, wint_t, (int c), _GL_ATTRIBUTE_PURE); | ||
| 174 | # endif | ||
| 175 | _GL_CXXALIAS_SYS (btoc32, wint_t, (int c)); | ||
| 176 | _GL_CXXALIASWARN (btoc32); | ||
| 177 | #endif | ||
| 178 | |||
| 179 | |||
| 180 | /* Test a specific property of a 32-bit wide character. */ | ||
| 181 | #if @GNULIB_C32ISALNUM@ | ||
| 182 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISALNUM | ||
| 183 | _GL_BEGIN_C_LINKAGE | ||
| 184 | _GL_INLINE int | ||
| 185 | c32isalnum (wint_t wc) | ||
| 186 | { | ||
| 187 | return | ||
| 188 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 189 | GNULIB_NAMESPACE:: | ||
| 190 | # endif | ||
| 191 | iswalnum (wc); | ||
| 192 | } | ||
| 193 | _GL_END_C_LINKAGE | ||
| 194 | # else | ||
| 195 | _GL_FUNCDECL_SYS (c32isalnum, int, (wint_t wc), ); | ||
| 196 | # endif | ||
| 197 | _GL_CXXALIAS_SYS (c32isalnum, int, (wint_t wc)); | ||
| 198 | _GL_CXXALIASWARN (c32isalnum); | ||
| 199 | #endif | ||
| 200 | #if @GNULIB_C32ISALPHA@ | ||
| 201 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISALPHA | ||
| 202 | _GL_BEGIN_C_LINKAGE | ||
| 203 | _GL_INLINE int | ||
| 204 | c32isalpha (wint_t wc) | ||
| 205 | { | ||
| 206 | return | ||
| 207 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 208 | GNULIB_NAMESPACE:: | ||
| 209 | # endif | ||
| 210 | iswalpha (wc); | ||
| 211 | } | ||
| 212 | _GL_END_C_LINKAGE | ||
| 213 | # else | ||
| 214 | _GL_FUNCDECL_SYS (c32isalpha, int, (wint_t wc), ); | ||
| 215 | # endif | ||
| 216 | _GL_CXXALIAS_SYS (c32isalpha, int, (wint_t wc)); | ||
| 217 | _GL_CXXALIASWARN (c32isalpha); | ||
| 218 | #endif | ||
| 219 | #if @GNULIB_C32ISBLANK@ | ||
| 220 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISBLANK | ||
| 221 | _GL_BEGIN_C_LINKAGE | ||
| 222 | _GL_INLINE int | ||
| 223 | c32isblank (wint_t wc) | ||
| 224 | { | ||
| 225 | return | ||
| 226 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 227 | GNULIB_NAMESPACE:: | ||
| 228 | # endif | ||
| 229 | iswblank (wc); | ||
| 230 | } | ||
| 231 | _GL_END_C_LINKAGE | ||
| 232 | # else | ||
| 233 | _GL_FUNCDECL_SYS (c32isblank, int, (wint_t wc), ); | ||
| 234 | # endif | ||
| 235 | _GL_CXXALIAS_SYS (c32isblank, int, (wint_t wc)); | ||
| 236 | _GL_CXXALIASWARN (c32isblank); | ||
| 237 | #endif | ||
| 238 | #if @GNULIB_C32ISCNTRL@ | ||
| 239 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISCNTRL | ||
| 240 | _GL_BEGIN_C_LINKAGE | ||
| 241 | _GL_INLINE int | ||
| 242 | c32iscntrl (wint_t wc) | ||
| 243 | { | ||
| 244 | return | ||
| 245 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 246 | GNULIB_NAMESPACE:: | ||
| 247 | # endif | ||
| 248 | iswcntrl (wc); | ||
| 249 | } | ||
| 250 | _GL_END_C_LINKAGE | ||
| 251 | # else | ||
| 252 | _GL_FUNCDECL_SYS (c32iscntrl, int, (wint_t wc), ); | ||
| 253 | # endif | ||
| 254 | _GL_CXXALIAS_SYS (c32iscntrl, int, (wint_t wc)); | ||
| 255 | _GL_CXXALIASWARN (c32iscntrl); | ||
| 256 | #endif | ||
| 257 | #if @GNULIB_C32ISDIGIT@ | ||
| 258 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISDIGIT | ||
| 259 | _GL_BEGIN_C_LINKAGE | ||
| 260 | _GL_INLINE int | ||
| 261 | c32isdigit (wint_t wc) | ||
| 262 | { | ||
| 263 | return | ||
| 264 | # if @GNULIB_ISWDIGIT@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 265 | GNULIB_NAMESPACE:: | ||
| 266 | # endif | ||
| 267 | iswdigit (wc); | ||
| 268 | } | ||
| 269 | _GL_END_C_LINKAGE | ||
| 270 | # else | ||
| 271 | _GL_FUNCDECL_SYS (c32isdigit, int, (wint_t wc), ); | ||
| 272 | # endif | ||
| 273 | _GL_CXXALIAS_SYS (c32isdigit, int, (wint_t wc)); | ||
| 274 | _GL_CXXALIASWARN (c32isdigit); | ||
| 275 | #endif | ||
| 276 | #if @GNULIB_C32ISGRAPH@ | ||
| 277 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISGRAPH | ||
| 278 | _GL_BEGIN_C_LINKAGE | ||
| 279 | _GL_INLINE int | ||
| 280 | c32isgraph (wint_t wc) | ||
| 281 | { | ||
| 282 | return | ||
| 283 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 284 | GNULIB_NAMESPACE:: | ||
| 285 | # endif | ||
| 286 | iswgraph (wc); | ||
| 287 | } | ||
| 288 | _GL_END_C_LINKAGE | ||
| 289 | # else | ||
| 290 | _GL_FUNCDECL_SYS (c32isgraph, int, (wint_t wc), ); | ||
| 291 | # endif | ||
| 292 | _GL_CXXALIAS_SYS (c32isgraph, int, (wint_t wc)); | ||
| 293 | _GL_CXXALIASWARN (c32isgraph); | ||
| 294 | #endif | ||
| 295 | #if @GNULIB_C32ISLOWER@ | ||
| 296 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISLOWER | ||
| 297 | _GL_BEGIN_C_LINKAGE | ||
| 298 | _GL_INLINE int | ||
| 299 | c32islower (wint_t wc) | ||
| 300 | { | ||
| 301 | return | ||
| 302 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 303 | GNULIB_NAMESPACE:: | ||
| 304 | # endif | ||
| 305 | iswlower (wc); | ||
| 306 | } | ||
| 307 | _GL_END_C_LINKAGE | ||
| 308 | # else | ||
| 309 | _GL_FUNCDECL_SYS (c32islower, int, (wint_t wc), ); | ||
| 310 | # endif | ||
| 311 | _GL_CXXALIAS_SYS (c32islower, int, (wint_t wc)); | ||
| 312 | _GL_CXXALIASWARN (c32islower); | ||
| 313 | #endif | ||
| 314 | #if @GNULIB_C32ISPRINT@ | ||
| 315 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISPRINT | ||
| 316 | _GL_BEGIN_C_LINKAGE | ||
| 317 | _GL_INLINE int | ||
| 318 | c32isprint (wint_t wc) | ||
| 319 | { | ||
| 320 | return | ||
| 321 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 322 | GNULIB_NAMESPACE:: | ||
| 323 | # endif | ||
| 324 | iswprint (wc); | ||
| 325 | } | ||
| 326 | _GL_END_C_LINKAGE | ||
| 327 | # else | ||
| 328 | _GL_FUNCDECL_SYS (c32isprint, int, (wint_t wc), ); | ||
| 329 | # endif | ||
| 330 | _GL_CXXALIAS_SYS (c32isprint, int, (wint_t wc)); | ||
| 331 | _GL_CXXALIASWARN (c32isprint); | ||
| 332 | #endif | ||
| 333 | #if @GNULIB_C32ISPUNCT@ | ||
| 334 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISPUNCT | ||
| 335 | _GL_BEGIN_C_LINKAGE | ||
| 336 | _GL_INLINE int | ||
| 337 | c32ispunct (wint_t wc) | ||
| 338 | { | ||
| 339 | return | ||
| 340 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 341 | GNULIB_NAMESPACE:: | ||
| 342 | # endif | ||
| 343 | iswpunct (wc); | ||
| 344 | } | ||
| 345 | _GL_END_C_LINKAGE | ||
| 346 | # else | ||
| 347 | _GL_FUNCDECL_SYS (c32ispunct, int, (wint_t wc), ); | ||
| 348 | # endif | ||
| 349 | _GL_CXXALIAS_SYS (c32ispunct, int, (wint_t wc)); | ||
| 350 | _GL_CXXALIASWARN (c32ispunct); | ||
| 351 | #endif | ||
| 352 | #if @GNULIB_C32ISSPACE@ | ||
| 353 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISSPACE | ||
| 354 | _GL_BEGIN_C_LINKAGE | ||
| 355 | _GL_INLINE int | ||
| 356 | c32isspace (wint_t wc) | ||
| 357 | { | ||
| 358 | return | ||
| 359 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 360 | GNULIB_NAMESPACE:: | ||
| 361 | # endif | ||
| 362 | iswspace (wc); | ||
| 363 | } | ||
| 364 | _GL_END_C_LINKAGE | ||
| 365 | # else | ||
| 366 | _GL_FUNCDECL_SYS (c32isspace, int, (wint_t wc), ); | ||
| 367 | # endif | ||
| 368 | _GL_CXXALIAS_SYS (c32isspace, int, (wint_t wc)); | ||
| 369 | _GL_CXXALIASWARN (c32isspace); | ||
| 370 | #endif | ||
| 371 | #if @GNULIB_C32ISUPPER@ | ||
| 372 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISUPPER | ||
| 373 | _GL_BEGIN_C_LINKAGE | ||
| 374 | _GL_INLINE int | ||
| 375 | c32isupper (wint_t wc) | ||
| 376 | { | ||
| 377 | return | ||
| 378 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 379 | GNULIB_NAMESPACE:: | ||
| 380 | # endif | ||
| 381 | iswupper (wc); | ||
| 382 | } | ||
| 383 | _GL_END_C_LINKAGE | ||
| 384 | # else | ||
| 385 | _GL_FUNCDECL_SYS (c32isupper, int, (wint_t wc), ); | ||
| 386 | # endif | ||
| 387 | _GL_CXXALIAS_SYS (c32isupper, int, (wint_t wc)); | ||
| 388 | _GL_CXXALIASWARN (c32isupper); | ||
| 389 | #endif | ||
| 390 | #if @GNULIB_C32ISXDIGIT@ | ||
| 391 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32ISXDIGIT | ||
| 392 | _GL_BEGIN_C_LINKAGE | ||
| 393 | _GL_INLINE int | ||
| 394 | c32isxdigit (wint_t wc) | ||
| 395 | { | ||
| 396 | return | ||
| 397 | # if @GNULIB_ISWXDIGIT@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 398 | GNULIB_NAMESPACE:: | ||
| 399 | # endif | ||
| 400 | iswxdigit (wc); | ||
| 401 | } | ||
| 402 | _GL_END_C_LINKAGE | ||
| 403 | # else | ||
| 404 | _GL_FUNCDECL_SYS (c32isxdigit, int, (wint_t wc), ); | ||
| 405 | # endif | ||
| 406 | _GL_CXXALIAS_SYS (c32isxdigit, int, (wint_t wc)); | ||
| 407 | _GL_CXXALIASWARN (c32isxdigit); | ||
| 408 | #endif | ||
| 409 | |||
| 410 | |||
| 411 | /* Case mapping of a 32-bit wide character. */ | ||
| 412 | #if @GNULIB_C32TOLOWER@ | ||
| 413 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32TOLOWER | ||
| 414 | _GL_BEGIN_C_LINKAGE | ||
| 415 | _GL_INLINE wint_t | ||
| 416 | c32tolower (wint_t wc) | ||
| 417 | { | ||
| 418 | return | ||
| 419 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 420 | GNULIB_NAMESPACE:: | ||
| 421 | # endif | ||
| 422 | towlower (wc); | ||
| 423 | } | ||
| 424 | _GL_END_C_LINKAGE | ||
| 425 | # else | ||
| 426 | _GL_FUNCDECL_SYS (c32tolower, wint_t, (wint_t wc), ); | ||
| 427 | # endif | ||
| 428 | _GL_CXXALIAS_SYS (c32tolower, wint_t, (wint_t wc)); | ||
| 429 | _GL_CXXALIASWARN (c32tolower); | ||
| 430 | #endif | ||
| 431 | #if @GNULIB_C32TOUPPER@ | ||
| 432 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32TOUPPER | ||
| 433 | _GL_BEGIN_C_LINKAGE | ||
| 434 | _GL_INLINE wint_t | ||
| 435 | c32toupper (wint_t wc) | ||
| 436 | { | ||
| 437 | return | ||
| 438 | # if defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 439 | GNULIB_NAMESPACE:: | ||
| 440 | # endif | ||
| 441 | towupper (wc); | ||
| 442 | } | ||
| 443 | _GL_END_C_LINKAGE | ||
| 444 | # else | ||
| 445 | _GL_FUNCDECL_SYS (c32toupper, wint_t, (wint_t wc), ); | ||
| 446 | # endif | ||
| 447 | _GL_CXXALIAS_SYS (c32toupper, wint_t, (wint_t wc)); | ||
| 448 | _GL_CXXALIASWARN (c32toupper); | ||
| 449 | #endif | ||
| 450 | |||
| 451 | |||
| 452 | /* Number of screen columns needed for a 32-bit wide character. */ | ||
| 453 | #if @GNULIB_C32WIDTH@ | ||
| 454 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32WIDTH | ||
| 455 | _GL_BEGIN_C_LINKAGE | ||
| 456 | _GL_INLINE int | ||
| 457 | c32width (char32_t wc) | ||
| 458 | { | ||
| 459 | return | ||
| 460 | # if @GNULIB_WCWIDTH@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 461 | GNULIB_NAMESPACE:: | ||
| 462 | # endif | ||
| 463 | wcwidth (wc); | ||
| 464 | } | ||
| 465 | _GL_END_C_LINKAGE | ||
| 466 | # else | ||
| 467 | _GL_FUNCDECL_SYS (c32width, int, (char32_t wc), ); | ||
| 468 | # endif | ||
| 469 | _GL_CXXALIAS_SYS (c32width, int, (char32_t wc)); | ||
| 470 | _GL_CXXALIASWARN (c32width); | ||
| 471 | #endif | ||
| 472 | |||
| 473 | |||
| 474 | /* Converts a 32-bit wide character to a multibyte character. */ | ||
| 475 | #if @GNULIB_C32RTOMB@ | ||
| 476 | # if @REPLACE_C32RTOMB@ | ||
| 477 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 478 | # undef c32rtomb | ||
| 479 | # define c32rtomb rpl_c32rtomb | ||
| 480 | # endif | ||
| 481 | _GL_FUNCDECL_RPL (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps), ); | ||
| 482 | _GL_CXXALIAS_RPL (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps)); | ||
| 483 | # else | ||
| 484 | # if !@HAVE_C32RTOMB@ | ||
| 485 | _GL_FUNCDECL_SYS (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps), ); | ||
| 486 | # endif | ||
| 487 | _GL_CXXALIAS_SYS (c32rtomb, size_t, (char *s, char32_t wc, mbstate_t *ps)); | ||
| 488 | # endif | ||
| 489 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 | ||
| 490 | _GL_CXXALIASWARN (c32rtomb); | ||
| 491 | # endif | ||
| 492 | #elif defined GNULIB_POSIXCHECK | ||
| 493 | # undef c32rtomb | ||
| 494 | # if HAVE_RAW_DECL_C32RTOMB | ||
| 495 | _GL_WARN_ON_USE (c32rtomb, "c32rtomb is not portable - " | ||
| 496 | "use gnulib module c32rtomb for portability"); | ||
| 497 | # endif | ||
| 498 | #endif | ||
| 499 | |||
| 500 | |||
| 501 | /* Convert a 32-bit wide string to a string. */ | ||
| 502 | #if @GNULIB_C32SNRTOMBS@ | ||
| 503 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32SNRTOMBS | ||
| 504 | _GL_BEGIN_C_LINKAGE | ||
| 505 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 506 | c32snrtombs (char *dest, const char32_t **srcp, size_t srclen, size_t len, | ||
| 507 | mbstate_t *ps) | ||
| 508 | { | ||
| 509 | return | ||
| 510 | # if @GNULIB_WCSNRTOMBS@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 511 | GNULIB_NAMESPACE:: | ||
| 512 | # endif | ||
| 513 | wcsnrtombs (dest, (const wchar_t **) srcp, srclen, len, ps); | ||
| 514 | } | ||
| 515 | _GL_END_C_LINKAGE | ||
| 516 | # else | ||
| 517 | _GL_FUNCDECL_SYS (c32snrtombs, size_t, | ||
| 518 | (char *dest, const char32_t **srcp, size_t srclen, size_t len, | ||
| 519 | mbstate_t *ps), | ||
| 520 | _GL_ARG_NONNULL ((2))); | ||
| 521 | # endif | ||
| 522 | _GL_CXXALIAS_SYS (c32snrtombs, size_t, | ||
| 523 | (char *dest, const char32_t **srcp, size_t srclen, size_t len, | ||
| 524 | mbstate_t *ps)); | ||
| 525 | _GL_CXXALIASWARN (c32snrtombs); | ||
| 526 | #endif | ||
| 527 | |||
| 528 | |||
| 529 | /* Convert a 32-bit wide string to a string. */ | ||
| 530 | #if @GNULIB_C32SRTOMBS@ | ||
| 531 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32SRTOMBS | ||
| 532 | _GL_BEGIN_C_LINKAGE | ||
| 533 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 534 | c32srtombs (char *dest, const char32_t **srcp, size_t len, mbstate_t *ps) | ||
| 535 | { | ||
| 536 | return | ||
| 537 | # if @GNULIB_WCSRTOMBS@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 538 | GNULIB_NAMESPACE:: | ||
| 539 | # endif | ||
| 540 | wcsrtombs (dest, (const wchar_t **) srcp, len, ps); | ||
| 541 | } | ||
| 542 | _GL_END_C_LINKAGE | ||
| 543 | # else | ||
| 544 | _GL_FUNCDECL_SYS (c32srtombs, size_t, | ||
| 545 | (char *dest, const char32_t **srcp, size_t len, | ||
| 546 | mbstate_t *ps), | ||
| 547 | _GL_ARG_NONNULL ((2))); | ||
| 548 | # endif | ||
| 549 | _GL_CXXALIAS_SYS (c32srtombs, size_t, | ||
| 550 | (char *dest, const char32_t **srcp, size_t len, | ||
| 551 | mbstate_t *ps)); | ||
| 552 | _GL_CXXALIASWARN (c32srtombs); | ||
| 553 | #endif | ||
| 554 | |||
| 555 | |||
| 556 | /* Convert a 32-bit wide string to a string. */ | ||
| 557 | #if @GNULIB_C32STOMBS@ | ||
| 558 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32STOMBS | ||
| 559 | _GL_BEGIN_C_LINKAGE | ||
| 560 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 561 | c32stombs (char *dest, const char32_t *src, size_t len) | ||
| 562 | { | ||
| 563 | mbstate_t state; | ||
| 564 | |||
| 565 | mbszero (&state); | ||
| 566 | return c32srtombs (dest, &src, len, &state); | ||
| 567 | } | ||
| 568 | _GL_END_C_LINKAGE | ||
| 569 | # else | ||
| 570 | _GL_FUNCDECL_SYS (c32stombs, size_t, | ||
| 571 | (char *dest, const char32_t *src, size_t len), | ||
| 572 | _GL_ARG_NONNULL ((2))); | ||
| 573 | # endif | ||
| 574 | _GL_CXXALIAS_SYS (c32stombs, size_t, | ||
| 575 | (char *dest, const char32_t *src, size_t len)); | ||
| 576 | _GL_CXXALIASWARN (c32stombs); | ||
| 577 | #endif | ||
| 578 | |||
| 579 | |||
| 580 | /* Number of screen columns needed for a size-bounded 32-bit wide string. */ | ||
| 581 | #if @GNULIB_C32SWIDTH@ | ||
| 582 | # if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32SWIDTH | ||
| 583 | _GL_BEGIN_C_LINKAGE | ||
| 584 | _GL_INLINE _GL_ARG_NONNULL ((1)) int | ||
| 585 | c32swidth (const char32_t *s, size_t n) | ||
| 586 | { | ||
| 587 | return | ||
| 588 | # if @GNULIB_WCSWIDTH@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 589 | GNULIB_NAMESPACE:: | ||
| 590 | # endif | ||
| 591 | wcswidth ((const wchar_t *) s, n); | ||
| 592 | } | ||
| 593 | _GL_END_C_LINKAGE | ||
| 594 | # else | ||
| 595 | _GL_FUNCDECL_SYS (c32swidth, int, (const char32_t *s, size_t n), | ||
| 596 | _GL_ARG_NONNULL ((1))); | ||
| 597 | # endif | ||
| 598 | _GL_CXXALIAS_SYS (c32swidth, int, (const char32_t *s, size_t n)); | ||
| 599 | _GL_CXXALIASWARN (c32swidth); | ||
| 600 | #endif | ||
| 601 | |||
| 602 | |||
| 603 | /* Converts a 32-bit wide character to unibyte character. | ||
| 604 | Returns the single-byte representation of WC if it exists, | ||
| 605 | or EOF otherwise. */ | ||
| 606 | #if @GNULIB_C32TOB@ | ||
| 607 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32TOB | ||
| 608 | _GL_BEGIN_C_LINKAGE | ||
| 609 | _GL_INLINE int | ||
| 610 | c32tob (wint_t wc) | ||
| 611 | { | ||
| 612 | return | ||
| 613 | # if @GNULIB_WCTOB@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 614 | GNULIB_NAMESPACE:: | ||
| 615 | # endif | ||
| 616 | wctob (wc); | ||
| 617 | } | ||
| 618 | _GL_END_C_LINKAGE | ||
| 619 | # else | ||
| 620 | _GL_FUNCDECL_SYS (c32tob, int, (wint_t wc), ); | ||
| 621 | # endif | ||
| 622 | _GL_CXXALIAS_SYS (c32tob, int, (wint_t wc)); | ||
| 623 | _GL_CXXALIASWARN (c32tob); | ||
| 624 | #endif | ||
| 625 | |||
| 626 | |||
| 627 | /* Converts a multibyte character to a 32-bit wide character. */ | ||
| 628 | #if @GNULIB_MBRTOC32@ | ||
| 629 | # if @REPLACE_MBRTOC32@ | ||
| 630 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 631 | # undef mbrtoc32 | ||
| 632 | # define mbrtoc32 rpl_mbrtoc32 | ||
| 633 | # endif | ||
| 634 | _GL_FUNCDECL_RPL (mbrtoc32, size_t, | ||
| 635 | (char32_t *pc, const char *s, size_t n, mbstate_t *ps), ); | ||
| 636 | _GL_CXXALIAS_RPL (mbrtoc32, size_t, | ||
| 637 | (char32_t *pc, const char *s, size_t n, mbstate_t *ps)); | ||
| 638 | # else | ||
| 639 | # if !@HAVE_MBRTOC32@ | ||
| 640 | _GL_FUNCDECL_SYS (mbrtoc32, size_t, | ||
| 641 | (char32_t *pc, const char *s, size_t n, mbstate_t *ps), ); | ||
| 642 | # endif | ||
| 643 | _GL_CXXALIAS_SYS (mbrtoc32, size_t, | ||
| 644 | (char32_t *pc, const char *s, size_t n, mbstate_t *ps)); | ||
| 645 | # endif | ||
| 646 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 | ||
| 647 | _GL_CXXALIASWARN (mbrtoc32); | ||
| 648 | # endif | ||
| 649 | #elif defined GNULIB_POSIXCHECK | ||
| 650 | # undef mbrtoc32 | ||
| 651 | # if HAVE_RAW_DECL_MBRTOC32 | ||
| 652 | _GL_WARN_ON_USE (mbrtoc32, "mbrtoc32 is not portable - " | ||
| 653 | "use gnulib module mbrtoc32 for portability"); | ||
| 654 | # endif | ||
| 655 | #endif | ||
| 656 | |||
| 657 | |||
| 658 | /* Converts a multibyte character and returns the next 16-bit wide | ||
| 659 | character. */ | ||
| 660 | #if @GNULIB_MBRTOC16@ | ||
| 661 | # if @REPLACE_MBRTOC16@ | ||
| 662 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | ||
| 663 | # undef mbrtoc16 | ||
| 664 | # define mbrtoc16 rpl_mbrtoc16 | ||
| 665 | # endif | ||
| 666 | _GL_FUNCDECL_RPL (mbrtoc16, size_t, | ||
| 667 | (char16_t *pc, const char *s, size_t n, mbstate_t *ps), ); | ||
| 668 | _GL_CXXALIAS_RPL (mbrtoc16, size_t, | ||
| 669 | (char16_t *pc, const char *s, size_t n, mbstate_t *ps)); | ||
| 670 | # else | ||
| 671 | # if !@HAVE_MBRTOC16@ | ||
| 672 | _GL_FUNCDECL_SYS (mbrtoc16, size_t, | ||
| 673 | (char16_t *pc, const char *s, size_t n, mbstate_t *ps), ); | ||
| 674 | # endif | ||
| 675 | _GL_CXXALIAS_SYS (mbrtoc16, size_t, | ||
| 676 | (char16_t *pc, const char *s, size_t n, mbstate_t *ps)); | ||
| 677 | # endif | ||
| 678 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2 | ||
| 679 | _GL_CXXALIASWARN (mbrtoc16); | ||
| 680 | # endif | ||
| 681 | #elif defined GNULIB_POSIXCHECK | ||
| 682 | # undef mbrtoc16 | ||
| 683 | # if HAVE_RAW_DECL_MBRTOC16 | ||
| 684 | _GL_WARN_ON_USE (mbrtoc16, "mbrtoc16 is not portable - " | ||
| 685 | "use gnulib module mbrtoc16 for portability"); | ||
| 686 | # endif | ||
| 687 | #endif | ||
| 688 | |||
| 689 | |||
| 690 | /* Convert a string to a 32-bit wide string. */ | ||
| 691 | #if @GNULIB_MBSNRTOC32S@ | ||
| 692 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSNRTOC32S | ||
| 693 | _GL_BEGIN_C_LINKAGE | ||
| 694 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 695 | mbsnrtoc32s (char32_t *dest, const char **srcp, size_t srclen, size_t len, | ||
| 696 | mbstate_t *ps) | ||
| 697 | { | ||
| 698 | return | ||
| 699 | # if @GNULIB_MBSNRTOWCS@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 700 | GNULIB_NAMESPACE:: | ||
| 701 | # endif | ||
| 702 | mbsnrtowcs ((wchar_t *) dest, srcp, srclen, len, ps); | ||
| 703 | } | ||
| 704 | _GL_END_C_LINKAGE | ||
| 705 | # else | ||
| 706 | _GL_FUNCDECL_SYS (mbsnrtoc32s, size_t, | ||
| 707 | (char32_t *dest, const char **srcp, size_t srclen, size_t len, | ||
| 708 | mbstate_t *ps), | ||
| 709 | _GL_ARG_NONNULL ((2))); | ||
| 710 | # endif | ||
| 711 | _GL_CXXALIAS_SYS (mbsnrtoc32s, size_t, | ||
| 712 | (char32_t *dest, const char **srcp, size_t srclen, size_t len, | ||
| 713 | mbstate_t *ps)); | ||
| 714 | _GL_CXXALIASWARN (mbsnrtoc32s); | ||
| 715 | #endif | ||
| 716 | |||
| 717 | |||
| 718 | /* Convert a string to a 32-bit wide string. */ | ||
| 719 | #if @GNULIB_MBSRTOC32S@ | ||
| 720 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSRTOC32S | ||
| 721 | _GL_BEGIN_C_LINKAGE | ||
| 722 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 723 | mbsrtoc32s (char32_t *dest, const char **srcp, size_t len, mbstate_t *ps) | ||
| 724 | { | ||
| 725 | return | ||
| 726 | # if @GNULIB_MBSRTOWCS@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 727 | GNULIB_NAMESPACE:: | ||
| 728 | # endif | ||
| 729 | mbsrtowcs ((wchar_t *) dest, srcp, len, ps); | ||
| 730 | } | ||
| 731 | _GL_END_C_LINKAGE | ||
| 732 | # else | ||
| 733 | _GL_FUNCDECL_SYS (mbsrtoc32s, size_t, | ||
| 734 | (char32_t *dest, const char **srcp, size_t len, | ||
| 735 | mbstate_t *ps), | ||
| 736 | _GL_ARG_NONNULL ((2))); | ||
| 737 | # endif | ||
| 738 | _GL_CXXALIAS_SYS (mbsrtoc32s, size_t, | ||
| 739 | (char32_t *dest, const char **srcp, size_t len, | ||
| 740 | mbstate_t *ps)); | ||
| 741 | _GL_CXXALIASWARN (mbsrtoc32s); | ||
| 742 | #endif | ||
| 743 | |||
| 744 | |||
| 745 | /* Convert a string to a 32-bit wide string. */ | ||
| 746 | #if @GNULIB_MBSTOC32S@ | ||
| 747 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_MBSTOC32S | ||
| 748 | _GL_BEGIN_C_LINKAGE | ||
| 749 | _GL_INLINE _GL_ARG_NONNULL ((2)) size_t | ||
| 750 | mbstoc32s (char32_t *dest, const char *src, size_t len) | ||
| 751 | { | ||
| 752 | mbstate_t state; | ||
| 753 | |||
| 754 | mbszero (&state); | ||
| 755 | return mbsrtoc32s (dest, &src, len, &state); | ||
| 756 | } | ||
| 757 | _GL_END_C_LINKAGE | ||
| 758 | # else | ||
| 759 | _GL_FUNCDECL_SYS (mbstoc32s, size_t, | ||
| 760 | (char32_t *dest, const char *src, size_t len), | ||
| 761 | _GL_ARG_NONNULL ((2))); | ||
| 762 | # endif | ||
| 763 | _GL_CXXALIAS_SYS (mbstoc32s, size_t, | ||
| 764 | (char32_t *dest, const char *src, size_t len)); | ||
| 765 | _GL_CXXALIASWARN (mbstoc32s); | ||
| 766 | #endif | ||
| 767 | |||
| 768 | |||
| 769 | #if @GNULIB_C32_GET_TYPE_TEST@ || @GNULIB_C32_APPLY_TYPE_TEST@ | ||
| 770 | /* A scalar type. Instances of this type, other than (c32_type_test_t) 0, | ||
| 771 | represent a character property, sometimes also viewed as a "character class". | ||
| 772 | It can be applied to 32-bit wide characters. It is the counterpart of | ||
| 773 | type 'wctype_t' for wide characters. | ||
| 774 | To test whether a given character has a certain property, use the function | ||
| 775 | 'c32_apply_type_test'. */ | ||
| 776 | # if _GL_WCHAR_T_IS_UCS4 | ||
| 777 | typedef wctype_t c32_type_test_t; | ||
| 778 | # else | ||
| 779 | typedef /*bool*/int (*c32_type_test_t) (wint_t wc); | ||
| 780 | # endif | ||
| 781 | #endif | ||
| 782 | |||
| 783 | /* Return a character property with the given name, or (c32_type_test_t) 0 | ||
| 784 | if the designated property does not exist. | ||
| 785 | This function is the counterpart of function 'wctype' for wide characters. | ||
| 786 | */ | ||
| 787 | #if @GNULIB_C32_GET_TYPE_TEST@ | ||
| 788 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32_GET_TYPE_TEST | ||
| 789 | _GL_BEGIN_C_LINKAGE | ||
| 790 | _GL_INLINE _GL_ARG_NONNULL ((1)) c32_type_test_t | ||
| 791 | c32_get_type_test (const char *name) | ||
| 792 | { | ||
| 793 | return | ||
| 794 | # if @GNULIB_WCTYPE@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 795 | GNULIB_NAMESPACE:: | ||
| 796 | # endif | ||
| 797 | wctype (name); | ||
| 798 | } | ||
| 799 | _GL_END_C_LINKAGE | ||
| 800 | # else | ||
| 801 | _GL_FUNCDECL_SYS (c32_get_type_test, c32_type_test_t, (const char *name), | ||
| 802 | _GL_ARG_NONNULL ((1))); | ||
| 803 | # endif | ||
| 804 | _GL_CXXALIAS_SYS (c32_get_type_test, c32_type_test_t, (const char *name)); | ||
| 805 | _GL_CXXALIASWARN (c32_get_type_test); | ||
| 806 | #endif | ||
| 807 | |||
| 808 | /* Test whether a given 32-bit wide character has the specified character | ||
| 809 | property. | ||
| 810 | Return non-zero if true, zero if false or if the argument is WEOF. | ||
| 811 | This function is the counterpart of function 'iswctype' for wide characters. | ||
| 812 | */ | ||
| 813 | #if @GNULIB_C32_APPLY_TYPE_TEST@ | ||
| 814 | # if _GL_WCHAR_T_IS_UCS4 | ||
| 815 | # if !defined IN_C32_APPLY_TYPE_TEST | ||
| 816 | _GL_BEGIN_C_LINKAGE | ||
| 817 | _GL_INLINE int | ||
| 818 | c32_apply_type_test (wint_t wc, c32_type_test_t property) | ||
| 819 | { | ||
| 820 | return | ||
| 821 | # if @GNULIB_ISWCTYPE@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 822 | GNULIB_NAMESPACE:: | ||
| 823 | # endif | ||
| 824 | iswctype (wc, property); | ||
| 825 | } | ||
| 826 | _GL_END_C_LINKAGE | ||
| 827 | # else | ||
| 828 | _GL_FUNCDECL_SYS (c32_apply_type_test, int, | ||
| 829 | (wint_t wc, c32_type_test_t property), ); | ||
| 830 | # endif | ||
| 831 | # else | ||
| 832 | _GL_FUNCDECL_SYS (c32_apply_type_test, int, | ||
| 833 | (wint_t wc, c32_type_test_t property), | ||
| 834 | _GL_ARG_NONNULL ((2))); | ||
| 835 | # endif | ||
| 836 | _GL_CXXALIAS_SYS (c32_apply_type_test, int, | ||
| 837 | (wint_t wc, c32_type_test_t property)); | ||
| 838 | _GL_CXXALIASWARN (c32_apply_type_test); | ||
| 839 | #endif | ||
| 840 | |||
| 841 | |||
| 842 | #if @GNULIB_C32_GET_MAPPING@ || @GNULIB_C32_APPLY_MAPPING@ | ||
| 843 | /* A scalar type. Instances of this type, other than (c32_mapping_t) 0, | ||
| 844 | represent a character mapping. It can be applied to 32-bit wide characters. | ||
| 845 | It is the counterpart of type 'wctrans_t' for wide characters. | ||
| 846 | To apply a certain mapping to a given character, use the function | ||
| 847 | 'c32_apply_mapping'. */ | ||
| 848 | # if _GL_WCHAR_T_IS_UCS4 | ||
| 849 | typedef wctrans_t c32_mapping_t; | ||
| 850 | # else | ||
| 851 | typedef wint_t (*c32_mapping_t) (wint_t wc); | ||
| 852 | # endif | ||
| 853 | #endif | ||
| 854 | |||
| 855 | /* Return a character mapping with the given name, or (c32_mapping_t) 0 | ||
| 856 | if the designated mapping does not exist. | ||
| 857 | This function is the counterpart of function 'wctrans' for wide characters. | ||
| 858 | */ | ||
| 859 | #if @GNULIB_C32_GET_MAPPING@ | ||
| 860 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32_GET_MAPPING | ||
| 861 | _GL_BEGIN_C_LINKAGE | ||
| 862 | _GL_INLINE _GL_ARG_NONNULL ((1)) c32_mapping_t | ||
| 863 | c32_get_mapping (const char *name) | ||
| 864 | { | ||
| 865 | return | ||
| 866 | # if @GNULIB_WCTRANS@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 867 | GNULIB_NAMESPACE:: | ||
| 868 | # endif | ||
| 869 | wctrans (name); | ||
| 870 | } | ||
| 871 | _GL_END_C_LINKAGE | ||
| 872 | # else | ||
| 873 | _GL_FUNCDECL_SYS (c32_get_mapping, c32_mapping_t, (const char *name), | ||
| 874 | _GL_ARG_NONNULL ((1))); | ||
| 875 | # endif | ||
| 876 | _GL_CXXALIAS_SYS (c32_get_mapping, c32_mapping_t, (const char *name)); | ||
| 877 | _GL_CXXALIASWARN (c32_get_mapping); | ||
| 878 | #endif | ||
| 879 | |||
| 880 | /* Apply the specified character mapping to a given 32-bit wide character. | ||
| 881 | Return the result of this mapping. Return the WC argument unchanged if it is | ||
| 882 | WEOF. | ||
| 883 | This function is the counterpart of function 'towctrans' for wide characters. | ||
| 884 | */ | ||
| 885 | #if @GNULIB_C32_APPLY_MAPPING@ | ||
| 886 | # if _GL_WCHAR_T_IS_UCS4 && !defined IN_C32_APPLY_MAPPING | ||
| 887 | _GL_BEGIN_C_LINKAGE | ||
| 888 | _GL_INLINE _GL_ARG_NONNULL ((2)) wint_t | ||
| 889 | c32_apply_mapping (wint_t wc, c32_mapping_t mapping) | ||
| 890 | { | ||
| 891 | return | ||
| 892 | # if @GNULIB_TOWCTRANS@ && defined __cplusplus && defined GNULIB_NAMESPACE | ||
| 893 | GNULIB_NAMESPACE:: | ||
| 894 | # endif | ||
| 895 | towctrans (wc, mapping); | ||
| 896 | } | ||
| 897 | _GL_END_C_LINKAGE | ||
| 898 | # else | ||
| 899 | _GL_FUNCDECL_SYS (c32_apply_mapping, wint_t, | ||
| 900 | (wint_t wc, c32_mapping_t mapping), | ||
| 901 | _GL_ARG_NONNULL ((2))); | ||
| 902 | # endif | ||
| 903 | _GL_CXXALIAS_SYS (c32_apply_mapping, wint_t, | ||
| 904 | (wint_t wc, c32_mapping_t mapping)); | ||
| 905 | _GL_CXXALIASWARN (c32_apply_mapping); | ||
| 906 | #endif | ||
| 907 | |||
| 908 | |||
| 909 | _GL_INLINE_HEADER_END | ||
| 910 | |||
| 911 | #endif /* _@GUARD_PREFIX@_UCHAR_H */ | ||
| 912 | #endif /* _@GUARD_PREFIX@_UCHAR_H */ | ||
diff --git a/gl/unicase.h b/gl/unicase.h new file mode 100644 index 00000000..507a83d0 --- /dev/null +++ b/gl/unicase.h | |||
| @@ -0,0 +1,472 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* Unicode character case mappings. | ||
| 3 | Copyright (C) 2002, 2009-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #ifndef _UNICASE_H | ||
| 19 | #define _UNICASE_H | ||
| 20 | |||
| 21 | #include "unitypes.h" | ||
| 22 | |||
| 23 | /* Get bool. */ | ||
| 24 | #include <stdbool.h> | ||
| 25 | |||
| 26 | /* Get size_t. */ | ||
| 27 | #include <stddef.h> | ||
| 28 | |||
| 29 | /* Get uninorm_t. */ | ||
| 30 | #include "uninorm.h" | ||
| 31 | |||
| 32 | #if 0 | ||
| 33 | # include <unistring/woe32dll.h> | ||
| 34 | #else | ||
| 35 | # define LIBUNISTRING_DLL_VARIABLE | ||
| 36 | #endif | ||
| 37 | |||
| 38 | #ifdef __cplusplus | ||
| 39 | extern "C" { | ||
| 40 | #endif | ||
| 41 | |||
| 42 | /* ========================================================================= */ | ||
| 43 | |||
| 44 | /* Character case mappings. | ||
| 45 | These mappings are locale and context independent. | ||
| 46 | WARNING! These functions are not sufficient for languages such as German. | ||
| 47 | Better use the functions below that treat an entire string at once and are | ||
| 48 | language aware. */ | ||
| 49 | |||
| 50 | /* Return the uppercase mapping of a Unicode character. */ | ||
| 51 | extern ucs4_t | ||
| 52 | uc_toupper (ucs4_t uc) | ||
| 53 | _UC_ATTRIBUTE_CONST; | ||
| 54 | |||
| 55 | /* Return the lowercase mapping of a Unicode character. */ | ||
| 56 | extern ucs4_t | ||
| 57 | uc_tolower (ucs4_t uc) | ||
| 58 | _UC_ATTRIBUTE_CONST; | ||
| 59 | |||
| 60 | /* Return the titlecase mapping of a Unicode character. */ | ||
| 61 | extern ucs4_t | ||
| 62 | uc_totitle (ucs4_t uc) | ||
| 63 | _UC_ATTRIBUTE_CONST; | ||
| 64 | |||
| 65 | /* ========================================================================= */ | ||
| 66 | |||
| 67 | /* String case mappings. */ | ||
| 68 | |||
| 69 | /* These functions are locale dependent. The iso639_language argument | ||
| 70 | identifies the language (e.g. "tr" for Turkish). NULL means to use | ||
| 71 | locale independent case mappings. */ | ||
| 72 | |||
| 73 | /* Return the ISO 639 language code of the current locale. | ||
| 74 | Return "" if it is unknown, or in the "C" locale. */ | ||
| 75 | extern const char * | ||
| 76 | uc_locale_language (void) | ||
| 77 | _UC_ATTRIBUTE_PURE; | ||
| 78 | |||
| 79 | /* Conventions: | ||
| 80 | |||
| 81 | All functions prefixed with u8_ operate on UTF-8 encoded strings. | ||
| 82 | Their unit is an uint8_t (1 byte). | ||
| 83 | |||
| 84 | All functions prefixed with u16_ operate on UTF-16 encoded strings. | ||
| 85 | Their unit is an uint16_t (a 2-byte word). | ||
| 86 | |||
| 87 | All functions prefixed with u32_ operate on UCS-4 encoded strings. | ||
| 88 | Their unit is an uint32_t (a 4-byte word). | ||
| 89 | |||
| 90 | All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly | ||
| 91 | n units. | ||
| 92 | |||
| 93 | Functions returning a string result take a (resultbuf, lengthp) argument | ||
| 94 | pair. If resultbuf is not NULL and the result fits into *lengthp units, | ||
| 95 | it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly | ||
| 96 | allocated string is returned. In both cases, *lengthp is set to the | ||
| 97 | length (number of units) of the returned string. In case of error, | ||
| 98 | NULL is returned and errno is set. */ | ||
| 99 | |||
| 100 | /* Return the uppercase mapping of a string. | ||
| 101 | The nf argument identifies the normalization form to apply after the | ||
| 102 | case-mapping. It can also be NULL, for no normalization. */ | ||
| 103 | extern uint8_t * | ||
| 104 | u8_toupper (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 105 | uninorm_t nf, | ||
| 106 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 107 | extern uint16_t * | ||
| 108 | u16_toupper (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 109 | uninorm_t nf, | ||
| 110 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 111 | extern uint32_t * | ||
| 112 | u32_toupper (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 113 | uninorm_t nf, | ||
| 114 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 115 | |||
| 116 | /* Return the lowercase mapping of a string. | ||
| 117 | The nf argument identifies the normalization form to apply after the | ||
| 118 | case-mapping. It can also be NULL, for no normalization. */ | ||
| 119 | extern uint8_t * | ||
| 120 | u8_tolower (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 121 | uninorm_t nf, | ||
| 122 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 123 | extern uint16_t * | ||
| 124 | u16_tolower (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 125 | uninorm_t nf, | ||
| 126 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 127 | extern uint32_t * | ||
| 128 | u32_tolower (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 129 | uninorm_t nf, | ||
| 130 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 131 | |||
| 132 | /* Return the titlecase mapping of a string. | ||
| 133 | The nf argument identifies the normalization form to apply after the | ||
| 134 | case-mapping. It can also be NULL, for no normalization. */ | ||
| 135 | extern uint8_t * | ||
| 136 | u8_totitle (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 137 | uninorm_t nf, | ||
| 138 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 139 | extern uint16_t * | ||
| 140 | u16_totitle (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 141 | uninorm_t nf, | ||
| 142 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 143 | extern uint32_t * | ||
| 144 | u32_totitle (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 145 | uninorm_t nf, | ||
| 146 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 147 | |||
| 148 | /* The case-mapping context given by a prefix string. */ | ||
| 149 | typedef struct casing_prefix_context | ||
| 150 | { | ||
| 151 | /* These fields are private, undocumented. */ | ||
| 152 | uint32_t last_char_except_ignorable; | ||
| 153 | uint32_t last_char_normal_or_above; | ||
| 154 | } | ||
| 155 | casing_prefix_context_t; | ||
| 156 | /* The case-mapping context of the empty prefix string. */ | ||
| 157 | extern LIBUNISTRING_DLL_VARIABLE const casing_prefix_context_t unicase_empty_prefix_context; | ||
| 158 | /* Return the case-mapping context of a given prefix string. */ | ||
| 159 | extern casing_prefix_context_t | ||
| 160 | u8_casing_prefix_context (const uint8_t *s, size_t n); | ||
| 161 | extern casing_prefix_context_t | ||
| 162 | u16_casing_prefix_context (const uint16_t *s, size_t n); | ||
| 163 | extern casing_prefix_context_t | ||
| 164 | u32_casing_prefix_context (const uint32_t *s, size_t n); | ||
| 165 | /* Return the case-mapping context of the prefix concat(A, S), given the | ||
| 166 | case-mapping context of the prefix A. */ | ||
| 167 | extern casing_prefix_context_t | ||
| 168 | u8_casing_prefixes_context (const uint8_t *s, size_t n, | ||
| 169 | casing_prefix_context_t a_context); | ||
| 170 | extern casing_prefix_context_t | ||
| 171 | u16_casing_prefixes_context (const uint16_t *s, size_t n, | ||
| 172 | casing_prefix_context_t a_context); | ||
| 173 | extern casing_prefix_context_t | ||
| 174 | u32_casing_prefixes_context (const uint32_t *s, size_t n, | ||
| 175 | casing_prefix_context_t a_context); | ||
| 176 | |||
| 177 | /* The case-mapping context given by a suffix string. */ | ||
| 178 | typedef struct casing_suffix_context | ||
| 179 | { | ||
| 180 | /* These fields are private, undocumented. */ | ||
| 181 | uint32_t first_char_except_ignorable; | ||
| 182 | uint32_t bits; | ||
| 183 | } | ||
| 184 | casing_suffix_context_t; | ||
| 185 | /* The case-mapping context of the empty suffix string. */ | ||
| 186 | extern LIBUNISTRING_DLL_VARIABLE const casing_suffix_context_t unicase_empty_suffix_context; | ||
| 187 | /* Return the case-mapping context of a given suffix string. */ | ||
| 188 | extern casing_suffix_context_t | ||
| 189 | u8_casing_suffix_context (const uint8_t *s, size_t n); | ||
| 190 | extern casing_suffix_context_t | ||
| 191 | u16_casing_suffix_context (const uint16_t *s, size_t n); | ||
| 192 | extern casing_suffix_context_t | ||
| 193 | u32_casing_suffix_context (const uint32_t *s, size_t n); | ||
| 194 | /* Return the case-mapping context of the suffix concat(S, A), given the | ||
| 195 | case-mapping context of the suffix A. */ | ||
| 196 | extern casing_suffix_context_t | ||
| 197 | u8_casing_suffixes_context (const uint8_t *s, size_t n, | ||
| 198 | casing_suffix_context_t a_context); | ||
| 199 | extern casing_suffix_context_t | ||
| 200 | u16_casing_suffixes_context (const uint16_t *s, size_t n, | ||
| 201 | casing_suffix_context_t a_context); | ||
| 202 | extern casing_suffix_context_t | ||
| 203 | u32_casing_suffixes_context (const uint32_t *s, size_t n, | ||
| 204 | casing_suffix_context_t a_context); | ||
| 205 | |||
| 206 | /* Return the uppercase mapping of a string that is surrounded by a prefix | ||
| 207 | and a suffix. */ | ||
| 208 | extern uint8_t * | ||
| 209 | u8_ct_toupper (const uint8_t *s, size_t n, | ||
| 210 | casing_prefix_context_t prefix_context, | ||
| 211 | casing_suffix_context_t suffix_context, | ||
| 212 | const char *iso639_language, | ||
| 213 | uninorm_t nf, | ||
| 214 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 215 | extern uint16_t * | ||
| 216 | u16_ct_toupper (const uint16_t *s, size_t n, | ||
| 217 | casing_prefix_context_t prefix_context, | ||
| 218 | casing_suffix_context_t suffix_context, | ||
| 219 | const char *iso639_language, | ||
| 220 | uninorm_t nf, | ||
| 221 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 222 | extern uint32_t * | ||
| 223 | u32_ct_toupper (const uint32_t *s, size_t n, | ||
| 224 | casing_prefix_context_t prefix_context, | ||
| 225 | casing_suffix_context_t suffix_context, | ||
| 226 | const char *iso639_language, | ||
| 227 | uninorm_t nf, | ||
| 228 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 229 | |||
| 230 | /* Return the lowercase mapping of a string that is surrounded by a prefix | ||
| 231 | and a suffix. */ | ||
| 232 | extern uint8_t * | ||
| 233 | u8_ct_tolower (const uint8_t *s, size_t n, | ||
| 234 | casing_prefix_context_t prefix_context, | ||
| 235 | casing_suffix_context_t suffix_context, | ||
| 236 | const char *iso639_language, | ||
| 237 | uninorm_t nf, | ||
| 238 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 239 | extern uint16_t * | ||
| 240 | u16_ct_tolower (const uint16_t *s, size_t n, | ||
| 241 | casing_prefix_context_t prefix_context, | ||
| 242 | casing_suffix_context_t suffix_context, | ||
| 243 | const char *iso639_language, | ||
| 244 | uninorm_t nf, | ||
| 245 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 246 | extern uint32_t * | ||
| 247 | u32_ct_tolower (const uint32_t *s, size_t n, | ||
| 248 | casing_prefix_context_t prefix_context, | ||
| 249 | casing_suffix_context_t suffix_context, | ||
| 250 | const char *iso639_language, | ||
| 251 | uninorm_t nf, | ||
| 252 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 253 | |||
| 254 | /* Return the titlecase mapping of a string that is surrounded by a prefix | ||
| 255 | and a suffix. */ | ||
| 256 | extern uint8_t * | ||
| 257 | u8_ct_totitle (const uint8_t *s, size_t n, | ||
| 258 | casing_prefix_context_t prefix_context, | ||
| 259 | casing_suffix_context_t suffix_context, | ||
| 260 | const char *iso639_language, | ||
| 261 | uninorm_t nf, | ||
| 262 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 263 | extern uint16_t * | ||
| 264 | u16_ct_totitle (const uint16_t *s, size_t n, | ||
| 265 | casing_prefix_context_t prefix_context, | ||
| 266 | casing_suffix_context_t suffix_context, | ||
| 267 | const char *iso639_language, | ||
| 268 | uninorm_t nf, | ||
| 269 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 270 | extern uint32_t * | ||
| 271 | u32_ct_totitle (const uint32_t *s, size_t n, | ||
| 272 | casing_prefix_context_t prefix_context, | ||
| 273 | casing_suffix_context_t suffix_context, | ||
| 274 | const char *iso639_language, | ||
| 275 | uninorm_t nf, | ||
| 276 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 277 | |||
| 278 | /* Return the case folded string. | ||
| 279 | Comparing uN_casefold (S1) and uN_casefold (S2) with uN_cmp2() is equivalent | ||
| 280 | to comparing S1 and S2 with uN_casecmp(). | ||
| 281 | The nf argument identifies the normalization form to apply after the | ||
| 282 | case-mapping. It can also be NULL, for no normalization. */ | ||
| 283 | extern uint8_t * | ||
| 284 | u8_casefold (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 285 | uninorm_t nf, | ||
| 286 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 287 | extern uint16_t * | ||
| 288 | u16_casefold (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 289 | uninorm_t nf, | ||
| 290 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 291 | extern uint32_t * | ||
| 292 | u32_casefold (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 293 | uninorm_t nf, | ||
| 294 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 295 | /* Likewise, for a string that is surrounded by a prefix and a suffix. */ | ||
| 296 | extern uint8_t * | ||
| 297 | u8_ct_casefold (const uint8_t *s, size_t n, | ||
| 298 | casing_prefix_context_t prefix_context, | ||
| 299 | casing_suffix_context_t suffix_context, | ||
| 300 | const char *iso639_language, | ||
| 301 | uninorm_t nf, | ||
| 302 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 303 | extern uint16_t * | ||
| 304 | u16_ct_casefold (const uint16_t *s, size_t n, | ||
| 305 | casing_prefix_context_t prefix_context, | ||
| 306 | casing_suffix_context_t suffix_context, | ||
| 307 | const char *iso639_language, | ||
| 308 | uninorm_t nf, | ||
| 309 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 310 | extern uint32_t * | ||
| 311 | u32_ct_casefold (const uint32_t *s, size_t n, | ||
| 312 | casing_prefix_context_t prefix_context, | ||
| 313 | casing_suffix_context_t suffix_context, | ||
| 314 | const char *iso639_language, | ||
| 315 | uninorm_t nf, | ||
| 316 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 317 | |||
| 318 | /* Compare S1 and S2, ignoring differences in case and normalization. | ||
| 319 | The nf argument identifies the normalization form to apply after the | ||
| 320 | case-mapping. It can also be NULL, for no normalization. | ||
| 321 | If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and | ||
| 322 | return 0. Upon failure, return -1 with errno set. */ | ||
| 323 | extern int | ||
| 324 | u8_casecmp (const uint8_t *s1, size_t n1, | ||
| 325 | const uint8_t *s2, size_t n2, | ||
| 326 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 327 | extern int | ||
| 328 | u16_casecmp (const uint16_t *s1, size_t n1, | ||
| 329 | const uint16_t *s2, size_t n2, | ||
| 330 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 331 | extern int | ||
| 332 | u32_casecmp (const uint32_t *s1, size_t n1, | ||
| 333 | const uint32_t *s2, size_t n2, | ||
| 334 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 335 | extern int | ||
| 336 | ulc_casecmp (const char *s1, size_t n1, | ||
| 337 | const char *s2, size_t n2, | ||
| 338 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 339 | |||
| 340 | /* Convert the string S of length N to a NUL-terminated byte sequence, in such | ||
| 341 | a way that comparing uN_casexfrm (S1) and uN_casexfrm (S2) with the gnulib | ||
| 342 | function memcmp2() is equivalent to comparing S1 and S2 with uN_casecoll(). | ||
| 343 | NF must be either UNINORM_NFC, UNINORM_NFKC, or NULL for no normalization. */ | ||
| 344 | extern char * | ||
| 345 | u8_casexfrm (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 346 | uninorm_t nf, | ||
| 347 | char *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 348 | extern char * | ||
| 349 | u16_casexfrm (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 350 | uninorm_t nf, | ||
| 351 | char *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 352 | extern char * | ||
| 353 | u32_casexfrm (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 354 | uninorm_t nf, | ||
| 355 | char *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 356 | extern char * | ||
| 357 | ulc_casexfrm (const char *s, size_t n, const char *iso639_language, | ||
| 358 | uninorm_t nf, | ||
| 359 | char *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 360 | |||
| 361 | /* Compare S1 and S2, ignoring differences in case and normalization, using the | ||
| 362 | collation rules of the current locale. | ||
| 363 | The nf argument identifies the normalization form to apply after the | ||
| 364 | case-mapping. It must be either UNINORM_NFC or UNINORM_NFKC. It can also | ||
| 365 | be NULL, for no normalization. | ||
| 366 | If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and | ||
| 367 | return 0. Upon failure, return -1 with errno set. */ | ||
| 368 | extern int | ||
| 369 | u8_casecoll (const uint8_t *s1, size_t n1, | ||
| 370 | const uint8_t *s2, size_t n2, | ||
| 371 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 372 | extern int | ||
| 373 | u16_casecoll (const uint16_t *s1, size_t n1, | ||
| 374 | const uint16_t *s2, size_t n2, | ||
| 375 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 376 | extern int | ||
| 377 | u32_casecoll (const uint32_t *s1, size_t n1, | ||
| 378 | const uint32_t *s2, size_t n2, | ||
| 379 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 380 | extern int | ||
| 381 | ulc_casecoll (const char *s1, size_t n1, | ||
| 382 | const char *s2, size_t n2, | ||
| 383 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 384 | |||
| 385 | |||
| 386 | /* Set *RESULTP to true if mapping NFD(S) to upper case is a no-op, or to false | ||
| 387 | otherwise, and return 0. Upon failure, return -1 with errno set. */ | ||
| 388 | extern int | ||
| 389 | u8_is_uppercase (const uint8_t *s, size_t n, | ||
| 390 | const char *iso639_language, | ||
| 391 | bool *resultp); | ||
| 392 | extern int | ||
| 393 | u16_is_uppercase (const uint16_t *s, size_t n, | ||
| 394 | const char *iso639_language, | ||
| 395 | bool *resultp); | ||
| 396 | extern int | ||
| 397 | u32_is_uppercase (const uint32_t *s, size_t n, | ||
| 398 | const char *iso639_language, | ||
| 399 | bool *resultp); | ||
| 400 | |||
| 401 | /* Set *RESULTP to true if mapping NFD(S) to lower case is a no-op, or to false | ||
| 402 | otherwise, and return 0. Upon failure, return -1 with errno set. */ | ||
| 403 | extern int | ||
| 404 | u8_is_lowercase (const uint8_t *s, size_t n, | ||
| 405 | const char *iso639_language, | ||
| 406 | bool *resultp); | ||
| 407 | extern int | ||
| 408 | u16_is_lowercase (const uint16_t *s, size_t n, | ||
| 409 | const char *iso639_language, | ||
| 410 | bool *resultp); | ||
| 411 | extern int | ||
| 412 | u32_is_lowercase (const uint32_t *s, size_t n, | ||
| 413 | const char *iso639_language, | ||
| 414 | bool *resultp); | ||
| 415 | |||
| 416 | /* Set *RESULTP to true if mapping NFD(S) to title case is a no-op, or to false | ||
| 417 | otherwise, and return 0. Upon failure, return -1 with errno set. */ | ||
| 418 | extern int | ||
| 419 | u8_is_titlecase (const uint8_t *s, size_t n, | ||
| 420 | const char *iso639_language, | ||
| 421 | bool *resultp); | ||
| 422 | extern int | ||
| 423 | u16_is_titlecase (const uint16_t *s, size_t n, | ||
| 424 | const char *iso639_language, | ||
| 425 | bool *resultp); | ||
| 426 | extern int | ||
| 427 | u32_is_titlecase (const uint32_t *s, size_t n, | ||
| 428 | const char *iso639_language, | ||
| 429 | bool *resultp); | ||
| 430 | |||
| 431 | /* Set *RESULTP to true if applying case folding to NFD(S) is a no-op, or to | ||
| 432 | false otherwise, and return 0. Upon failure, return -1 with errno set. */ | ||
| 433 | extern int | ||
| 434 | u8_is_casefolded (const uint8_t *s, size_t n, | ||
| 435 | const char *iso639_language, | ||
| 436 | bool *resultp); | ||
| 437 | extern int | ||
| 438 | u16_is_casefolded (const uint16_t *s, size_t n, | ||
| 439 | const char *iso639_language, | ||
| 440 | bool *resultp); | ||
| 441 | extern int | ||
| 442 | u32_is_casefolded (const uint32_t *s, size_t n, | ||
| 443 | const char *iso639_language, | ||
| 444 | bool *resultp); | ||
| 445 | |||
| 446 | /* Set *RESULTP to true if case matters for S, that is, if mapping NFD(S) to | ||
| 447 | either upper case or lower case or title case is not a no-op. | ||
| 448 | Set *RESULTP to false if NFD(S) maps to itself under the upper case mapping, | ||
| 449 | under the lower case mapping, and under the title case mapping; in other | ||
| 450 | words, when NFD(S) consists entirely of caseless characters. | ||
| 451 | Upon failure, return -1 with errno set. */ | ||
| 452 | extern int | ||
| 453 | u8_is_cased (const uint8_t *s, size_t n, | ||
| 454 | const char *iso639_language, | ||
| 455 | bool *resultp); | ||
| 456 | extern int | ||
| 457 | u16_is_cased (const uint16_t *s, size_t n, | ||
| 458 | const char *iso639_language, | ||
| 459 | bool *resultp); | ||
| 460 | extern int | ||
| 461 | u32_is_cased (const uint32_t *s, size_t n, | ||
| 462 | const char *iso639_language, | ||
| 463 | bool *resultp); | ||
| 464 | |||
| 465 | |||
| 466 | /* ========================================================================= */ | ||
| 467 | |||
| 468 | #ifdef __cplusplus | ||
| 469 | } | ||
| 470 | #endif | ||
| 471 | |||
| 472 | #endif /* _UNICASE_H */ | ||
diff --git a/gl/unicase.in.h b/gl/unicase.in.h new file mode 100644 index 00000000..c6df04b3 --- /dev/null +++ b/gl/unicase.in.h | |||
| @@ -0,0 +1,471 @@ | |||
| 1 | /* Unicode character case mappings. | ||
| 2 | Copyright (C) 2002, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #ifndef _UNICASE_H | ||
| 18 | #define _UNICASE_H | ||
| 19 | |||
| 20 | #include "unitypes.h" | ||
| 21 | |||
| 22 | /* Get bool. */ | ||
| 23 | #include <stdbool.h> | ||
| 24 | |||
| 25 | /* Get size_t. */ | ||
| 26 | #include <stddef.h> | ||
| 27 | |||
| 28 | /* Get uninorm_t. */ | ||
| 29 | #include "uninorm.h" | ||
| 30 | |||
| 31 | #if @HAVE_UNISTRING_WOE32DLL_H@ | ||
| 32 | # include <unistring/woe32dll.h> | ||
| 33 | #else | ||
| 34 | # define LIBUNISTRING_DLL_VARIABLE | ||
| 35 | #endif | ||
| 36 | |||
| 37 | #ifdef __cplusplus | ||
| 38 | extern "C" { | ||
| 39 | #endif | ||
| 40 | |||
| 41 | /* ========================================================================= */ | ||
| 42 | |||
| 43 | /* Character case mappings. | ||
| 44 | These mappings are locale and context independent. | ||
| 45 | WARNING! These functions are not sufficient for languages such as German. | ||
| 46 | Better use the functions below that treat an entire string at once and are | ||
| 47 | language aware. */ | ||
| 48 | |||
| 49 | /* Return the uppercase mapping of a Unicode character. */ | ||
| 50 | extern ucs4_t | ||
| 51 | uc_toupper (ucs4_t uc) | ||
| 52 | _UC_ATTRIBUTE_CONST; | ||
| 53 | |||
| 54 | /* Return the lowercase mapping of a Unicode character. */ | ||
| 55 | extern ucs4_t | ||
| 56 | uc_tolower (ucs4_t uc) | ||
| 57 | _UC_ATTRIBUTE_CONST; | ||
| 58 | |||
| 59 | /* Return the titlecase mapping of a Unicode character. */ | ||
| 60 | extern ucs4_t | ||
| 61 | uc_totitle (ucs4_t uc) | ||
| 62 | _UC_ATTRIBUTE_CONST; | ||
| 63 | |||
| 64 | /* ========================================================================= */ | ||
| 65 | |||
| 66 | /* String case mappings. */ | ||
| 67 | |||
| 68 | /* These functions are locale dependent. The iso639_language argument | ||
| 69 | identifies the language (e.g. "tr" for Turkish). NULL means to use | ||
| 70 | locale independent case mappings. */ | ||
| 71 | |||
| 72 | /* Return the ISO 639 language code of the current locale. | ||
| 73 | Return "" if it is unknown, or in the "C" locale. */ | ||
| 74 | extern const char * | ||
| 75 | uc_locale_language (void) | ||
| 76 | _UC_ATTRIBUTE_PURE; | ||
| 77 | |||
| 78 | /* Conventions: | ||
| 79 | |||
| 80 | All functions prefixed with u8_ operate on UTF-8 encoded strings. | ||
| 81 | Their unit is an uint8_t (1 byte). | ||
| 82 | |||
| 83 | All functions prefixed with u16_ operate on UTF-16 encoded strings. | ||
| 84 | Their unit is an uint16_t (a 2-byte word). | ||
| 85 | |||
| 86 | All functions prefixed with u32_ operate on UCS-4 encoded strings. | ||
| 87 | Their unit is an uint32_t (a 4-byte word). | ||
| 88 | |||
| 89 | All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly | ||
| 90 | n units. | ||
| 91 | |||
| 92 | Functions returning a string result take a (resultbuf, lengthp) argument | ||
| 93 | pair. If resultbuf is not NULL and the result fits into *lengthp units, | ||
| 94 | it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly | ||
| 95 | allocated string is returned. In both cases, *lengthp is set to the | ||
| 96 | length (number of units) of the returned string. In case of error, | ||
| 97 | NULL is returned and errno is set. */ | ||
| 98 | |||
| 99 | /* Return the uppercase mapping of a string. | ||
| 100 | The nf argument identifies the normalization form to apply after the | ||
| 101 | case-mapping. It can also be NULL, for no normalization. */ | ||
| 102 | extern uint8_t * | ||
| 103 | u8_toupper (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 104 | uninorm_t nf, | ||
| 105 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 106 | extern uint16_t * | ||
| 107 | u16_toupper (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 108 | uninorm_t nf, | ||
| 109 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 110 | extern uint32_t * | ||
| 111 | u32_toupper (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 112 | uninorm_t nf, | ||
| 113 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 114 | |||
| 115 | /* Return the lowercase mapping of a string. | ||
| 116 | The nf argument identifies the normalization form to apply after the | ||
| 117 | case-mapping. It can also be NULL, for no normalization. */ | ||
| 118 | extern uint8_t * | ||
| 119 | u8_tolower (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 120 | uninorm_t nf, | ||
| 121 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 122 | extern uint16_t * | ||
| 123 | u16_tolower (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 124 | uninorm_t nf, | ||
| 125 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 126 | extern uint32_t * | ||
| 127 | u32_tolower (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 128 | uninorm_t nf, | ||
| 129 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 130 | |||
| 131 | /* Return the titlecase mapping of a string. | ||
| 132 | The nf argument identifies the normalization form to apply after the | ||
| 133 | case-mapping. It can also be NULL, for no normalization. */ | ||
| 134 | extern uint8_t * | ||
| 135 | u8_totitle (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 136 | uninorm_t nf, | ||
| 137 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 138 | extern uint16_t * | ||
| 139 | u16_totitle (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 140 | uninorm_t nf, | ||
| 141 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 142 | extern uint32_t * | ||
| 143 | u32_totitle (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 144 | uninorm_t nf, | ||
| 145 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 146 | |||
| 147 | /* The case-mapping context given by a prefix string. */ | ||
| 148 | typedef struct casing_prefix_context | ||
| 149 | { | ||
| 150 | /* These fields are private, undocumented. */ | ||
| 151 | uint32_t last_char_except_ignorable; | ||
| 152 | uint32_t last_char_normal_or_above; | ||
| 153 | } | ||
| 154 | casing_prefix_context_t; | ||
| 155 | /* The case-mapping context of the empty prefix string. */ | ||
| 156 | extern @GNULIB_UNICASE_EMPTY_PREFIX_CONTEXT_DLL_VARIABLE@ const casing_prefix_context_t unicase_empty_prefix_context; | ||
| 157 | /* Return the case-mapping context of a given prefix string. */ | ||
| 158 | extern casing_prefix_context_t | ||
| 159 | u8_casing_prefix_context (const uint8_t *s, size_t n); | ||
| 160 | extern casing_prefix_context_t | ||
| 161 | u16_casing_prefix_context (const uint16_t *s, size_t n); | ||
| 162 | extern casing_prefix_context_t | ||
| 163 | u32_casing_prefix_context (const uint32_t *s, size_t n); | ||
| 164 | /* Return the case-mapping context of the prefix concat(A, S), given the | ||
| 165 | case-mapping context of the prefix A. */ | ||
| 166 | extern casing_prefix_context_t | ||
| 167 | u8_casing_prefixes_context (const uint8_t *s, size_t n, | ||
| 168 | casing_prefix_context_t a_context); | ||
| 169 | extern casing_prefix_context_t | ||
| 170 | u16_casing_prefixes_context (const uint16_t *s, size_t n, | ||
| 171 | casing_prefix_context_t a_context); | ||
| 172 | extern casing_prefix_context_t | ||
| 173 | u32_casing_prefixes_context (const uint32_t *s, size_t n, | ||
| 174 | casing_prefix_context_t a_context); | ||
| 175 | |||
| 176 | /* The case-mapping context given by a suffix string. */ | ||
| 177 | typedef struct casing_suffix_context | ||
| 178 | { | ||
| 179 | /* These fields are private, undocumented. */ | ||
| 180 | uint32_t first_char_except_ignorable; | ||
| 181 | uint32_t bits; | ||
| 182 | } | ||
| 183 | casing_suffix_context_t; | ||
| 184 | /* The case-mapping context of the empty suffix string. */ | ||
| 185 | extern @GNULIB_UNICASE_EMPTY_SUFFIX_CONTEXT_DLL_VARIABLE@ const casing_suffix_context_t unicase_empty_suffix_context; | ||
| 186 | /* Return the case-mapping context of a given suffix string. */ | ||
| 187 | extern casing_suffix_context_t | ||
| 188 | u8_casing_suffix_context (const uint8_t *s, size_t n); | ||
| 189 | extern casing_suffix_context_t | ||
| 190 | u16_casing_suffix_context (const uint16_t *s, size_t n); | ||
| 191 | extern casing_suffix_context_t | ||
| 192 | u32_casing_suffix_context (const uint32_t *s, size_t n); | ||
| 193 | /* Return the case-mapping context of the suffix concat(S, A), given the | ||
| 194 | case-mapping context of the suffix A. */ | ||
| 195 | extern casing_suffix_context_t | ||
| 196 | u8_casing_suffixes_context (const uint8_t *s, size_t n, | ||
| 197 | casing_suffix_context_t a_context); | ||
| 198 | extern casing_suffix_context_t | ||
| 199 | u16_casing_suffixes_context (const uint16_t *s, size_t n, | ||
| 200 | casing_suffix_context_t a_context); | ||
| 201 | extern casing_suffix_context_t | ||
| 202 | u32_casing_suffixes_context (const uint32_t *s, size_t n, | ||
| 203 | casing_suffix_context_t a_context); | ||
| 204 | |||
| 205 | /* Return the uppercase mapping of a string that is surrounded by a prefix | ||
| 206 | and a suffix. */ | ||
| 207 | extern uint8_t * | ||
| 208 | u8_ct_toupper (const uint8_t *s, size_t n, | ||
| 209 | casing_prefix_context_t prefix_context, | ||
| 210 | casing_suffix_context_t suffix_context, | ||
| 211 | const char *iso639_language, | ||
| 212 | uninorm_t nf, | ||
| 213 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 214 | extern uint16_t * | ||
| 215 | u16_ct_toupper (const uint16_t *s, size_t n, | ||
| 216 | casing_prefix_context_t prefix_context, | ||
| 217 | casing_suffix_context_t suffix_context, | ||
| 218 | const char *iso639_language, | ||
| 219 | uninorm_t nf, | ||
| 220 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 221 | extern uint32_t * | ||
| 222 | u32_ct_toupper (const uint32_t *s, size_t n, | ||
| 223 | casing_prefix_context_t prefix_context, | ||
| 224 | casing_suffix_context_t suffix_context, | ||
| 225 | const char *iso639_language, | ||
| 226 | uninorm_t nf, | ||
| 227 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 228 | |||
| 229 | /* Return the lowercase mapping of a string that is surrounded by a prefix | ||
| 230 | and a suffix. */ | ||
| 231 | extern uint8_t * | ||
| 232 | u8_ct_tolower (const uint8_t *s, size_t n, | ||
| 233 | casing_prefix_context_t prefix_context, | ||
| 234 | casing_suffix_context_t suffix_context, | ||
| 235 | const char *iso639_language, | ||
| 236 | uninorm_t nf, | ||
| 237 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 238 | extern uint16_t * | ||
| 239 | u16_ct_tolower (const uint16_t *s, size_t n, | ||
| 240 | casing_prefix_context_t prefix_context, | ||
| 241 | casing_suffix_context_t suffix_context, | ||
| 242 | const char *iso639_language, | ||
| 243 | uninorm_t nf, | ||
| 244 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 245 | extern uint32_t * | ||
| 246 | u32_ct_tolower (const uint32_t *s, size_t n, | ||
| 247 | casing_prefix_context_t prefix_context, | ||
| 248 | casing_suffix_context_t suffix_context, | ||
| 249 | const char *iso639_language, | ||
| 250 | uninorm_t nf, | ||
| 251 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 252 | |||
| 253 | /* Return the titlecase mapping of a string that is surrounded by a prefix | ||
| 254 | and a suffix. */ | ||
| 255 | extern uint8_t * | ||
| 256 | u8_ct_totitle (const uint8_t *s, size_t n, | ||
| 257 | casing_prefix_context_t prefix_context, | ||
| 258 | casing_suffix_context_t suffix_context, | ||
| 259 | const char *iso639_language, | ||
| 260 | uninorm_t nf, | ||
| 261 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 262 | extern uint16_t * | ||
| 263 | u16_ct_totitle (const uint16_t *s, size_t n, | ||
| 264 | casing_prefix_context_t prefix_context, | ||
| 265 | casing_suffix_context_t suffix_context, | ||
| 266 | const char *iso639_language, | ||
| 267 | uninorm_t nf, | ||
| 268 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 269 | extern uint32_t * | ||
| 270 | u32_ct_totitle (const uint32_t *s, size_t n, | ||
| 271 | casing_prefix_context_t prefix_context, | ||
| 272 | casing_suffix_context_t suffix_context, | ||
| 273 | const char *iso639_language, | ||
| 274 | uninorm_t nf, | ||
| 275 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 276 | |||
| 277 | /* Return the case folded string. | ||
| 278 | Comparing uN_casefold (S1) and uN_casefold (S2) with uN_cmp2() is equivalent | ||
| 279 | to comparing S1 and S2 with uN_casecmp(). | ||
| 280 | The nf argument identifies the normalization form to apply after the | ||
| 281 | case-mapping. It can also be NULL, for no normalization. */ | ||
| 282 | extern uint8_t * | ||
| 283 | u8_casefold (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 284 | uninorm_t nf, | ||
| 285 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 286 | extern uint16_t * | ||
| 287 | u16_casefold (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 288 | uninorm_t nf, | ||
| 289 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 290 | extern uint32_t * | ||
| 291 | u32_casefold (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 292 | uninorm_t nf, | ||
| 293 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 294 | /* Likewise, for a string that is surrounded by a prefix and a suffix. */ | ||
| 295 | extern uint8_t * | ||
| 296 | u8_ct_casefold (const uint8_t *s, size_t n, | ||
| 297 | casing_prefix_context_t prefix_context, | ||
| 298 | casing_suffix_context_t suffix_context, | ||
| 299 | const char *iso639_language, | ||
| 300 | uninorm_t nf, | ||
| 301 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 302 | extern uint16_t * | ||
| 303 | u16_ct_casefold (const uint16_t *s, size_t n, | ||
| 304 | casing_prefix_context_t prefix_context, | ||
| 305 | casing_suffix_context_t suffix_context, | ||
| 306 | const char *iso639_language, | ||
| 307 | uninorm_t nf, | ||
| 308 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 309 | extern uint32_t * | ||
| 310 | u32_ct_casefold (const uint32_t *s, size_t n, | ||
| 311 | casing_prefix_context_t prefix_context, | ||
| 312 | casing_suffix_context_t suffix_context, | ||
| 313 | const char *iso639_language, | ||
| 314 | uninorm_t nf, | ||
| 315 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 316 | |||
| 317 | /* Compare S1 and S2, ignoring differences in case and normalization. | ||
| 318 | The nf argument identifies the normalization form to apply after the | ||
| 319 | case-mapping. It can also be NULL, for no normalization. | ||
| 320 | If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and | ||
| 321 | return 0. Upon failure, return -1 with errno set. */ | ||
| 322 | extern int | ||
| 323 | u8_casecmp (const uint8_t *s1, size_t n1, | ||
| 324 | const uint8_t *s2, size_t n2, | ||
| 325 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 326 | extern int | ||
| 327 | u16_casecmp (const uint16_t *s1, size_t n1, | ||
| 328 | const uint16_t *s2, size_t n2, | ||
| 329 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 330 | extern int | ||
| 331 | u32_casecmp (const uint32_t *s1, size_t n1, | ||
| 332 | const uint32_t *s2, size_t n2, | ||
| 333 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 334 | extern int | ||
| 335 | ulc_casecmp (const char *s1, size_t n1, | ||
| 336 | const char *s2, size_t n2, | ||
| 337 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 338 | |||
| 339 | /* Convert the string S of length N to a NUL-terminated byte sequence, in such | ||
| 340 | a way that comparing uN_casexfrm (S1) and uN_casexfrm (S2) with the gnulib | ||
| 341 | function memcmp2() is equivalent to comparing S1 and S2 with uN_casecoll(). | ||
| 342 | NF must be either UNINORM_NFC, UNINORM_NFKC, or NULL for no normalization. */ | ||
| 343 | extern char * | ||
| 344 | u8_casexfrm (const uint8_t *s, size_t n, const char *iso639_language, | ||
| 345 | uninorm_t nf, | ||
| 346 | char *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 347 | extern char * | ||
| 348 | u16_casexfrm (const uint16_t *s, size_t n, const char *iso639_language, | ||
| 349 | uninorm_t nf, | ||
| 350 | char *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 351 | extern char * | ||
| 352 | u32_casexfrm (const uint32_t *s, size_t n, const char *iso639_language, | ||
| 353 | uninorm_t nf, | ||
| 354 | char *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 355 | extern char * | ||
| 356 | ulc_casexfrm (const char *s, size_t n, const char *iso639_language, | ||
| 357 | uninorm_t nf, | ||
| 358 | char *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 359 | |||
| 360 | /* Compare S1 and S2, ignoring differences in case and normalization, using the | ||
| 361 | collation rules of the current locale. | ||
| 362 | The nf argument identifies the normalization form to apply after the | ||
| 363 | case-mapping. It must be either UNINORM_NFC or UNINORM_NFKC. It can also | ||
| 364 | be NULL, for no normalization. | ||
| 365 | If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and | ||
| 366 | return 0. Upon failure, return -1 with errno set. */ | ||
| 367 | extern int | ||
| 368 | u8_casecoll (const uint8_t *s1, size_t n1, | ||
| 369 | const uint8_t *s2, size_t n2, | ||
| 370 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 371 | extern int | ||
| 372 | u16_casecoll (const uint16_t *s1, size_t n1, | ||
| 373 | const uint16_t *s2, size_t n2, | ||
| 374 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 375 | extern int | ||
| 376 | u32_casecoll (const uint32_t *s1, size_t n1, | ||
| 377 | const uint32_t *s2, size_t n2, | ||
| 378 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 379 | extern int | ||
| 380 | ulc_casecoll (const char *s1, size_t n1, | ||
| 381 | const char *s2, size_t n2, | ||
| 382 | const char *iso639_language, uninorm_t nf, int *resultp); | ||
| 383 | |||
| 384 | |||
| 385 | /* Set *RESULTP to true if mapping NFD(S) to upper case is a no-op, or to false | ||
| 386 | otherwise, and return 0. Upon failure, return -1 with errno set. */ | ||
| 387 | extern int | ||
| 388 | u8_is_uppercase (const uint8_t *s, size_t n, | ||
| 389 | const char *iso639_language, | ||
| 390 | bool *resultp); | ||
| 391 | extern int | ||
| 392 | u16_is_uppercase (const uint16_t *s, size_t n, | ||
| 393 | const char *iso639_language, | ||
| 394 | bool *resultp); | ||
| 395 | extern int | ||
| 396 | u32_is_uppercase (const uint32_t *s, size_t n, | ||
| 397 | const char *iso639_language, | ||
| 398 | bool *resultp); | ||
| 399 | |||
| 400 | /* Set *RESULTP to true if mapping NFD(S) to lower case is a no-op, or to false | ||
| 401 | otherwise, and return 0. Upon failure, return -1 with errno set. */ | ||
| 402 | extern int | ||
| 403 | u8_is_lowercase (const uint8_t *s, size_t n, | ||
| 404 | const char *iso639_language, | ||
| 405 | bool *resultp); | ||
| 406 | extern int | ||
| 407 | u16_is_lowercase (const uint16_t *s, size_t n, | ||
| 408 | const char *iso639_language, | ||
| 409 | bool *resultp); | ||
| 410 | extern int | ||
| 411 | u32_is_lowercase (const uint32_t *s, size_t n, | ||
| 412 | const char *iso639_language, | ||
| 413 | bool *resultp); | ||
| 414 | |||
| 415 | /* Set *RESULTP to true if mapping NFD(S) to title case is a no-op, or to false | ||
| 416 | otherwise, and return 0. Upon failure, return -1 with errno set. */ | ||
| 417 | extern int | ||
| 418 | u8_is_titlecase (const uint8_t *s, size_t n, | ||
| 419 | const char *iso639_language, | ||
| 420 | bool *resultp); | ||
| 421 | extern int | ||
| 422 | u16_is_titlecase (const uint16_t *s, size_t n, | ||
| 423 | const char *iso639_language, | ||
| 424 | bool *resultp); | ||
| 425 | extern int | ||
| 426 | u32_is_titlecase (const uint32_t *s, size_t n, | ||
| 427 | const char *iso639_language, | ||
| 428 | bool *resultp); | ||
| 429 | |||
| 430 | /* Set *RESULTP to true if applying case folding to NFD(S) is a no-op, or to | ||
| 431 | false otherwise, and return 0. Upon failure, return -1 with errno set. */ | ||
| 432 | extern int | ||
| 433 | u8_is_casefolded (const uint8_t *s, size_t n, | ||
| 434 | const char *iso639_language, | ||
| 435 | bool *resultp); | ||
| 436 | extern int | ||
| 437 | u16_is_casefolded (const uint16_t *s, size_t n, | ||
| 438 | const char *iso639_language, | ||
| 439 | bool *resultp); | ||
| 440 | extern int | ||
| 441 | u32_is_casefolded (const uint32_t *s, size_t n, | ||
| 442 | const char *iso639_language, | ||
| 443 | bool *resultp); | ||
| 444 | |||
| 445 | /* Set *RESULTP to true if case matters for S, that is, if mapping NFD(S) to | ||
| 446 | either upper case or lower case or title case is not a no-op. | ||
| 447 | Set *RESULTP to false if NFD(S) maps to itself under the upper case mapping, | ||
| 448 | under the lower case mapping, and under the title case mapping; in other | ||
| 449 | words, when NFD(S) consists entirely of caseless characters. | ||
| 450 | Upon failure, return -1 with errno set. */ | ||
| 451 | extern int | ||
| 452 | u8_is_cased (const uint8_t *s, size_t n, | ||
| 453 | const char *iso639_language, | ||
| 454 | bool *resultp); | ||
| 455 | extern int | ||
| 456 | u16_is_cased (const uint16_t *s, size_t n, | ||
| 457 | const char *iso639_language, | ||
| 458 | bool *resultp); | ||
| 459 | extern int | ||
| 460 | u32_is_cased (const uint32_t *s, size_t n, | ||
| 461 | const char *iso639_language, | ||
| 462 | bool *resultp); | ||
| 463 | |||
| 464 | |||
| 465 | /* ========================================================================= */ | ||
| 466 | |||
| 467 | #ifdef __cplusplus | ||
| 468 | } | ||
| 469 | #endif | ||
| 470 | |||
| 471 | #endif /* _UNICASE_H */ | ||
diff --git a/gl/unicase/.deps/.dirstamp b/gl/unicase/.deps/.dirstamp new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/gl/unicase/.deps/.dirstamp | |||
diff --git a/gl/unicase/.deps/libgnu_a-tolower.Po b/gl/unicase/.deps/libgnu_a-tolower.Po new file mode 100644 index 00000000..1ba6bacb --- /dev/null +++ b/gl/unicase/.deps/libgnu_a-tolower.Po | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | unicase/libgnu_a-tolower.o: unicase/tolower.c /usr/include/stdc-predef.h \ | ||
| 2 | ../config.h unicase.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h uninorm.h \ | ||
| 21 | unicase/tolower.h unicase/simple-mapping.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unicase.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | uninorm.h: | ||
| 48 | unicase/tolower.h: | ||
| 49 | unicase/simple-mapping.h: | ||
diff --git a/gl/unicase/.dirstamp b/gl/unicase/.dirstamp new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/gl/unicase/.dirstamp | |||
diff --git a/gl/unicase/simple-mapping.h b/gl/unicase/simple-mapping.h new file mode 100644 index 00000000..0c4c75b3 --- /dev/null +++ b/gl/unicase/simple-mapping.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* Simple case mapping for Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2009. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | ucs4_t | ||
| 19 | FUNC (ucs4_t uc) | ||
| 20 | { | ||
| 21 | unsigned int index1 = uc >> mapping_header_0; | ||
| 22 | if (index1 < mapping_header_1) | ||
| 23 | { | ||
| 24 | int lookup1 = u_mapping.level1[index1]; | ||
| 25 | if (lookup1 >= 0) | ||
| 26 | { | ||
| 27 | unsigned int index2 = (uc >> mapping_header_2) & mapping_header_3; | ||
| 28 | int lookup2 = u_mapping.level2[lookup1 + index2]; | ||
| 29 | if (lookup2 >= 0) | ||
| 30 | { | ||
| 31 | unsigned int index3 = (uc & mapping_header_4); | ||
| 32 | int lookup3 = u_mapping.level3[lookup2 + index3]; | ||
| 33 | |||
| 34 | return uc + lookup3; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | return uc; | ||
| 39 | } | ||
diff --git a/gl/unicase/tolower.c b/gl/unicase/tolower.c new file mode 100644 index 00000000..a1c898ef --- /dev/null +++ b/gl/unicase/tolower.c | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* Lowercase mapping for Unicode characters (locale and context independent). | ||
| 2 | Copyright (C) 2002, 2006, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2009. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unicase.h" | ||
| 22 | |||
| 23 | /* Define u_mapping table. */ | ||
| 24 | #include "tolower.h" | ||
| 25 | |||
| 26 | #define FUNC uc_tolower | ||
| 27 | #include "simple-mapping.h" | ||
diff --git a/gl/unicase/tolower.h b/gl/unicase/tolower.h new file mode 100644 index 00000000..794f4c0c --- /dev/null +++ b/gl/unicase/tolower.h | |||
| @@ -0,0 +1,743 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* Simple character mapping of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define mapping_header_0 16 | ||
| 21 | #define mapping_header_1 2 | ||
| 22 | #define mapping_header_2 7 | ||
| 23 | #define mapping_header_3 511 | ||
| 24 | #define mapping_header_4 127 | ||
| 25 | static const | ||
| 26 | struct | ||
| 27 | { | ||
| 28 | int level1[2]; | ||
| 29 | short level2[2 << 9]; | ||
| 30 | int level3[36 << 7]; | ||
| 31 | } | ||
| 32 | u_mapping = | ||
| 33 | { | ||
| 34 | { 0, 512 }, | ||
| 35 | { | ||
| 36 | 0, 128, 256, 384, 512, -1, 640, 768, | ||
| 37 | 896, 1024, 1152, -1, -1, -1, -1, -1, | ||
| 38 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 39 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 40 | -1, 1280, -1, -1, -1, -1, -1, 1408, | ||
| 41 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 42 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 43 | -1, 1536, -1, -1, 1664, 1792, 1920, 2048, | ||
| 44 | -1, -1, 2176, 2304, -1, -1, -1, -1, | ||
| 45 | -1, 2432, -1, -1, -1, -1, -1, -1, | ||
| 46 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 47 | 2560, 2688, -1, -1, -1, -1, -1, -1, | ||
| 48 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 49 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 50 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 51 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 52 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 53 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 54 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 55 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 56 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 57 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 58 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 59 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 60 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 61 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 62 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 63 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 64 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 65 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 66 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 67 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 68 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 69 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 70 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 71 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 72 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 73 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 74 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 75 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 76 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 77 | -1, -1, -1, -1, 2816, 2944, 3072, 3200, | ||
| 78 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 79 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 80 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 81 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 82 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 83 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 84 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 85 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 86 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 87 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 88 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 89 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 90 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 91 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 92 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 93 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 94 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 95 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 96 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 97 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 98 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 99 | -1, -1, -1, -1, -1, -1, 3328, -1, | ||
| 100 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 101 | 3456, 3584, 3712, 3840, -1, -1, -1, -1, | ||
| 102 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 103 | -1, 3968, 4096, -1, -1, -1, -1, -1, | ||
| 104 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 105 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 106 | -1, 4224, -1, -1, -1, -1, -1, -1, | ||
| 107 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 108 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 109 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 110 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 111 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 112 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 113 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 114 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 115 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 116 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 117 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 118 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 119 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 120 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 121 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 122 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 123 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 124 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 125 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 126 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 127 | -1, -1, -1, -1, 4352, -1, -1, -1, | ||
| 128 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 129 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 130 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 131 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 132 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 133 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 134 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 135 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 136 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 137 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 138 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 139 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 140 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 141 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 142 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 143 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 144 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 145 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 146 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 147 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 148 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 149 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 150 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 151 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 152 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 153 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 154 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 155 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 156 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 157 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 158 | -1, -1, 4480, -1, -1, -1, -1, -1, | ||
| 159 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 160 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 161 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 162 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 163 | -1, -1, -1, -1, -1, -1, -1, -1 | ||
| 164 | }, | ||
| 165 | { | ||
| 166 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 167 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 168 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 169 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 170 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 171 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 172 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 173 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 174 | 0, 32, 32, 32, 32, 32, 32, 32, | ||
| 175 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 176 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 177 | 32, 32, 32, 0, 0, 0, 0, 0, | ||
| 178 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 179 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 180 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 181 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 182 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 183 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 184 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 185 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 186 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 187 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 188 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 189 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 190 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 191 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 192 | 32, 32, 32, 32, 32, 32, 32, 0, | ||
| 193 | 32, 32, 32, 32, 32, 32, 32, 0, | ||
| 194 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 195 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 196 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 197 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 198 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 199 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 200 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 201 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 202 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 203 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 204 | -199, 0, 1, 0, 1, 0, 1, 0, | ||
| 205 | 0, 1, 0, 1, 0, 1, 0, 1, | ||
| 206 | 0, 1, 0, 1, 0, 1, 0, 1, | ||
| 207 | 0, 0, 1, 0, 1, 0, 1, 0, | ||
| 208 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 209 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 210 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 211 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 212 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 213 | -121, 1, 0, 1, 0, 1, 0, 0, | ||
| 214 | 0, 210, 1, 0, 1, 0, 206, 1, | ||
| 215 | 0, 205, 205, 1, 0, 0, 79, 202, | ||
| 216 | 203, 1, 0, 205, 207, 0, 211, 209, | ||
| 217 | 1, 0, 0, 0, 211, 213, 0, 214, | ||
| 218 | 1, 0, 1, 0, 1, 0, 218, 1, | ||
| 219 | 0, 218, 0, 0, 1, 0, 218, 1, | ||
| 220 | 0, 217, 217, 1, 0, 1, 0, 219, | ||
| 221 | 1, 0, 0, 0, 1, 0, 0, 0, | ||
| 222 | 0, 0, 0, 0, 2, 1, 0, 2, | ||
| 223 | 1, 0, 2, 1, 0, 1, 0, 1, | ||
| 224 | 0, 1, 0, 1, 0, 1, 0, 1, | ||
| 225 | 0, 1, 0, 1, 0, 0, 1, 0, | ||
| 226 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 227 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 228 | 0, 2, 1, 0, 1, 0, -97, -56, | ||
| 229 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 230 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 231 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 232 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 233 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 234 | -130, 0, 1, 0, 1, 0, 1, 0, | ||
| 235 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 236 | 1, 0, 1, 0, 0, 0, 0, 0, | ||
| 237 | 0, 0, 10795, 1, 0, -163, 10792, 0, | ||
| 238 | 0, 1, 0, -195, 69, 71, 1, 0, | ||
| 239 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 240 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 241 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 242 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 243 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 244 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 245 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 246 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 247 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 248 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 249 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 250 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 251 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 252 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 253 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 254 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 255 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 256 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 257 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 258 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 259 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 260 | 1, 0, 1, 0, 0, 0, 1, 0, | ||
| 261 | 0, 0, 0, 0, 0, 0, 0, 116, | ||
| 262 | 0, 0, 0, 0, 0, 0, 38, 0, | ||
| 263 | 37, 37, 37, 0, 64, 0, 63, 63, | ||
| 264 | 0, 32, 32, 32, 32, 32, 32, 32, | ||
| 265 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 266 | 32, 32, 0, 32, 32, 32, 32, 32, | ||
| 267 | 32, 32, 32, 32, 0, 0, 0, 0, | ||
| 268 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 269 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 270 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 271 | 0, 0, 0, 0, 0, 0, 0, 8, | ||
| 272 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 273 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 274 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 275 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 276 | 0, 0, 0, 0, -60, 0, 0, 1, | ||
| 277 | 0, -7, 1, 0, 0, -130, -130, -130, | ||
| 278 | 80, 80, 80, 80, 80, 80, 80, 80, | ||
| 279 | 80, 80, 80, 80, 80, 80, 80, 80, | ||
| 280 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 281 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 282 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 283 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 284 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 285 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 286 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 287 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 288 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 289 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 290 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 291 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 292 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 293 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 294 | 1, 0, 0, 0, 0, 0, 0, 0, | ||
| 295 | 0, 0, 1, 0, 1, 0, 1, 0, | ||
| 296 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 297 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 298 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 299 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 300 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 301 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 302 | 15, 1, 0, 1, 0, 1, 0, 1, | ||
| 303 | 0, 1, 0, 1, 0, 1, 0, 0, | ||
| 304 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 305 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 306 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 307 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 308 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 309 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 310 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 311 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 312 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 313 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 314 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 315 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 316 | 0, 48, 48, 48, 48, 48, 48, 48, | ||
| 317 | 48, 48, 48, 48, 48, 48, 48, 48, | ||
| 318 | 48, 48, 48, 48, 48, 48, 48, 48, | ||
| 319 | 48, 48, 48, 48, 48, 48, 48, 48, | ||
| 320 | 48, 48, 48, 48, 48, 48, 48, 0, | ||
| 321 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 322 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 323 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 324 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 325 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 326 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 327 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 328 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 329 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 330 | 7264, 7264, 7264, 7264, 7264, 7264, 7264, 7264, | ||
| 331 | 7264, 7264, 7264, 7264, 7264, 7264, 7264, 7264, | ||
| 332 | 7264, 7264, 7264, 7264, 7264, 7264, 7264, 7264, | ||
| 333 | 7264, 7264, 7264, 7264, 7264, 7264, 7264, 7264, | ||
| 334 | 7264, 7264, 7264, 7264, 7264, 7264, 0, 7264, | ||
| 335 | 0, 0, 0, 0, 0, 7264, 0, 0, | ||
| 336 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 337 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 338 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 339 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 340 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 341 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 342 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 343 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 344 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 345 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 346 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 347 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 348 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 349 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 350 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 351 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 352 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 353 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 354 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 355 | 38864, 38864, 38864, 38864, 38864, 38864, 38864, 38864, | ||
| 356 | 8, 8, 8, 8, 8, 8, 0, 0, | ||
| 357 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 358 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 359 | 0, 1, 0, 0, 0, 0, 0, 0, | ||
| 360 | -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, | ||
| 361 | -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, | ||
| 362 | -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, | ||
| 363 | -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, | ||
| 364 | -3008, -3008, -3008, -3008, -3008, -3008, -3008, -3008, | ||
| 365 | -3008, -3008, -3008, 0, 0, -3008, -3008, -3008, | ||
| 366 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 367 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 368 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 369 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 370 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 371 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 372 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 373 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 374 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 375 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 376 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 377 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 378 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 379 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 380 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 381 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 382 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 383 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 384 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 385 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 386 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 387 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 388 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 389 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 390 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 391 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 392 | 1, 0, 1, 0, 1, 0, 0, 0, | ||
| 393 | 0, 0, 0, 0, 0, 0, -7615, 0, | ||
| 394 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 395 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 396 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 397 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 398 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 399 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 400 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 401 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 402 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 403 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 404 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 405 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 406 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 407 | -8, -8, -8, -8, -8, -8, -8, -8, | ||
| 408 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 409 | -8, -8, -8, -8, -8, -8, 0, 0, | ||
| 410 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 411 | -8, -8, -8, -8, -8, -8, -8, -8, | ||
| 412 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 413 | -8, -8, -8, -8, -8, -8, -8, -8, | ||
| 414 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 415 | -8, -8, -8, -8, -8, -8, 0, 0, | ||
| 416 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 417 | 0, -8, 0, -8, 0, -8, 0, -8, | ||
| 418 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 419 | -8, -8, -8, -8, -8, -8, -8, -8, | ||
| 420 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 421 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 422 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 423 | -8, -8, -8, -8, -8, -8, -8, -8, | ||
| 424 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 425 | -8, -8, -8, -8, -8, -8, -8, -8, | ||
| 426 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 427 | -8, -8, -8, -8, -8, -8, -8, -8, | ||
| 428 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 429 | -8, -8, -74, -74, -9, 0, 0, 0, | ||
| 430 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 431 | -86, -86, -86, -86, -9, 0, 0, 0, | ||
| 432 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 433 | -8, -8, -100, -100, 0, 0, 0, 0, | ||
| 434 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 435 | -8, -8, -112, -112, -7, 0, 0, 0, | ||
| 436 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 437 | -128, -128, -126, -126, -9, 0, 0, 0, | ||
| 438 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 439 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 440 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 441 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 442 | 0, 0, 0, 0, 0, 0, -7517, 0, | ||
| 443 | 0, 0, -8383, -8262, 0, 0, 0, 0, | ||
| 444 | 0, 0, 28, 0, 0, 0, 0, 0, | ||
| 445 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 446 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 447 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 448 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 449 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 450 | 16, 16, 16, 16, 16, 16, 16, 16, | ||
| 451 | 16, 16, 16, 16, 16, 16, 16, 16, | ||
| 452 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 453 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 454 | 0, 0, 0, 1, 0, 0, 0, 0, | ||
| 455 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 456 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 457 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 458 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 459 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 460 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 461 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 462 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 463 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 464 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 465 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 466 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 467 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 468 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 469 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 470 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 471 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 472 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 473 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 474 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 475 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 476 | 0, 0, 0, 0, 0, 0, 26, 26, | ||
| 477 | 26, 26, 26, 26, 26, 26, 26, 26, | ||
| 478 | 26, 26, 26, 26, 26, 26, 26, 26, | ||
| 479 | 26, 26, 26, 26, 26, 26, 26, 26, | ||
| 480 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 481 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 482 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 483 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 484 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 485 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 486 | 48, 48, 48, 48, 48, 48, 48, 48, | ||
| 487 | 48, 48, 48, 48, 48, 48, 48, 48, | ||
| 488 | 48, 48, 48, 48, 48, 48, 48, 48, | ||
| 489 | 48, 48, 48, 48, 48, 48, 48, 48, | ||
| 490 | 48, 48, 48, 48, 48, 48, 48, 48, | ||
| 491 | 48, 48, 48, 48, 48, 48, 48, 48, | ||
| 492 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 493 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 494 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 495 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 496 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 497 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 498 | 1, 0, -10743, -3814, -10727, 0, 0, 1, | ||
| 499 | 0, 1, 0, 1, 0, -10780, -10749, -10783, | ||
| 500 | -10782, 0, 1, 0, 0, 1, 0, 0, | ||
| 501 | 0, 0, 0, 0, 0, 0, -10815, -10815, | ||
| 502 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 503 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 504 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 505 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 506 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 507 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 508 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 509 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 510 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 511 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 512 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 513 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 514 | 1, 0, 1, 0, 0, 0, 0, 0, | ||
| 515 | 0, 0, 0, 1, 0, 1, 0, 0, | ||
| 516 | 0, 0, 1, 0, 0, 0, 0, 0, | ||
| 517 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 518 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 519 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 520 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 521 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 522 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 523 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 524 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 525 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 526 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 527 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 528 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 529 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 530 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 531 | 1, 0, 1, 0, 1, 0, 0, 0, | ||
| 532 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 533 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 534 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 535 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 536 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 537 | 1, 0, 1, 0, 0, 0, 0, 0, | ||
| 538 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 539 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 540 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 541 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 542 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 543 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 544 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 545 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 546 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 547 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 548 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 549 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 550 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 551 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 552 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 553 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 554 | 0, 0, 1, 0, 1, 0, 1, 0, | ||
| 555 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 556 | 0, 0, 1, 0, 1, 0, 1, 0, | ||
| 557 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 558 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 559 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 560 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 561 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 562 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 563 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 564 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 565 | 0, 1, 0, 1, 0, -35332, 1, 0, | ||
| 566 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 567 | 0, 0, 0, 1, 0, -42280, 0, 0, | ||
| 568 | 1, 0, 1, 0, 0, 0, 1, 0, | ||
| 569 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 570 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 571 | 1, 0, -42308, -42319, -42315, -42305, -42308, 0, | ||
| 572 | -42258, -42282, -42261, 928, 1, 0, 1, 0, | ||
| 573 | 1, 0, 1, 0, 1, 0, 1, 0, | ||
| 574 | 1, 0, 1, 0, -48, -42307, -35384, 1, | ||
| 575 | 0, 1, 0, -42343, 1, 0, 0, 0, | ||
| 576 | 1, 0, 0, 0, 0, 0, 1, 0, | ||
| 577 | 1, 0, 1, 0, -42561, 0, 0, 0, | ||
| 578 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 579 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 580 | 0, 0, 0, 0, 0, 1, 0, 0, | ||
| 581 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 582 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 583 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 584 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 585 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 586 | 0, 32, 32, 32, 32, 32, 32, 32, | ||
| 587 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 588 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 589 | 32, 32, 32, 0, 0, 0, 0, 0, | ||
| 590 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 591 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 592 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 593 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 594 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 595 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 596 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 597 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 598 | 40, 40, 40, 40, 40, 40, 40, 40, | ||
| 599 | 40, 40, 40, 40, 40, 40, 40, 40, | ||
| 600 | 40, 40, 40, 40, 40, 40, 40, 40, | ||
| 601 | 40, 40, 40, 40, 40, 40, 40, 40, | ||
| 602 | 40, 40, 40, 40, 40, 40, 40, 40, | ||
| 603 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 604 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 605 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 606 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 607 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 608 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 609 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 610 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 611 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 612 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 613 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 614 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 615 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 616 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 617 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 618 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 619 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 620 | 40, 40, 40, 40, 40, 40, 40, 40, | ||
| 621 | 40, 40, 40, 40, 40, 40, 40, 40, | ||
| 622 | 40, 40, 40, 40, 40, 40, 40, 40, | ||
| 623 | 40, 40, 40, 40, 40, 40, 40, 40, | ||
| 624 | 40, 40, 40, 40, 0, 0, 0, 0, | ||
| 625 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 626 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 627 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 628 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 629 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 630 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 631 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 632 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 633 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 634 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 635 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 636 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 637 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 638 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 639 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 640 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 641 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 642 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 643 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 644 | 39, 39, 39, 39, 39, 39, 39, 39, | ||
| 645 | 39, 39, 39, 0, 39, 39, 39, 39, | ||
| 646 | 39, 39, 39, 39, 39, 39, 39, 39, | ||
| 647 | 39, 39, 39, 0, 39, 39, 39, 39, | ||
| 648 | 39, 39, 39, 0, 39, 39, 0, 0, | ||
| 649 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 650 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 651 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 652 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 653 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 654 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 655 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 656 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 657 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 658 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 659 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 660 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 661 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 662 | 64, 64, 64, 64, 64, 64, 64, 64, | ||
| 663 | 64, 64, 64, 64, 64, 64, 64, 64, | ||
| 664 | 64, 64, 64, 64, 64, 64, 64, 64, | ||
| 665 | 64, 64, 64, 64, 64, 64, 64, 64, | ||
| 666 | 64, 64, 64, 64, 64, 64, 64, 64, | ||
| 667 | 64, 64, 64, 64, 64, 64, 64, 64, | ||
| 668 | 64, 64, 64, 0, 0, 0, 0, 0, | ||
| 669 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 670 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 671 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 672 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 673 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 674 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 675 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 676 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 677 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 678 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 679 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 680 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 681 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 682 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 683 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 684 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 685 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 686 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 687 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 688 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 689 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 690 | 32, 32, 32, 32, 32, 32, 0, 0, | ||
| 691 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 692 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 693 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 694 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 695 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 696 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 697 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 698 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 699 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 700 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 701 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 702 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 703 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 704 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 705 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 706 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 707 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 708 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 709 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 710 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 711 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 712 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 713 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 714 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 715 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 716 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 717 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 718 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 719 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 720 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 721 | 32, 32, 32, 32, 32, 32, 32, 32, | ||
| 722 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 723 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 724 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 725 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 726 | 34, 34, 34, 34, 34, 34, 34, 34, | ||
| 727 | 34, 34, 34, 34, 34, 34, 34, 34, | ||
| 728 | 34, 34, 34, 34, 34, 34, 34, 34, | ||
| 729 | 34, 34, 34, 34, 34, 34, 34, 34, | ||
| 730 | 34, 34, 0, 0, 0, 0, 0, 0, | ||
| 731 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 732 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 733 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 734 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 735 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 736 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 737 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 738 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 739 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 740 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 741 | 0, 0, 0, 0, 0, 0, 0, 0 | ||
| 742 | } | ||
| 743 | }; | ||
diff --git a/gl/unictype.h b/gl/unictype.h new file mode 100644 index 00000000..78072c2a --- /dev/null +++ b/gl/unictype.h | |||
| @@ -0,0 +1,1148 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* Unicode character classification and properties. | ||
| 3 | Copyright (C) 2002, 2005-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #ifndef _UNICTYPE_H | ||
| 19 | #define _UNICTYPE_H | ||
| 20 | |||
| 21 | #include "unitypes.h" | ||
| 22 | |||
| 23 | /* Get bool. */ | ||
| 24 | #include <stdbool.h> | ||
| 25 | |||
| 26 | /* Get size_t. */ | ||
| 27 | #include <stddef.h> | ||
| 28 | |||
| 29 | #if 0 | ||
| 30 | # include <unistring/woe32dll.h> | ||
| 31 | #else | ||
| 32 | # define LIBUNISTRING_DLL_VARIABLE | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #ifdef __cplusplus | ||
| 36 | extern "C" { | ||
| 37 | #endif | ||
| 38 | |||
| 39 | /* ========================================================================= */ | ||
| 40 | |||
| 41 | /* Field 1 of Unicode Character Database: Character name. | ||
| 42 | See "uniname.h". */ | ||
| 43 | |||
| 44 | /* ========================================================================= */ | ||
| 45 | |||
| 46 | /* Field 2 of Unicode Character Database: General category. */ | ||
| 47 | |||
| 48 | /* Data type denoting a General category value. This is not just a bitmask, | ||
| 49 | but rather a bitmask and a pointer to the lookup table, so that programs | ||
| 50 | that use only the predefined bitmasks (i.e. don't combine bitmasks with & | ||
| 51 | and |) don't have a link-time dependency towards the big general table. */ | ||
| 52 | typedef struct | ||
| 53 | { | ||
| 54 | uint32_t bitmask : 31; | ||
| 55 | /*bool*/ unsigned int generic : 1; | ||
| 56 | union | ||
| 57 | { | ||
| 58 | const void *table; /* when generic is 0 */ | ||
| 59 | bool (*lookup_fn) (ucs4_t uc, uint32_t bitmask); /* when generic is 1 */ | ||
| 60 | } lookup; | ||
| 61 | } | ||
| 62 | uc_general_category_t; | ||
| 63 | |||
| 64 | /* Bits and bit masks denoting General category values. UnicodeData-3.2.0.html | ||
| 65 | says a 32-bit integer will always suffice to represent them. | ||
| 66 | These bit masks can only be used with the uc_is_general_category_withtable | ||
| 67 | function. */ | ||
| 68 | enum | ||
| 69 | { | ||
| 70 | UC_CATEGORY_MASK_L = 0x0000001f, | ||
| 71 | UC_CATEGORY_MASK_LC = 0x00000007, | ||
| 72 | UC_CATEGORY_MASK_Lu = 0x00000001, | ||
| 73 | UC_CATEGORY_MASK_Ll = 0x00000002, | ||
| 74 | UC_CATEGORY_MASK_Lt = 0x00000004, | ||
| 75 | UC_CATEGORY_MASK_Lm = 0x00000008, | ||
| 76 | UC_CATEGORY_MASK_Lo = 0x00000010, | ||
| 77 | UC_CATEGORY_MASK_M = 0x000000e0, | ||
| 78 | UC_CATEGORY_MASK_Mn = 0x00000020, | ||
| 79 | UC_CATEGORY_MASK_Mc = 0x00000040, | ||
| 80 | UC_CATEGORY_MASK_Me = 0x00000080, | ||
| 81 | UC_CATEGORY_MASK_N = 0x00000700, | ||
| 82 | UC_CATEGORY_MASK_Nd = 0x00000100, | ||
| 83 | UC_CATEGORY_MASK_Nl = 0x00000200, | ||
| 84 | UC_CATEGORY_MASK_No = 0x00000400, | ||
| 85 | UC_CATEGORY_MASK_P = 0x0003f800, | ||
| 86 | UC_CATEGORY_MASK_Pc = 0x00000800, | ||
| 87 | UC_CATEGORY_MASK_Pd = 0x00001000, | ||
| 88 | UC_CATEGORY_MASK_Ps = 0x00002000, | ||
| 89 | UC_CATEGORY_MASK_Pe = 0x00004000, | ||
| 90 | UC_CATEGORY_MASK_Pi = 0x00008000, | ||
| 91 | UC_CATEGORY_MASK_Pf = 0x00010000, | ||
| 92 | UC_CATEGORY_MASK_Po = 0x00020000, | ||
| 93 | UC_CATEGORY_MASK_S = 0x003c0000, | ||
| 94 | UC_CATEGORY_MASK_Sm = 0x00040000, | ||
| 95 | UC_CATEGORY_MASK_Sc = 0x00080000, | ||
| 96 | UC_CATEGORY_MASK_Sk = 0x00100000, | ||
| 97 | UC_CATEGORY_MASK_So = 0x00200000, | ||
| 98 | UC_CATEGORY_MASK_Z = 0x01c00000, | ||
| 99 | UC_CATEGORY_MASK_Zs = 0x00400000, | ||
| 100 | UC_CATEGORY_MASK_Zl = 0x00800000, | ||
| 101 | UC_CATEGORY_MASK_Zp = 0x01000000, | ||
| 102 | UC_CATEGORY_MASK_C = 0x3e000000, | ||
| 103 | UC_CATEGORY_MASK_Cc = 0x02000000, | ||
| 104 | UC_CATEGORY_MASK_Cf = 0x04000000, | ||
| 105 | UC_CATEGORY_MASK_Cs = 0x08000000, | ||
| 106 | UC_CATEGORY_MASK_Co = 0x10000000, | ||
| 107 | UC_CATEGORY_MASK_Cn = 0x20000000 | ||
| 108 | }; | ||
| 109 | |||
| 110 | /* Predefined General category values. */ | ||
| 111 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_L; | ||
| 112 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_LC; | ||
| 113 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Lu; | ||
| 114 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Ll; | ||
| 115 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Lt; | ||
| 116 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Lm; | ||
| 117 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Lo; | ||
| 118 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_M; | ||
| 119 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Mn; | ||
| 120 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Mc; | ||
| 121 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Me; | ||
| 122 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_N; | ||
| 123 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Nd; | ||
| 124 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Nl; | ||
| 125 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_No; | ||
| 126 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_P; | ||
| 127 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Pc; | ||
| 128 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Pd; | ||
| 129 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Ps; | ||
| 130 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Pe; | ||
| 131 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Pi; | ||
| 132 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Pf; | ||
| 133 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Po; | ||
| 134 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_S; | ||
| 135 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Sm; | ||
| 136 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Sc; | ||
| 137 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Sk; | ||
| 138 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_So; | ||
| 139 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Z; | ||
| 140 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Zs; | ||
| 141 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Zl; | ||
| 142 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Zp; | ||
| 143 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_C; | ||
| 144 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Cc; | ||
| 145 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Cf; | ||
| 146 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Cs; | ||
| 147 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Co; | ||
| 148 | extern LIBUNISTRING_DLL_VARIABLE const uc_general_category_t UC_CATEGORY_Cn; | ||
| 149 | /* Non-public. */ | ||
| 150 | extern const uc_general_category_t _UC_CATEGORY_NONE; | ||
| 151 | |||
| 152 | /* Alias names for predefined General category values. */ | ||
| 153 | #define UC_LETTER UC_CATEGORY_L | ||
| 154 | #define UC_CASED_LETTER UC_CATEGORY_LC | ||
| 155 | #define UC_UPPERCASE_LETTER UC_CATEGORY_Lu | ||
| 156 | #define UC_LOWERCASE_LETTER UC_CATEGORY_Ll | ||
| 157 | #define UC_TITLECASE_LETTER UC_CATEGORY_Lt | ||
| 158 | #define UC_MODIFIER_LETTER UC_CATEGORY_Lm | ||
| 159 | #define UC_OTHER_LETTER UC_CATEGORY_Lo | ||
| 160 | #define UC_MARK UC_CATEGORY_M | ||
| 161 | #define UC_NON_SPACING_MARK UC_CATEGORY_Mn | ||
| 162 | #define UC_COMBINING_SPACING_MARK UC_CATEGORY_Mc | ||
| 163 | #define UC_ENCLOSING_MARK UC_CATEGORY_Me | ||
| 164 | #define UC_NUMBER UC_CATEGORY_N | ||
| 165 | #define UC_DECIMAL_DIGIT_NUMBER UC_CATEGORY_Nd | ||
| 166 | #define UC_LETTER_NUMBER UC_CATEGORY_Nl | ||
| 167 | #define UC_OTHER_NUMBER UC_CATEGORY_No | ||
| 168 | #define UC_PUNCTUATION UC_CATEGORY_P | ||
| 169 | #define UC_CONNECTOR_PUNCTUATION UC_CATEGORY_Pc | ||
| 170 | #define UC_DASH_PUNCTUATION UC_CATEGORY_Pd | ||
| 171 | #define UC_OPEN_PUNCTUATION UC_CATEGORY_Ps /* a.k.a. UC_START_PUNCTUATION */ | ||
| 172 | #define UC_CLOSE_PUNCTUATION UC_CATEGORY_Pe /* a.k.a. UC_END_PUNCTUATION */ | ||
| 173 | #define UC_INITIAL_QUOTE_PUNCTUATION UC_CATEGORY_Pi | ||
| 174 | #define UC_FINAL_QUOTE_PUNCTUATION UC_CATEGORY_Pf | ||
| 175 | #define UC_OTHER_PUNCTUATION UC_CATEGORY_Po | ||
| 176 | #define UC_SYMBOL UC_CATEGORY_S | ||
| 177 | #define UC_MATH_SYMBOL UC_CATEGORY_Sm | ||
| 178 | #define UC_CURRENCY_SYMBOL UC_CATEGORY_Sc | ||
| 179 | #define UC_MODIFIER_SYMBOL UC_CATEGORY_Sk | ||
| 180 | #define UC_OTHER_SYMBOL UC_CATEGORY_So | ||
| 181 | #define UC_SEPARATOR UC_CATEGORY_Z | ||
| 182 | #define UC_SPACE_SEPARATOR UC_CATEGORY_Zs | ||
| 183 | #define UC_LINE_SEPARATOR UC_CATEGORY_Zl | ||
| 184 | #define UC_PARAGRAPH_SEPARATOR UC_CATEGORY_Zp | ||
| 185 | #define UC_OTHER UC_CATEGORY_C | ||
| 186 | #define UC_CONTROL UC_CATEGORY_Cc | ||
| 187 | #define UC_FORMAT UC_CATEGORY_Cf | ||
| 188 | #define UC_SURROGATE UC_CATEGORY_Cs /* all of them are invalid characters */ | ||
| 189 | #define UC_PRIVATE_USE UC_CATEGORY_Co | ||
| 190 | #define UC_UNASSIGNED UC_CATEGORY_Cn /* some of them are invalid characters */ | ||
| 191 | |||
| 192 | /* Return the union of two general categories. | ||
| 193 | This corresponds to the unions of the two sets of characters. */ | ||
| 194 | extern uc_general_category_t | ||
| 195 | uc_general_category_or (uc_general_category_t category1, | ||
| 196 | uc_general_category_t category2); | ||
| 197 | |||
| 198 | /* Return the intersection of two general categories as bit masks. | ||
| 199 | This *does*not* correspond to the intersection of the two sets of | ||
| 200 | characters. */ | ||
| 201 | extern uc_general_category_t | ||
| 202 | uc_general_category_and (uc_general_category_t category1, | ||
| 203 | uc_general_category_t category2); | ||
| 204 | |||
| 205 | /* Return the intersection of a general category with the complement of a | ||
| 206 | second general category, as bit masks. | ||
| 207 | This *does*not* correspond to the intersection with complement, when | ||
| 208 | viewing the categories as sets of characters. */ | ||
| 209 | extern uc_general_category_t | ||
| 210 | uc_general_category_and_not (uc_general_category_t category1, | ||
| 211 | uc_general_category_t category2); | ||
| 212 | |||
| 213 | /* Return the name of a general category. */ | ||
| 214 | extern const char * | ||
| 215 | uc_general_category_name (uc_general_category_t category) | ||
| 216 | _UC_ATTRIBUTE_PURE; | ||
| 217 | |||
| 218 | /* Return the long name of a general category. */ | ||
| 219 | extern const char * | ||
| 220 | uc_general_category_long_name (uc_general_category_t category) | ||
| 221 | _UC_ATTRIBUTE_PURE; | ||
| 222 | |||
| 223 | /* Return the general category given by name, e.g. "Lu", or by long name, | ||
| 224 | e.g. "Uppercase Letter". */ | ||
| 225 | extern uc_general_category_t | ||
| 226 | uc_general_category_byname (const char *category_name) | ||
| 227 | _UC_ATTRIBUTE_PURE; | ||
| 228 | |||
| 229 | /* Return the general category of a Unicode character. */ | ||
| 230 | extern uc_general_category_t | ||
| 231 | uc_general_category (ucs4_t uc) | ||
| 232 | _UC_ATTRIBUTE_PURE; | ||
| 233 | |||
| 234 | /* Test whether a Unicode character belongs to a given category. | ||
| 235 | The CATEGORY argument can be the combination of several predefined | ||
| 236 | general categories. */ | ||
| 237 | extern bool | ||
| 238 | uc_is_general_category (ucs4_t uc, uc_general_category_t category) | ||
| 239 | _UC_ATTRIBUTE_PURE; | ||
| 240 | /* Likewise. This function uses a big table comprising all categories. */ | ||
| 241 | extern bool | ||
| 242 | uc_is_general_category_withtable (ucs4_t uc, uint32_t bitmask) | ||
| 243 | _UC_ATTRIBUTE_CONST; | ||
| 244 | |||
| 245 | /* ========================================================================= */ | ||
| 246 | |||
| 247 | /* Field 3 of Unicode Character Database: Canonical combining class. */ | ||
| 248 | |||
| 249 | /* The possible results of uc_combining_class (0..255) are described in | ||
| 250 | UCD.html. The list here is not definitive; more values can be added | ||
| 251 | in future versions. */ | ||
| 252 | enum | ||
| 253 | { | ||
| 254 | UC_CCC_NR = 0, /* Not Reordered */ | ||
| 255 | UC_CCC_OV = 1, /* Overlay */ | ||
| 256 | UC_CCC_NK = 7, /* Nukta */ | ||
| 257 | UC_CCC_KV = 8, /* Kana Voicing */ | ||
| 258 | UC_CCC_VR = 9, /* Virama */ | ||
| 259 | UC_CCC_ATBL = 200, /* Attached Below Left */ | ||
| 260 | UC_CCC_ATB = 202, /* Attached Below */ | ||
| 261 | UC_CCC_ATA = 214, /* Attached Above */ | ||
| 262 | UC_CCC_ATAR = 216, /* Attached Above Right */ | ||
| 263 | UC_CCC_BL = 218, /* Below Left */ | ||
| 264 | UC_CCC_B = 220, /* Below */ | ||
| 265 | UC_CCC_BR = 222, /* Below Right */ | ||
| 266 | UC_CCC_L = 224, /* Left */ | ||
| 267 | UC_CCC_R = 226, /* Right */ | ||
| 268 | UC_CCC_AL = 228, /* Above Left */ | ||
| 269 | UC_CCC_A = 230, /* Above */ | ||
| 270 | UC_CCC_AR = 232, /* Above Right */ | ||
| 271 | UC_CCC_DB = 233, /* Double Below */ | ||
| 272 | UC_CCC_DA = 234, /* Double Above */ | ||
| 273 | UC_CCC_IS = 240 /* Iota Subscript */ | ||
| 274 | }; | ||
| 275 | |||
| 276 | /* Return the canonical combining class of a Unicode character. */ | ||
| 277 | extern int | ||
| 278 | uc_combining_class (ucs4_t uc) | ||
| 279 | _UC_ATTRIBUTE_CONST; | ||
| 280 | |||
| 281 | /* Return the name of a canonical combining class. */ | ||
| 282 | extern const char * | ||
| 283 | uc_combining_class_name (int ccc) | ||
| 284 | _UC_ATTRIBUTE_CONST; | ||
| 285 | |||
| 286 | /* Return the long name of a canonical combining class. */ | ||
| 287 | extern const char * | ||
| 288 | uc_combining_class_long_name (int ccc) | ||
| 289 | _UC_ATTRIBUTE_CONST; | ||
| 290 | |||
| 291 | /* Return the canonical combining class given by name, e.g. "BL", or by long | ||
| 292 | name, e.g. "Below Left". */ | ||
| 293 | extern int | ||
| 294 | uc_combining_class_byname (const char *ccc_name) | ||
| 295 | _UC_ATTRIBUTE_PURE; | ||
| 296 | |||
| 297 | /* ========================================================================= */ | ||
| 298 | |||
| 299 | /* Field 4 of Unicode Character Database: Bidi class. | ||
| 300 | Before Unicode 4.0, this field was called "Bidirectional category". */ | ||
| 301 | |||
| 302 | enum | ||
| 303 | { | ||
| 304 | UC_BIDI_L, /* Left-to-Right */ | ||
| 305 | UC_BIDI_LRE, /* Left-to-Right Embedding */ | ||
| 306 | UC_BIDI_LRO, /* Left-to-Right Override */ | ||
| 307 | UC_BIDI_R, /* Right-to-Left */ | ||
| 308 | UC_BIDI_AL, /* Right-to-Left Arabic */ | ||
| 309 | UC_BIDI_RLE, /* Right-to-Left Embedding */ | ||
| 310 | UC_BIDI_RLO, /* Right-to-Left Override */ | ||
| 311 | UC_BIDI_PDF, /* Pop Directional Format */ | ||
| 312 | UC_BIDI_EN, /* European Number */ | ||
| 313 | UC_BIDI_ES, /* European Number Separator */ | ||
| 314 | UC_BIDI_ET, /* European Number Terminator */ | ||
| 315 | UC_BIDI_AN, /* Arabic Number */ | ||
| 316 | UC_BIDI_CS, /* Common Number Separator */ | ||
| 317 | UC_BIDI_NSM, /* Non-Spacing Mark */ | ||
| 318 | UC_BIDI_BN, /* Boundary Neutral */ | ||
| 319 | UC_BIDI_B, /* Paragraph Separator */ | ||
| 320 | UC_BIDI_S, /* Segment Separator */ | ||
| 321 | UC_BIDI_WS, /* Whitespace */ | ||
| 322 | UC_BIDI_ON, /* Other Neutral */ | ||
| 323 | UC_BIDI_LRI, /* Left-to-Right Isolate */ | ||
| 324 | UC_BIDI_RLI, /* Right-to-Left Isolate */ | ||
| 325 | UC_BIDI_FSI, /* First Strong Isolate */ | ||
| 326 | UC_BIDI_PDI /* Pop Directional Isolate */ | ||
| 327 | }; | ||
| 328 | |||
| 329 | /* Return the name of a bidi class. */ | ||
| 330 | extern const char * | ||
| 331 | uc_bidi_class_name (int bidi_class) | ||
| 332 | _UC_ATTRIBUTE_CONST; | ||
| 333 | /* Same; obsolete function name. */ | ||
| 334 | extern const char * | ||
| 335 | uc_bidi_category_name (int category) | ||
| 336 | _UC_ATTRIBUTE_CONST; | ||
| 337 | |||
| 338 | /* Return the long name of a bidi class. */ | ||
| 339 | extern const char * | ||
| 340 | uc_bidi_class_long_name (int bidi_class) | ||
| 341 | _UC_ATTRIBUTE_CONST; | ||
| 342 | |||
| 343 | /* Return the bidi class given by name, e.g. "LRE", or by long name, e.g. | ||
| 344 | "Left-to-Right Embedding". */ | ||
| 345 | extern int | ||
| 346 | uc_bidi_class_byname (const char *bidi_class_name) | ||
| 347 | _UC_ATTRIBUTE_PURE; | ||
| 348 | /* Same; obsolete function name. */ | ||
| 349 | extern int | ||
| 350 | uc_bidi_category_byname (const char *category_name) | ||
| 351 | _UC_ATTRIBUTE_PURE; | ||
| 352 | |||
| 353 | /* Return the bidi class of a Unicode character. */ | ||
| 354 | extern int | ||
| 355 | uc_bidi_class (ucs4_t uc) | ||
| 356 | _UC_ATTRIBUTE_CONST; | ||
| 357 | /* Same; obsolete function name. */ | ||
| 358 | extern int | ||
| 359 | uc_bidi_category (ucs4_t uc) | ||
| 360 | _UC_ATTRIBUTE_CONST; | ||
| 361 | |||
| 362 | /* Test whether a Unicode character belongs to a given bidi class. */ | ||
| 363 | extern bool | ||
| 364 | uc_is_bidi_class (ucs4_t uc, int bidi_class) | ||
| 365 | _UC_ATTRIBUTE_CONST; | ||
| 366 | /* Same; obsolete function name. */ | ||
| 367 | extern bool | ||
| 368 | uc_is_bidi_category (ucs4_t uc, int category) | ||
| 369 | _UC_ATTRIBUTE_CONST; | ||
| 370 | |||
| 371 | /* ========================================================================= */ | ||
| 372 | |||
| 373 | /* Field 5 of Unicode Character Database: Character decomposition mapping. | ||
| 374 | See "uninorm.h". */ | ||
| 375 | |||
| 376 | /* ========================================================================= */ | ||
| 377 | |||
| 378 | /* Field 6 of Unicode Character Database: Decimal digit value. */ | ||
| 379 | |||
| 380 | /* Return the decimal digit value of a Unicode character. */ | ||
| 381 | extern int | ||
| 382 | uc_decimal_value (ucs4_t uc) | ||
| 383 | _UC_ATTRIBUTE_CONST; | ||
| 384 | |||
| 385 | /* ========================================================================= */ | ||
| 386 | |||
| 387 | /* Field 7 of Unicode Character Database: Digit value. */ | ||
| 388 | |||
| 389 | /* Return the digit value of a Unicode character. */ | ||
| 390 | extern int | ||
| 391 | uc_digit_value (ucs4_t uc) | ||
| 392 | _UC_ATTRIBUTE_CONST; | ||
| 393 | |||
| 394 | /* ========================================================================= */ | ||
| 395 | |||
| 396 | /* Field 8 of Unicode Character Database: Numeric value. */ | ||
| 397 | |||
| 398 | /* Return the numeric value of a Unicode character. */ | ||
| 399 | typedef struct | ||
| 400 | { | ||
| 401 | int numerator; | ||
| 402 | int denominator; | ||
| 403 | } | ||
| 404 | uc_fraction_t; | ||
| 405 | extern uc_fraction_t | ||
| 406 | uc_numeric_value (ucs4_t uc) | ||
| 407 | _UC_ATTRIBUTE_CONST; | ||
| 408 | |||
| 409 | /* ========================================================================= */ | ||
| 410 | |||
| 411 | /* Field 9 of Unicode Character Database: Mirrored. */ | ||
| 412 | |||
| 413 | /* Return the mirrored character of a Unicode character UC in *PUC. */ | ||
| 414 | extern bool | ||
| 415 | uc_mirror_char (ucs4_t uc, ucs4_t *puc); | ||
| 416 | |||
| 417 | /* ========================================================================= */ | ||
| 418 | |||
| 419 | /* Field 10 of Unicode Character Database: Unicode 1.0 Name. | ||
| 420 | Not available in this library. */ | ||
| 421 | |||
| 422 | /* ========================================================================= */ | ||
| 423 | |||
| 424 | /* Field 11 of Unicode Character Database: ISO 10646 comment. | ||
| 425 | Not available in this library. */ | ||
| 426 | |||
| 427 | /* ========================================================================= */ | ||
| 428 | |||
| 429 | /* Field 12, 13, 14 of Unicode Character Database: Uppercase mapping, | ||
| 430 | lowercase mapping, titlecase mapping. See "unicase.h". */ | ||
| 431 | |||
| 432 | /* ========================================================================= */ | ||
| 433 | |||
| 434 | /* Field 2 of the file ArabicShaping.txt in the Unicode Character Database. */ | ||
| 435 | |||
| 436 | /* Possible joining types. */ | ||
| 437 | enum | ||
| 438 | { | ||
| 439 | UC_JOINING_TYPE_U, /* Non_Joining */ | ||
| 440 | UC_JOINING_TYPE_T, /* Transparent */ | ||
| 441 | UC_JOINING_TYPE_C, /* Join_Causing */ | ||
| 442 | UC_JOINING_TYPE_L, /* Left_Joining */ | ||
| 443 | UC_JOINING_TYPE_R, /* Right_Joining */ | ||
| 444 | UC_JOINING_TYPE_D /* Dual_Joining */ | ||
| 445 | }; | ||
| 446 | |||
| 447 | /* Return the name of a joining type. */ | ||
| 448 | extern const char * | ||
| 449 | uc_joining_type_name (int joining_type) | ||
| 450 | _UC_ATTRIBUTE_CONST; | ||
| 451 | |||
| 452 | /* Return the long name of a joining type. */ | ||
| 453 | extern const char * | ||
| 454 | uc_joining_type_long_name (int joining_type) | ||
| 455 | _UC_ATTRIBUTE_CONST; | ||
| 456 | |||
| 457 | /* Return the joining type given by name, e.g. "D", or by long name, e.g. | ||
| 458 | "Dual Joining". */ | ||
| 459 | extern int | ||
| 460 | uc_joining_type_byname (const char *joining_type_name) | ||
| 461 | _UC_ATTRIBUTE_PURE; | ||
| 462 | |||
| 463 | /* Return the joining type of a Unicode character. */ | ||
| 464 | extern int | ||
| 465 | uc_joining_type (ucs4_t uc) | ||
| 466 | _UC_ATTRIBUTE_CONST; | ||
| 467 | |||
| 468 | /* ========================================================================= */ | ||
| 469 | |||
| 470 | /* Field 3 of the file ArabicShaping.txt in the Unicode Character Database. */ | ||
| 471 | |||
| 472 | /* Possible joining groups. | ||
| 473 | This enumeration may be extended in the future. */ | ||
| 474 | enum | ||
| 475 | { | ||
| 476 | UC_JOINING_GROUP_NONE, /* No_Joining_Group */ | ||
| 477 | UC_JOINING_GROUP_AIN, /* Ain */ | ||
| 478 | UC_JOINING_GROUP_ALAPH, /* Alaph */ | ||
| 479 | UC_JOINING_GROUP_ALEF, /* Alef */ | ||
| 480 | UC_JOINING_GROUP_BEH, /* Beh */ | ||
| 481 | UC_JOINING_GROUP_BETH, /* Beth */ | ||
| 482 | UC_JOINING_GROUP_BURUSHASKI_YEH_BARREE, /* Burushaski_Yeh_Barree */ | ||
| 483 | UC_JOINING_GROUP_DAL, /* Dal */ | ||
| 484 | UC_JOINING_GROUP_DALATH_RISH, /* Dalath_Rish */ | ||
| 485 | UC_JOINING_GROUP_E, /* E */ | ||
| 486 | UC_JOINING_GROUP_FARSI_YEH, /* Farsi_Yeh */ | ||
| 487 | UC_JOINING_GROUP_FE, /* Fe */ | ||
| 488 | UC_JOINING_GROUP_FEH, /* Feh */ | ||
| 489 | UC_JOINING_GROUP_FINAL_SEMKATH, /* Final_Semkath */ | ||
| 490 | UC_JOINING_GROUP_GAF, /* Gaf */ | ||
| 491 | UC_JOINING_GROUP_GAMAL, /* Gamal */ | ||
| 492 | UC_JOINING_GROUP_HAH, /* Hah */ | ||
| 493 | UC_JOINING_GROUP_HE, /* He */ | ||
| 494 | UC_JOINING_GROUP_HEH, /* Heh */ | ||
| 495 | UC_JOINING_GROUP_HEH_GOAL, /* Heh_Goal */ | ||
| 496 | UC_JOINING_GROUP_HETH, /* Heth */ | ||
| 497 | UC_JOINING_GROUP_KAF, /* Kaf */ | ||
| 498 | UC_JOINING_GROUP_KAPH, /* Kaph */ | ||
| 499 | UC_JOINING_GROUP_KHAPH, /* Khaph */ | ||
| 500 | UC_JOINING_GROUP_KNOTTED_HEH, /* Knotted_Heh */ | ||
| 501 | UC_JOINING_GROUP_LAM, /* Lam */ | ||
| 502 | UC_JOINING_GROUP_LAMADH, /* Lamadh */ | ||
| 503 | UC_JOINING_GROUP_MEEM, /* Meem */ | ||
| 504 | UC_JOINING_GROUP_MIM, /* Mim */ | ||
| 505 | UC_JOINING_GROUP_NOON, /* Noon */ | ||
| 506 | UC_JOINING_GROUP_NUN, /* Nun */ | ||
| 507 | UC_JOINING_GROUP_NYA, /* Nya */ | ||
| 508 | UC_JOINING_GROUP_PE, /* Pe */ | ||
| 509 | UC_JOINING_GROUP_QAF, /* Qaf */ | ||
| 510 | UC_JOINING_GROUP_QAPH, /* Qaph */ | ||
| 511 | UC_JOINING_GROUP_REH, /* Reh */ | ||
| 512 | UC_JOINING_GROUP_REVERSED_PE, /* Reversed_Pe */ | ||
| 513 | UC_JOINING_GROUP_SAD, /* Sad */ | ||
| 514 | UC_JOINING_GROUP_SADHE, /* Sadhe */ | ||
| 515 | UC_JOINING_GROUP_SEEN, /* Seen */ | ||
| 516 | UC_JOINING_GROUP_SEMKATH, /* Semkath */ | ||
| 517 | UC_JOINING_GROUP_SHIN, /* Shin */ | ||
| 518 | UC_JOINING_GROUP_SWASH_KAF, /* Swash_Kaf */ | ||
| 519 | UC_JOINING_GROUP_SYRIAC_WAW, /* Syriac_Waw */ | ||
| 520 | UC_JOINING_GROUP_TAH, /* Tah */ | ||
| 521 | UC_JOINING_GROUP_TAW, /* Taw */ | ||
| 522 | UC_JOINING_GROUP_TEH_MARBUTA, /* Teh_Marbuta */ | ||
| 523 | UC_JOINING_GROUP_TEH_MARBUTA_GOAL, /* Teh_Marbuta_Goal */ | ||
| 524 | UC_JOINING_GROUP_TETH, /* Teth */ | ||
| 525 | UC_JOINING_GROUP_WAW, /* Waw */ | ||
| 526 | UC_JOINING_GROUP_YEH, /* Yeh */ | ||
| 527 | UC_JOINING_GROUP_YEH_BARREE, /* Yeh_Barree */ | ||
| 528 | UC_JOINING_GROUP_YEH_WITH_TAIL, /* Yeh_With_Tail */ | ||
| 529 | UC_JOINING_GROUP_YUDH, /* Yudh */ | ||
| 530 | UC_JOINING_GROUP_YUDH_HE, /* Yudh_He */ | ||
| 531 | UC_JOINING_GROUP_ZAIN, /* Zain */ | ||
| 532 | UC_JOINING_GROUP_ZHAIN, /* Zhain */ | ||
| 533 | UC_JOINING_GROUP_ROHINGYA_YEH, /* Rohingya_Yeh */ | ||
| 534 | UC_JOINING_GROUP_STRAIGHT_WAW, /* Straight_Waw */ | ||
| 535 | UC_JOINING_GROUP_MANICHAEAN_ALEPH, /* Manichaean_Aleph */ | ||
| 536 | UC_JOINING_GROUP_MANICHAEAN_BETH, /* Manichaean_Beth */ | ||
| 537 | UC_JOINING_GROUP_MANICHAEAN_GIMEL, /* Manichaean_Gimel */ | ||
| 538 | UC_JOINING_GROUP_MANICHAEAN_DALETH, /* Manichaean_Daleth */ | ||
| 539 | UC_JOINING_GROUP_MANICHAEAN_WAW, /* Manichaean_Waw */ | ||
| 540 | UC_JOINING_GROUP_MANICHAEAN_ZAYIN, /* Manichaean_Zayin */ | ||
| 541 | UC_JOINING_GROUP_MANICHAEAN_HETH, /* Manichaean_Heth */ | ||
| 542 | UC_JOINING_GROUP_MANICHAEAN_TETH, /* Manichaean_Teth */ | ||
| 543 | UC_JOINING_GROUP_MANICHAEAN_YODH, /* Manichaean_Yodh */ | ||
| 544 | UC_JOINING_GROUP_MANICHAEAN_KAPH, /* Manichaean_Kaph */ | ||
| 545 | UC_JOINING_GROUP_MANICHAEAN_LAMEDH, /* Manichaean_Lamedh */ | ||
| 546 | UC_JOINING_GROUP_MANICHAEAN_DHAMEDH, /* Manichaean_Dhamedh */ | ||
| 547 | UC_JOINING_GROUP_MANICHAEAN_THAMEDH, /* Manichaean_Thamedh */ | ||
| 548 | UC_JOINING_GROUP_MANICHAEAN_MEM, /* Manichaean_Mem */ | ||
| 549 | UC_JOINING_GROUP_MANICHAEAN_NUN, /* Manichaean_Nun */ | ||
| 550 | UC_JOINING_GROUP_MANICHAEAN_SAMEKH, /* Manichaean_Aleph */ | ||
| 551 | UC_JOINING_GROUP_MANICHAEAN_AYIN, /* Manichaean_Ayin */ | ||
| 552 | UC_JOINING_GROUP_MANICHAEAN_PE, /* Manichaean_Pe */ | ||
| 553 | UC_JOINING_GROUP_MANICHAEAN_SADHE, /* Manichaean_Sadhe */ | ||
| 554 | UC_JOINING_GROUP_MANICHAEAN_QOPH, /* Manichaean_Qoph */ | ||
| 555 | UC_JOINING_GROUP_MANICHAEAN_RESH, /* Manichaean_Resh */ | ||
| 556 | UC_JOINING_GROUP_MANICHAEAN_TAW, /* Manichaean_Taw */ | ||
| 557 | UC_JOINING_GROUP_MANICHAEAN_ONE, /* Manichaean_One */ | ||
| 558 | UC_JOINING_GROUP_MANICHAEAN_FIVE, /* Manichaean_Five */ | ||
| 559 | UC_JOINING_GROUP_MANICHAEAN_TEN, /* Manichaean_Ten */ | ||
| 560 | UC_JOINING_GROUP_MANICHAEAN_TWENTY, /* Manichaean_Twenty */ | ||
| 561 | UC_JOINING_GROUP_MANICHAEAN_HUNDRED, /* Manichaean_Hundred */ | ||
| 562 | UC_JOINING_GROUP_AFRICAN_FEH, /* African_Feh */ | ||
| 563 | UC_JOINING_GROUP_AFRICAN_QAF, /* African_Qaf */ | ||
| 564 | UC_JOINING_GROUP_AFRICAN_NOON, /* African_Noon */ | ||
| 565 | UC_JOINING_GROUP_MALAYALAM_NGA, /* Malayalam_Nga */ | ||
| 566 | UC_JOINING_GROUP_MALAYALAM_JA, /* Malayalam_Ja */ | ||
| 567 | UC_JOINING_GROUP_MALAYALAM_NYA, /* Malayalam_Nya */ | ||
| 568 | UC_JOINING_GROUP_MALAYALAM_TTA, /* Malayalam_Tta */ | ||
| 569 | UC_JOINING_GROUP_MALAYALAM_NNA, /* Malayalam_Nna */ | ||
| 570 | UC_JOINING_GROUP_MALAYALAM_NNNA, /* Malayalam_Nnna */ | ||
| 571 | UC_JOINING_GROUP_MALAYALAM_BHA, /* Malayalam_Bha */ | ||
| 572 | UC_JOINING_GROUP_MALAYALAM_RA, /* Malayalam_Ra */ | ||
| 573 | UC_JOINING_GROUP_MALAYALAM_LLA, /* Malayalam_Lla */ | ||
| 574 | UC_JOINING_GROUP_MALAYALAM_LLLA, /* Malayalam_Llla */ | ||
| 575 | UC_JOINING_GROUP_MALAYALAM_SSA, /* Malayalam_Ssa */ | ||
| 576 | UC_JOINING_GROUP_HANIFI_ROHINGYA_PA, /* Hanifi_Rohingya_Pa */ | ||
| 577 | UC_JOINING_GROUP_HANIFI_ROHINGYA_KINNA_YA, /* Hanifi_Rohingya_Kinna_Ya */ | ||
| 578 | UC_JOINING_GROUP_THIN_YEH, /* Thin_Yeh */ | ||
| 579 | UC_JOINING_GROUP_VERTICAL_TAIL, /* Vertical_Tail */ | ||
| 580 | UC_JOINING_GROUP_KASHMIRI_YEH, /* Kashmiri_Yeh */ | ||
| 581 | UC_JOINING_GROUP_THIN_NOON /* Thin_Noon */ | ||
| 582 | }; | ||
| 583 | |||
| 584 | /* Return the name of a joining group. */ | ||
| 585 | extern const char * | ||
| 586 | uc_joining_group_name (int joining_group) | ||
| 587 | _UC_ATTRIBUTE_CONST; | ||
| 588 | |||
| 589 | /* Return the joining group given by name, e.g. "Teh_Marbuta". */ | ||
| 590 | extern int | ||
| 591 | uc_joining_group_byname (const char *joining_group_name) | ||
| 592 | _UC_ATTRIBUTE_PURE; | ||
| 593 | |||
| 594 | /* Return the joining group of a Unicode character. */ | ||
| 595 | extern int | ||
| 596 | uc_joining_group (ucs4_t uc) | ||
| 597 | _UC_ATTRIBUTE_CONST; | ||
| 598 | |||
| 599 | /* ========================================================================= */ | ||
| 600 | |||
| 601 | /* Common API for properties. */ | ||
| 602 | |||
| 603 | /* Data type denoting a property. This is not just a number, but rather a | ||
| 604 | pointer to the test functions, so that programs that use only few of the | ||
| 605 | properties don't have a link-time dependency towards all the tables. */ | ||
| 606 | typedef struct | ||
| 607 | { | ||
| 608 | bool (*test_fn) (ucs4_t uc); | ||
| 609 | } | ||
| 610 | uc_property_t; | ||
| 611 | |||
| 612 | /* Predefined properties. */ | ||
| 613 | /* General. */ | ||
| 614 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_WHITE_SPACE; | ||
| 615 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_ALPHABETIC; | ||
| 616 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_OTHER_ALPHABETIC; | ||
| 617 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_NOT_A_CHARACTER; | ||
| 618 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT; | ||
| 619 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_OTHER_DEFAULT_IGNORABLE_CODE_POINT; | ||
| 620 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_DEPRECATED; | ||
| 621 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_LOGICAL_ORDER_EXCEPTION; | ||
| 622 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_VARIATION_SELECTOR; | ||
| 623 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_PRIVATE_USE; | ||
| 624 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_UNASSIGNED_CODE_VALUE; | ||
| 625 | /* Case. */ | ||
| 626 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_UPPERCASE; | ||
| 627 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_OTHER_UPPERCASE; | ||
| 628 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_LOWERCASE; | ||
| 629 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_OTHER_LOWERCASE; | ||
| 630 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_TITLECASE; | ||
| 631 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_CASED; | ||
| 632 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_CASE_IGNORABLE; | ||
| 633 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_CHANGES_WHEN_LOWERCASED; | ||
| 634 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_CHANGES_WHEN_UPPERCASED; | ||
| 635 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_CHANGES_WHEN_TITLECASED; | ||
| 636 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_CHANGES_WHEN_CASEFOLDED; | ||
| 637 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_CHANGES_WHEN_CASEMAPPED; | ||
| 638 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_SOFT_DOTTED; | ||
| 639 | /* Identifiers. */ | ||
| 640 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_ID_START; | ||
| 641 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_OTHER_ID_START; | ||
| 642 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_ID_CONTINUE; | ||
| 643 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_OTHER_ID_CONTINUE; | ||
| 644 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_XID_START; | ||
| 645 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_XID_CONTINUE; | ||
| 646 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_ID_COMPAT_MATH_START; | ||
| 647 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_ID_COMPAT_MATH_CONTINUE; | ||
| 648 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_PATTERN_WHITE_SPACE; | ||
| 649 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_PATTERN_SYNTAX; | ||
| 650 | /* Shaping and rendering. */ | ||
| 651 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_JOIN_CONTROL; | ||
| 652 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_GRAPHEME_BASE; | ||
| 653 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_GRAPHEME_EXTEND; | ||
| 654 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_OTHER_GRAPHEME_EXTEND; | ||
| 655 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_GRAPHEME_LINK; | ||
| 656 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_MODIFIER_COMBINING_MARK; | ||
| 657 | /* Bidi. */ | ||
| 658 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_CONTROL; | ||
| 659 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_LEFT_TO_RIGHT; | ||
| 660 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_HEBREW_RIGHT_TO_LEFT; | ||
| 661 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_ARABIC_RIGHT_TO_LEFT; | ||
| 662 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_EUROPEAN_DIGIT; | ||
| 663 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_EUR_NUM_SEPARATOR; | ||
| 664 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_EUR_NUM_TERMINATOR; | ||
| 665 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_ARABIC_DIGIT; | ||
| 666 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_COMMON_SEPARATOR; | ||
| 667 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_BLOCK_SEPARATOR; | ||
| 668 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_SEGMENT_SEPARATOR; | ||
| 669 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_WHITESPACE; | ||
| 670 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_NON_SPACING_MARK; | ||
| 671 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_BOUNDARY_NEUTRAL; | ||
| 672 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_PDF; | ||
| 673 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_EMBEDDING_OR_OVERRIDE; | ||
| 674 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_BIDI_OTHER_NEUTRAL; | ||
| 675 | /* Numeric. */ | ||
| 676 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_HEX_DIGIT; | ||
| 677 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_ASCII_HEX_DIGIT; | ||
| 678 | /* CJK. */ | ||
| 679 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_IDEOGRAPHIC; | ||
| 680 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_UNIFIED_IDEOGRAPH; | ||
| 681 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_RADICAL; | ||
| 682 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_IDS_UNARY_OPERATOR; | ||
| 683 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_IDS_BINARY_OPERATOR; | ||
| 684 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_IDS_TRINARY_OPERATOR; | ||
| 685 | /* Emoji. */ | ||
| 686 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_EMOJI; | ||
| 687 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_EMOJI_PRESENTATION; | ||
| 688 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_EMOJI_MODIFIER; | ||
| 689 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_EMOJI_MODIFIER_BASE; | ||
| 690 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_EMOJI_COMPONENT; | ||
| 691 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_EXTENDED_PICTOGRAPHIC; | ||
| 692 | /* Misc. */ | ||
| 693 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_ZERO_WIDTH; | ||
| 694 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_SPACE; | ||
| 695 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_NON_BREAK; | ||
| 696 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_ISO_CONTROL; | ||
| 697 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_FORMAT_CONTROL; | ||
| 698 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_PREPENDED_CONCATENATION_MARK; | ||
| 699 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_DASH; | ||
| 700 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_HYPHEN; | ||
| 701 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_PUNCTUATION; | ||
| 702 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_LINE_SEPARATOR; | ||
| 703 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_PARAGRAPH_SEPARATOR; | ||
| 704 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_QUOTATION_MARK; | ||
| 705 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_SENTENCE_TERMINAL; | ||
| 706 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_TERMINAL_PUNCTUATION; | ||
| 707 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_CURRENCY_SYMBOL; | ||
| 708 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_MATH; | ||
| 709 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_OTHER_MATH; | ||
| 710 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_PAIRED_PUNCTUATION; | ||
| 711 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_LEFT_OF_PAIR; | ||
| 712 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_COMBINING; | ||
| 713 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_COMPOSITE; | ||
| 714 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_DECIMAL_DIGIT; | ||
| 715 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_NUMERIC; | ||
| 716 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_DIACRITIC; | ||
| 717 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_EXTENDER; | ||
| 718 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_IGNORABLE_CONTROL; | ||
| 719 | extern LIBUNISTRING_DLL_VARIABLE const uc_property_t UC_PROPERTY_REGIONAL_INDICATOR; | ||
| 720 | |||
| 721 | /* Return the property given by name, e.g. "White space". */ | ||
| 722 | extern uc_property_t | ||
| 723 | uc_property_byname (const char *property_name); | ||
| 724 | |||
| 725 | /* Test whether a property is valid. */ | ||
| 726 | #define uc_property_is_valid(property) ((property).test_fn != NULL) | ||
| 727 | |||
| 728 | /* Test whether a Unicode character has a given property. */ | ||
| 729 | extern bool | ||
| 730 | uc_is_property (ucs4_t uc, uc_property_t property); | ||
| 731 | extern bool uc_is_property_white_space (ucs4_t uc) | ||
| 732 | _UC_ATTRIBUTE_CONST; | ||
| 733 | extern bool uc_is_property_alphabetic (ucs4_t uc) | ||
| 734 | _UC_ATTRIBUTE_CONST; | ||
| 735 | extern bool uc_is_property_other_alphabetic (ucs4_t uc) | ||
| 736 | _UC_ATTRIBUTE_CONST; | ||
| 737 | extern bool uc_is_property_not_a_character (ucs4_t uc) | ||
| 738 | _UC_ATTRIBUTE_CONST; | ||
| 739 | extern bool uc_is_property_default_ignorable_code_point (ucs4_t uc) | ||
| 740 | _UC_ATTRIBUTE_CONST; | ||
| 741 | extern bool uc_is_property_other_default_ignorable_code_point (ucs4_t uc) | ||
| 742 | _UC_ATTRIBUTE_CONST; | ||
| 743 | extern bool uc_is_property_deprecated (ucs4_t uc) | ||
| 744 | _UC_ATTRIBUTE_CONST; | ||
| 745 | extern bool uc_is_property_logical_order_exception (ucs4_t uc) | ||
| 746 | _UC_ATTRIBUTE_CONST; | ||
| 747 | extern bool uc_is_property_variation_selector (ucs4_t uc) | ||
| 748 | _UC_ATTRIBUTE_CONST; | ||
| 749 | extern bool uc_is_property_private_use (ucs4_t uc) | ||
| 750 | _UC_ATTRIBUTE_CONST; | ||
| 751 | extern bool uc_is_property_unassigned_code_value (ucs4_t uc) | ||
| 752 | _UC_ATTRIBUTE_CONST; | ||
| 753 | extern bool uc_is_property_uppercase (ucs4_t uc) | ||
| 754 | _UC_ATTRIBUTE_CONST; | ||
| 755 | extern bool uc_is_property_other_uppercase (ucs4_t uc) | ||
| 756 | _UC_ATTRIBUTE_CONST; | ||
| 757 | extern bool uc_is_property_lowercase (ucs4_t uc) | ||
| 758 | _UC_ATTRIBUTE_CONST; | ||
| 759 | extern bool uc_is_property_other_lowercase (ucs4_t uc) | ||
| 760 | _UC_ATTRIBUTE_CONST; | ||
| 761 | extern bool uc_is_property_titlecase (ucs4_t uc) | ||
| 762 | _UC_ATTRIBUTE_CONST; | ||
| 763 | extern bool uc_is_property_cased (ucs4_t uc) | ||
| 764 | _UC_ATTRIBUTE_CONST; | ||
| 765 | extern bool uc_is_property_case_ignorable (ucs4_t uc) | ||
| 766 | _UC_ATTRIBUTE_CONST; | ||
| 767 | extern bool uc_is_property_changes_when_lowercased (ucs4_t uc) | ||
| 768 | _UC_ATTRIBUTE_CONST; | ||
| 769 | extern bool uc_is_property_changes_when_uppercased (ucs4_t uc) | ||
| 770 | _UC_ATTRIBUTE_CONST; | ||
| 771 | extern bool uc_is_property_changes_when_titlecased (ucs4_t uc) | ||
| 772 | _UC_ATTRIBUTE_CONST; | ||
| 773 | extern bool uc_is_property_changes_when_casefolded (ucs4_t uc) | ||
| 774 | _UC_ATTRIBUTE_CONST; | ||
| 775 | extern bool uc_is_property_changes_when_casemapped (ucs4_t uc) | ||
| 776 | _UC_ATTRIBUTE_CONST; | ||
| 777 | extern bool uc_is_property_soft_dotted (ucs4_t uc) | ||
| 778 | _UC_ATTRIBUTE_CONST; | ||
| 779 | extern bool uc_is_property_id_start (ucs4_t uc) | ||
| 780 | _UC_ATTRIBUTE_CONST; | ||
| 781 | extern bool uc_is_property_other_id_start (ucs4_t uc) | ||
| 782 | _UC_ATTRIBUTE_CONST; | ||
| 783 | extern bool uc_is_property_id_continue (ucs4_t uc) | ||
| 784 | _UC_ATTRIBUTE_CONST; | ||
| 785 | extern bool uc_is_property_other_id_continue (ucs4_t uc) | ||
| 786 | _UC_ATTRIBUTE_CONST; | ||
| 787 | extern bool uc_is_property_xid_start (ucs4_t uc) | ||
| 788 | _UC_ATTRIBUTE_CONST; | ||
| 789 | extern bool uc_is_property_xid_continue (ucs4_t uc) | ||
| 790 | _UC_ATTRIBUTE_CONST; | ||
| 791 | extern bool uc_is_property_id_compat_math_start (ucs4_t uc) | ||
| 792 | _UC_ATTRIBUTE_CONST; | ||
| 793 | extern bool uc_is_property_id_compat_math_continue (ucs4_t uc) | ||
| 794 | _UC_ATTRIBUTE_CONST; | ||
| 795 | extern bool uc_is_property_pattern_white_space (ucs4_t uc) | ||
| 796 | _UC_ATTRIBUTE_CONST; | ||
| 797 | extern bool uc_is_property_pattern_syntax (ucs4_t uc) | ||
| 798 | _UC_ATTRIBUTE_CONST; | ||
| 799 | extern bool uc_is_property_join_control (ucs4_t uc) | ||
| 800 | _UC_ATTRIBUTE_CONST; | ||
| 801 | extern bool uc_is_property_grapheme_base (ucs4_t uc) | ||
| 802 | _UC_ATTRIBUTE_CONST; | ||
| 803 | extern bool uc_is_property_grapheme_extend (ucs4_t uc) | ||
| 804 | _UC_ATTRIBUTE_CONST; | ||
| 805 | extern bool uc_is_property_other_grapheme_extend (ucs4_t uc) | ||
| 806 | _UC_ATTRIBUTE_CONST; | ||
| 807 | extern bool uc_is_property_grapheme_link (ucs4_t uc) | ||
| 808 | _UC_ATTRIBUTE_CONST; | ||
| 809 | extern bool uc_is_property_modifier_combining_mark (ucs4_t uc) | ||
| 810 | _UC_ATTRIBUTE_CONST; | ||
| 811 | extern bool uc_is_property_bidi_control (ucs4_t uc) | ||
| 812 | _UC_ATTRIBUTE_CONST; | ||
| 813 | extern bool uc_is_property_bidi_left_to_right (ucs4_t uc) | ||
| 814 | _UC_ATTRIBUTE_CONST; | ||
| 815 | extern bool uc_is_property_bidi_hebrew_right_to_left (ucs4_t uc) | ||
| 816 | _UC_ATTRIBUTE_CONST; | ||
| 817 | extern bool uc_is_property_bidi_arabic_right_to_left (ucs4_t uc) | ||
| 818 | _UC_ATTRIBUTE_CONST; | ||
| 819 | extern bool uc_is_property_bidi_european_digit (ucs4_t uc) | ||
| 820 | _UC_ATTRIBUTE_CONST; | ||
| 821 | extern bool uc_is_property_bidi_eur_num_separator (ucs4_t uc) | ||
| 822 | _UC_ATTRIBUTE_CONST; | ||
| 823 | extern bool uc_is_property_bidi_eur_num_terminator (ucs4_t uc) | ||
| 824 | _UC_ATTRIBUTE_CONST; | ||
| 825 | extern bool uc_is_property_bidi_arabic_digit (ucs4_t uc) | ||
| 826 | _UC_ATTRIBUTE_CONST; | ||
| 827 | extern bool uc_is_property_bidi_common_separator (ucs4_t uc) | ||
| 828 | _UC_ATTRIBUTE_CONST; | ||
| 829 | extern bool uc_is_property_bidi_block_separator (ucs4_t uc) | ||
| 830 | _UC_ATTRIBUTE_CONST; | ||
| 831 | extern bool uc_is_property_bidi_segment_separator (ucs4_t uc) | ||
| 832 | _UC_ATTRIBUTE_CONST; | ||
| 833 | extern bool uc_is_property_bidi_whitespace (ucs4_t uc) | ||
| 834 | _UC_ATTRIBUTE_CONST; | ||
| 835 | extern bool uc_is_property_bidi_non_spacing_mark (ucs4_t uc) | ||
| 836 | _UC_ATTRIBUTE_CONST; | ||
| 837 | extern bool uc_is_property_bidi_boundary_neutral (ucs4_t uc) | ||
| 838 | _UC_ATTRIBUTE_CONST; | ||
| 839 | extern bool uc_is_property_bidi_pdf (ucs4_t uc) | ||
| 840 | _UC_ATTRIBUTE_CONST; | ||
| 841 | extern bool uc_is_property_bidi_embedding_or_override (ucs4_t uc) | ||
| 842 | _UC_ATTRIBUTE_CONST; | ||
| 843 | extern bool uc_is_property_bidi_other_neutral (ucs4_t uc) | ||
| 844 | _UC_ATTRIBUTE_CONST; | ||
| 845 | extern bool uc_is_property_hex_digit (ucs4_t uc) | ||
| 846 | _UC_ATTRIBUTE_CONST; | ||
| 847 | extern bool uc_is_property_ascii_hex_digit (ucs4_t uc) | ||
| 848 | _UC_ATTRIBUTE_CONST; | ||
| 849 | extern bool uc_is_property_ideographic (ucs4_t uc) | ||
| 850 | _UC_ATTRIBUTE_CONST; | ||
| 851 | extern bool uc_is_property_unified_ideograph (ucs4_t uc) | ||
| 852 | _UC_ATTRIBUTE_CONST; | ||
| 853 | extern bool uc_is_property_radical (ucs4_t uc) | ||
| 854 | _UC_ATTRIBUTE_CONST; | ||
| 855 | extern bool uc_is_property_ids_unary_operator (ucs4_t uc) | ||
| 856 | _UC_ATTRIBUTE_CONST; | ||
| 857 | extern bool uc_is_property_ids_binary_operator (ucs4_t uc) | ||
| 858 | _UC_ATTRIBUTE_CONST; | ||
| 859 | extern bool uc_is_property_ids_trinary_operator (ucs4_t uc) | ||
| 860 | _UC_ATTRIBUTE_CONST; | ||
| 861 | extern bool uc_is_property_emoji (ucs4_t uc) | ||
| 862 | _UC_ATTRIBUTE_CONST; | ||
| 863 | extern bool uc_is_property_emoji_presentation (ucs4_t uc) | ||
| 864 | _UC_ATTRIBUTE_CONST; | ||
| 865 | extern bool uc_is_property_emoji_modifier (ucs4_t uc) | ||
| 866 | _UC_ATTRIBUTE_CONST; | ||
| 867 | extern bool uc_is_property_emoji_modifier_base (ucs4_t uc) | ||
| 868 | _UC_ATTRIBUTE_CONST; | ||
| 869 | extern bool uc_is_property_emoji_component (ucs4_t uc) | ||
| 870 | _UC_ATTRIBUTE_CONST; | ||
| 871 | extern bool uc_is_property_extended_pictographic (ucs4_t uc) | ||
| 872 | _UC_ATTRIBUTE_CONST; | ||
| 873 | extern bool uc_is_property_zero_width (ucs4_t uc) | ||
| 874 | _UC_ATTRIBUTE_CONST; | ||
| 875 | extern bool uc_is_property_space (ucs4_t uc) | ||
| 876 | _UC_ATTRIBUTE_CONST; | ||
| 877 | extern bool uc_is_property_non_break (ucs4_t uc) | ||
| 878 | _UC_ATTRIBUTE_CONST; | ||
| 879 | extern bool uc_is_property_iso_control (ucs4_t uc) | ||
| 880 | _UC_ATTRIBUTE_CONST; | ||
| 881 | extern bool uc_is_property_format_control (ucs4_t uc) | ||
| 882 | _UC_ATTRIBUTE_CONST; | ||
| 883 | extern bool uc_is_property_prepended_concatenation_mark (ucs4_t uc) | ||
| 884 | _UC_ATTRIBUTE_CONST; | ||
| 885 | extern bool uc_is_property_dash (ucs4_t uc) | ||
| 886 | _UC_ATTRIBUTE_CONST; | ||
| 887 | extern bool uc_is_property_hyphen (ucs4_t uc) | ||
| 888 | _UC_ATTRIBUTE_CONST; | ||
| 889 | extern bool uc_is_property_punctuation (ucs4_t uc) | ||
| 890 | _UC_ATTRIBUTE_CONST; | ||
| 891 | extern bool uc_is_property_line_separator (ucs4_t uc) | ||
| 892 | _UC_ATTRIBUTE_CONST; | ||
| 893 | extern bool uc_is_property_paragraph_separator (ucs4_t uc) | ||
| 894 | _UC_ATTRIBUTE_CONST; | ||
| 895 | extern bool uc_is_property_quotation_mark (ucs4_t uc) | ||
| 896 | _UC_ATTRIBUTE_CONST; | ||
| 897 | extern bool uc_is_property_sentence_terminal (ucs4_t uc) | ||
| 898 | _UC_ATTRIBUTE_CONST; | ||
| 899 | extern bool uc_is_property_terminal_punctuation (ucs4_t uc) | ||
| 900 | _UC_ATTRIBUTE_CONST; | ||
| 901 | extern bool uc_is_property_currency_symbol (ucs4_t uc) | ||
| 902 | _UC_ATTRIBUTE_CONST; | ||
| 903 | extern bool uc_is_property_math (ucs4_t uc) | ||
| 904 | _UC_ATTRIBUTE_CONST; | ||
| 905 | extern bool uc_is_property_other_math (ucs4_t uc) | ||
| 906 | _UC_ATTRIBUTE_CONST; | ||
| 907 | extern bool uc_is_property_paired_punctuation (ucs4_t uc) | ||
| 908 | _UC_ATTRIBUTE_CONST; | ||
| 909 | extern bool uc_is_property_left_of_pair (ucs4_t uc) | ||
| 910 | _UC_ATTRIBUTE_CONST; | ||
| 911 | extern bool uc_is_property_combining (ucs4_t uc) | ||
| 912 | _UC_ATTRIBUTE_CONST; | ||
| 913 | extern bool uc_is_property_composite (ucs4_t uc) | ||
| 914 | _UC_ATTRIBUTE_CONST; | ||
| 915 | extern bool uc_is_property_decimal_digit (ucs4_t uc) | ||
| 916 | _UC_ATTRIBUTE_CONST; | ||
| 917 | extern bool uc_is_property_numeric (ucs4_t uc) | ||
| 918 | _UC_ATTRIBUTE_CONST; | ||
| 919 | extern bool uc_is_property_diacritic (ucs4_t uc) | ||
| 920 | _UC_ATTRIBUTE_CONST; | ||
| 921 | extern bool uc_is_property_extender (ucs4_t uc) | ||
| 922 | _UC_ATTRIBUTE_CONST; | ||
| 923 | extern bool uc_is_property_ignorable_control (ucs4_t uc) | ||
| 924 | _UC_ATTRIBUTE_CONST; | ||
| 925 | extern bool uc_is_property_regional_indicator (ucs4_t uc) | ||
| 926 | _UC_ATTRIBUTE_CONST; | ||
| 927 | |||
| 928 | /* ========================================================================= */ | ||
| 929 | |||
| 930 | /* Other attributes. */ | ||
| 931 | |||
| 932 | /* ------------------------------------------------------------------------- */ | ||
| 933 | |||
| 934 | /* Indic_Conjunct_Break (InCB): from the file DerivedCoreProperties.txt | ||
| 935 | in the Unicode Character Database. */ | ||
| 936 | |||
| 937 | /* Possible values of the Indic_Conjunct_Break attribute. | ||
| 938 | This enumeration may be extended in the future. */ | ||
| 939 | enum | ||
| 940 | { | ||
| 941 | UC_INDIC_CONJUNCT_BREAK_NONE, /* None */ | ||
| 942 | UC_INDIC_CONJUNCT_BREAK_CONSONANT, /* Consonant */ | ||
| 943 | UC_INDIC_CONJUNCT_BREAK_LINKER, /* Linker */ | ||
| 944 | UC_INDIC_CONJUNCT_BREAK_EXTEND /* Extend */ | ||
| 945 | }; | ||
| 946 | |||
| 947 | /* Return the name of an Indic_Conjunct_Break value. */ | ||
| 948 | extern const char * | ||
| 949 | uc_indic_conjunct_break_name (int indic_conjunct_break) | ||
| 950 | _UC_ATTRIBUTE_CONST; | ||
| 951 | |||
| 952 | /* Return the Indic_Conjunct_Break value given by name, e.g. "Consonant". */ | ||
| 953 | extern int | ||
| 954 | uc_indic_conjunct_break_byname (const char *indic_conjunct_break_name) | ||
| 955 | _UC_ATTRIBUTE_PURE; | ||
| 956 | |||
| 957 | /* Return the Indic_Conjunct_Break attribute of a Unicode character. */ | ||
| 958 | extern int | ||
| 959 | uc_indic_conjunct_break (ucs4_t uc) | ||
| 960 | _UC_ATTRIBUTE_CONST; | ||
| 961 | |||
| 962 | /* ========================================================================= */ | ||
| 963 | |||
| 964 | /* Subdivision of the Unicode characters into scripts. */ | ||
| 965 | |||
| 966 | typedef struct | ||
| 967 | { | ||
| 968 | unsigned int code : 21; | ||
| 969 | unsigned int start : 1; | ||
| 970 | unsigned int end : 1; | ||
| 971 | } | ||
| 972 | uc_interval_t; | ||
| 973 | typedef struct | ||
| 974 | { | ||
| 975 | unsigned int nintervals; | ||
| 976 | const uc_interval_t *intervals; | ||
| 977 | const char *name; | ||
| 978 | } | ||
| 979 | uc_script_t; | ||
| 980 | |||
| 981 | /* Return the script of a Unicode character. */ | ||
| 982 | extern const uc_script_t * | ||
| 983 | uc_script (ucs4_t uc) | ||
| 984 | _UC_ATTRIBUTE_CONST; | ||
| 985 | |||
| 986 | /* Return the script given by name, e.g. "HAN". */ | ||
| 987 | extern const uc_script_t * | ||
| 988 | uc_script_byname (const char *script_name) | ||
| 989 | _UC_ATTRIBUTE_PURE; | ||
| 990 | |||
| 991 | /* Test whether a Unicode character belongs to a given script. */ | ||
| 992 | extern bool | ||
| 993 | uc_is_script (ucs4_t uc, const uc_script_t *script) | ||
| 994 | _UC_ATTRIBUTE_PURE; | ||
| 995 | |||
| 996 | /* Get the list of all scripts. */ | ||
| 997 | extern void | ||
| 998 | uc_all_scripts (const uc_script_t **scripts, size_t *count); | ||
| 999 | |||
| 1000 | /* ========================================================================= */ | ||
| 1001 | |||
| 1002 | /* Subdivision of the Unicode character range into blocks. */ | ||
| 1003 | |||
| 1004 | typedef struct | ||
| 1005 | { | ||
| 1006 | ucs4_t start; | ||
| 1007 | ucs4_t end; | ||
| 1008 | const char *name; | ||
| 1009 | } | ||
| 1010 | uc_block_t; | ||
| 1011 | |||
| 1012 | /* Return the block a character belongs to. */ | ||
| 1013 | extern const uc_block_t * | ||
| 1014 | uc_block (ucs4_t uc) | ||
| 1015 | _UC_ATTRIBUTE_CONST; | ||
| 1016 | |||
| 1017 | /* Test whether a Unicode character belongs to a given block. */ | ||
| 1018 | extern bool | ||
| 1019 | uc_is_block (ucs4_t uc, const uc_block_t *block) | ||
| 1020 | _UC_ATTRIBUTE_PURE; | ||
| 1021 | |||
| 1022 | /* Get the list of all blocks. */ | ||
| 1023 | extern void | ||
| 1024 | uc_all_blocks (const uc_block_t **blocks, size_t *count); | ||
| 1025 | |||
| 1026 | /* ========================================================================= */ | ||
| 1027 | |||
| 1028 | /* Properties taken from language standards. */ | ||
| 1029 | |||
| 1030 | /* Test whether a Unicode character is considered whitespace in ISO C 99. */ | ||
| 1031 | extern bool | ||
| 1032 | uc_is_c_whitespace (ucs4_t uc) | ||
| 1033 | _UC_ATTRIBUTE_CONST; | ||
| 1034 | |||
| 1035 | /* Test whether a Unicode character is considered whitespace in Java. */ | ||
| 1036 | extern bool | ||
| 1037 | uc_is_java_whitespace (ucs4_t uc) | ||
| 1038 | _UC_ATTRIBUTE_CONST; | ||
| 1039 | |||
| 1040 | enum | ||
| 1041 | { | ||
| 1042 | UC_IDENTIFIER_START, /* valid as first or subsequent character */ | ||
| 1043 | UC_IDENTIFIER_VALID, /* valid as subsequent character only */ | ||
| 1044 | UC_IDENTIFIER_INVALID, /* not valid */ | ||
| 1045 | UC_IDENTIFIER_IGNORABLE /* ignorable (Java only) */ | ||
| 1046 | }; | ||
| 1047 | |||
| 1048 | /* Return the categorization of a Unicode character w.r.t. the ISO C 99 | ||
| 1049 | identifier syntax. */ | ||
| 1050 | extern int | ||
| 1051 | uc_c_ident_category (ucs4_t uc) | ||
| 1052 | _UC_ATTRIBUTE_CONST; | ||
| 1053 | |||
| 1054 | /* Return the categorization of a Unicode character w.r.t. the Java | ||
| 1055 | identifier syntax. */ | ||
| 1056 | extern int | ||
| 1057 | uc_java_ident_category (ucs4_t uc) | ||
| 1058 | _UC_ATTRIBUTE_CONST; | ||
| 1059 | |||
| 1060 | /* ========================================================================= */ | ||
| 1061 | |||
| 1062 | /* Like ISO C <ctype.h> and <wctype.h>. These functions are deprecated, | ||
| 1063 | because this set of functions was designed with ASCII in mind and cannot | ||
| 1064 | reflect the more diverse reality of the Unicode character set. But they | ||
| 1065 | can be a quick-and-dirty porting aid when migrating from wchar_t APIs | ||
| 1066 | to Unicode strings. */ | ||
| 1067 | |||
| 1068 | /* Test for any character for which 'uc_is_alpha' or 'uc_is_digit' is true. */ | ||
| 1069 | extern bool | ||
| 1070 | uc_is_alnum (ucs4_t uc) | ||
| 1071 | _UC_ATTRIBUTE_CONST; | ||
| 1072 | |||
| 1073 | /* Test for any character for which 'uc_is_upper' or 'uc_is_lower' is true, | ||
| 1074 | or any character that is one of a locale-specific set of characters for | ||
| 1075 | which none of 'uc_is_cntrl', 'uc_is_digit', 'uc_is_punct', or 'uc_is_space' | ||
| 1076 | is true. */ | ||
| 1077 | extern bool | ||
| 1078 | uc_is_alpha (ucs4_t uc) | ||
| 1079 | _UC_ATTRIBUTE_CONST; | ||
| 1080 | |||
| 1081 | /* Test for any control character. */ | ||
| 1082 | extern bool | ||
| 1083 | uc_is_cntrl (ucs4_t uc) | ||
| 1084 | _UC_ATTRIBUTE_CONST; | ||
| 1085 | |||
| 1086 | /* Test for any character that corresponds to a decimal-digit character. */ | ||
| 1087 | extern bool | ||
| 1088 | uc_is_digit (ucs4_t uc) | ||
| 1089 | _UC_ATTRIBUTE_CONST; | ||
| 1090 | |||
| 1091 | /* Test for any character for which 'uc_is_print' is true and 'uc_is_space' | ||
| 1092 | is false. */ | ||
| 1093 | extern bool | ||
| 1094 | uc_is_graph (ucs4_t uc) | ||
| 1095 | _UC_ATTRIBUTE_CONST; | ||
| 1096 | |||
| 1097 | /* Test for any character that corresponds to a lowercase letter or is one | ||
| 1098 | of a locale-specific set of characters for which none of 'uc_is_cntrl', | ||
| 1099 | 'uc_is_digit', 'uc_is_punct', or 'uc_is_space' is true. */ | ||
| 1100 | extern bool | ||
| 1101 | uc_is_lower (ucs4_t uc) | ||
| 1102 | _UC_ATTRIBUTE_CONST; | ||
| 1103 | |||
| 1104 | /* Test for any printing character. */ | ||
| 1105 | extern bool | ||
| 1106 | uc_is_print (ucs4_t uc) | ||
| 1107 | _UC_ATTRIBUTE_CONST; | ||
| 1108 | |||
| 1109 | /* Test for any printing character that is one of a locale-specific set of | ||
| 1110 | characters for which neither 'uc_is_space' nor 'uc_is_alnum' is true. */ | ||
| 1111 | extern bool | ||
| 1112 | uc_is_punct (ucs4_t uc) | ||
| 1113 | _UC_ATTRIBUTE_CONST; | ||
| 1114 | |||
| 1115 | /* Test for any character that corresponds to a locale-specific set of | ||
| 1116 | characters for which none of 'uc_is_alnum', 'uc_is_graph', or 'uc_is_punct' | ||
| 1117 | is true. */ | ||
| 1118 | extern bool | ||
| 1119 | uc_is_space (ucs4_t uc) | ||
| 1120 | _UC_ATTRIBUTE_CONST; | ||
| 1121 | |||
| 1122 | /* Test for any character that corresponds to an uppercase letter or is one | ||
| 1123 | of a locale-specific set of character for which none of 'uc_is_cntrl', | ||
| 1124 | 'uc_is_digit', 'uc_is_punct', or 'uc_is_space' is true. */ | ||
| 1125 | extern bool | ||
| 1126 | uc_is_upper (ucs4_t uc) | ||
| 1127 | _UC_ATTRIBUTE_CONST; | ||
| 1128 | |||
| 1129 | /* Test for any character that corresponds to a hexadecimal-digit | ||
| 1130 | character. */ | ||
| 1131 | extern bool | ||
| 1132 | uc_is_xdigit (ucs4_t uc) | ||
| 1133 | _UC_ATTRIBUTE_CONST; | ||
| 1134 | |||
| 1135 | /* GNU extension. */ | ||
| 1136 | /* Test for any character that corresponds to a standard blank character or | ||
| 1137 | a locale-specific set of characters for which 'uc_is_alnum' is false. */ | ||
| 1138 | extern bool | ||
| 1139 | uc_is_blank (ucs4_t uc) | ||
| 1140 | _UC_ATTRIBUTE_CONST; | ||
| 1141 | |||
| 1142 | /* ========================================================================= */ | ||
| 1143 | |||
| 1144 | #ifdef __cplusplus | ||
| 1145 | } | ||
| 1146 | #endif | ||
| 1147 | |||
| 1148 | #endif /* _UNICTYPE_H */ | ||
diff --git a/gl/unictype.in.h b/gl/unictype.in.h new file mode 100644 index 00000000..3818da91 --- /dev/null +++ b/gl/unictype.in.h | |||
| @@ -0,0 +1,1146 @@ | |||
| 1 | /* Unicode character classification and properties. | ||
| 2 | Copyright (C) 2002, 2005-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #ifndef _UNICTYPE_H | ||
| 18 | #define _UNICTYPE_H | ||
| 19 | |||
| 20 | #include "unitypes.h" | ||
| 21 | |||
| 22 | /* Get bool. */ | ||
| 23 | #include <stdbool.h> | ||
| 24 | |||
| 25 | /* Get size_t. */ | ||
| 26 | #include <stddef.h> | ||
| 27 | |||
| 28 | #if @HAVE_UNISTRING_WOE32DLL_H@ | ||
| 29 | # include <unistring/woe32dll.h> | ||
| 30 | #else | ||
| 31 | # define LIBUNISTRING_DLL_VARIABLE | ||
| 32 | #endif | ||
| 33 | |||
| 34 | #ifdef __cplusplus | ||
| 35 | extern "C" { | ||
| 36 | #endif | ||
| 37 | |||
| 38 | /* ========================================================================= */ | ||
| 39 | |||
| 40 | /* Field 1 of Unicode Character Database: Character name. | ||
| 41 | See "uniname.h". */ | ||
| 42 | |||
| 43 | /* ========================================================================= */ | ||
| 44 | |||
| 45 | /* Field 2 of Unicode Character Database: General category. */ | ||
| 46 | |||
| 47 | /* Data type denoting a General category value. This is not just a bitmask, | ||
| 48 | but rather a bitmask and a pointer to the lookup table, so that programs | ||
| 49 | that use only the predefined bitmasks (i.e. don't combine bitmasks with & | ||
| 50 | and |) don't have a link-time dependency towards the big general table. */ | ||
| 51 | typedef struct | ||
| 52 | { | ||
| 53 | uint32_t bitmask : 31; | ||
| 54 | /*bool*/ unsigned int generic : 1; | ||
| 55 | union | ||
| 56 | { | ||
| 57 | const void *table; /* when generic is 0 */ | ||
| 58 | bool (*lookup_fn) (ucs4_t uc, uint32_t bitmask); /* when generic is 1 */ | ||
| 59 | } lookup; | ||
| 60 | } | ||
| 61 | uc_general_category_t; | ||
| 62 | |||
| 63 | /* Bits and bit masks denoting General category values. UnicodeData-3.2.0.html | ||
| 64 | says a 32-bit integer will always suffice to represent them. | ||
| 65 | These bit masks can only be used with the uc_is_general_category_withtable | ||
| 66 | function. */ | ||
| 67 | enum | ||
| 68 | { | ||
| 69 | UC_CATEGORY_MASK_L = 0x0000001f, | ||
| 70 | UC_CATEGORY_MASK_LC = 0x00000007, | ||
| 71 | UC_CATEGORY_MASK_Lu = 0x00000001, | ||
| 72 | UC_CATEGORY_MASK_Ll = 0x00000002, | ||
| 73 | UC_CATEGORY_MASK_Lt = 0x00000004, | ||
| 74 | UC_CATEGORY_MASK_Lm = 0x00000008, | ||
| 75 | UC_CATEGORY_MASK_Lo = 0x00000010, | ||
| 76 | UC_CATEGORY_MASK_M = 0x000000e0, | ||
| 77 | UC_CATEGORY_MASK_Mn = 0x00000020, | ||
| 78 | UC_CATEGORY_MASK_Mc = 0x00000040, | ||
| 79 | UC_CATEGORY_MASK_Me = 0x00000080, | ||
| 80 | UC_CATEGORY_MASK_N = 0x00000700, | ||
| 81 | UC_CATEGORY_MASK_Nd = 0x00000100, | ||
| 82 | UC_CATEGORY_MASK_Nl = 0x00000200, | ||
| 83 | UC_CATEGORY_MASK_No = 0x00000400, | ||
| 84 | UC_CATEGORY_MASK_P = 0x0003f800, | ||
| 85 | UC_CATEGORY_MASK_Pc = 0x00000800, | ||
| 86 | UC_CATEGORY_MASK_Pd = 0x00001000, | ||
| 87 | UC_CATEGORY_MASK_Ps = 0x00002000, | ||
| 88 | UC_CATEGORY_MASK_Pe = 0x00004000, | ||
| 89 | UC_CATEGORY_MASK_Pi = 0x00008000, | ||
| 90 | UC_CATEGORY_MASK_Pf = 0x00010000, | ||
| 91 | UC_CATEGORY_MASK_Po = 0x00020000, | ||
| 92 | UC_CATEGORY_MASK_S = 0x003c0000, | ||
| 93 | UC_CATEGORY_MASK_Sm = 0x00040000, | ||
| 94 | UC_CATEGORY_MASK_Sc = 0x00080000, | ||
| 95 | UC_CATEGORY_MASK_Sk = 0x00100000, | ||
| 96 | UC_CATEGORY_MASK_So = 0x00200000, | ||
| 97 | UC_CATEGORY_MASK_Z = 0x01c00000, | ||
| 98 | UC_CATEGORY_MASK_Zs = 0x00400000, | ||
| 99 | UC_CATEGORY_MASK_Zl = 0x00800000, | ||
| 100 | UC_CATEGORY_MASK_Zp = 0x01000000, | ||
| 101 | UC_CATEGORY_MASK_C = 0x3e000000, | ||
| 102 | UC_CATEGORY_MASK_Cc = 0x02000000, | ||
| 103 | UC_CATEGORY_MASK_Cf = 0x04000000, | ||
| 104 | UC_CATEGORY_MASK_Cs = 0x08000000, | ||
| 105 | UC_CATEGORY_MASK_Co = 0x10000000, | ||
| 106 | UC_CATEGORY_MASK_Cn = 0x20000000 | ||
| 107 | }; | ||
| 108 | |||
| 109 | /* Predefined General category values. */ | ||
| 110 | extern @GNULIB_UNICTYPE_CATEGORY_L_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_L; | ||
| 111 | extern @GNULIB_UNICTYPE_CATEGORY_LC_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_LC; | ||
| 112 | extern @GNULIB_UNICTYPE_CATEGORY_LU_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Lu; | ||
| 113 | extern @GNULIB_UNICTYPE_CATEGORY_LL_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Ll; | ||
| 114 | extern @GNULIB_UNICTYPE_CATEGORY_LT_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Lt; | ||
| 115 | extern @GNULIB_UNICTYPE_CATEGORY_LM_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Lm; | ||
| 116 | extern @GNULIB_UNICTYPE_CATEGORY_LO_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Lo; | ||
| 117 | extern @GNULIB_UNICTYPE_CATEGORY_M_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_M; | ||
| 118 | extern @GNULIB_UNICTYPE_CATEGORY_MN_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Mn; | ||
| 119 | extern @GNULIB_UNICTYPE_CATEGORY_MC_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Mc; | ||
| 120 | extern @GNULIB_UNICTYPE_CATEGORY_ME_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Me; | ||
| 121 | extern @GNULIB_UNICTYPE_CATEGORY_N_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_N; | ||
| 122 | extern @GNULIB_UNICTYPE_CATEGORY_ND_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Nd; | ||
| 123 | extern @GNULIB_UNICTYPE_CATEGORY_NL_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Nl; | ||
| 124 | extern @GNULIB_UNICTYPE_CATEGORY_NO_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_No; | ||
| 125 | extern @GNULIB_UNICTYPE_CATEGORY_P_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_P; | ||
| 126 | extern @GNULIB_UNICTYPE_CATEGORY_PC_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Pc; | ||
| 127 | extern @GNULIB_UNICTYPE_CATEGORY_PD_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Pd; | ||
| 128 | extern @GNULIB_UNICTYPE_CATEGORY_PS_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Ps; | ||
| 129 | extern @GNULIB_UNICTYPE_CATEGORY_PE_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Pe; | ||
| 130 | extern @GNULIB_UNICTYPE_CATEGORY_PI_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Pi; | ||
| 131 | extern @GNULIB_UNICTYPE_CATEGORY_PF_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Pf; | ||
| 132 | extern @GNULIB_UNICTYPE_CATEGORY_PO_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Po; | ||
| 133 | extern @GNULIB_UNICTYPE_CATEGORY_S_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_S; | ||
| 134 | extern @GNULIB_UNICTYPE_CATEGORY_SM_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Sm; | ||
| 135 | extern @GNULIB_UNICTYPE_CATEGORY_SC_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Sc; | ||
| 136 | extern @GNULIB_UNICTYPE_CATEGORY_SK_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Sk; | ||
| 137 | extern @GNULIB_UNICTYPE_CATEGORY_SO_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_So; | ||
| 138 | extern @GNULIB_UNICTYPE_CATEGORY_Z_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Z; | ||
| 139 | extern @GNULIB_UNICTYPE_CATEGORY_ZS_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Zs; | ||
| 140 | extern @GNULIB_UNICTYPE_CATEGORY_ZL_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Zl; | ||
| 141 | extern @GNULIB_UNICTYPE_CATEGORY_ZP_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Zp; | ||
| 142 | extern @GNULIB_UNICTYPE_CATEGORY_C_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_C; | ||
| 143 | extern @GNULIB_UNICTYPE_CATEGORY_CC_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Cc; | ||
| 144 | extern @GNULIB_UNICTYPE_CATEGORY_CF_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Cf; | ||
| 145 | extern @GNULIB_UNICTYPE_CATEGORY_CS_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Cs; | ||
| 146 | extern @GNULIB_UNICTYPE_CATEGORY_CO_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Co; | ||
| 147 | extern @GNULIB_UNICTYPE_CATEGORY_CN_DLL_VARIABLE@ const uc_general_category_t UC_CATEGORY_Cn; | ||
| 148 | /* Non-public. */ | ||
| 149 | extern const uc_general_category_t _UC_CATEGORY_NONE; | ||
| 150 | |||
| 151 | /* Alias names for predefined General category values. */ | ||
| 152 | #define UC_LETTER UC_CATEGORY_L | ||
| 153 | #define UC_CASED_LETTER UC_CATEGORY_LC | ||
| 154 | #define UC_UPPERCASE_LETTER UC_CATEGORY_Lu | ||
| 155 | #define UC_LOWERCASE_LETTER UC_CATEGORY_Ll | ||
| 156 | #define UC_TITLECASE_LETTER UC_CATEGORY_Lt | ||
| 157 | #define UC_MODIFIER_LETTER UC_CATEGORY_Lm | ||
| 158 | #define UC_OTHER_LETTER UC_CATEGORY_Lo | ||
| 159 | #define UC_MARK UC_CATEGORY_M | ||
| 160 | #define UC_NON_SPACING_MARK UC_CATEGORY_Mn | ||
| 161 | #define UC_COMBINING_SPACING_MARK UC_CATEGORY_Mc | ||
| 162 | #define UC_ENCLOSING_MARK UC_CATEGORY_Me | ||
| 163 | #define UC_NUMBER UC_CATEGORY_N | ||
| 164 | #define UC_DECIMAL_DIGIT_NUMBER UC_CATEGORY_Nd | ||
| 165 | #define UC_LETTER_NUMBER UC_CATEGORY_Nl | ||
| 166 | #define UC_OTHER_NUMBER UC_CATEGORY_No | ||
| 167 | #define UC_PUNCTUATION UC_CATEGORY_P | ||
| 168 | #define UC_CONNECTOR_PUNCTUATION UC_CATEGORY_Pc | ||
| 169 | #define UC_DASH_PUNCTUATION UC_CATEGORY_Pd | ||
| 170 | #define UC_OPEN_PUNCTUATION UC_CATEGORY_Ps /* a.k.a. UC_START_PUNCTUATION */ | ||
| 171 | #define UC_CLOSE_PUNCTUATION UC_CATEGORY_Pe /* a.k.a. UC_END_PUNCTUATION */ | ||
| 172 | #define UC_INITIAL_QUOTE_PUNCTUATION UC_CATEGORY_Pi | ||
| 173 | #define UC_FINAL_QUOTE_PUNCTUATION UC_CATEGORY_Pf | ||
| 174 | #define UC_OTHER_PUNCTUATION UC_CATEGORY_Po | ||
| 175 | #define UC_SYMBOL UC_CATEGORY_S | ||
| 176 | #define UC_MATH_SYMBOL UC_CATEGORY_Sm | ||
| 177 | #define UC_CURRENCY_SYMBOL UC_CATEGORY_Sc | ||
| 178 | #define UC_MODIFIER_SYMBOL UC_CATEGORY_Sk | ||
| 179 | #define UC_OTHER_SYMBOL UC_CATEGORY_So | ||
| 180 | #define UC_SEPARATOR UC_CATEGORY_Z | ||
| 181 | #define UC_SPACE_SEPARATOR UC_CATEGORY_Zs | ||
| 182 | #define UC_LINE_SEPARATOR UC_CATEGORY_Zl | ||
| 183 | #define UC_PARAGRAPH_SEPARATOR UC_CATEGORY_Zp | ||
| 184 | #define UC_OTHER UC_CATEGORY_C | ||
| 185 | #define UC_CONTROL UC_CATEGORY_Cc | ||
| 186 | #define UC_FORMAT UC_CATEGORY_Cf | ||
| 187 | #define UC_SURROGATE UC_CATEGORY_Cs /* all of them are invalid characters */ | ||
| 188 | #define UC_PRIVATE_USE UC_CATEGORY_Co | ||
| 189 | #define UC_UNASSIGNED UC_CATEGORY_Cn /* some of them are invalid characters */ | ||
| 190 | |||
| 191 | /* Return the union of two general categories. | ||
| 192 | This corresponds to the unions of the two sets of characters. */ | ||
| 193 | extern uc_general_category_t | ||
| 194 | uc_general_category_or (uc_general_category_t category1, | ||
| 195 | uc_general_category_t category2); | ||
| 196 | |||
| 197 | /* Return the intersection of two general categories as bit masks. | ||
| 198 | This *does*not* correspond to the intersection of the two sets of | ||
| 199 | characters. */ | ||
| 200 | extern uc_general_category_t | ||
| 201 | uc_general_category_and (uc_general_category_t category1, | ||
| 202 | uc_general_category_t category2); | ||
| 203 | |||
| 204 | /* Return the intersection of a general category with the complement of a | ||
| 205 | second general category, as bit masks. | ||
| 206 | This *does*not* correspond to the intersection with complement, when | ||
| 207 | viewing the categories as sets of characters. */ | ||
| 208 | extern uc_general_category_t | ||
| 209 | uc_general_category_and_not (uc_general_category_t category1, | ||
| 210 | uc_general_category_t category2); | ||
| 211 | |||
| 212 | /* Return the name of a general category. */ | ||
| 213 | extern const char * | ||
| 214 | uc_general_category_name (uc_general_category_t category) | ||
| 215 | _UC_ATTRIBUTE_PURE; | ||
| 216 | |||
| 217 | /* Return the long name of a general category. */ | ||
| 218 | extern const char * | ||
| 219 | uc_general_category_long_name (uc_general_category_t category) | ||
| 220 | _UC_ATTRIBUTE_PURE; | ||
| 221 | |||
| 222 | /* Return the general category given by name, e.g. "Lu", or by long name, | ||
| 223 | e.g. "Uppercase Letter". */ | ||
| 224 | extern uc_general_category_t | ||
| 225 | uc_general_category_byname (const char *category_name) | ||
| 226 | _UC_ATTRIBUTE_PURE; | ||
| 227 | |||
| 228 | /* Return the general category of a Unicode character. */ | ||
| 229 | extern uc_general_category_t | ||
| 230 | uc_general_category (ucs4_t uc) | ||
| 231 | _UC_ATTRIBUTE_PURE; | ||
| 232 | |||
| 233 | /* Test whether a Unicode character belongs to a given category. | ||
| 234 | The CATEGORY argument can be the combination of several predefined | ||
| 235 | general categories. */ | ||
| 236 | extern bool | ||
| 237 | uc_is_general_category (ucs4_t uc, uc_general_category_t category) | ||
| 238 | _UC_ATTRIBUTE_PURE; | ||
| 239 | /* Likewise. This function uses a big table comprising all categories. */ | ||
| 240 | extern bool | ||
| 241 | uc_is_general_category_withtable (ucs4_t uc, uint32_t bitmask) | ||
| 242 | _UC_ATTRIBUTE_CONST; | ||
| 243 | |||
| 244 | /* ========================================================================= */ | ||
| 245 | |||
| 246 | /* Field 3 of Unicode Character Database: Canonical combining class. */ | ||
| 247 | |||
| 248 | /* The possible results of uc_combining_class (0..255) are described in | ||
| 249 | UCD.html. The list here is not definitive; more values can be added | ||
| 250 | in future versions. */ | ||
| 251 | enum | ||
| 252 | { | ||
| 253 | UC_CCC_NR = 0, /* Not Reordered */ | ||
| 254 | UC_CCC_OV = 1, /* Overlay */ | ||
| 255 | UC_CCC_NK = 7, /* Nukta */ | ||
| 256 | UC_CCC_KV = 8, /* Kana Voicing */ | ||
| 257 | UC_CCC_VR = 9, /* Virama */ | ||
| 258 | UC_CCC_ATBL = 200, /* Attached Below Left */ | ||
| 259 | UC_CCC_ATB = 202, /* Attached Below */ | ||
| 260 | UC_CCC_ATA = 214, /* Attached Above */ | ||
| 261 | UC_CCC_ATAR = 216, /* Attached Above Right */ | ||
| 262 | UC_CCC_BL = 218, /* Below Left */ | ||
| 263 | UC_CCC_B = 220, /* Below */ | ||
| 264 | UC_CCC_BR = 222, /* Below Right */ | ||
| 265 | UC_CCC_L = 224, /* Left */ | ||
| 266 | UC_CCC_R = 226, /* Right */ | ||
| 267 | UC_CCC_AL = 228, /* Above Left */ | ||
| 268 | UC_CCC_A = 230, /* Above */ | ||
| 269 | UC_CCC_AR = 232, /* Above Right */ | ||
| 270 | UC_CCC_DB = 233, /* Double Below */ | ||
| 271 | UC_CCC_DA = 234, /* Double Above */ | ||
| 272 | UC_CCC_IS = 240 /* Iota Subscript */ | ||
| 273 | }; | ||
| 274 | |||
| 275 | /* Return the canonical combining class of a Unicode character. */ | ||
| 276 | extern int | ||
| 277 | uc_combining_class (ucs4_t uc) | ||
| 278 | _UC_ATTRIBUTE_CONST; | ||
| 279 | |||
| 280 | /* Return the name of a canonical combining class. */ | ||
| 281 | extern const char * | ||
| 282 | uc_combining_class_name (int ccc) | ||
| 283 | _UC_ATTRIBUTE_CONST; | ||
| 284 | |||
| 285 | /* Return the long name of a canonical combining class. */ | ||
| 286 | extern const char * | ||
| 287 | uc_combining_class_long_name (int ccc) | ||
| 288 | _UC_ATTRIBUTE_CONST; | ||
| 289 | |||
| 290 | /* Return the canonical combining class given by name, e.g. "BL", or by long | ||
| 291 | name, e.g. "Below Left". */ | ||
| 292 | extern int | ||
| 293 | uc_combining_class_byname (const char *ccc_name) | ||
| 294 | _UC_ATTRIBUTE_PURE; | ||
| 295 | |||
| 296 | /* ========================================================================= */ | ||
| 297 | |||
| 298 | /* Field 4 of Unicode Character Database: Bidi class. | ||
| 299 | Before Unicode 4.0, this field was called "Bidirectional category". */ | ||
| 300 | |||
| 301 | enum | ||
| 302 | { | ||
| 303 | UC_BIDI_L, /* Left-to-Right */ | ||
| 304 | UC_BIDI_LRE, /* Left-to-Right Embedding */ | ||
| 305 | UC_BIDI_LRO, /* Left-to-Right Override */ | ||
| 306 | UC_BIDI_R, /* Right-to-Left */ | ||
| 307 | UC_BIDI_AL, /* Right-to-Left Arabic */ | ||
| 308 | UC_BIDI_RLE, /* Right-to-Left Embedding */ | ||
| 309 | UC_BIDI_RLO, /* Right-to-Left Override */ | ||
| 310 | UC_BIDI_PDF, /* Pop Directional Format */ | ||
| 311 | UC_BIDI_EN, /* European Number */ | ||
| 312 | UC_BIDI_ES, /* European Number Separator */ | ||
| 313 | UC_BIDI_ET, /* European Number Terminator */ | ||
| 314 | UC_BIDI_AN, /* Arabic Number */ | ||
| 315 | UC_BIDI_CS, /* Common Number Separator */ | ||
| 316 | UC_BIDI_NSM, /* Non-Spacing Mark */ | ||
| 317 | UC_BIDI_BN, /* Boundary Neutral */ | ||
| 318 | UC_BIDI_B, /* Paragraph Separator */ | ||
| 319 | UC_BIDI_S, /* Segment Separator */ | ||
| 320 | UC_BIDI_WS, /* Whitespace */ | ||
| 321 | UC_BIDI_ON, /* Other Neutral */ | ||
| 322 | UC_BIDI_LRI, /* Left-to-Right Isolate */ | ||
| 323 | UC_BIDI_RLI, /* Right-to-Left Isolate */ | ||
| 324 | UC_BIDI_FSI, /* First Strong Isolate */ | ||
| 325 | UC_BIDI_PDI /* Pop Directional Isolate */ | ||
| 326 | }; | ||
| 327 | |||
| 328 | /* Return the name of a bidi class. */ | ||
| 329 | extern const char * | ||
| 330 | uc_bidi_class_name (int bidi_class) | ||
| 331 | _UC_ATTRIBUTE_CONST; | ||
| 332 | /* Same; obsolete function name. */ | ||
| 333 | extern const char * | ||
| 334 | uc_bidi_category_name (int category) | ||
| 335 | _UC_ATTRIBUTE_CONST; | ||
| 336 | |||
| 337 | /* Return the long name of a bidi class. */ | ||
| 338 | extern const char * | ||
| 339 | uc_bidi_class_long_name (int bidi_class) | ||
| 340 | _UC_ATTRIBUTE_CONST; | ||
| 341 | |||
| 342 | /* Return the bidi class given by name, e.g. "LRE", or by long name, e.g. | ||
| 343 | "Left-to-Right Embedding". */ | ||
| 344 | extern int | ||
| 345 | uc_bidi_class_byname (const char *bidi_class_name) | ||
| 346 | _UC_ATTRIBUTE_PURE; | ||
| 347 | /* Same; obsolete function name. */ | ||
| 348 | extern int | ||
| 349 | uc_bidi_category_byname (const char *category_name) | ||
| 350 | _UC_ATTRIBUTE_PURE; | ||
| 351 | |||
| 352 | /* Return the bidi class of a Unicode character. */ | ||
| 353 | extern int | ||
| 354 | uc_bidi_class (ucs4_t uc) | ||
| 355 | _UC_ATTRIBUTE_CONST; | ||
| 356 | /* Same; obsolete function name. */ | ||
| 357 | extern int | ||
| 358 | uc_bidi_category (ucs4_t uc) | ||
| 359 | _UC_ATTRIBUTE_CONST; | ||
| 360 | |||
| 361 | /* Test whether a Unicode character belongs to a given bidi class. */ | ||
| 362 | extern bool | ||
| 363 | uc_is_bidi_class (ucs4_t uc, int bidi_class) | ||
| 364 | _UC_ATTRIBUTE_CONST; | ||
| 365 | /* Same; obsolete function name. */ | ||
| 366 | extern bool | ||
| 367 | uc_is_bidi_category (ucs4_t uc, int category) | ||
| 368 | _UC_ATTRIBUTE_CONST; | ||
| 369 | |||
| 370 | /* ========================================================================= */ | ||
| 371 | |||
| 372 | /* Field 5 of Unicode Character Database: Character decomposition mapping. | ||
| 373 | See "uninorm.h". */ | ||
| 374 | |||
| 375 | /* ========================================================================= */ | ||
| 376 | |||
| 377 | /* Field 6 of Unicode Character Database: Decimal digit value. */ | ||
| 378 | |||
| 379 | /* Return the decimal digit value of a Unicode character. */ | ||
| 380 | extern int | ||
| 381 | uc_decimal_value (ucs4_t uc) | ||
| 382 | _UC_ATTRIBUTE_CONST; | ||
| 383 | |||
| 384 | /* ========================================================================= */ | ||
| 385 | |||
| 386 | /* Field 7 of Unicode Character Database: Digit value. */ | ||
| 387 | |||
| 388 | /* Return the digit value of a Unicode character. */ | ||
| 389 | extern int | ||
| 390 | uc_digit_value (ucs4_t uc) | ||
| 391 | _UC_ATTRIBUTE_CONST; | ||
| 392 | |||
| 393 | /* ========================================================================= */ | ||
| 394 | |||
| 395 | /* Field 8 of Unicode Character Database: Numeric value. */ | ||
| 396 | |||
| 397 | /* Return the numeric value of a Unicode character. */ | ||
| 398 | typedef struct | ||
| 399 | { | ||
| 400 | int numerator; | ||
| 401 | int denominator; | ||
| 402 | } | ||
| 403 | uc_fraction_t; | ||
| 404 | extern uc_fraction_t | ||
| 405 | uc_numeric_value (ucs4_t uc) | ||
| 406 | _UC_ATTRIBUTE_CONST; | ||
| 407 | |||
| 408 | /* ========================================================================= */ | ||
| 409 | |||
| 410 | /* Field 9 of Unicode Character Database: Mirrored. */ | ||
| 411 | |||
| 412 | /* Return the mirrored character of a Unicode character UC in *PUC. */ | ||
| 413 | extern bool | ||
| 414 | uc_mirror_char (ucs4_t uc, ucs4_t *puc); | ||
| 415 | |||
| 416 | /* ========================================================================= */ | ||
| 417 | |||
| 418 | /* Field 10 of Unicode Character Database: Unicode 1.0 Name. | ||
| 419 | Not available in this library. */ | ||
| 420 | |||
| 421 | /* ========================================================================= */ | ||
| 422 | |||
| 423 | /* Field 11 of Unicode Character Database: ISO 10646 comment. | ||
| 424 | Not available in this library. */ | ||
| 425 | |||
| 426 | /* ========================================================================= */ | ||
| 427 | |||
| 428 | /* Field 12, 13, 14 of Unicode Character Database: Uppercase mapping, | ||
| 429 | lowercase mapping, titlecase mapping. See "unicase.h". */ | ||
| 430 | |||
| 431 | /* ========================================================================= */ | ||
| 432 | |||
| 433 | /* Field 2 of the file ArabicShaping.txt in the Unicode Character Database. */ | ||
| 434 | |||
| 435 | /* Possible joining types. */ | ||
| 436 | enum | ||
| 437 | { | ||
| 438 | UC_JOINING_TYPE_U, /* Non_Joining */ | ||
| 439 | UC_JOINING_TYPE_T, /* Transparent */ | ||
| 440 | UC_JOINING_TYPE_C, /* Join_Causing */ | ||
| 441 | UC_JOINING_TYPE_L, /* Left_Joining */ | ||
| 442 | UC_JOINING_TYPE_R, /* Right_Joining */ | ||
| 443 | UC_JOINING_TYPE_D /* Dual_Joining */ | ||
| 444 | }; | ||
| 445 | |||
| 446 | /* Return the name of a joining type. */ | ||
| 447 | extern const char * | ||
| 448 | uc_joining_type_name (int joining_type) | ||
| 449 | _UC_ATTRIBUTE_CONST; | ||
| 450 | |||
| 451 | /* Return the long name of a joining type. */ | ||
| 452 | extern const char * | ||
| 453 | uc_joining_type_long_name (int joining_type) | ||
| 454 | _UC_ATTRIBUTE_CONST; | ||
| 455 | |||
| 456 | /* Return the joining type given by name, e.g. "D", or by long name, e.g. | ||
| 457 | "Dual Joining". */ | ||
| 458 | extern int | ||
| 459 | uc_joining_type_byname (const char *joining_type_name) | ||
| 460 | _UC_ATTRIBUTE_PURE; | ||
| 461 | |||
| 462 | /* Return the joining type of a Unicode character. */ | ||
| 463 | extern int | ||
| 464 | uc_joining_type (ucs4_t uc) | ||
| 465 | _UC_ATTRIBUTE_CONST; | ||
| 466 | |||
| 467 | /* ========================================================================= */ | ||
| 468 | |||
| 469 | /* Field 3 of the file ArabicShaping.txt in the Unicode Character Database. */ | ||
| 470 | |||
| 471 | /* Possible joining groups. | ||
| 472 | This enumeration may be extended in the future. */ | ||
| 473 | enum | ||
| 474 | { | ||
| 475 | UC_JOINING_GROUP_NONE, /* No_Joining_Group */ | ||
| 476 | UC_JOINING_GROUP_AIN, /* Ain */ | ||
| 477 | UC_JOINING_GROUP_ALAPH, /* Alaph */ | ||
| 478 | UC_JOINING_GROUP_ALEF, /* Alef */ | ||
| 479 | UC_JOINING_GROUP_BEH, /* Beh */ | ||
| 480 | UC_JOINING_GROUP_BETH, /* Beth */ | ||
| 481 | UC_JOINING_GROUP_BURUSHASKI_YEH_BARREE, /* Burushaski_Yeh_Barree */ | ||
| 482 | UC_JOINING_GROUP_DAL, /* Dal */ | ||
| 483 | UC_JOINING_GROUP_DALATH_RISH, /* Dalath_Rish */ | ||
| 484 | UC_JOINING_GROUP_E, /* E */ | ||
| 485 | UC_JOINING_GROUP_FARSI_YEH, /* Farsi_Yeh */ | ||
| 486 | UC_JOINING_GROUP_FE, /* Fe */ | ||
| 487 | UC_JOINING_GROUP_FEH, /* Feh */ | ||
| 488 | UC_JOINING_GROUP_FINAL_SEMKATH, /* Final_Semkath */ | ||
| 489 | UC_JOINING_GROUP_GAF, /* Gaf */ | ||
| 490 | UC_JOINING_GROUP_GAMAL, /* Gamal */ | ||
| 491 | UC_JOINING_GROUP_HAH, /* Hah */ | ||
| 492 | UC_JOINING_GROUP_HE, /* He */ | ||
| 493 | UC_JOINING_GROUP_HEH, /* Heh */ | ||
| 494 | UC_JOINING_GROUP_HEH_GOAL, /* Heh_Goal */ | ||
| 495 | UC_JOINING_GROUP_HETH, /* Heth */ | ||
| 496 | UC_JOINING_GROUP_KAF, /* Kaf */ | ||
| 497 | UC_JOINING_GROUP_KAPH, /* Kaph */ | ||
| 498 | UC_JOINING_GROUP_KHAPH, /* Khaph */ | ||
| 499 | UC_JOINING_GROUP_KNOTTED_HEH, /* Knotted_Heh */ | ||
| 500 | UC_JOINING_GROUP_LAM, /* Lam */ | ||
| 501 | UC_JOINING_GROUP_LAMADH, /* Lamadh */ | ||
| 502 | UC_JOINING_GROUP_MEEM, /* Meem */ | ||
| 503 | UC_JOINING_GROUP_MIM, /* Mim */ | ||
| 504 | UC_JOINING_GROUP_NOON, /* Noon */ | ||
| 505 | UC_JOINING_GROUP_NUN, /* Nun */ | ||
| 506 | UC_JOINING_GROUP_NYA, /* Nya */ | ||
| 507 | UC_JOINING_GROUP_PE, /* Pe */ | ||
| 508 | UC_JOINING_GROUP_QAF, /* Qaf */ | ||
| 509 | UC_JOINING_GROUP_QAPH, /* Qaph */ | ||
| 510 | UC_JOINING_GROUP_REH, /* Reh */ | ||
| 511 | UC_JOINING_GROUP_REVERSED_PE, /* Reversed_Pe */ | ||
| 512 | UC_JOINING_GROUP_SAD, /* Sad */ | ||
| 513 | UC_JOINING_GROUP_SADHE, /* Sadhe */ | ||
| 514 | UC_JOINING_GROUP_SEEN, /* Seen */ | ||
| 515 | UC_JOINING_GROUP_SEMKATH, /* Semkath */ | ||
| 516 | UC_JOINING_GROUP_SHIN, /* Shin */ | ||
| 517 | UC_JOINING_GROUP_SWASH_KAF, /* Swash_Kaf */ | ||
| 518 | UC_JOINING_GROUP_SYRIAC_WAW, /* Syriac_Waw */ | ||
| 519 | UC_JOINING_GROUP_TAH, /* Tah */ | ||
| 520 | UC_JOINING_GROUP_TAW, /* Taw */ | ||
| 521 | UC_JOINING_GROUP_TEH_MARBUTA, /* Teh_Marbuta */ | ||
| 522 | UC_JOINING_GROUP_TEH_MARBUTA_GOAL, /* Teh_Marbuta_Goal */ | ||
| 523 | UC_JOINING_GROUP_TETH, /* Teth */ | ||
| 524 | UC_JOINING_GROUP_WAW, /* Waw */ | ||
| 525 | UC_JOINING_GROUP_YEH, /* Yeh */ | ||
| 526 | UC_JOINING_GROUP_YEH_BARREE, /* Yeh_Barree */ | ||
| 527 | UC_JOINING_GROUP_YEH_WITH_TAIL, /* Yeh_With_Tail */ | ||
| 528 | UC_JOINING_GROUP_YUDH, /* Yudh */ | ||
| 529 | UC_JOINING_GROUP_YUDH_HE, /* Yudh_He */ | ||
| 530 | UC_JOINING_GROUP_ZAIN, /* Zain */ | ||
| 531 | UC_JOINING_GROUP_ZHAIN, /* Zhain */ | ||
| 532 | UC_JOINING_GROUP_ROHINGYA_YEH, /* Rohingya_Yeh */ | ||
| 533 | UC_JOINING_GROUP_STRAIGHT_WAW, /* Straight_Waw */ | ||
| 534 | UC_JOINING_GROUP_MANICHAEAN_ALEPH, /* Manichaean_Aleph */ | ||
| 535 | UC_JOINING_GROUP_MANICHAEAN_BETH, /* Manichaean_Beth */ | ||
| 536 | UC_JOINING_GROUP_MANICHAEAN_GIMEL, /* Manichaean_Gimel */ | ||
| 537 | UC_JOINING_GROUP_MANICHAEAN_DALETH, /* Manichaean_Daleth */ | ||
| 538 | UC_JOINING_GROUP_MANICHAEAN_WAW, /* Manichaean_Waw */ | ||
| 539 | UC_JOINING_GROUP_MANICHAEAN_ZAYIN, /* Manichaean_Zayin */ | ||
| 540 | UC_JOINING_GROUP_MANICHAEAN_HETH, /* Manichaean_Heth */ | ||
| 541 | UC_JOINING_GROUP_MANICHAEAN_TETH, /* Manichaean_Teth */ | ||
| 542 | UC_JOINING_GROUP_MANICHAEAN_YODH, /* Manichaean_Yodh */ | ||
| 543 | UC_JOINING_GROUP_MANICHAEAN_KAPH, /* Manichaean_Kaph */ | ||
| 544 | UC_JOINING_GROUP_MANICHAEAN_LAMEDH, /* Manichaean_Lamedh */ | ||
| 545 | UC_JOINING_GROUP_MANICHAEAN_DHAMEDH, /* Manichaean_Dhamedh */ | ||
| 546 | UC_JOINING_GROUP_MANICHAEAN_THAMEDH, /* Manichaean_Thamedh */ | ||
| 547 | UC_JOINING_GROUP_MANICHAEAN_MEM, /* Manichaean_Mem */ | ||
| 548 | UC_JOINING_GROUP_MANICHAEAN_NUN, /* Manichaean_Nun */ | ||
| 549 | UC_JOINING_GROUP_MANICHAEAN_SAMEKH, /* Manichaean_Aleph */ | ||
| 550 | UC_JOINING_GROUP_MANICHAEAN_AYIN, /* Manichaean_Ayin */ | ||
| 551 | UC_JOINING_GROUP_MANICHAEAN_PE, /* Manichaean_Pe */ | ||
| 552 | UC_JOINING_GROUP_MANICHAEAN_SADHE, /* Manichaean_Sadhe */ | ||
| 553 | UC_JOINING_GROUP_MANICHAEAN_QOPH, /* Manichaean_Qoph */ | ||
| 554 | UC_JOINING_GROUP_MANICHAEAN_RESH, /* Manichaean_Resh */ | ||
| 555 | UC_JOINING_GROUP_MANICHAEAN_TAW, /* Manichaean_Taw */ | ||
| 556 | UC_JOINING_GROUP_MANICHAEAN_ONE, /* Manichaean_One */ | ||
| 557 | UC_JOINING_GROUP_MANICHAEAN_FIVE, /* Manichaean_Five */ | ||
| 558 | UC_JOINING_GROUP_MANICHAEAN_TEN, /* Manichaean_Ten */ | ||
| 559 | UC_JOINING_GROUP_MANICHAEAN_TWENTY, /* Manichaean_Twenty */ | ||
| 560 | UC_JOINING_GROUP_MANICHAEAN_HUNDRED, /* Manichaean_Hundred */ | ||
| 561 | UC_JOINING_GROUP_AFRICAN_FEH, /* African_Feh */ | ||
| 562 | UC_JOINING_GROUP_AFRICAN_QAF, /* African_Qaf */ | ||
| 563 | UC_JOINING_GROUP_AFRICAN_NOON, /* African_Noon */ | ||
| 564 | UC_JOINING_GROUP_MALAYALAM_NGA, /* Malayalam_Nga */ | ||
| 565 | UC_JOINING_GROUP_MALAYALAM_JA, /* Malayalam_Ja */ | ||
| 566 | UC_JOINING_GROUP_MALAYALAM_NYA, /* Malayalam_Nya */ | ||
| 567 | UC_JOINING_GROUP_MALAYALAM_TTA, /* Malayalam_Tta */ | ||
| 568 | UC_JOINING_GROUP_MALAYALAM_NNA, /* Malayalam_Nna */ | ||
| 569 | UC_JOINING_GROUP_MALAYALAM_NNNA, /* Malayalam_Nnna */ | ||
| 570 | UC_JOINING_GROUP_MALAYALAM_BHA, /* Malayalam_Bha */ | ||
| 571 | UC_JOINING_GROUP_MALAYALAM_RA, /* Malayalam_Ra */ | ||
| 572 | UC_JOINING_GROUP_MALAYALAM_LLA, /* Malayalam_Lla */ | ||
| 573 | UC_JOINING_GROUP_MALAYALAM_LLLA, /* Malayalam_Llla */ | ||
| 574 | UC_JOINING_GROUP_MALAYALAM_SSA, /* Malayalam_Ssa */ | ||
| 575 | UC_JOINING_GROUP_HANIFI_ROHINGYA_PA, /* Hanifi_Rohingya_Pa */ | ||
| 576 | UC_JOINING_GROUP_HANIFI_ROHINGYA_KINNA_YA, /* Hanifi_Rohingya_Kinna_Ya */ | ||
| 577 | UC_JOINING_GROUP_THIN_YEH, /* Thin_Yeh */ | ||
| 578 | UC_JOINING_GROUP_VERTICAL_TAIL, /* Vertical_Tail */ | ||
| 579 | UC_JOINING_GROUP_KASHMIRI_YEH /* Kashmiri_Yeh */ | ||
| 580 | }; | ||
| 581 | |||
| 582 | /* Return the name of a joining group. */ | ||
| 583 | extern const char * | ||
| 584 | uc_joining_group_name (int joining_group) | ||
| 585 | _UC_ATTRIBUTE_CONST; | ||
| 586 | |||
| 587 | /* Return the joining group given by name, e.g. "Teh_Marbuta". */ | ||
| 588 | extern int | ||
| 589 | uc_joining_group_byname (const char *joining_group_name) | ||
| 590 | _UC_ATTRIBUTE_PURE; | ||
| 591 | |||
| 592 | /* Return the joining group of a Unicode character. */ | ||
| 593 | extern int | ||
| 594 | uc_joining_group (ucs4_t uc) | ||
| 595 | _UC_ATTRIBUTE_CONST; | ||
| 596 | |||
| 597 | /* ========================================================================= */ | ||
| 598 | |||
| 599 | /* Common API for properties. */ | ||
| 600 | |||
| 601 | /* Data type denoting a property. This is not just a number, but rather a | ||
| 602 | pointer to the test functions, so that programs that use only few of the | ||
| 603 | properties don't have a link-time dependency towards all the tables. */ | ||
| 604 | typedef struct | ||
| 605 | { | ||
| 606 | bool (*test_fn) (ucs4_t uc); | ||
| 607 | } | ||
| 608 | uc_property_t; | ||
| 609 | |||
| 610 | /* Predefined properties. */ | ||
| 611 | /* General. */ | ||
| 612 | extern @GNULIB_UNICTYPE_PROPERTY_WHITE_SPACE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_WHITE_SPACE; | ||
| 613 | extern @GNULIB_UNICTYPE_PROPERTY_ALPHABETIC_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_ALPHABETIC; | ||
| 614 | extern @GNULIB_UNICTYPE_PROPERTY_OTHER_ALPHABETIC_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_OTHER_ALPHABETIC; | ||
| 615 | extern @GNULIB_UNICTYPE_PROPERTY_NOT_A_CHARACTER_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_NOT_A_CHARACTER; | ||
| 616 | extern @GNULIB_UNICTYPE_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_DEFAULT_IGNORABLE_CODE_POINT; | ||
| 617 | extern @GNULIB_UNICTYPE_PROPERTY_OTHER_DEFAULT_IGNORABLE_CODE_POINT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_OTHER_DEFAULT_IGNORABLE_CODE_POINT; | ||
| 618 | extern @GNULIB_UNICTYPE_PROPERTY_DEPRECATED_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_DEPRECATED; | ||
| 619 | extern @GNULIB_UNICTYPE_PROPERTY_LOGICAL_ORDER_EXCEPTION_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_LOGICAL_ORDER_EXCEPTION; | ||
| 620 | extern @GNULIB_UNICTYPE_PROPERTY_VARIATION_SELECTOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_VARIATION_SELECTOR; | ||
| 621 | extern @GNULIB_UNICTYPE_PROPERTY_PRIVATE_USE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_PRIVATE_USE; | ||
| 622 | extern @GNULIB_UNICTYPE_PROPERTY_UNASSIGNED_CODE_VALUE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_UNASSIGNED_CODE_VALUE; | ||
| 623 | /* Case. */ | ||
| 624 | extern @GNULIB_UNICTYPE_PROPERTY_UPPERCASE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_UPPERCASE; | ||
| 625 | extern @GNULIB_UNICTYPE_PROPERTY_OTHER_UPPERCASE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_OTHER_UPPERCASE; | ||
| 626 | extern @GNULIB_UNICTYPE_PROPERTY_LOWERCASE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_LOWERCASE; | ||
| 627 | extern @GNULIB_UNICTYPE_PROPERTY_OTHER_LOWERCASE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_OTHER_LOWERCASE; | ||
| 628 | extern @GNULIB_UNICTYPE_PROPERTY_TITLECASE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_TITLECASE; | ||
| 629 | extern @GNULIB_UNICTYPE_PROPERTY_CASED_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_CASED; | ||
| 630 | extern @GNULIB_UNICTYPE_PROPERTY_CASE_IGNORABLE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_CASE_IGNORABLE; | ||
| 631 | extern @GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_LOWERCASED_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_CHANGES_WHEN_LOWERCASED; | ||
| 632 | extern @GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_UPPERCASED_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_CHANGES_WHEN_UPPERCASED; | ||
| 633 | extern @GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_TITLECASED_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_CHANGES_WHEN_TITLECASED; | ||
| 634 | extern @GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_CASEFOLDED_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_CHANGES_WHEN_CASEFOLDED; | ||
| 635 | extern @GNULIB_UNICTYPE_PROPERTY_CHANGES_WHEN_CASEMAPPED_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_CHANGES_WHEN_CASEMAPPED; | ||
| 636 | extern @GNULIB_UNICTYPE_PROPERTY_SOFT_DOTTED_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_SOFT_DOTTED; | ||
| 637 | /* Identifiers. */ | ||
| 638 | extern @GNULIB_UNICTYPE_PROPERTY_ID_START_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_ID_START; | ||
| 639 | extern @GNULIB_UNICTYPE_PROPERTY_OTHER_ID_START_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_OTHER_ID_START; | ||
| 640 | extern @GNULIB_UNICTYPE_PROPERTY_ID_CONTINUE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_ID_CONTINUE; | ||
| 641 | extern @GNULIB_UNICTYPE_PROPERTY_OTHER_ID_CONTINUE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_OTHER_ID_CONTINUE; | ||
| 642 | extern @GNULIB_UNICTYPE_PROPERTY_XID_START_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_XID_START; | ||
| 643 | extern @GNULIB_UNICTYPE_PROPERTY_XID_CONTINUE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_XID_CONTINUE; | ||
| 644 | extern @GNULIB_UNICTYPE_PROPERTY_ID_COMPAT_MATH_START_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_ID_COMPAT_MATH_START; | ||
| 645 | extern @GNULIB_UNICTYPE_PROPERTY_ID_COMPAT_MATH_CONTINUE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_ID_COMPAT_MATH_CONTINUE; | ||
| 646 | extern @GNULIB_UNICTYPE_PROPERTY_PATTERN_WHITE_SPACE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_PATTERN_WHITE_SPACE; | ||
| 647 | extern @GNULIB_UNICTYPE_PROPERTY_PATTERN_SYNTAX_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_PATTERN_SYNTAX; | ||
| 648 | /* Shaping and rendering. */ | ||
| 649 | extern @GNULIB_UNICTYPE_PROPERTY_JOIN_CONTROL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_JOIN_CONTROL; | ||
| 650 | extern @GNULIB_UNICTYPE_PROPERTY_GRAPHEME_BASE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_GRAPHEME_BASE; | ||
| 651 | extern @GNULIB_UNICTYPE_PROPERTY_GRAPHEME_EXTEND_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_GRAPHEME_EXTEND; | ||
| 652 | extern @GNULIB_UNICTYPE_PROPERTY_OTHER_GRAPHEME_EXTEND_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_OTHER_GRAPHEME_EXTEND; | ||
| 653 | extern @GNULIB_UNICTYPE_PROPERTY_GRAPHEME_LINK_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_GRAPHEME_LINK; | ||
| 654 | extern @GNULIB_UNICTYPE_PROPERTY_MODIFIER_COMBINING_MARK_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_MODIFIER_COMBINING_MARK; | ||
| 655 | /* Bidi. */ | ||
| 656 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_CONTROL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_CONTROL; | ||
| 657 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_LEFT_TO_RIGHT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_LEFT_TO_RIGHT; | ||
| 658 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_HEBREW_RIGHT_TO_LEFT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_HEBREW_RIGHT_TO_LEFT; | ||
| 659 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_ARABIC_RIGHT_TO_LEFT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_ARABIC_RIGHT_TO_LEFT; | ||
| 660 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_EUROPEAN_DIGIT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_EUROPEAN_DIGIT; | ||
| 661 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_EUR_NUM_SEPARATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_EUR_NUM_SEPARATOR; | ||
| 662 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_EUR_NUM_TERMINATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_EUR_NUM_TERMINATOR; | ||
| 663 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_ARABIC_DIGIT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_ARABIC_DIGIT; | ||
| 664 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_COMMON_SEPARATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_COMMON_SEPARATOR; | ||
| 665 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_BLOCK_SEPARATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_BLOCK_SEPARATOR; | ||
| 666 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_SEGMENT_SEPARATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_SEGMENT_SEPARATOR; | ||
| 667 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_WHITESPACE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_WHITESPACE; | ||
| 668 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_NON_SPACING_MARK_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_NON_SPACING_MARK; | ||
| 669 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_BOUNDARY_NEUTRAL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_BOUNDARY_NEUTRAL; | ||
| 670 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_PDF_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_PDF; | ||
| 671 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_EMBEDDING_OR_OVERRIDE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_EMBEDDING_OR_OVERRIDE; | ||
| 672 | extern @GNULIB_UNICTYPE_PROPERTY_BIDI_OTHER_NEUTRAL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_BIDI_OTHER_NEUTRAL; | ||
| 673 | /* Numeric. */ | ||
| 674 | extern @GNULIB_UNICTYPE_PROPERTY_HEX_DIGIT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_HEX_DIGIT; | ||
| 675 | extern @GNULIB_UNICTYPE_PROPERTY_ASCII_HEX_DIGIT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_ASCII_HEX_DIGIT; | ||
| 676 | /* CJK. */ | ||
| 677 | extern @GNULIB_UNICTYPE_PROPERTY_IDEOGRAPHIC_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_IDEOGRAPHIC; | ||
| 678 | extern @GNULIB_UNICTYPE_PROPERTY_UNIFIED_IDEOGRAPH_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_UNIFIED_IDEOGRAPH; | ||
| 679 | extern @GNULIB_UNICTYPE_PROPERTY_RADICAL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_RADICAL; | ||
| 680 | extern @GNULIB_UNICTYPE_PROPERTY_IDS_UNARY_OPERATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_IDS_UNARY_OPERATOR; | ||
| 681 | extern @GNULIB_UNICTYPE_PROPERTY_IDS_BINARY_OPERATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_IDS_BINARY_OPERATOR; | ||
| 682 | extern @GNULIB_UNICTYPE_PROPERTY_IDS_TRINARY_OPERATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_IDS_TRINARY_OPERATOR; | ||
| 683 | /* Emoji. */ | ||
| 684 | extern @GNULIB_UNICTYPE_PROPERTY_EMOJI_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_EMOJI; | ||
| 685 | extern @GNULIB_UNICTYPE_PROPERTY_EMOJI_PRESENTATION_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_EMOJI_PRESENTATION; | ||
| 686 | extern @GNULIB_UNICTYPE_PROPERTY_EMOJI_MODIFIER_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_EMOJI_MODIFIER; | ||
| 687 | extern @GNULIB_UNICTYPE_PROPERTY_EMOJI_MODIFIER_BASE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_EMOJI_MODIFIER_BASE; | ||
| 688 | extern @GNULIB_UNICTYPE_PROPERTY_EMOJI_COMPONENT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_EMOJI_COMPONENT; | ||
| 689 | extern @GNULIB_UNICTYPE_PROPERTY_EXTENDED_PICTOGRAPHIC_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_EXTENDED_PICTOGRAPHIC; | ||
| 690 | /* Misc. */ | ||
| 691 | extern @GNULIB_UNICTYPE_PROPERTY_ZERO_WIDTH_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_ZERO_WIDTH; | ||
| 692 | extern @GNULIB_UNICTYPE_PROPERTY_SPACE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_SPACE; | ||
| 693 | extern @GNULIB_UNICTYPE_PROPERTY_NON_BREAK_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_NON_BREAK; | ||
| 694 | extern @GNULIB_UNICTYPE_PROPERTY_ISO_CONTROL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_ISO_CONTROL; | ||
| 695 | extern @GNULIB_UNICTYPE_PROPERTY_FORMAT_CONTROL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_FORMAT_CONTROL; | ||
| 696 | extern @GNULIB_UNICTYPE_PROPERTY_PREPENDED_CONCATENATION_MARK_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_PREPENDED_CONCATENATION_MARK; | ||
| 697 | extern @GNULIB_UNICTYPE_PROPERTY_DASH_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_DASH; | ||
| 698 | extern @GNULIB_UNICTYPE_PROPERTY_HYPHEN_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_HYPHEN; | ||
| 699 | extern @GNULIB_UNICTYPE_PROPERTY_PUNCTUATION_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_PUNCTUATION; | ||
| 700 | extern @GNULIB_UNICTYPE_PROPERTY_LINE_SEPARATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_LINE_SEPARATOR; | ||
| 701 | extern @GNULIB_UNICTYPE_PROPERTY_PARAGRAPH_SEPARATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_PARAGRAPH_SEPARATOR; | ||
| 702 | extern @GNULIB_UNICTYPE_PROPERTY_QUOTATION_MARK_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_QUOTATION_MARK; | ||
| 703 | extern @GNULIB_UNICTYPE_PROPERTY_SENTENCE_TERMINAL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_SENTENCE_TERMINAL; | ||
| 704 | extern @GNULIB_UNICTYPE_PROPERTY_TERMINAL_PUNCTUATION_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_TERMINAL_PUNCTUATION; | ||
| 705 | extern @GNULIB_UNICTYPE_PROPERTY_CURRENCY_SYMBOL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_CURRENCY_SYMBOL; | ||
| 706 | extern @GNULIB_UNICTYPE_PROPERTY_MATH_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_MATH; | ||
| 707 | extern @GNULIB_UNICTYPE_PROPERTY_OTHER_MATH_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_OTHER_MATH; | ||
| 708 | extern @GNULIB_UNICTYPE_PROPERTY_PAIRED_PUNCTUATION_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_PAIRED_PUNCTUATION; | ||
| 709 | extern @GNULIB_UNICTYPE_PROPERTY_LEFT_OF_PAIR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_LEFT_OF_PAIR; | ||
| 710 | extern @GNULIB_UNICTYPE_PROPERTY_COMBINING_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_COMBINING; | ||
| 711 | extern @GNULIB_UNICTYPE_PROPERTY_COMPOSITE_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_COMPOSITE; | ||
| 712 | extern @GNULIB_UNICTYPE_PROPERTY_DECIMAL_DIGIT_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_DECIMAL_DIGIT; | ||
| 713 | extern @GNULIB_UNICTYPE_PROPERTY_NUMERIC_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_NUMERIC; | ||
| 714 | extern @GNULIB_UNICTYPE_PROPERTY_DIACRITIC_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_DIACRITIC; | ||
| 715 | extern @GNULIB_UNICTYPE_PROPERTY_EXTENDER_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_EXTENDER; | ||
| 716 | extern @GNULIB_UNICTYPE_PROPERTY_IGNORABLE_CONTROL_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_IGNORABLE_CONTROL; | ||
| 717 | extern @GNULIB_UNICTYPE_PROPERTY_REGIONAL_INDICATOR_DLL_VARIABLE@ const uc_property_t UC_PROPERTY_REGIONAL_INDICATOR; | ||
| 718 | |||
| 719 | /* Return the property given by name, e.g. "White space". */ | ||
| 720 | extern uc_property_t | ||
| 721 | uc_property_byname (const char *property_name); | ||
| 722 | |||
| 723 | /* Test whether a property is valid. */ | ||
| 724 | #define uc_property_is_valid(property) ((property).test_fn != NULL) | ||
| 725 | |||
| 726 | /* Test whether a Unicode character has a given property. */ | ||
| 727 | extern bool | ||
| 728 | uc_is_property (ucs4_t uc, uc_property_t property); | ||
| 729 | extern bool uc_is_property_white_space (ucs4_t uc) | ||
| 730 | _UC_ATTRIBUTE_CONST; | ||
| 731 | extern bool uc_is_property_alphabetic (ucs4_t uc) | ||
| 732 | _UC_ATTRIBUTE_CONST; | ||
| 733 | extern bool uc_is_property_other_alphabetic (ucs4_t uc) | ||
| 734 | _UC_ATTRIBUTE_CONST; | ||
| 735 | extern bool uc_is_property_not_a_character (ucs4_t uc) | ||
| 736 | _UC_ATTRIBUTE_CONST; | ||
| 737 | extern bool uc_is_property_default_ignorable_code_point (ucs4_t uc) | ||
| 738 | _UC_ATTRIBUTE_CONST; | ||
| 739 | extern bool uc_is_property_other_default_ignorable_code_point (ucs4_t uc) | ||
| 740 | _UC_ATTRIBUTE_CONST; | ||
| 741 | extern bool uc_is_property_deprecated (ucs4_t uc) | ||
| 742 | _UC_ATTRIBUTE_CONST; | ||
| 743 | extern bool uc_is_property_logical_order_exception (ucs4_t uc) | ||
| 744 | _UC_ATTRIBUTE_CONST; | ||
| 745 | extern bool uc_is_property_variation_selector (ucs4_t uc) | ||
| 746 | _UC_ATTRIBUTE_CONST; | ||
| 747 | extern bool uc_is_property_private_use (ucs4_t uc) | ||
| 748 | _UC_ATTRIBUTE_CONST; | ||
| 749 | extern bool uc_is_property_unassigned_code_value (ucs4_t uc) | ||
| 750 | _UC_ATTRIBUTE_CONST; | ||
| 751 | extern bool uc_is_property_uppercase (ucs4_t uc) | ||
| 752 | _UC_ATTRIBUTE_CONST; | ||
| 753 | extern bool uc_is_property_other_uppercase (ucs4_t uc) | ||
| 754 | _UC_ATTRIBUTE_CONST; | ||
| 755 | extern bool uc_is_property_lowercase (ucs4_t uc) | ||
| 756 | _UC_ATTRIBUTE_CONST; | ||
| 757 | extern bool uc_is_property_other_lowercase (ucs4_t uc) | ||
| 758 | _UC_ATTRIBUTE_CONST; | ||
| 759 | extern bool uc_is_property_titlecase (ucs4_t uc) | ||
| 760 | _UC_ATTRIBUTE_CONST; | ||
| 761 | extern bool uc_is_property_cased (ucs4_t uc) | ||
| 762 | _UC_ATTRIBUTE_CONST; | ||
| 763 | extern bool uc_is_property_case_ignorable (ucs4_t uc) | ||
| 764 | _UC_ATTRIBUTE_CONST; | ||
| 765 | extern bool uc_is_property_changes_when_lowercased (ucs4_t uc) | ||
| 766 | _UC_ATTRIBUTE_CONST; | ||
| 767 | extern bool uc_is_property_changes_when_uppercased (ucs4_t uc) | ||
| 768 | _UC_ATTRIBUTE_CONST; | ||
| 769 | extern bool uc_is_property_changes_when_titlecased (ucs4_t uc) | ||
| 770 | _UC_ATTRIBUTE_CONST; | ||
| 771 | extern bool uc_is_property_changes_when_casefolded (ucs4_t uc) | ||
| 772 | _UC_ATTRIBUTE_CONST; | ||
| 773 | extern bool uc_is_property_changes_when_casemapped (ucs4_t uc) | ||
| 774 | _UC_ATTRIBUTE_CONST; | ||
| 775 | extern bool uc_is_property_soft_dotted (ucs4_t uc) | ||
| 776 | _UC_ATTRIBUTE_CONST; | ||
| 777 | extern bool uc_is_property_id_start (ucs4_t uc) | ||
| 778 | _UC_ATTRIBUTE_CONST; | ||
| 779 | extern bool uc_is_property_other_id_start (ucs4_t uc) | ||
| 780 | _UC_ATTRIBUTE_CONST; | ||
| 781 | extern bool uc_is_property_id_continue (ucs4_t uc) | ||
| 782 | _UC_ATTRIBUTE_CONST; | ||
| 783 | extern bool uc_is_property_other_id_continue (ucs4_t uc) | ||
| 784 | _UC_ATTRIBUTE_CONST; | ||
| 785 | extern bool uc_is_property_xid_start (ucs4_t uc) | ||
| 786 | _UC_ATTRIBUTE_CONST; | ||
| 787 | extern bool uc_is_property_xid_continue (ucs4_t uc) | ||
| 788 | _UC_ATTRIBUTE_CONST; | ||
| 789 | extern bool uc_is_property_id_compat_math_start (ucs4_t uc) | ||
| 790 | _UC_ATTRIBUTE_CONST; | ||
| 791 | extern bool uc_is_property_id_compat_math_continue (ucs4_t uc) | ||
| 792 | _UC_ATTRIBUTE_CONST; | ||
| 793 | extern bool uc_is_property_pattern_white_space (ucs4_t uc) | ||
| 794 | _UC_ATTRIBUTE_CONST; | ||
| 795 | extern bool uc_is_property_pattern_syntax (ucs4_t uc) | ||
| 796 | _UC_ATTRIBUTE_CONST; | ||
| 797 | extern bool uc_is_property_join_control (ucs4_t uc) | ||
| 798 | _UC_ATTRIBUTE_CONST; | ||
| 799 | extern bool uc_is_property_grapheme_base (ucs4_t uc) | ||
| 800 | _UC_ATTRIBUTE_CONST; | ||
| 801 | extern bool uc_is_property_grapheme_extend (ucs4_t uc) | ||
| 802 | _UC_ATTRIBUTE_CONST; | ||
| 803 | extern bool uc_is_property_other_grapheme_extend (ucs4_t uc) | ||
| 804 | _UC_ATTRIBUTE_CONST; | ||
| 805 | extern bool uc_is_property_grapheme_link (ucs4_t uc) | ||
| 806 | _UC_ATTRIBUTE_CONST; | ||
| 807 | extern bool uc_is_property_modifier_combining_mark (ucs4_t uc) | ||
| 808 | _UC_ATTRIBUTE_CONST; | ||
| 809 | extern bool uc_is_property_bidi_control (ucs4_t uc) | ||
| 810 | _UC_ATTRIBUTE_CONST; | ||
| 811 | extern bool uc_is_property_bidi_left_to_right (ucs4_t uc) | ||
| 812 | _UC_ATTRIBUTE_CONST; | ||
| 813 | extern bool uc_is_property_bidi_hebrew_right_to_left (ucs4_t uc) | ||
| 814 | _UC_ATTRIBUTE_CONST; | ||
| 815 | extern bool uc_is_property_bidi_arabic_right_to_left (ucs4_t uc) | ||
| 816 | _UC_ATTRIBUTE_CONST; | ||
| 817 | extern bool uc_is_property_bidi_european_digit (ucs4_t uc) | ||
| 818 | _UC_ATTRIBUTE_CONST; | ||
| 819 | extern bool uc_is_property_bidi_eur_num_separator (ucs4_t uc) | ||
| 820 | _UC_ATTRIBUTE_CONST; | ||
| 821 | extern bool uc_is_property_bidi_eur_num_terminator (ucs4_t uc) | ||
| 822 | _UC_ATTRIBUTE_CONST; | ||
| 823 | extern bool uc_is_property_bidi_arabic_digit (ucs4_t uc) | ||
| 824 | _UC_ATTRIBUTE_CONST; | ||
| 825 | extern bool uc_is_property_bidi_common_separator (ucs4_t uc) | ||
| 826 | _UC_ATTRIBUTE_CONST; | ||
| 827 | extern bool uc_is_property_bidi_block_separator (ucs4_t uc) | ||
| 828 | _UC_ATTRIBUTE_CONST; | ||
| 829 | extern bool uc_is_property_bidi_segment_separator (ucs4_t uc) | ||
| 830 | _UC_ATTRIBUTE_CONST; | ||
| 831 | extern bool uc_is_property_bidi_whitespace (ucs4_t uc) | ||
| 832 | _UC_ATTRIBUTE_CONST; | ||
| 833 | extern bool uc_is_property_bidi_non_spacing_mark (ucs4_t uc) | ||
| 834 | _UC_ATTRIBUTE_CONST; | ||
| 835 | extern bool uc_is_property_bidi_boundary_neutral (ucs4_t uc) | ||
| 836 | _UC_ATTRIBUTE_CONST; | ||
| 837 | extern bool uc_is_property_bidi_pdf (ucs4_t uc) | ||
| 838 | _UC_ATTRIBUTE_CONST; | ||
| 839 | extern bool uc_is_property_bidi_embedding_or_override (ucs4_t uc) | ||
| 840 | _UC_ATTRIBUTE_CONST; | ||
| 841 | extern bool uc_is_property_bidi_other_neutral (ucs4_t uc) | ||
| 842 | _UC_ATTRIBUTE_CONST; | ||
| 843 | extern bool uc_is_property_hex_digit (ucs4_t uc) | ||
| 844 | _UC_ATTRIBUTE_CONST; | ||
| 845 | extern bool uc_is_property_ascii_hex_digit (ucs4_t uc) | ||
| 846 | _UC_ATTRIBUTE_CONST; | ||
| 847 | extern bool uc_is_property_ideographic (ucs4_t uc) | ||
| 848 | _UC_ATTRIBUTE_CONST; | ||
| 849 | extern bool uc_is_property_unified_ideograph (ucs4_t uc) | ||
| 850 | _UC_ATTRIBUTE_CONST; | ||
| 851 | extern bool uc_is_property_radical (ucs4_t uc) | ||
| 852 | _UC_ATTRIBUTE_CONST; | ||
| 853 | extern bool uc_is_property_ids_unary_operator (ucs4_t uc) | ||
| 854 | _UC_ATTRIBUTE_CONST; | ||
| 855 | extern bool uc_is_property_ids_binary_operator (ucs4_t uc) | ||
| 856 | _UC_ATTRIBUTE_CONST; | ||
| 857 | extern bool uc_is_property_ids_trinary_operator (ucs4_t uc) | ||
| 858 | _UC_ATTRIBUTE_CONST; | ||
| 859 | extern bool uc_is_property_emoji (ucs4_t uc) | ||
| 860 | _UC_ATTRIBUTE_CONST; | ||
| 861 | extern bool uc_is_property_emoji_presentation (ucs4_t uc) | ||
| 862 | _UC_ATTRIBUTE_CONST; | ||
| 863 | extern bool uc_is_property_emoji_modifier (ucs4_t uc) | ||
| 864 | _UC_ATTRIBUTE_CONST; | ||
| 865 | extern bool uc_is_property_emoji_modifier_base (ucs4_t uc) | ||
| 866 | _UC_ATTRIBUTE_CONST; | ||
| 867 | extern bool uc_is_property_emoji_component (ucs4_t uc) | ||
| 868 | _UC_ATTRIBUTE_CONST; | ||
| 869 | extern bool uc_is_property_extended_pictographic (ucs4_t uc) | ||
| 870 | _UC_ATTRIBUTE_CONST; | ||
| 871 | extern bool uc_is_property_zero_width (ucs4_t uc) | ||
| 872 | _UC_ATTRIBUTE_CONST; | ||
| 873 | extern bool uc_is_property_space (ucs4_t uc) | ||
| 874 | _UC_ATTRIBUTE_CONST; | ||
| 875 | extern bool uc_is_property_non_break (ucs4_t uc) | ||
| 876 | _UC_ATTRIBUTE_CONST; | ||
| 877 | extern bool uc_is_property_iso_control (ucs4_t uc) | ||
| 878 | _UC_ATTRIBUTE_CONST; | ||
| 879 | extern bool uc_is_property_format_control (ucs4_t uc) | ||
| 880 | _UC_ATTRIBUTE_CONST; | ||
| 881 | extern bool uc_is_property_prepended_concatenation_mark (ucs4_t uc) | ||
| 882 | _UC_ATTRIBUTE_CONST; | ||
| 883 | extern bool uc_is_property_dash (ucs4_t uc) | ||
| 884 | _UC_ATTRIBUTE_CONST; | ||
| 885 | extern bool uc_is_property_hyphen (ucs4_t uc) | ||
| 886 | _UC_ATTRIBUTE_CONST; | ||
| 887 | extern bool uc_is_property_punctuation (ucs4_t uc) | ||
| 888 | _UC_ATTRIBUTE_CONST; | ||
| 889 | extern bool uc_is_property_line_separator (ucs4_t uc) | ||
| 890 | _UC_ATTRIBUTE_CONST; | ||
| 891 | extern bool uc_is_property_paragraph_separator (ucs4_t uc) | ||
| 892 | _UC_ATTRIBUTE_CONST; | ||
| 893 | extern bool uc_is_property_quotation_mark (ucs4_t uc) | ||
| 894 | _UC_ATTRIBUTE_CONST; | ||
| 895 | extern bool uc_is_property_sentence_terminal (ucs4_t uc) | ||
| 896 | _UC_ATTRIBUTE_CONST; | ||
| 897 | extern bool uc_is_property_terminal_punctuation (ucs4_t uc) | ||
| 898 | _UC_ATTRIBUTE_CONST; | ||
| 899 | extern bool uc_is_property_currency_symbol (ucs4_t uc) | ||
| 900 | _UC_ATTRIBUTE_CONST; | ||
| 901 | extern bool uc_is_property_math (ucs4_t uc) | ||
| 902 | _UC_ATTRIBUTE_CONST; | ||
| 903 | extern bool uc_is_property_other_math (ucs4_t uc) | ||
| 904 | _UC_ATTRIBUTE_CONST; | ||
| 905 | extern bool uc_is_property_paired_punctuation (ucs4_t uc) | ||
| 906 | _UC_ATTRIBUTE_CONST; | ||
| 907 | extern bool uc_is_property_left_of_pair (ucs4_t uc) | ||
| 908 | _UC_ATTRIBUTE_CONST; | ||
| 909 | extern bool uc_is_property_combining (ucs4_t uc) | ||
| 910 | _UC_ATTRIBUTE_CONST; | ||
| 911 | extern bool uc_is_property_composite (ucs4_t uc) | ||
| 912 | _UC_ATTRIBUTE_CONST; | ||
| 913 | extern bool uc_is_property_decimal_digit (ucs4_t uc) | ||
| 914 | _UC_ATTRIBUTE_CONST; | ||
| 915 | extern bool uc_is_property_numeric (ucs4_t uc) | ||
| 916 | _UC_ATTRIBUTE_CONST; | ||
| 917 | extern bool uc_is_property_diacritic (ucs4_t uc) | ||
| 918 | _UC_ATTRIBUTE_CONST; | ||
| 919 | extern bool uc_is_property_extender (ucs4_t uc) | ||
| 920 | _UC_ATTRIBUTE_CONST; | ||
| 921 | extern bool uc_is_property_ignorable_control (ucs4_t uc) | ||
| 922 | _UC_ATTRIBUTE_CONST; | ||
| 923 | extern bool uc_is_property_regional_indicator (ucs4_t uc) | ||
| 924 | _UC_ATTRIBUTE_CONST; | ||
| 925 | |||
| 926 | /* ========================================================================= */ | ||
| 927 | |||
| 928 | /* Other attributes. */ | ||
| 929 | |||
| 930 | /* ------------------------------------------------------------------------- */ | ||
| 931 | |||
| 932 | /* Indic_Conjunct_Break (InCB): from the file DerivedCoreProperties.txt | ||
| 933 | in the Unicode Character Database. */ | ||
| 934 | |||
| 935 | /* Possible values of the Indic_Conjunct_Break attribute. | ||
| 936 | This enumeration may be extended in the future. */ | ||
| 937 | enum | ||
| 938 | { | ||
| 939 | UC_INDIC_CONJUNCT_BREAK_NONE, /* None */ | ||
| 940 | UC_INDIC_CONJUNCT_BREAK_CONSONANT, /* Consonant */ | ||
| 941 | UC_INDIC_CONJUNCT_BREAK_LINKER, /* Linker */ | ||
| 942 | UC_INDIC_CONJUNCT_BREAK_EXTEND /* Extend */ | ||
| 943 | }; | ||
| 944 | |||
| 945 | /* Return the name of an Indic_Conjunct_Break value. */ | ||
| 946 | extern const char * | ||
| 947 | uc_indic_conjunct_break_name (int indic_conjunct_break) | ||
| 948 | _UC_ATTRIBUTE_CONST; | ||
| 949 | |||
| 950 | /* Return the Indic_Conjunct_Break value given by name, e.g. "Consonant". */ | ||
| 951 | extern int | ||
| 952 | uc_indic_conjunct_break_byname (const char *indic_conjunct_break_name) | ||
| 953 | _UC_ATTRIBUTE_PURE; | ||
| 954 | |||
| 955 | /* Return the Indic_Conjunct_Break attribute of a Unicode character. */ | ||
| 956 | extern int | ||
| 957 | uc_indic_conjunct_break (ucs4_t uc) | ||
| 958 | _UC_ATTRIBUTE_CONST; | ||
| 959 | |||
| 960 | /* ========================================================================= */ | ||
| 961 | |||
| 962 | /* Subdivision of the Unicode characters into scripts. */ | ||
| 963 | |||
| 964 | typedef struct | ||
| 965 | { | ||
| 966 | unsigned int code : 21; | ||
| 967 | unsigned int start : 1; | ||
| 968 | unsigned int end : 1; | ||
| 969 | } | ||
| 970 | uc_interval_t; | ||
| 971 | typedef struct | ||
| 972 | { | ||
| 973 | unsigned int nintervals; | ||
| 974 | const uc_interval_t *intervals; | ||
| 975 | const char *name; | ||
| 976 | } | ||
| 977 | uc_script_t; | ||
| 978 | |||
| 979 | /* Return the script of a Unicode character. */ | ||
| 980 | extern const uc_script_t * | ||
| 981 | uc_script (ucs4_t uc) | ||
| 982 | _UC_ATTRIBUTE_CONST; | ||
| 983 | |||
| 984 | /* Return the script given by name, e.g. "HAN". */ | ||
| 985 | extern const uc_script_t * | ||
| 986 | uc_script_byname (const char *script_name) | ||
| 987 | _UC_ATTRIBUTE_PURE; | ||
| 988 | |||
| 989 | /* Test whether a Unicode character belongs to a given script. */ | ||
| 990 | extern bool | ||
| 991 | uc_is_script (ucs4_t uc, const uc_script_t *script) | ||
| 992 | _UC_ATTRIBUTE_PURE; | ||
| 993 | |||
| 994 | /* Get the list of all scripts. */ | ||
| 995 | extern void | ||
| 996 | uc_all_scripts (const uc_script_t **scripts, size_t *count); | ||
| 997 | |||
| 998 | /* ========================================================================= */ | ||
| 999 | |||
| 1000 | /* Subdivision of the Unicode character range into blocks. */ | ||
| 1001 | |||
| 1002 | typedef struct | ||
| 1003 | { | ||
| 1004 | ucs4_t start; | ||
| 1005 | ucs4_t end; | ||
| 1006 | const char *name; | ||
| 1007 | } | ||
| 1008 | uc_block_t; | ||
| 1009 | |||
| 1010 | /* Return the block a character belongs to. */ | ||
| 1011 | extern const uc_block_t * | ||
| 1012 | uc_block (ucs4_t uc) | ||
| 1013 | _UC_ATTRIBUTE_CONST; | ||
| 1014 | |||
| 1015 | /* Test whether a Unicode character belongs to a given block. */ | ||
| 1016 | extern bool | ||
| 1017 | uc_is_block (ucs4_t uc, const uc_block_t *block) | ||
| 1018 | _UC_ATTRIBUTE_PURE; | ||
| 1019 | |||
| 1020 | /* Get the list of all blocks. */ | ||
| 1021 | extern void | ||
| 1022 | uc_all_blocks (const uc_block_t **blocks, size_t *count); | ||
| 1023 | |||
| 1024 | /* ========================================================================= */ | ||
| 1025 | |||
| 1026 | /* Properties taken from language standards. */ | ||
| 1027 | |||
| 1028 | /* Test whether a Unicode character is considered whitespace in ISO C 99. */ | ||
| 1029 | extern bool | ||
| 1030 | uc_is_c_whitespace (ucs4_t uc) | ||
| 1031 | _UC_ATTRIBUTE_CONST; | ||
| 1032 | |||
| 1033 | /* Test whether a Unicode character is considered whitespace in Java. */ | ||
| 1034 | extern bool | ||
| 1035 | uc_is_java_whitespace (ucs4_t uc) | ||
| 1036 | _UC_ATTRIBUTE_CONST; | ||
| 1037 | |||
| 1038 | enum | ||
| 1039 | { | ||
| 1040 | UC_IDENTIFIER_START, /* valid as first or subsequent character */ | ||
| 1041 | UC_IDENTIFIER_VALID, /* valid as subsequent character only */ | ||
| 1042 | UC_IDENTIFIER_INVALID, /* not valid */ | ||
| 1043 | UC_IDENTIFIER_IGNORABLE /* ignorable (Java only) */ | ||
| 1044 | }; | ||
| 1045 | |||
| 1046 | /* Return the categorization of a Unicode character w.r.t. the ISO C 99 | ||
| 1047 | identifier syntax. */ | ||
| 1048 | extern int | ||
| 1049 | uc_c_ident_category (ucs4_t uc) | ||
| 1050 | _UC_ATTRIBUTE_CONST; | ||
| 1051 | |||
| 1052 | /* Return the categorization of a Unicode character w.r.t. the Java | ||
| 1053 | identifier syntax. */ | ||
| 1054 | extern int | ||
| 1055 | uc_java_ident_category (ucs4_t uc) | ||
| 1056 | _UC_ATTRIBUTE_CONST; | ||
| 1057 | |||
| 1058 | /* ========================================================================= */ | ||
| 1059 | |||
| 1060 | /* Like ISO C <ctype.h> and <wctype.h>. These functions are deprecated, | ||
| 1061 | because this set of functions was designed with ASCII in mind and cannot | ||
| 1062 | reflect the more diverse reality of the Unicode character set. But they | ||
| 1063 | can be a quick-and-dirty porting aid when migrating from wchar_t APIs | ||
| 1064 | to Unicode strings. */ | ||
| 1065 | |||
| 1066 | /* Test for any character for which 'uc_is_alpha' or 'uc_is_digit' is true. */ | ||
| 1067 | extern bool | ||
| 1068 | uc_is_alnum (ucs4_t uc) | ||
| 1069 | _UC_ATTRIBUTE_CONST; | ||
| 1070 | |||
| 1071 | /* Test for any character for which 'uc_is_upper' or 'uc_is_lower' is true, | ||
| 1072 | or any character that is one of a locale-specific set of characters for | ||
| 1073 | which none of 'uc_is_cntrl', 'uc_is_digit', 'uc_is_punct', or 'uc_is_space' | ||
| 1074 | is true. */ | ||
| 1075 | extern bool | ||
| 1076 | uc_is_alpha (ucs4_t uc) | ||
| 1077 | _UC_ATTRIBUTE_CONST; | ||
| 1078 | |||
| 1079 | /* Test for any control character. */ | ||
| 1080 | extern bool | ||
| 1081 | uc_is_cntrl (ucs4_t uc) | ||
| 1082 | _UC_ATTRIBUTE_CONST; | ||
| 1083 | |||
| 1084 | /* Test for any character that corresponds to a decimal-digit character. */ | ||
| 1085 | extern bool | ||
| 1086 | uc_is_digit (ucs4_t uc) | ||
| 1087 | _UC_ATTRIBUTE_CONST; | ||
| 1088 | |||
| 1089 | /* Test for any character for which 'uc_is_print' is true and 'uc_is_space' | ||
| 1090 | is false. */ | ||
| 1091 | extern bool | ||
| 1092 | uc_is_graph (ucs4_t uc) | ||
| 1093 | _UC_ATTRIBUTE_CONST; | ||
| 1094 | |||
| 1095 | /* Test for any character that corresponds to a lowercase letter or is one | ||
| 1096 | of a locale-specific set of characters for which none of 'uc_is_cntrl', | ||
| 1097 | 'uc_is_digit', 'uc_is_punct', or 'uc_is_space' is true. */ | ||
| 1098 | extern bool | ||
| 1099 | uc_is_lower (ucs4_t uc) | ||
| 1100 | _UC_ATTRIBUTE_CONST; | ||
| 1101 | |||
| 1102 | /* Test for any printing character. */ | ||
| 1103 | extern bool | ||
| 1104 | uc_is_print (ucs4_t uc) | ||
| 1105 | _UC_ATTRIBUTE_CONST; | ||
| 1106 | |||
| 1107 | /* Test for any printing character that is one of a locale-specific set of | ||
| 1108 | characters for which neither 'uc_is_space' nor 'uc_is_alnum' is true. */ | ||
| 1109 | extern bool | ||
| 1110 | uc_is_punct (ucs4_t uc) | ||
| 1111 | _UC_ATTRIBUTE_CONST; | ||
| 1112 | |||
| 1113 | /* Test for any character that corresponds to a locale-specific set of | ||
| 1114 | characters for which none of 'uc_is_alnum', 'uc_is_graph', or 'uc_is_punct' | ||
| 1115 | is true. */ | ||
| 1116 | extern bool | ||
| 1117 | uc_is_space (ucs4_t uc) | ||
| 1118 | _UC_ATTRIBUTE_CONST; | ||
| 1119 | |||
| 1120 | /* Test for any character that corresponds to an uppercase letter or is one | ||
| 1121 | of a locale-specific set of character for which none of 'uc_is_cntrl', | ||
| 1122 | 'uc_is_digit', 'uc_is_punct', or 'uc_is_space' is true. */ | ||
| 1123 | extern bool | ||
| 1124 | uc_is_upper (ucs4_t uc) | ||
| 1125 | _UC_ATTRIBUTE_CONST; | ||
| 1126 | |||
| 1127 | /* Test for any character that corresponds to a hexadecimal-digit | ||
| 1128 | character. */ | ||
| 1129 | extern bool | ||
| 1130 | uc_is_xdigit (ucs4_t uc) | ||
| 1131 | _UC_ATTRIBUTE_CONST; | ||
| 1132 | |||
| 1133 | /* GNU extension. */ | ||
| 1134 | /* Test for any character that corresponds to a standard blank character or | ||
| 1135 | a locale-specific set of characters for which 'uc_is_alnum' is false. */ | ||
| 1136 | extern bool | ||
| 1137 | uc_is_blank (ucs4_t uc) | ||
| 1138 | _UC_ATTRIBUTE_CONST; | ||
| 1139 | |||
| 1140 | /* ========================================================================= */ | ||
| 1141 | |||
| 1142 | #ifdef __cplusplus | ||
| 1143 | } | ||
| 1144 | #endif | ||
| 1145 | |||
| 1146 | #endif /* _UNICTYPE_H */ | ||
diff --git a/gl/unictype/.deps/.dirstamp b/gl/unictype/.deps/.dirstamp new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/gl/unictype/.deps/.dirstamp | |||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_alnum.Po b/gl/unictype/.deps/libgnu_a-ctype_alnum.Po new file mode 100644 index 00000000..429d1968 --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_alnum.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_alnum.o: unictype/ctype_alnum.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_alnum.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_alnum.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_alpha.Po b/gl/unictype/.deps/libgnu_a-ctype_alpha.Po new file mode 100644 index 00000000..f2d01713 --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_alpha.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_alpha.o: unictype/ctype_alpha.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_alpha.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_alpha.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_blank.Po b/gl/unictype/.deps/libgnu_a-ctype_blank.Po new file mode 100644 index 00000000..82be4126 --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_blank.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_blank.o: unictype/ctype_blank.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_blank.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_blank.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_cntrl.Po b/gl/unictype/.deps/libgnu_a-ctype_cntrl.Po new file mode 100644 index 00000000..dfb2233d --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_cntrl.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_cntrl.o: unictype/ctype_cntrl.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_cntrl.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_cntrl.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_digit.Po b/gl/unictype/.deps/libgnu_a-ctype_digit.Po new file mode 100644 index 00000000..d243fcc1 --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_digit.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_digit.o: unictype/ctype_digit.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_digit.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_digit.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_graph.Po b/gl/unictype/.deps/libgnu_a-ctype_graph.Po new file mode 100644 index 00000000..9850fe6f --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_graph.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_graph.o: unictype/ctype_graph.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_graph.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_graph.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_lower.Po b/gl/unictype/.deps/libgnu_a-ctype_lower.Po new file mode 100644 index 00000000..6447d3e4 --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_lower.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_lower.o: unictype/ctype_lower.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_lower.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_lower.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_print.Po b/gl/unictype/.deps/libgnu_a-ctype_print.Po new file mode 100644 index 00000000..f592e16c --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_print.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_print.o: unictype/ctype_print.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_print.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_print.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_punct.Po b/gl/unictype/.deps/libgnu_a-ctype_punct.Po new file mode 100644 index 00000000..245e5396 --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_punct.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_punct.o: unictype/ctype_punct.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_punct.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_punct.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_space.Po b/gl/unictype/.deps/libgnu_a-ctype_space.Po new file mode 100644 index 00000000..2b51c518 --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_space.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_space.o: unictype/ctype_space.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_space.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_space.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_upper.Po b/gl/unictype/.deps/libgnu_a-ctype_upper.Po new file mode 100644 index 00000000..3395834f --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_upper.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_upper.o: unictype/ctype_upper.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_upper.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_upper.h: | ||
diff --git a/gl/unictype/.deps/libgnu_a-ctype_xdigit.Po b/gl/unictype/.deps/libgnu_a-ctype_xdigit.Po new file mode 100644 index 00000000..3c05b331 --- /dev/null +++ b/gl/unictype/.deps/libgnu_a-ctype_xdigit.Po | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | unictype/libgnu_a-ctype_xdigit.o: unictype/ctype_xdigit.c \ | ||
| 2 | /usr/include/stdc-predef.h ../config.h unictype.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h stddef.h \ | ||
| 20 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h unictype/bitmap.h \ | ||
| 21 | unictype/ctype_xdigit.h | ||
| 22 | /usr/include/stdc-predef.h: | ||
| 23 | ../config.h: | ||
| 24 | unictype.h: | ||
| 25 | unitypes.h: | ||
| 26 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 27 | /usr/include/stdint.h: | ||
| 28 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 29 | /usr/include/features.h: | ||
| 30 | /usr/include/features-time64.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 32 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 33 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 44 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdbool.h: | ||
| 45 | stddef.h: | ||
| 46 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 47 | unictype/bitmap.h: | ||
| 48 | unictype/ctype_xdigit.h: | ||
diff --git a/gl/unictype/.dirstamp b/gl/unictype/.dirstamp new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/gl/unictype/.dirstamp | |||
diff --git a/gl/unictype/bitmap.h b/gl/unictype/bitmap.h new file mode 100644 index 00000000..869ac066 --- /dev/null +++ b/gl/unictype/bitmap.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* Three-level bitmap lookup. | ||
| 2 | Copyright (C) 2000-2002, 2005-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2000-2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | static inline int bitmap_lookup (const void *table, ucs4_t uc); | ||
| 19 | |||
| 20 | /* These values are currently hardcoded into gen-uni-tables.c, function | ||
| 21 | output_predicate(). */ | ||
| 22 | #define header_0 16 | ||
| 23 | #define header_2 9 | ||
| 24 | #define header_3 127 | ||
| 25 | #define header_4 15 | ||
| 26 | |||
| 27 | static inline int | ||
| 28 | bitmap_lookup (const void *table, ucs4_t uc) | ||
| 29 | { | ||
| 30 | unsigned int index1 = uc >> header_0; | ||
| 31 | if (index1 < ((const int *) table)[0]) | ||
| 32 | { | ||
| 33 | int lookup1 = ((const int *) table)[1 + index1]; | ||
| 34 | if (lookup1 >= 0) | ||
| 35 | { | ||
| 36 | unsigned int index2 = (uc >> header_2) & header_3; | ||
| 37 | int lookup2 = ((const short *) table)[lookup1 + index2]; | ||
| 38 | if (lookup2 >= 0) | ||
| 39 | { | ||
| 40 | unsigned int index3 = (uc >> 5) & header_4; | ||
| 41 | unsigned int lookup3 = ((const unsigned int *) table)[lookup2 + index3]; | ||
| 42 | |||
| 43 | return (lookup3 >> (uc & 0x1f)) & 1; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | } | ||
| 47 | return 0; | ||
| 48 | } | ||
diff --git a/gl/unictype/ctype_alnum.c b/gl/unictype/ctype_alnum.c new file mode 100644 index 00000000..f58f4310 --- /dev/null +++ b/gl/unictype/ctype_alnum.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_alnum table. */ | ||
| 26 | #include "ctype_alnum.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_alnum (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_alnum, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_alnum.h b/gl/unictype/ctype_alnum.h new file mode 100644 index 00000000..3ee771ab --- /dev/null +++ b/gl/unictype/ctype_alnum.h | |||
| @@ -0,0 +1,897 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[4]; | ||
| 29 | short level2[4 << 7]; | ||
| 30 | unsigned int level3[85 << 4]; | ||
| 31 | } | ||
| 32 | u_is_alnum = | ||
| 33 | { | ||
| 34 | { 4 }, | ||
| 35 | { | ||
| 36 | 5 * sizeof (int) / sizeof (short) + 0, | ||
| 37 | 5 * sizeof (int) / sizeof (short) + 128, | ||
| 38 | 5 * sizeof (int) / sizeof (short) + 256, | ||
| 39 | 5 * sizeof (int) / sizeof (short) + 384 | ||
| 40 | }, | ||
| 41 | { | ||
| 42 | 5 + 512 * sizeof (short) / sizeof (int) + 0, | ||
| 43 | 5 + 512 * sizeof (short) / sizeof (int) + 16, | ||
| 44 | 5 + 512 * sizeof (short) / sizeof (int) + 32, | ||
| 45 | 5 + 512 * sizeof (short) / sizeof (int) + 48, | ||
| 46 | 5 + 512 * sizeof (short) / sizeof (int) + 64, | ||
| 47 | 5 + 512 * sizeof (short) / sizeof (int) + 80, | ||
| 48 | 5 + 512 * sizeof (short) / sizeof (int) + 96, | ||
| 49 | 5 + 512 * sizeof (short) / sizeof (int) + 112, | ||
| 50 | 5 + 512 * sizeof (short) / sizeof (int) + 128, | ||
| 51 | 5 + 512 * sizeof (short) / sizeof (int) + 144, | ||
| 52 | 5 + 512 * sizeof (short) / sizeof (int) + 160, | ||
| 53 | 5 + 512 * sizeof (short) / sizeof (int) + 176, | ||
| 54 | 5 + 512 * sizeof (short) / sizeof (int) + 192, | ||
| 55 | 5 + 512 * sizeof (short) / sizeof (int) + 208, | ||
| 56 | 5 + 512 * sizeof (short) / sizeof (int) + 224, | ||
| 57 | 5 + 512 * sizeof (short) / sizeof (int) + 240, | ||
| 58 | 5 + 512 * sizeof (short) / sizeof (int) + 256, | ||
| 59 | -1, | ||
| 60 | 5 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 61 | -1, | ||
| 62 | -1, | ||
| 63 | -1, | ||
| 64 | 5 + 512 * sizeof (short) / sizeof (int) + 288, | ||
| 65 | 5 + 512 * sizeof (short) / sizeof (int) + 304, | ||
| 66 | 5 + 512 * sizeof (short) / sizeof (int) + 320, | ||
| 67 | -1, | ||
| 68 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 69 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 70 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 71 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 72 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 73 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 74 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 75 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 76 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 77 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 78 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 79 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 80 | 5 + 512 * sizeof (short) / sizeof (int) + 352, | ||
| 81 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 82 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 83 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 84 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 85 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 86 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 87 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 88 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 89 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 90 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 91 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 92 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 93 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 94 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 95 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 96 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 97 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 98 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 99 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 100 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 101 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 102 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 103 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 104 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 105 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 106 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 107 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 108 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 109 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 110 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 111 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 112 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 113 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 114 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 115 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 116 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 117 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 118 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 119 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 120 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 121 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 122 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 123 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 124 | 5 + 512 * sizeof (short) / sizeof (int) + 368, | ||
| 125 | 5 + 512 * sizeof (short) / sizeof (int) + 384, | ||
| 126 | 5 + 512 * sizeof (short) / sizeof (int) + 400, | ||
| 127 | 5 + 512 * sizeof (short) / sizeof (int) + 416, | ||
| 128 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 129 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 130 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 131 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 132 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 133 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 134 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 135 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 136 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 137 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 138 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 139 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 140 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 141 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 142 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 143 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 144 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 145 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 146 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 147 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 148 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 149 | 5 + 512 * sizeof (short) / sizeof (int) + 432, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1, | ||
| 165 | -1, | ||
| 166 | 5 + 512 * sizeof (short) / sizeof (int) + 448, | ||
| 167 | 5 + 512 * sizeof (short) / sizeof (int) + 464, | ||
| 168 | 5 + 512 * sizeof (short) / sizeof (int) + 480, | ||
| 169 | 5 + 512 * sizeof (short) / sizeof (int) + 496, | ||
| 170 | 5 + 512 * sizeof (short) / sizeof (int) + 512, | ||
| 171 | 5 + 512 * sizeof (short) / sizeof (int) + 528, | ||
| 172 | 5 + 512 * sizeof (short) / sizeof (int) + 544, | ||
| 173 | 5 + 512 * sizeof (short) / sizeof (int) + 560, | ||
| 174 | 5 + 512 * sizeof (short) / sizeof (int) + 576, | ||
| 175 | 5 + 512 * sizeof (short) / sizeof (int) + 592, | ||
| 176 | 5 + 512 * sizeof (short) / sizeof (int) + 608, | ||
| 177 | 5 + 512 * sizeof (short) / sizeof (int) + 624, | ||
| 178 | 5 + 512 * sizeof (short) / sizeof (int) + 640, | ||
| 179 | 5 + 512 * sizeof (short) / sizeof (int) + 656, | ||
| 180 | 5 + 512 * sizeof (short) / sizeof (int) + 672, | ||
| 181 | 5 + 512 * sizeof (short) / sizeof (int) + 688, | ||
| 182 | 5 + 512 * sizeof (short) / sizeof (int) + 704, | ||
| 183 | 5 + 512 * sizeof (short) / sizeof (int) + 720, | ||
| 184 | 5 + 512 * sizeof (short) / sizeof (int) + 736, | ||
| 185 | 5 + 512 * sizeof (short) / sizeof (int) + 752, | ||
| 186 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 187 | 5 + 512 * sizeof (short) / sizeof (int) + 768, | ||
| 188 | 5 + 512 * sizeof (short) / sizeof (int) + 784, | ||
| 189 | -1, | ||
| 190 | -1, | ||
| 191 | -1, | ||
| 192 | -1, | ||
| 193 | 5 + 512 * sizeof (short) / sizeof (int) + 800, | ||
| 194 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 195 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 196 | 5 + 512 * sizeof (short) / sizeof (int) + 816, | ||
| 197 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 198 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 199 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 200 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 201 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 202 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 203 | 5 + 512 * sizeof (short) / sizeof (int) + 832, | ||
| 204 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 205 | 5 + 512 * sizeof (short) / sizeof (int) + 848, | ||
| 206 | -1, | ||
| 207 | -1, | ||
| 208 | -1, | ||
| 209 | -1, | ||
| 210 | -1, | ||
| 211 | -1, | ||
| 212 | -1, | ||
| 213 | -1, | ||
| 214 | -1, | ||
| 215 | -1, | ||
| 216 | -1, | ||
| 217 | -1, | ||
| 218 | 5 + 512 * sizeof (short) / sizeof (int) + 864, | ||
| 219 | -1, | ||
| 220 | -1, | ||
| 221 | -1, | ||
| 222 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 223 | 5 + 512 * sizeof (short) / sizeof (int) + 880, | ||
| 224 | 5 + 512 * sizeof (short) / sizeof (int) + 896, | ||
| 225 | 5 + 512 * sizeof (short) / sizeof (int) + 912, | ||
| 226 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 227 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 228 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 229 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 230 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 231 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 232 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 233 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 234 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 235 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 236 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 237 | 5 + 512 * sizeof (short) / sizeof (int) + 928, | ||
| 238 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 239 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 240 | 5 + 512 * sizeof (short) / sizeof (int) + 944, | ||
| 241 | -1, | ||
| 242 | -1, | ||
| 243 | -1, | ||
| 244 | -1, | ||
| 245 | -1, | ||
| 246 | -1, | ||
| 247 | -1, | ||
| 248 | -1, | ||
| 249 | -1, | ||
| 250 | -1, | ||
| 251 | -1, | ||
| 252 | -1, | ||
| 253 | -1, | ||
| 254 | -1, | ||
| 255 | -1, | ||
| 256 | -1, | ||
| 257 | 5 + 512 * sizeof (short) / sizeof (int) + 960, | ||
| 258 | 5 + 512 * sizeof (short) / sizeof (int) + 976, | ||
| 259 | 5 + 512 * sizeof (short) / sizeof (int) + 992, | ||
| 260 | -1, | ||
| 261 | -1, | ||
| 262 | -1, | ||
| 263 | -1, | ||
| 264 | 5 + 512 * sizeof (short) / sizeof (int) + 1008, | ||
| 265 | -1, | ||
| 266 | -1, | ||
| 267 | -1, | ||
| 268 | -1, | ||
| 269 | -1, | ||
| 270 | -1, | ||
| 271 | -1, | ||
| 272 | 5 + 512 * sizeof (short) / sizeof (int) + 1024, | ||
| 273 | -1, | ||
| 274 | -1, | ||
| 275 | -1, | ||
| 276 | 5 + 512 * sizeof (short) / sizeof (int) + 1040, | ||
| 277 | 5 + 512 * sizeof (short) / sizeof (int) + 1056, | ||
| 278 | -1, | ||
| 279 | -1, | ||
| 280 | -1, | ||
| 281 | 5 + 512 * sizeof (short) / sizeof (int) + 1072, | ||
| 282 | 5 + 512 * sizeof (short) / sizeof (int) + 1088, | ||
| 283 | 5 + 512 * sizeof (short) / sizeof (int) + 1104, | ||
| 284 | 5 + 512 * sizeof (short) / sizeof (int) + 1120, | ||
| 285 | 5 + 512 * sizeof (short) / sizeof (int) + 1136, | ||
| 286 | 5 + 512 * sizeof (short) / sizeof (int) + 1152, | ||
| 287 | -1, | ||
| 288 | -1, | ||
| 289 | 5 + 512 * sizeof (short) / sizeof (int) + 1168, | ||
| 290 | 5 + 512 * sizeof (short) / sizeof (int) + 1184, | ||
| 291 | -1, | ||
| 292 | -1, | ||
| 293 | -1, | ||
| 294 | -1, | ||
| 295 | 5 + 512 * sizeof (short) / sizeof (int) + 1200, | ||
| 296 | -1, | ||
| 297 | -1, | ||
| 298 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 299 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 300 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 301 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 302 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 303 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 304 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 305 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 306 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 307 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 308 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 309 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 310 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 311 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 312 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 313 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 314 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 315 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 316 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 317 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 318 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 319 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 320 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 321 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 322 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 323 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 324 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 325 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 326 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 327 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 328 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 329 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 330 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 331 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 332 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 333 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 334 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 335 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 336 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 337 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 338 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 339 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 340 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 341 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 342 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 343 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 344 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 345 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 346 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 347 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 348 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 349 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 350 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 351 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 352 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 353 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 354 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 355 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 356 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 357 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 358 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 359 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 360 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 361 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 362 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 363 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 364 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 365 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 366 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 367 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 368 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 369 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 370 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 371 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 372 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 373 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 374 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 375 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 376 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 377 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 378 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 379 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 380 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 381 | 5 + 512 * sizeof (short) / sizeof (int) + 1216, | ||
| 382 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 383 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 384 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 385 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 386 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 387 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 388 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 389 | 5 + 512 * sizeof (short) / sizeof (int) + 1232, | ||
| 390 | 5 + 512 * sizeof (short) / sizeof (int) + 1248, | ||
| 391 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 392 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 393 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 394 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 395 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 396 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 397 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 398 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 399 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 400 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 401 | 5 + 512 * sizeof (short) / sizeof (int) + 1264, | ||
| 402 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 403 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 404 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 405 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 406 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 407 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 408 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 409 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 410 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 411 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 412 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 413 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 414 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 415 | 5 + 512 * sizeof (short) / sizeof (int) + 1280, | ||
| 416 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 417 | 5 + 512 * sizeof (short) / sizeof (int) + 1296, | ||
| 418 | -1, | ||
| 419 | -1, | ||
| 420 | -1, | ||
| 421 | -1, | ||
| 422 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 423 | 5 + 512 * sizeof (short) / sizeof (int) + 1312, | ||
| 424 | -1, | ||
| 425 | -1, | ||
| 426 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 427 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 428 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 429 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 430 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 431 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 432 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 433 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 434 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 435 | 5 + 512 * sizeof (short) / sizeof (int) + 1328, | ||
| 436 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 437 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 438 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 439 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 440 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 441 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 442 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 443 | 5 + 512 * sizeof (short) / sizeof (int) + 1344, | ||
| 444 | -1, | ||
| 445 | -1, | ||
| 446 | -1, | ||
| 447 | -1, | ||
| 448 | -1, | ||
| 449 | -1, | ||
| 450 | -1, | ||
| 451 | -1, | ||
| 452 | -1, | ||
| 453 | -1, | ||
| 454 | -1, | ||
| 455 | -1, | ||
| 456 | -1, | ||
| 457 | -1, | ||
| 458 | -1, | ||
| 459 | -1, | ||
| 460 | -1, | ||
| 461 | -1, | ||
| 462 | -1, | ||
| 463 | -1, | ||
| 464 | -1, | ||
| 465 | -1, | ||
| 466 | -1, | ||
| 467 | -1, | ||
| 468 | -1, | ||
| 469 | -1, | ||
| 470 | -1, | ||
| 471 | -1, | ||
| 472 | -1, | ||
| 473 | -1, | ||
| 474 | -1, | ||
| 475 | -1, | ||
| 476 | -1, | ||
| 477 | -1, | ||
| 478 | -1, | ||
| 479 | -1, | ||
| 480 | -1, | ||
| 481 | -1, | ||
| 482 | -1, | ||
| 483 | -1, | ||
| 484 | -1, | ||
| 485 | -1, | ||
| 486 | -1, | ||
| 487 | -1, | ||
| 488 | -1, | ||
| 489 | -1, | ||
| 490 | -1, | ||
| 491 | -1, | ||
| 492 | -1, | ||
| 493 | -1, | ||
| 494 | -1, | ||
| 495 | -1, | ||
| 496 | -1, | ||
| 497 | -1, | ||
| 498 | -1, | ||
| 499 | -1, | ||
| 500 | -1, | ||
| 501 | -1, | ||
| 502 | -1, | ||
| 503 | -1, | ||
| 504 | -1, | ||
| 505 | -1, | ||
| 506 | -1, | ||
| 507 | -1, | ||
| 508 | -1, | ||
| 509 | -1, | ||
| 510 | -1, | ||
| 511 | -1, | ||
| 512 | -1, | ||
| 513 | -1, | ||
| 514 | -1, | ||
| 515 | -1, | ||
| 516 | -1, | ||
| 517 | -1, | ||
| 518 | -1, | ||
| 519 | -1, | ||
| 520 | -1, | ||
| 521 | -1, | ||
| 522 | -1, | ||
| 523 | -1, | ||
| 524 | -1, | ||
| 525 | -1, | ||
| 526 | -1, | ||
| 527 | -1, | ||
| 528 | -1, | ||
| 529 | -1, | ||
| 530 | -1, | ||
| 531 | -1, | ||
| 532 | -1, | ||
| 533 | -1, | ||
| 534 | -1, | ||
| 535 | -1, | ||
| 536 | -1, | ||
| 537 | -1, | ||
| 538 | -1, | ||
| 539 | -1, | ||
| 540 | -1, | ||
| 541 | -1, | ||
| 542 | -1, | ||
| 543 | -1, | ||
| 544 | -1, | ||
| 545 | -1, | ||
| 546 | -1, | ||
| 547 | -1, | ||
| 548 | -1, | ||
| 549 | -1, | ||
| 550 | -1, | ||
| 551 | -1, | ||
| 552 | -1, | ||
| 553 | -1 | ||
| 554 | }, | ||
| 555 | { | ||
| 556 | 0x00000000U, 0x03FF0000U, 0x07FFFFFEU, 0x07FFFFFEU, | ||
| 557 | 0x00000000U, 0x04200400U, 0xFF7FFFFFU, 0xFF7FFFFFU, | ||
| 558 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 559 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 560 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 561 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0003FFC3U, 0x0000501FU, | ||
| 562 | 0x00000000U, 0x00000000U, 0x00000020U, 0xBCDF0000U, | ||
| 563 | 0xFFFFD740U, 0xFFFFFFFBU, 0xFFFFFFFFU, 0xFFBFFFFFU, | ||
| 564 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 565 | 0xFFFFFC03U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 566 | 0xFFFFFFFFU, 0xFFFEFFFFU, 0x027FFFFFU, 0xFFFFFFFFU, | ||
| 567 | 0x000001FFU, 0x00000000U, 0xFFFF0000U, 0x000787FFU, | ||
| 568 | 0x00000000U, 0xFFFFFFFFU, 0x000007FFU, 0xFFFEC3FFU, | ||
| 569 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x002FFFFFU, 0x9FFFC060U, | ||
| 570 | 0xFFFD0000U, 0x0000FFFFU, 0xFFFFE000U, 0xFFFFFFFFU, | ||
| 571 | 0xFFFFFFFFU, 0x0002003FU, 0xFFFFFFFFU, 0x043007FFU, | ||
| 572 | 0x043FFFFFU, 0x00000110U, 0x01FFFFFFU, 0xFFFF07FFU, | ||
| 573 | 0x00007EFFU, 0xFFFFFFFFU, 0x000003FFU, 0x00000000U, | ||
| 574 | 0xFFFFFFF0U, 0x23FFFFFFU, 0xFF010000U, 0xFFFEFFC3U, | ||
| 575 | 0xFFF99FE1U, 0x23C5FDFFU, 0xB0004000U, 0x1003FFC3U, | ||
| 576 | 0xFFF987E0U, 0x036DFDFFU, 0x5E000000U, 0x001CFFC0U, | ||
| 577 | 0xFFFBBFE0U, 0x23EDFDFFU, 0x00010000U, 0x0200FFC3U, | ||
| 578 | 0xFFF99FE0U, 0x23EDFDFFU, 0xB0000000U, 0x0002FFC3U, | ||
| 579 | 0xD63DC7E8U, 0x03FFC718U, 0x00010000U, 0x0000FFC0U, | ||
| 580 | 0xFFFDDFE0U, 0x23FFFDFFU, 0x27000000U, 0x0000FFC3U, | ||
| 581 | 0xFFFDDFE1U, 0x23EFFDFFU, 0x60000000U, 0x0006FFC3U, | ||
| 582 | 0xFFFDDFF0U, 0x27FFFFFFU, 0x80704000U, 0xFC00FFC3U, | ||
| 583 | 0xFC7FFFE0U, 0x2FFBFFFFU, 0x0000007FU, 0x0000FFC0U, | ||
| 584 | 0xFFFFFFFEU, 0x07FF7FFFU, 0x03FF7FBFU, 0x00000000U, | ||
| 585 | 0xFFFFF7D6U, 0x200DFFAFU, 0xF3FF005FU, 0x00000000U, | ||
| 586 | 0x00000001U, 0x000003FFU, 0xFFFFFEFFU, 0x00001FFFU, | ||
| 587 | 0x00001F00U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 588 | 0xFFFFFFFFU, 0x800007FFU, 0x3C3F03FFU, 0xFFE1C062U, | ||
| 589 | 0x03FF4003U, 0xFFFFFFFFU, 0xFFFF20BFU, 0xF7FFFFFFU, | ||
| 590 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 591 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 592 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3D7F3DFFU, 0xFFFFFFFFU, | ||
| 593 | 0xFFFF3DFFU, 0x7F3DFFFFU, 0xFF7FFF3DU, 0xFFFFFFFFU, | ||
| 594 | 0xFF3DFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, 0x00000000U, | ||
| 595 | 0x0000FFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3F3FFFFFU, | ||
| 596 | 0xFFFFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 597 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 598 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 599 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 600 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF9FFFU, | ||
| 601 | 0x07FFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x01FFC7FFU, | ||
| 602 | 0x8003FFFFU, 0x0003FFFFU, 0x0003FFFFU, 0x0001DFFFU, | ||
| 603 | 0xFFFFFFFFU, 0x000FFFFFU, 0x10800000U, 0x000003FFU, | ||
| 604 | 0x03FF0000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 605 | 0xFFFFFF9FU, 0xFFFF05FFU, 0xFFFFFFFFU, 0x003FFFFFU, | ||
| 606 | 0x7FFFFFFFU, 0x00000000U, 0xFFFFFFC0U, 0x001F3FFFU, | ||
| 607 | 0xFFFFFFFFU, 0xFFFF0FFFU, 0x03FF03FFU, 0x00000000U, | ||
| 608 | 0x007FFFFFU, 0xFFFFFFFFU, 0x001FFFFFU, 0x00000000U, | ||
| 609 | 0x03FF03FFU, 0x00000080U, 0x00000000U, 0x00000000U, | ||
| 610 | 0xFFFFFFE0U, 0x000FFFFFU, 0x03FF1FE0U, 0x00000000U, | ||
| 611 | 0xFFFFFFF8U, 0xFFFFC001U, 0xFFFFFFFFU, 0x0000003FU, | ||
| 612 | 0xFFFFFFFFU, 0x0000000FU, 0xFFFFE3FFU, 0x3FFFFFFFU, | ||
| 613 | 0xFFFF07FFU, 0xE7FFFFFFU, 0x00000000U, 0x046FDE00U, | ||
| 614 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 615 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 616 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 617 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 618 | 0x3F3FFFFFU, 0xFFFFFFFFU, 0xAAFF3F3FU, 0x3FFFFFFFU, | ||
| 619 | 0xFFFFFFFFU, 0x5FDFFFFFU, 0x0FCF1FDCU, 0x1FDC1FFFU, | ||
| 620 | 0x00000000U, 0x00000000U, 0x00000000U, 0x80020000U, | ||
| 621 | 0x1FFF0000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 622 | 0x3E2FFC84U, 0xF3FFBF50U, 0x000043E0U, 0xFFFFFFFFU, | ||
| 623 | 0x000001FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 624 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 625 | 0xF0000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000003FFU, | ||
| 626 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 627 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 628 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 629 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000C781FU, | ||
| 630 | 0xFFFFFFFFU, 0xFFFF20BFU, 0xFFFFFFFFU, 0x000080FFU, | ||
| 631 | 0x007FFFFFU, 0x7F7F7F7FU, 0x7F7F7F7FU, 0x00000000U, | ||
| 632 | 0x00000000U, 0x00008000U, 0x00000000U, 0x00000000U, | ||
| 633 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 634 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 635 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 636 | 0x000000E0U, 0x1F3E03FEU, 0xFFFFFFFEU, 0xFFFFFFFFU, | ||
| 637 | 0xE07FFFFFU, 0xFFFFFFFEU, 0xFFFFFFFFU, 0xF7FFFFFFU, | ||
| 638 | 0xFFFFFFE0U, 0xFFFEFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 639 | 0x00007FFFU, 0xFFFFFFFFU, 0x00000000U, 0xFFFF0000U, | ||
| 640 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 641 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 642 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 643 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 644 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 645 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 646 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 647 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 648 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 649 | 0x00001FFFU, 0x00000000U, 0xFFFF0000U, 0x3FFFFFFFU, | ||
| 650 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 651 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 652 | 0xFFFF1FFFU, 0x00000FFFU, 0xFFFFFFFFU, 0x80007FFFU, | ||
| 653 | 0x3FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, | ||
| 654 | 0xFF800000U, 0xFFFFFFFCU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 655 | 0xFFFFF9FFU, 0xFFFFFFFFU, 0x1FEB3FFFU, 0xFFFC0000U, | ||
| 656 | 0xFFFFF7BBU, 0x00000007U, 0xFFFFFFFFU, 0x000FFFFFU, | ||
| 657 | 0xFFFFFFFCU, 0x000FFFFFU, 0x03FF0000U, 0x68FC0000U, | ||
| 658 | 0xFFFFFFFFU, 0xFFFF003FU, 0x0000007FU, 0x1FFFFFFFU, | ||
| 659 | 0xFFFFFFF0U, 0x0007FFFFU, 0x03FF8000U, 0x7FFFFFDFU, | ||
| 660 | 0xFFFFFFFFU, 0x000001FFU, 0x03FF0FF7U, 0xC47FFFFFU, | ||
| 661 | 0xFFFFFFFFU, 0x3E62FFFFU, 0x38000005U, 0x001C07FFU, | ||
| 662 | 0x007E7E7EU, 0xFFFF7F7FU, 0xF7FFFFFFU, 0xFFFF03FFU, | ||
| 663 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF0007U, | ||
| 664 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 665 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 666 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 667 | 0xFFFFFFFFU, 0xFFFF000FU, 0xFFFFF87FU, 0x0FFFFFFFU, | ||
| 668 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 669 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 670 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 671 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 672 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF3FFFU, | ||
| 673 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, 0x00000000U, | ||
| 674 | 0xA0F8007FU, 0x5F7FFDFFU, 0xFFFFFFDBU, 0xFFFFFFFFU, | ||
| 675 | 0xFFFFFFFFU, 0x0003FFFFU, 0xFFF80000U, 0xFFFFFFFFU, | ||
| 676 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 677 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 678 | 0xFFFFFFFFU, 0x3FFFFFFFU, 0xFFFF0000U, 0xFFFFFFFFU, | ||
| 679 | 0xFFFCFFFFU, 0xFFFFFFFFU, 0x000000FFU, 0x0FFF0000U, | ||
| 680 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFFDF0000U, | ||
| 681 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x1FFFFFFFU, | ||
| 682 | 0x03FF0000U, 0x07FFFFFEU, 0x07FFFFFEU, 0xFFFFFFC0U, | ||
| 683 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0x1CFCFCFCU, 0x00000000U, | ||
| 684 | 0xFFFFEFFFU, 0xB7FFFF7FU, 0x3FFF3FFFU, 0x00000000U, | ||
| 685 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, | ||
| 686 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x001FFFFFU, | ||
| 687 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 688 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 689 | 0x1FFFFFFFU, 0xFFFFFFFFU, 0x0001FFFFU, 0x00000000U, | ||
| 690 | 0xFFFFFFFFU, 0xFFFFE000U, 0xFFFF07FFU, 0x003FFFFFU, | ||
| 691 | 0x3FFFFFFFU, 0xFFFFFFFFU, 0x003EFF0FU, 0x00000000U, | ||
| 692 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 693 | 0x3FFFFFFFU, 0xFFFF03FFU, 0xFF0FFFFFU, 0x0FFFFFFFU, | ||
| 694 | 0xFFFFFFFFU, 0xFFFF00FFU, 0xFFFFFFFFU, 0xF7FF000FU, | ||
| 695 | 0xFFB7F7FFU, 0x1BFBFFFBU, 0xFFFFFFFFU, 0x000FFFFFU, | ||
| 696 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 697 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 698 | 0xFFFFFFFFU, 0x007FFFFFU, 0x003FFFFFU, 0x000000FFU, | ||
| 699 | 0xFFFFFFBFU, 0x07FDFFFFU, 0x00000000U, 0x00000000U, | ||
| 700 | 0xFFFFFD3FU, 0x91BFFFFFU, 0x003FFFFFU, 0x007FFFFFU, | ||
| 701 | 0x7FFFFFFFU, 0x00000000U, 0x00000000U, 0x0037FFFFU, | ||
| 702 | 0x003FFFFFU, 0x03FFFFFFU, 0x00000000U, 0x00000000U, | ||
| 703 | 0xFFFFFFFFU, 0xC0FFFFFFU, 0x00000000U, 0x00000000U, | ||
| 704 | 0xFEEF0001U, 0x003FFFFFU, 0x00000000U, 0x1FFFFFFFU, | ||
| 705 | 0x1FFFFFFFU, 0x00000000U, 0xFFFFFEFFU, 0x0000001FU, | ||
| 706 | 0xFFFFFFFFU, 0x003FFFFFU, 0x003FFFFFU, 0x0007FFFFU, | ||
| 707 | 0x0003FFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 708 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000001FFU, 0x00000000U, | ||
| 709 | 0xFFFFFFFFU, 0x0007FFFFU, 0xFFFFFFFFU, 0x0007FFFFU, | ||
| 710 | 0xFFFFFFFFU, 0x03FF000FU, 0xFFFFFFFFU, 0xFFFF803FU, | ||
| 711 | 0x0000003FU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 712 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 713 | 0xFFFFFFFFU, 0x000303FFU, 0x0000001CU, 0x00000000U, | ||
| 714 | 0x1FFFFFFFU, 0xFFFF0080U, 0x0000003FU, 0xFFFF0000U, | ||
| 715 | 0x00000003U, 0xFFFF0000U, 0x0000001FU, 0x007FFFFFU, | ||
| 716 | 0xFFFFFFF8U, 0x00FFFFFFU, 0x00000000U, 0x0026FFC0U, | ||
| 717 | 0xFFFFFFF8U, 0x0000FFFFU, 0xFFFF0000U, 0x03FF01FFU, | ||
| 718 | 0xFFFFFFF8U, 0xFFC0007FU, 0xFFFF0090U, 0x0047FFFFU, | ||
| 719 | 0xFFFFFFF8U, 0x0007FFFFU, 0x17FF001EU, 0x00000000U, | ||
| 720 | 0xFFFBFFFFU, 0x80000FFFU, 0x00000001U, 0x00000000U, | ||
| 721 | 0xBFFFBD7FU, 0xFFFF01FFU, 0x7FFFFFFFU, 0x03FF0000U, | ||
| 722 | 0xFFF99FE0U, 0x23EDFDFFU, 0xE0010000U, 0x00000003U, | ||
| 723 | 0xFFFF4BFFU, 0x00BFFFFFU, 0x000A0000U, 0x00000000U, | ||
| 724 | 0xFFFFFFFFU, 0x001FFFFFU, 0x83FF0780U, 0x00000003U, | ||
| 725 | 0xFFFFFFFFU, 0x0000FFFFU, 0x03FF00B0U, 0x00000000U, | ||
| 726 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 727 | 0xFFFFFFFFU, 0x00007FFFU, 0x0F000000U, 0x00000000U, | ||
| 728 | 0xFFFFFFFFU, 0x0000FFFFU, 0x03FF0010U, 0x00000000U, | ||
| 729 | 0xFFFFFFFFU, 0x010007FFU, 0xFFFF03FFU, 0x0000000FU, | ||
| 730 | 0x07FFFFFFU, 0x03FF0000U, 0x0000007FU, 0x00000000U, | ||
| 731 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 732 | 0xFFFFFFFFU, 0x00000FFFU, 0x00000000U, 0x00000000U, | ||
| 733 | 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x800003FFU, | ||
| 734 | 0xFF6FF27FU, 0x8000FFFFU, 0x03FF0002U, 0x00000000U, | ||
| 735 | 0x00000000U, 0xFFFFFCFFU, 0x0001FFFFU, 0x0000000AU, | ||
| 736 | 0xFFFFF801U, 0x0407FFFFU, 0xF0010000U, 0xFFFFFFFFU, | ||
| 737 | 0x200003FFU, 0xFFFF0000U, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 738 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 739 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x03FF0001U, | ||
| 740 | 0xFFFFFDFFU, 0x00007FFFU, 0x03FF0001U, 0xFFFC0000U, | ||
| 741 | 0x0000FFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 742 | 0xFFFFFB7FU, 0x0001FFFFU, 0x03FF0040U, 0xFFFFFDBFU, | ||
| 743 | 0x010003FFU, 0x000003FFU, 0x00000000U, 0x00000000U, | ||
| 744 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 745 | 0x00000000U, 0x00000000U, 0x00000000U, 0x0007FFFFU, | ||
| 746 | 0xFFFDFFF4U, 0x000FFFFFU, 0x03FF0000U, 0x00000000U, | ||
| 747 | 0x00000000U, 0x00010000U, 0x00000000U, 0x00000000U, | ||
| 748 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 749 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 750 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 751 | 0x03FFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 752 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00007FFFU, | ||
| 753 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 754 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, | ||
| 755 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 756 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 757 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 758 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 759 | 0xFFFF0000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0001FFFFU, | ||
| 760 | 0xFFFFFFFFU, 0x0000FFFFU, 0x0000007EU, 0xFFFFFFFFU, | ||
| 761 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 762 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 763 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 764 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 765 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 766 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 767 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, | ||
| 768 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000007FU, 0x00000000U, | ||
| 769 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 770 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 771 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 772 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 773 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 774 | 0x3FFFFFFFU, 0x03FF0000U, 0x00000000U, 0x00000000U, | ||
| 775 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 776 | 0xFFFFFFFFU, 0x01FFFFFFU, 0x7FFFFFFFU, 0xFFFF03FFU, | ||
| 777 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0xFFFF03FFU, 0x00003FFFU, | ||
| 778 | 0xFFFFFFFFU, 0x0000FFFFU, 0x03FF000FU, 0xE0FFFFF8U, | ||
| 779 | 0x0000FFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 780 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 781 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 782 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x03FF1FFFU, | ||
| 783 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 784 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 785 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 786 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000107FFU, 0x00000000U, | ||
| 787 | 0xFFF80000U, 0x00000000U, 0x00000000U, 0x0000000BU, | ||
| 788 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 789 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 790 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 791 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00FFFFFFU, | ||
| 792 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 793 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0x80000000U, | ||
| 794 | 0x000001FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 795 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 796 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 797 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 798 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 799 | 0x00000000U, 0x00000000U, 0x00000000U, 0x6FEF0000U, | ||
| 800 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 801 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 802 | 0xFFFFFFFFU, 0x00040007U, 0x00270000U, 0xFFFF00F0U, | ||
| 803 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 804 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 805 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0FFFFFFFU, | ||
| 806 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 807 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 808 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x1FFF07FFU, | ||
| 809 | 0x03FF01FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 810 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 811 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 812 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 813 | 0x00000000U, 0x00000000U, 0xFFC00000U, 0x03FFFFFFU, | ||
| 814 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 815 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 816 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFDFFFFFU, 0xFFFFFFFFU, | ||
| 817 | 0xDFFFFFFFU, 0xEBFFDE64U, 0xFFFFFFEFU, 0xFFFFFFFFU, | ||
| 818 | 0xDFDFE7BFU, 0x7BFFFFFFU, 0xFFFDFC5FU, 0xFFFFFFFFU, | ||
| 819 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 820 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 821 | 0xFFFFFFFFU, 0xFFFFFF3FU, 0xF7FFFFFDU, 0xF7FFFFFFU, | ||
| 822 | 0xFFDFFFFFU, 0xFFDFFFFFU, 0xFFFF7FFFU, 0xFFFF7FFFU, | ||
| 823 | 0xFFFFFDFFU, 0xFFFFFDFFU, 0xFFFFCFF7U, 0xFFFFFFFFU, | ||
| 824 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 825 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 826 | 0x7FFFFFFFU, 0x000007E0U, 0x00000000U, 0x00000000U, | ||
| 827 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 828 | 0x00000000U, 0xFFFF0000U, 0xFFFFFFFFU, 0x00003FFFU, | ||
| 829 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 830 | 0xFFFFFFFFU, 0x3F801FFFU, 0x000043FFU, 0x00000000U, | ||
| 831 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 832 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 833 | 0xFFFF0000U, 0x00003FFFU, 0xFFFFFFFFU, 0x03FF0FFFU, | ||
| 834 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 835 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 836 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 837 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x03FF0FFFU, | ||
| 838 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 839 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x07FF3FFFU, | ||
| 840 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 841 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 842 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 843 | 0x00000000U, 0x00000000U, 0x00000000U, 0x7FFF6F7FU, | ||
| 844 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 845 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000001FU, 0x00000000U, | ||
| 846 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF080FU, 0x00000000U, | ||
| 847 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 848 | 0xFFFFFFEFU, 0x0AF7FE96U, 0xAA96EA84U, 0x5EF7F796U, | ||
| 849 | 0x0FFFFBFFU, 0x0FFFFBEEU, 0x00000000U, 0x00000000U, | ||
| 850 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 851 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 852 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 853 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 854 | 0xFFFF0000U, 0xFFFF1FFFU, 0xFFFF03FFU, 0xFFFF03FFU, | ||
| 855 | 0x000007FFU, 0x00000020U, 0x00000000U, 0xFFFFFFC0U, | ||
| 856 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 857 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 858 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 859 | 0x00000000U, 0x00000000U, 0x00000000U, 0x03FF0000U, | ||
| 860 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 861 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, | ||
| 862 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 863 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 864 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 865 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 866 | 0xFFFFFFFFU, 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 867 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 868 | 0x3FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 869 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 870 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 871 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 872 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 873 | 0xFFFFFFFFU, 0xFFFF0003U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 874 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 875 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 876 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 877 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 878 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 879 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF0001U, | ||
| 880 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU, 0x00000000U, | ||
| 881 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 882 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 883 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 884 | 0x3FFFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 885 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 886 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 887 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 888 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 889 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 890 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF07FFU, 0xFFFFFFFFU, | ||
| 891 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 892 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 893 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 894 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 895 | 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, 0x00000000U | ||
| 896 | } | ||
| 897 | }; | ||
diff --git a/gl/unictype/ctype_alpha.c b/gl/unictype/ctype_alpha.c new file mode 100644 index 00000000..c422fec6 --- /dev/null +++ b/gl/unictype/ctype_alpha.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_alpha table. */ | ||
| 26 | #include "ctype_alpha.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_alpha (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_alpha, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_alpha.h b/gl/unictype/ctype_alpha.h new file mode 100644 index 00000000..cd129cb9 --- /dev/null +++ b/gl/unictype/ctype_alpha.h | |||
| @@ -0,0 +1,897 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[4]; | ||
| 29 | short level2[4 << 7]; | ||
| 30 | unsigned int level3[85 << 4]; | ||
| 31 | } | ||
| 32 | u_is_alpha = | ||
| 33 | { | ||
| 34 | { 4 }, | ||
| 35 | { | ||
| 36 | 5 * sizeof (int) / sizeof (short) + 0, | ||
| 37 | 5 * sizeof (int) / sizeof (short) + 128, | ||
| 38 | 5 * sizeof (int) / sizeof (short) + 256, | ||
| 39 | 5 * sizeof (int) / sizeof (short) + 384 | ||
| 40 | }, | ||
| 41 | { | ||
| 42 | 5 + 512 * sizeof (short) / sizeof (int) + 0, | ||
| 43 | 5 + 512 * sizeof (short) / sizeof (int) + 16, | ||
| 44 | 5 + 512 * sizeof (short) / sizeof (int) + 32, | ||
| 45 | 5 + 512 * sizeof (short) / sizeof (int) + 48, | ||
| 46 | 5 + 512 * sizeof (short) / sizeof (int) + 64, | ||
| 47 | 5 + 512 * sizeof (short) / sizeof (int) + 80, | ||
| 48 | 5 + 512 * sizeof (short) / sizeof (int) + 96, | ||
| 49 | 5 + 512 * sizeof (short) / sizeof (int) + 112, | ||
| 50 | 5 + 512 * sizeof (short) / sizeof (int) + 128, | ||
| 51 | 5 + 512 * sizeof (short) / sizeof (int) + 144, | ||
| 52 | 5 + 512 * sizeof (short) / sizeof (int) + 160, | ||
| 53 | 5 + 512 * sizeof (short) / sizeof (int) + 176, | ||
| 54 | 5 + 512 * sizeof (short) / sizeof (int) + 192, | ||
| 55 | 5 + 512 * sizeof (short) / sizeof (int) + 208, | ||
| 56 | 5 + 512 * sizeof (short) / sizeof (int) + 224, | ||
| 57 | 5 + 512 * sizeof (short) / sizeof (int) + 240, | ||
| 58 | 5 + 512 * sizeof (short) / sizeof (int) + 256, | ||
| 59 | -1, | ||
| 60 | 5 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 61 | -1, | ||
| 62 | -1, | ||
| 63 | -1, | ||
| 64 | 5 + 512 * sizeof (short) / sizeof (int) + 288, | ||
| 65 | 5 + 512 * sizeof (short) / sizeof (int) + 304, | ||
| 66 | 5 + 512 * sizeof (short) / sizeof (int) + 320, | ||
| 67 | -1, | ||
| 68 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 69 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 70 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 71 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 72 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 73 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 74 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 75 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 76 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 77 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 78 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 79 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 80 | 5 + 512 * sizeof (short) / sizeof (int) + 352, | ||
| 81 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 82 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 83 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 84 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 85 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 86 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 87 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 88 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 89 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 90 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 91 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 92 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 93 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 94 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 95 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 96 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 97 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 98 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 99 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 100 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 101 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 102 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 103 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 104 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 105 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 106 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 107 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 108 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 109 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 110 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 111 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 112 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 113 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 114 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 115 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 116 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 117 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 118 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 119 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 120 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 121 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 122 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 123 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 124 | 5 + 512 * sizeof (short) / sizeof (int) + 368, | ||
| 125 | 5 + 512 * sizeof (short) / sizeof (int) + 384, | ||
| 126 | 5 + 512 * sizeof (short) / sizeof (int) + 400, | ||
| 127 | 5 + 512 * sizeof (short) / sizeof (int) + 416, | ||
| 128 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 129 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 130 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 131 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 132 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 133 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 134 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 135 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 136 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 137 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 138 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 139 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 140 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 141 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 142 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 143 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 144 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 145 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 146 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 147 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 148 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 149 | 5 + 512 * sizeof (short) / sizeof (int) + 432, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1, | ||
| 165 | -1, | ||
| 166 | 5 + 512 * sizeof (short) / sizeof (int) + 448, | ||
| 167 | 5 + 512 * sizeof (short) / sizeof (int) + 464, | ||
| 168 | 5 + 512 * sizeof (short) / sizeof (int) + 480, | ||
| 169 | 5 + 512 * sizeof (short) / sizeof (int) + 496, | ||
| 170 | 5 + 512 * sizeof (short) / sizeof (int) + 512, | ||
| 171 | 5 + 512 * sizeof (short) / sizeof (int) + 528, | ||
| 172 | 5 + 512 * sizeof (short) / sizeof (int) + 544, | ||
| 173 | 5 + 512 * sizeof (short) / sizeof (int) + 560, | ||
| 174 | 5 + 512 * sizeof (short) / sizeof (int) + 576, | ||
| 175 | 5 + 512 * sizeof (short) / sizeof (int) + 592, | ||
| 176 | 5 + 512 * sizeof (short) / sizeof (int) + 608, | ||
| 177 | 5 + 512 * sizeof (short) / sizeof (int) + 624, | ||
| 178 | 5 + 512 * sizeof (short) / sizeof (int) + 640, | ||
| 179 | 5 + 512 * sizeof (short) / sizeof (int) + 656, | ||
| 180 | 5 + 512 * sizeof (short) / sizeof (int) + 672, | ||
| 181 | 5 + 512 * sizeof (short) / sizeof (int) + 688, | ||
| 182 | 5 + 512 * sizeof (short) / sizeof (int) + 704, | ||
| 183 | 5 + 512 * sizeof (short) / sizeof (int) + 720, | ||
| 184 | 5 + 512 * sizeof (short) / sizeof (int) + 736, | ||
| 185 | 5 + 512 * sizeof (short) / sizeof (int) + 752, | ||
| 186 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 187 | 5 + 512 * sizeof (short) / sizeof (int) + 768, | ||
| 188 | 5 + 512 * sizeof (short) / sizeof (int) + 784, | ||
| 189 | -1, | ||
| 190 | -1, | ||
| 191 | -1, | ||
| 192 | -1, | ||
| 193 | 5 + 512 * sizeof (short) / sizeof (int) + 800, | ||
| 194 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 195 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 196 | 5 + 512 * sizeof (short) / sizeof (int) + 816, | ||
| 197 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 198 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 199 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 200 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 201 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 202 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 203 | 5 + 512 * sizeof (short) / sizeof (int) + 832, | ||
| 204 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 205 | 5 + 512 * sizeof (short) / sizeof (int) + 848, | ||
| 206 | -1, | ||
| 207 | -1, | ||
| 208 | -1, | ||
| 209 | -1, | ||
| 210 | -1, | ||
| 211 | -1, | ||
| 212 | -1, | ||
| 213 | -1, | ||
| 214 | -1, | ||
| 215 | -1, | ||
| 216 | -1, | ||
| 217 | -1, | ||
| 218 | 5 + 512 * sizeof (short) / sizeof (int) + 864, | ||
| 219 | -1, | ||
| 220 | -1, | ||
| 221 | -1, | ||
| 222 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 223 | 5 + 512 * sizeof (short) / sizeof (int) + 880, | ||
| 224 | 5 + 512 * sizeof (short) / sizeof (int) + 896, | ||
| 225 | 5 + 512 * sizeof (short) / sizeof (int) + 912, | ||
| 226 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 227 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 228 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 229 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 230 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 231 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 232 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 233 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 234 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 235 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 236 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 237 | 5 + 512 * sizeof (short) / sizeof (int) + 928, | ||
| 238 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 239 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 240 | 5 + 512 * sizeof (short) / sizeof (int) + 944, | ||
| 241 | -1, | ||
| 242 | -1, | ||
| 243 | -1, | ||
| 244 | -1, | ||
| 245 | -1, | ||
| 246 | -1, | ||
| 247 | -1, | ||
| 248 | -1, | ||
| 249 | -1, | ||
| 250 | -1, | ||
| 251 | -1, | ||
| 252 | -1, | ||
| 253 | -1, | ||
| 254 | -1, | ||
| 255 | -1, | ||
| 256 | -1, | ||
| 257 | 5 + 512 * sizeof (short) / sizeof (int) + 960, | ||
| 258 | 5 + 512 * sizeof (short) / sizeof (int) + 976, | ||
| 259 | 5 + 512 * sizeof (short) / sizeof (int) + 992, | ||
| 260 | -1, | ||
| 261 | -1, | ||
| 262 | -1, | ||
| 263 | -1, | ||
| 264 | 5 + 512 * sizeof (short) / sizeof (int) + 1008, | ||
| 265 | -1, | ||
| 266 | -1, | ||
| 267 | -1, | ||
| 268 | -1, | ||
| 269 | -1, | ||
| 270 | -1, | ||
| 271 | -1, | ||
| 272 | 5 + 512 * sizeof (short) / sizeof (int) + 1024, | ||
| 273 | -1, | ||
| 274 | -1, | ||
| 275 | -1, | ||
| 276 | 5 + 512 * sizeof (short) / sizeof (int) + 1040, | ||
| 277 | 5 + 512 * sizeof (short) / sizeof (int) + 1056, | ||
| 278 | -1, | ||
| 279 | -1, | ||
| 280 | -1, | ||
| 281 | 5 + 512 * sizeof (short) / sizeof (int) + 1072, | ||
| 282 | 5 + 512 * sizeof (short) / sizeof (int) + 1088, | ||
| 283 | 5 + 512 * sizeof (short) / sizeof (int) + 1104, | ||
| 284 | 5 + 512 * sizeof (short) / sizeof (int) + 1120, | ||
| 285 | 5 + 512 * sizeof (short) / sizeof (int) + 1136, | ||
| 286 | 5 + 512 * sizeof (short) / sizeof (int) + 1152, | ||
| 287 | -1, | ||
| 288 | -1, | ||
| 289 | 5 + 512 * sizeof (short) / sizeof (int) + 1168, | ||
| 290 | 5 + 512 * sizeof (short) / sizeof (int) + 1184, | ||
| 291 | -1, | ||
| 292 | -1, | ||
| 293 | -1, | ||
| 294 | -1, | ||
| 295 | 5 + 512 * sizeof (short) / sizeof (int) + 1200, | ||
| 296 | -1, | ||
| 297 | -1, | ||
| 298 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 299 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 300 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 301 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 302 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 303 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 304 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 305 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 306 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 307 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 308 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 309 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 310 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 311 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 312 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 313 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 314 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 315 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 316 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 317 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 318 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 319 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 320 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 321 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 322 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 323 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 324 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 325 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 326 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 327 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 328 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 329 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 330 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 331 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 332 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 333 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 334 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 335 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 336 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 337 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 338 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 339 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 340 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 341 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 342 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 343 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 344 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 345 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 346 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 347 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 348 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 349 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 350 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 351 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 352 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 353 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 354 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 355 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 356 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 357 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 358 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 359 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 360 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 361 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 362 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 363 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 364 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 365 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 366 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 367 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 368 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 369 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 370 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 371 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 372 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 373 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 374 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 375 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 376 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 377 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 378 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 379 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 380 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 381 | 5 + 512 * sizeof (short) / sizeof (int) + 1216, | ||
| 382 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 383 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 384 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 385 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 386 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 387 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 388 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 389 | 5 + 512 * sizeof (short) / sizeof (int) + 1232, | ||
| 390 | 5 + 512 * sizeof (short) / sizeof (int) + 1248, | ||
| 391 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 392 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 393 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 394 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 395 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 396 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 397 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 398 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 399 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 400 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 401 | 5 + 512 * sizeof (short) / sizeof (int) + 1264, | ||
| 402 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 403 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 404 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 405 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 406 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 407 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 408 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 409 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 410 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 411 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 412 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 413 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 414 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 415 | 5 + 512 * sizeof (short) / sizeof (int) + 1280, | ||
| 416 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 417 | 5 + 512 * sizeof (short) / sizeof (int) + 1296, | ||
| 418 | -1, | ||
| 419 | -1, | ||
| 420 | -1, | ||
| 421 | -1, | ||
| 422 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 423 | 5 + 512 * sizeof (short) / sizeof (int) + 1312, | ||
| 424 | -1, | ||
| 425 | -1, | ||
| 426 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 427 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 428 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 429 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 430 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 431 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 432 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 433 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 434 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 435 | 5 + 512 * sizeof (short) / sizeof (int) + 1328, | ||
| 436 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 437 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 438 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 439 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 440 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 441 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 442 | 5 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 443 | 5 + 512 * sizeof (short) / sizeof (int) + 1344, | ||
| 444 | -1, | ||
| 445 | -1, | ||
| 446 | -1, | ||
| 447 | -1, | ||
| 448 | -1, | ||
| 449 | -1, | ||
| 450 | -1, | ||
| 451 | -1, | ||
| 452 | -1, | ||
| 453 | -1, | ||
| 454 | -1, | ||
| 455 | -1, | ||
| 456 | -1, | ||
| 457 | -1, | ||
| 458 | -1, | ||
| 459 | -1, | ||
| 460 | -1, | ||
| 461 | -1, | ||
| 462 | -1, | ||
| 463 | -1, | ||
| 464 | -1, | ||
| 465 | -1, | ||
| 466 | -1, | ||
| 467 | -1, | ||
| 468 | -1, | ||
| 469 | -1, | ||
| 470 | -1, | ||
| 471 | -1, | ||
| 472 | -1, | ||
| 473 | -1, | ||
| 474 | -1, | ||
| 475 | -1, | ||
| 476 | -1, | ||
| 477 | -1, | ||
| 478 | -1, | ||
| 479 | -1, | ||
| 480 | -1, | ||
| 481 | -1, | ||
| 482 | -1, | ||
| 483 | -1, | ||
| 484 | -1, | ||
| 485 | -1, | ||
| 486 | -1, | ||
| 487 | -1, | ||
| 488 | -1, | ||
| 489 | -1, | ||
| 490 | -1, | ||
| 491 | -1, | ||
| 492 | -1, | ||
| 493 | -1, | ||
| 494 | -1, | ||
| 495 | -1, | ||
| 496 | -1, | ||
| 497 | -1, | ||
| 498 | -1, | ||
| 499 | -1, | ||
| 500 | -1, | ||
| 501 | -1, | ||
| 502 | -1, | ||
| 503 | -1, | ||
| 504 | -1, | ||
| 505 | -1, | ||
| 506 | -1, | ||
| 507 | -1, | ||
| 508 | -1, | ||
| 509 | -1, | ||
| 510 | -1, | ||
| 511 | -1, | ||
| 512 | -1, | ||
| 513 | -1, | ||
| 514 | -1, | ||
| 515 | -1, | ||
| 516 | -1, | ||
| 517 | -1, | ||
| 518 | -1, | ||
| 519 | -1, | ||
| 520 | -1, | ||
| 521 | -1, | ||
| 522 | -1, | ||
| 523 | -1, | ||
| 524 | -1, | ||
| 525 | -1, | ||
| 526 | -1, | ||
| 527 | -1, | ||
| 528 | -1, | ||
| 529 | -1, | ||
| 530 | -1, | ||
| 531 | -1, | ||
| 532 | -1, | ||
| 533 | -1, | ||
| 534 | -1, | ||
| 535 | -1, | ||
| 536 | -1, | ||
| 537 | -1, | ||
| 538 | -1, | ||
| 539 | -1, | ||
| 540 | -1, | ||
| 541 | -1, | ||
| 542 | -1, | ||
| 543 | -1, | ||
| 544 | -1, | ||
| 545 | -1, | ||
| 546 | -1, | ||
| 547 | -1, | ||
| 548 | -1, | ||
| 549 | -1, | ||
| 550 | -1, | ||
| 551 | -1, | ||
| 552 | -1, | ||
| 553 | -1 | ||
| 554 | }, | ||
| 555 | { | ||
| 556 | 0x00000000U, 0x00000000U, 0x07FFFFFEU, 0x07FFFFFEU, | ||
| 557 | 0x00000000U, 0x04200400U, 0xFF7FFFFFU, 0xFF7FFFFFU, | ||
| 558 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 559 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 560 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 561 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0003FFC3U, 0x0000501FU, | ||
| 562 | 0x00000000U, 0x00000000U, 0x00000020U, 0xBCDF0000U, | ||
| 563 | 0xFFFFD740U, 0xFFFFFFFBU, 0xFFFFFFFFU, 0xFFBFFFFFU, | ||
| 564 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 565 | 0xFFFFFC03U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 566 | 0xFFFFFFFFU, 0xFFFEFFFFU, 0x027FFFFFU, 0xFFFFFFFFU, | ||
| 567 | 0x000001FFU, 0x00000000U, 0xFFFF0000U, 0x000787FFU, | ||
| 568 | 0x00000000U, 0xFFFFFFFFU, 0x000007FFU, 0xFFFEC3FFU, | ||
| 569 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x002FFFFFU, 0x9FFFC060U, | ||
| 570 | 0xFFFD0000U, 0x0000FFFFU, 0xFFFFE000U, 0xFFFFFFFFU, | ||
| 571 | 0xFFFFFFFFU, 0x0002003FU, 0xFFFFFFFFU, 0x043007FFU, | ||
| 572 | 0x043FFFFFU, 0x00000110U, 0x01FFFFFFU, 0xFFFF07FFU, | ||
| 573 | 0x00007EFFU, 0xFFFFFFFFU, 0x000003FFU, 0x00000000U, | ||
| 574 | 0xFFFFFFF0U, 0x23FFFFFFU, 0xFF010000U, 0xFFFEFFC3U, | ||
| 575 | 0xFFF99FE1U, 0x23C5FDFFU, 0xB0004000U, 0x1003FFC3U, | ||
| 576 | 0xFFF987E0U, 0x036DFDFFU, 0x5E000000U, 0x001CFFC0U, | ||
| 577 | 0xFFFBBFE0U, 0x23EDFDFFU, 0x00010000U, 0x0200FFC3U, | ||
| 578 | 0xFFF99FE0U, 0x23EDFDFFU, 0xB0000000U, 0x0002FFC3U, | ||
| 579 | 0xD63DC7E8U, 0x03FFC718U, 0x00010000U, 0x0000FFC0U, | ||
| 580 | 0xFFFDDFE0U, 0x23FFFDFFU, 0x27000000U, 0x0000FFC3U, | ||
| 581 | 0xFFFDDFE1U, 0x23EFFDFFU, 0x60000000U, 0x0006FFC3U, | ||
| 582 | 0xFFFDDFF0U, 0x27FFFFFFU, 0x80704000U, 0xFC00FFC3U, | ||
| 583 | 0xFC7FFFE0U, 0x2FFBFFFFU, 0x0000007FU, 0x0000FFC0U, | ||
| 584 | 0xFFFFFFFEU, 0x07FF7FFFU, 0x03FF7FBFU, 0x00000000U, | ||
| 585 | 0xFFFFF7D6U, 0x200DFFAFU, 0xF3FF005FU, 0x00000000U, | ||
| 586 | 0x00000001U, 0x000003FFU, 0xFFFFFEFFU, 0x00001FFFU, | ||
| 587 | 0x00001F00U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 588 | 0xFFFFFFFFU, 0x800007FFU, 0x3C3F03FFU, 0xFFE1C062U, | ||
| 589 | 0x03FF4003U, 0xFFFFFFFFU, 0xFFFF20BFU, 0xF7FFFFFFU, | ||
| 590 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 591 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 592 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3D7F3DFFU, 0xFFFFFFFFU, | ||
| 593 | 0xFFFF3DFFU, 0x7F3DFFFFU, 0xFF7FFF3DU, 0xFFFFFFFFU, | ||
| 594 | 0xFF3DFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, 0x00000000U, | ||
| 595 | 0x0000FFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3F3FFFFFU, | ||
| 596 | 0xFFFFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 597 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 598 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 599 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 600 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF9FFFU, | ||
| 601 | 0x07FFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x01FFC7FFU, | ||
| 602 | 0x8003FFFFU, 0x0003FFFFU, 0x0003FFFFU, 0x0001DFFFU, | ||
| 603 | 0xFFFFFFFFU, 0x000FFFFFU, 0x10800000U, 0x000003FFU, | ||
| 604 | 0x03FF0000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 605 | 0xFFFFFF9FU, 0xFFFF05FFU, 0xFFFFFFFFU, 0x003FFFFFU, | ||
| 606 | 0x7FFFFFFFU, 0x00000000U, 0xFFFFFFC0U, 0x001F3FFFU, | ||
| 607 | 0xFFFFFFFFU, 0xFFFF0FFFU, 0x03FF03FFU, 0x00000000U, | ||
| 608 | 0x007FFFFFU, 0xFFFFFFFFU, 0x001FFFFFU, 0x00000000U, | ||
| 609 | 0x03FF03FFU, 0x00000080U, 0x00000000U, 0x00000000U, | ||
| 610 | 0xFFFFFFE0U, 0x000FFFFFU, 0x03FF1FE0U, 0x00000000U, | ||
| 611 | 0xFFFFFFF8U, 0xFFFFC001U, 0xFFFFFFFFU, 0x0000003FU, | ||
| 612 | 0xFFFFFFFFU, 0x0000000FU, 0xFFFFE3FFU, 0x3FFFFFFFU, | ||
| 613 | 0xFFFF07FFU, 0xE7FFFFFFU, 0x00000000U, 0x046FDE00U, | ||
| 614 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 615 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 616 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 617 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 618 | 0x3F3FFFFFU, 0xFFFFFFFFU, 0xAAFF3F3FU, 0x3FFFFFFFU, | ||
| 619 | 0xFFFFFFFFU, 0x5FDFFFFFU, 0x0FCF1FDCU, 0x1FDC1FFFU, | ||
| 620 | 0x00000000U, 0x00000000U, 0x00000000U, 0x80020000U, | ||
| 621 | 0x1FFF0000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 622 | 0x3E2FFC84U, 0xF3FFBF50U, 0x000043E0U, 0xFFFFFFFFU, | ||
| 623 | 0x000001FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 624 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 625 | 0xF0000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000003FFU, | ||
| 626 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 627 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 628 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 629 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000C781FU, | ||
| 630 | 0xFFFFFFFFU, 0xFFFF20BFU, 0xFFFFFFFFU, 0x000080FFU, | ||
| 631 | 0x007FFFFFU, 0x7F7F7F7FU, 0x7F7F7F7FU, 0x00000000U, | ||
| 632 | 0x00000000U, 0x00008000U, 0x00000000U, 0x00000000U, | ||
| 633 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 634 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 635 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 636 | 0x000000E0U, 0x1F3E03FEU, 0xFFFFFFFEU, 0xFFFFFFFFU, | ||
| 637 | 0xE07FFFFFU, 0xFFFFFFFEU, 0xFFFFFFFFU, 0xF7FFFFFFU, | ||
| 638 | 0xFFFFFFE0U, 0xFFFEFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 639 | 0x00007FFFU, 0xFFFFFFFFU, 0x00000000U, 0xFFFF0000U, | ||
| 640 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 641 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 642 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 643 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 644 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 645 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 646 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 647 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 648 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 649 | 0x00001FFFU, 0x00000000U, 0xFFFF0000U, 0x3FFFFFFFU, | ||
| 650 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 651 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 652 | 0xFFFF1FFFU, 0x00000FFFU, 0xFFFFFFFFU, 0x80007FFFU, | ||
| 653 | 0x3FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, | ||
| 654 | 0xFF800000U, 0xFFFFFFFCU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 655 | 0xFFFFF9FFU, 0xFFFFFFFFU, 0x1FEB3FFFU, 0xFFFC0000U, | ||
| 656 | 0xFFFFF7BBU, 0x00000007U, 0xFFFFFFFFU, 0x000FFFFFU, | ||
| 657 | 0xFFFFFFFCU, 0x000FFFFFU, 0x03FF0000U, 0x68FC0000U, | ||
| 658 | 0xFFFFFFFFU, 0xFFFF003FU, 0x0000007FU, 0x1FFFFFFFU, | ||
| 659 | 0xFFFFFFF0U, 0x0007FFFFU, 0x03FF8000U, 0x7FFFFFDFU, | ||
| 660 | 0xFFFFFFFFU, 0x000001FFU, 0x03FF0FF7U, 0xC47FFFFFU, | ||
| 661 | 0xFFFFFFFFU, 0x3E62FFFFU, 0x38000005U, 0x001C07FFU, | ||
| 662 | 0x007E7E7EU, 0xFFFF7F7FU, 0xF7FFFFFFU, 0xFFFF03FFU, | ||
| 663 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF0007U, | ||
| 664 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 665 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 666 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 667 | 0xFFFFFFFFU, 0xFFFF000FU, 0xFFFFF87FU, 0x0FFFFFFFU, | ||
| 668 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 669 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 670 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 671 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 672 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF3FFFU, | ||
| 673 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, 0x00000000U, | ||
| 674 | 0xA0F8007FU, 0x5F7FFDFFU, 0xFFFFFFDBU, 0xFFFFFFFFU, | ||
| 675 | 0xFFFFFFFFU, 0x0003FFFFU, 0xFFF80000U, 0xFFFFFFFFU, | ||
| 676 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 677 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 678 | 0xFFFFFFFFU, 0x3FFFFFFFU, 0xFFFF0000U, 0xFFFFFFFFU, | ||
| 679 | 0xFFFCFFFFU, 0xFFFFFFFFU, 0x000000FFU, 0x0FFF0000U, | ||
| 680 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFFDF0000U, | ||
| 681 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x1FFFFFFFU, | ||
| 682 | 0x03FF0000U, 0x07FFFFFEU, 0x07FFFFFEU, 0xFFFFFFC0U, | ||
| 683 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0x1CFCFCFCU, 0x00000000U, | ||
| 684 | 0xFFFFEFFFU, 0xB7FFFF7FU, 0x3FFF3FFFU, 0x00000000U, | ||
| 685 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, | ||
| 686 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x001FFFFFU, | ||
| 687 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 688 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 689 | 0x1FFFFFFFU, 0xFFFFFFFFU, 0x0001FFFFU, 0x00000000U, | ||
| 690 | 0xFFFFFFFFU, 0xFFFFE000U, 0xFFFF07FFU, 0x003FFFFFU, | ||
| 691 | 0x3FFFFFFFU, 0xFFFFFFFFU, 0x003EFF0FU, 0x00000000U, | ||
| 692 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 693 | 0x3FFFFFFFU, 0xFFFF03FFU, 0xFF0FFFFFU, 0x0FFFFFFFU, | ||
| 694 | 0xFFFFFFFFU, 0xFFFF00FFU, 0xFFFFFFFFU, 0xF7FF000FU, | ||
| 695 | 0xFFB7F7FFU, 0x1BFBFFFBU, 0xFFFFFFFFU, 0x000FFFFFU, | ||
| 696 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 697 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 698 | 0xFFFFFFFFU, 0x007FFFFFU, 0x003FFFFFU, 0x000000FFU, | ||
| 699 | 0xFFFFFFBFU, 0x07FDFFFFU, 0x00000000U, 0x00000000U, | ||
| 700 | 0xFFFFFD3FU, 0x91BFFFFFU, 0x003FFFFFU, 0x007FFFFFU, | ||
| 701 | 0x7FFFFFFFU, 0x00000000U, 0x00000000U, 0x0037FFFFU, | ||
| 702 | 0x003FFFFFU, 0x03FFFFFFU, 0x00000000U, 0x00000000U, | ||
| 703 | 0xFFFFFFFFU, 0xC0FFFFFFU, 0x00000000U, 0x00000000U, | ||
| 704 | 0xFEEF0001U, 0x003FFFFFU, 0x00000000U, 0x1FFFFFFFU, | ||
| 705 | 0x1FFFFFFFU, 0x00000000U, 0xFFFFFEFFU, 0x0000001FU, | ||
| 706 | 0xFFFFFFFFU, 0x003FFFFFU, 0x003FFFFFU, 0x0007FFFFU, | ||
| 707 | 0x0003FFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 708 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000001FFU, 0x00000000U, | ||
| 709 | 0xFFFFFFFFU, 0x0007FFFFU, 0xFFFFFFFFU, 0x0007FFFFU, | ||
| 710 | 0xFFFFFFFFU, 0x03FF000FU, 0xFFFFFFFFU, 0xFFFF803FU, | ||
| 711 | 0x0000003FU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 712 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 713 | 0xFFFFFFFFU, 0x000303FFU, 0x0000001CU, 0x00000000U, | ||
| 714 | 0x1FFFFFFFU, 0xFFFF0080U, 0x0000003FU, 0xFFFF0000U, | ||
| 715 | 0x00000003U, 0xFFFF0000U, 0x0000001FU, 0x007FFFFFU, | ||
| 716 | 0xFFFFFFF8U, 0x00FFFFFFU, 0x00000000U, 0x0026FFC0U, | ||
| 717 | 0xFFFFFFF8U, 0x0000FFFFU, 0xFFFF0000U, 0x03FF01FFU, | ||
| 718 | 0xFFFFFFF8U, 0xFFC0007FU, 0xFFFF0090U, 0x0047FFFFU, | ||
| 719 | 0xFFFFFFF8U, 0x0007FFFFU, 0x17FF001EU, 0x00000000U, | ||
| 720 | 0xFFFBFFFFU, 0x80000FFFU, 0x00000001U, 0x00000000U, | ||
| 721 | 0xBFFFBD7FU, 0xFFFF01FFU, 0x7FFFFFFFU, 0x03FF0000U, | ||
| 722 | 0xFFF99FE0U, 0x23EDFDFFU, 0xE0010000U, 0x00000003U, | ||
| 723 | 0xFFFF4BFFU, 0x00BFFFFFU, 0x000A0000U, 0x00000000U, | ||
| 724 | 0xFFFFFFFFU, 0x001FFFFFU, 0x83FF0780U, 0x00000003U, | ||
| 725 | 0xFFFFFFFFU, 0x0000FFFFU, 0x03FF00B0U, 0x00000000U, | ||
| 726 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 727 | 0xFFFFFFFFU, 0x00007FFFU, 0x0F000000U, 0x00000000U, | ||
| 728 | 0xFFFFFFFFU, 0x0000FFFFU, 0x03FF0010U, 0x00000000U, | ||
| 729 | 0xFFFFFFFFU, 0x010007FFU, 0xFFFF03FFU, 0x0000000FU, | ||
| 730 | 0x07FFFFFFU, 0x03FF0000U, 0x0000007FU, 0x00000000U, | ||
| 731 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 732 | 0xFFFFFFFFU, 0x00000FFFU, 0x00000000U, 0x00000000U, | ||
| 733 | 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x800003FFU, | ||
| 734 | 0xFF6FF27FU, 0x8000FFFFU, 0x03FF0002U, 0x00000000U, | ||
| 735 | 0x00000000U, 0xFFFFFCFFU, 0x0001FFFFU, 0x0000000AU, | ||
| 736 | 0xFFFFF801U, 0x0407FFFFU, 0xF0010000U, 0xFFFFFFFFU, | ||
| 737 | 0x200003FFU, 0xFFFF0000U, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 738 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 739 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x03FF0001U, | ||
| 740 | 0xFFFFFDFFU, 0x00007FFFU, 0x03FF0001U, 0xFFFC0000U, | ||
| 741 | 0x0000FFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 742 | 0xFFFFFB7FU, 0x0001FFFFU, 0x03FF0040U, 0xFFFFFDBFU, | ||
| 743 | 0x010003FFU, 0x000003FFU, 0x00000000U, 0x00000000U, | ||
| 744 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 745 | 0x00000000U, 0x00000000U, 0x00000000U, 0x0007FFFFU, | ||
| 746 | 0xFFFDFFF4U, 0x000FFFFFU, 0x03FF0000U, 0x00000000U, | ||
| 747 | 0x00000000U, 0x00010000U, 0x00000000U, 0x00000000U, | ||
| 748 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 749 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 750 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 751 | 0x03FFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 752 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00007FFFU, | ||
| 753 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 754 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, | ||
| 755 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 756 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 757 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 758 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 759 | 0xFFFF0000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0001FFFFU, | ||
| 760 | 0xFFFFFFFFU, 0x0000FFFFU, 0x0000007EU, 0xFFFFFFFFU, | ||
| 761 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 762 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 763 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 764 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 765 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 766 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 767 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, | ||
| 768 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000007FU, 0x00000000U, | ||
| 769 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 770 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 771 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 772 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 773 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 774 | 0x3FFFFFFFU, 0x03FF0000U, 0x00000000U, 0x00000000U, | ||
| 775 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 776 | 0xFFFFFFFFU, 0x01FFFFFFU, 0x7FFFFFFFU, 0xFFFF03FFU, | ||
| 777 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0xFFFF03FFU, 0x00003FFFU, | ||
| 778 | 0xFFFFFFFFU, 0x0000FFFFU, 0x03FF000FU, 0xE0FFFFF8U, | ||
| 779 | 0x0000FFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 780 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 781 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 782 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x03FF1FFFU, | ||
| 783 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 784 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 785 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 786 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000107FFU, 0x00000000U, | ||
| 787 | 0xFFF80000U, 0x00000000U, 0x00000000U, 0x0000000BU, | ||
| 788 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 789 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 790 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 791 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00FFFFFFU, | ||
| 792 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 793 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0x80000000U, | ||
| 794 | 0x000001FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 795 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 796 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 797 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 798 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 799 | 0x00000000U, 0x00000000U, 0x00000000U, 0x6FEF0000U, | ||
| 800 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 801 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 802 | 0xFFFFFFFFU, 0x00040007U, 0x00270000U, 0xFFFF00F0U, | ||
| 803 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 804 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 805 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0FFFFFFFU, | ||
| 806 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 807 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 808 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x1FFF07FFU, | ||
| 809 | 0x03FF01FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 810 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 811 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 812 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 813 | 0x00000000U, 0x00000000U, 0xFFC00000U, 0x03FFFFFFU, | ||
| 814 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 815 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 816 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFDFFFFFU, 0xFFFFFFFFU, | ||
| 817 | 0xDFFFFFFFU, 0xEBFFDE64U, 0xFFFFFFEFU, 0xFFFFFFFFU, | ||
| 818 | 0xDFDFE7BFU, 0x7BFFFFFFU, 0xFFFDFC5FU, 0xFFFFFFFFU, | ||
| 819 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 820 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 821 | 0xFFFFFFFFU, 0xFFFFFF3FU, 0xF7FFFFFDU, 0xF7FFFFFFU, | ||
| 822 | 0xFFDFFFFFU, 0xFFDFFFFFU, 0xFFFF7FFFU, 0xFFFF7FFFU, | ||
| 823 | 0xFFFFFDFFU, 0xFFFFFDFFU, 0xFFFFCFF7U, 0xFFFFFFFFU, | ||
| 824 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 825 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 826 | 0x7FFFFFFFU, 0x000007E0U, 0x00000000U, 0x00000000U, | ||
| 827 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 828 | 0x00000000U, 0xFFFF0000U, 0xFFFFFFFFU, 0x00003FFFU, | ||
| 829 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 830 | 0xFFFFFFFFU, 0x3F801FFFU, 0x000043FFU, 0x00000000U, | ||
| 831 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 832 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 833 | 0xFFFF0000U, 0x00003FFFU, 0xFFFFFFFFU, 0x03FF0FFFU, | ||
| 834 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 835 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 836 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 837 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x03FF0FFFU, | ||
| 838 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 839 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x07FF3FFFU, | ||
| 840 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 841 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 842 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 843 | 0x00000000U, 0x00000000U, 0x00000000U, 0x7FFF6F7FU, | ||
| 844 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 845 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000001FU, 0x00000000U, | ||
| 846 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF080FU, 0x00000000U, | ||
| 847 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 848 | 0xFFFFFFEFU, 0x0AF7FE96U, 0xAA96EA84U, 0x5EF7F796U, | ||
| 849 | 0x0FFFFBFFU, 0x0FFFFBEEU, 0x00000000U, 0x00000000U, | ||
| 850 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 851 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 852 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 853 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 854 | 0xFFFF0000U, 0xFFFF1FFFU, 0xFFFF03FFU, 0xFFFF03FFU, | ||
| 855 | 0x000007FFU, 0x00000020U, 0x00000000U, 0xFFFFFFC0U, | ||
| 856 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 857 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 858 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 859 | 0x00000000U, 0x00000000U, 0x00000000U, 0x03FF0000U, | ||
| 860 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 861 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, | ||
| 862 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 863 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 864 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 865 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 866 | 0xFFFFFFFFU, 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 867 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 868 | 0x3FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 869 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 870 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 871 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 872 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 873 | 0xFFFFFFFFU, 0xFFFF0003U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 874 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 875 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 876 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 877 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 878 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 879 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF0001U, | ||
| 880 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU, 0x00000000U, | ||
| 881 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 882 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 883 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 884 | 0x3FFFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 885 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 886 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 887 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 888 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 889 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 890 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF07FFU, 0xFFFFFFFFU, | ||
| 891 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 892 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 893 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 894 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 895 | 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, 0x00000000U | ||
| 896 | } | ||
| 897 | }; | ||
diff --git a/gl/unictype/ctype_blank.c b/gl/unictype/ctype_blank.c new file mode 100644 index 00000000..25a08013 --- /dev/null +++ b/gl/unictype/ctype_blank.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_blank table. */ | ||
| 26 | #include "ctype_blank.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_blank (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_blank, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_blank.h b/gl/unictype/ctype_blank.h new file mode 100644 index 00000000..23fac0f3 --- /dev/null +++ b/gl/unictype/ctype_blank.h | |||
| @@ -0,0 +1,184 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[1]; | ||
| 29 | short level2[1 << 7]; | ||
| 30 | unsigned int level3[4 << 4]; | ||
| 31 | } | ||
| 32 | u_is_blank = | ||
| 33 | { | ||
| 34 | { 1 }, | ||
| 35 | { 2 * sizeof (int) / sizeof (short) + 0 }, | ||
| 36 | { | ||
| 37 | 2 + 128 * sizeof (short) / sizeof (int) + 0, | ||
| 38 | -1, | ||
| 39 | -1, | ||
| 40 | -1, | ||
| 41 | -1, | ||
| 42 | -1, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | 2 + 128 * sizeof (short) / sizeof (int) + 16, | ||
| 49 | -1, | ||
| 50 | -1, | ||
| 51 | -1, | ||
| 52 | -1, | ||
| 53 | 2 + 128 * sizeof (short) / sizeof (int) + 32, | ||
| 54 | -1, | ||
| 55 | -1, | ||
| 56 | -1, | ||
| 57 | -1, | ||
| 58 | -1, | ||
| 59 | -1, | ||
| 60 | -1, | ||
| 61 | 2 + 128 * sizeof (short) / sizeof (int) + 48, | ||
| 62 | -1, | ||
| 63 | -1, | ||
| 64 | -1, | ||
| 65 | -1, | ||
| 66 | -1, | ||
| 67 | -1, | ||
| 68 | -1, | ||
| 69 | -1, | ||
| 70 | -1, | ||
| 71 | -1, | ||
| 72 | -1, | ||
| 73 | -1, | ||
| 74 | -1, | ||
| 75 | -1, | ||
| 76 | -1, | ||
| 77 | -1, | ||
| 78 | -1, | ||
| 79 | -1, | ||
| 80 | -1, | ||
| 81 | -1, | ||
| 82 | -1, | ||
| 83 | -1, | ||
| 84 | -1, | ||
| 85 | -1, | ||
| 86 | -1, | ||
| 87 | -1, | ||
| 88 | -1, | ||
| 89 | -1, | ||
| 90 | -1, | ||
| 91 | -1, | ||
| 92 | -1, | ||
| 93 | -1, | ||
| 94 | -1, | ||
| 95 | -1, | ||
| 96 | -1, | ||
| 97 | -1, | ||
| 98 | -1, | ||
| 99 | -1, | ||
| 100 | -1, | ||
| 101 | -1, | ||
| 102 | -1, | ||
| 103 | -1, | ||
| 104 | -1, | ||
| 105 | -1, | ||
| 106 | -1, | ||
| 107 | -1, | ||
| 108 | -1, | ||
| 109 | -1, | ||
| 110 | -1, | ||
| 111 | -1, | ||
| 112 | -1, | ||
| 113 | -1, | ||
| 114 | -1, | ||
| 115 | -1, | ||
| 116 | -1, | ||
| 117 | -1, | ||
| 118 | -1, | ||
| 119 | -1, | ||
| 120 | -1, | ||
| 121 | -1, | ||
| 122 | -1, | ||
| 123 | -1, | ||
| 124 | -1, | ||
| 125 | -1, | ||
| 126 | -1, | ||
| 127 | -1, | ||
| 128 | -1, | ||
| 129 | -1, | ||
| 130 | -1, | ||
| 131 | -1, | ||
| 132 | -1, | ||
| 133 | -1, | ||
| 134 | -1, | ||
| 135 | -1, | ||
| 136 | -1, | ||
| 137 | -1, | ||
| 138 | -1, | ||
| 139 | -1, | ||
| 140 | -1, | ||
| 141 | -1, | ||
| 142 | -1, | ||
| 143 | -1, | ||
| 144 | -1, | ||
| 145 | -1, | ||
| 146 | -1, | ||
| 147 | -1, | ||
| 148 | -1, | ||
| 149 | -1, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1 | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | 0x00000200U, 0x00000001U, 0x00000000U, 0x00000000U, | ||
| 168 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 169 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 170 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 171 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 172 | 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 173 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 174 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 175 | 0x0000077FU, 0x00000000U, 0x80000000U, 0x00000000U, | ||
| 176 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 177 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 178 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 179 | 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 180 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 181 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 182 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U | ||
| 183 | } | ||
| 184 | }; | ||
diff --git a/gl/unictype/ctype_cntrl.c b/gl/unictype/ctype_cntrl.c new file mode 100644 index 00000000..eb7467dd --- /dev/null +++ b/gl/unictype/ctype_cntrl.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_cntrl table. */ | ||
| 26 | #include "ctype_cntrl.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_cntrl (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_cntrl, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_cntrl.h b/gl/unictype/ctype_cntrl.h new file mode 100644 index 00000000..58df7e76 --- /dev/null +++ b/gl/unictype/ctype_cntrl.h | |||
| @@ -0,0 +1,176 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[1]; | ||
| 29 | short level2[1 << 7]; | ||
| 30 | unsigned int level3[2 << 4]; | ||
| 31 | } | ||
| 32 | u_is_cntrl = | ||
| 33 | { | ||
| 34 | { 1 }, | ||
| 35 | { 2 * sizeof (int) / sizeof (short) + 0 }, | ||
| 36 | { | ||
| 37 | 2 + 128 * sizeof (short) / sizeof (int) + 0, | ||
| 38 | -1, | ||
| 39 | -1, | ||
| 40 | -1, | ||
| 41 | -1, | ||
| 42 | -1, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | -1, | ||
| 49 | -1, | ||
| 50 | -1, | ||
| 51 | -1, | ||
| 52 | -1, | ||
| 53 | 2 + 128 * sizeof (short) / sizeof (int) + 16, | ||
| 54 | -1, | ||
| 55 | -1, | ||
| 56 | -1, | ||
| 57 | -1, | ||
| 58 | -1, | ||
| 59 | -1, | ||
| 60 | -1, | ||
| 61 | -1, | ||
| 62 | -1, | ||
| 63 | -1, | ||
| 64 | -1, | ||
| 65 | -1, | ||
| 66 | -1, | ||
| 67 | -1, | ||
| 68 | -1, | ||
| 69 | -1, | ||
| 70 | -1, | ||
| 71 | -1, | ||
| 72 | -1, | ||
| 73 | -1, | ||
| 74 | -1, | ||
| 75 | -1, | ||
| 76 | -1, | ||
| 77 | -1, | ||
| 78 | -1, | ||
| 79 | -1, | ||
| 80 | -1, | ||
| 81 | -1, | ||
| 82 | -1, | ||
| 83 | -1, | ||
| 84 | -1, | ||
| 85 | -1, | ||
| 86 | -1, | ||
| 87 | -1, | ||
| 88 | -1, | ||
| 89 | -1, | ||
| 90 | -1, | ||
| 91 | -1, | ||
| 92 | -1, | ||
| 93 | -1, | ||
| 94 | -1, | ||
| 95 | -1, | ||
| 96 | -1, | ||
| 97 | -1, | ||
| 98 | -1, | ||
| 99 | -1, | ||
| 100 | -1, | ||
| 101 | -1, | ||
| 102 | -1, | ||
| 103 | -1, | ||
| 104 | -1, | ||
| 105 | -1, | ||
| 106 | -1, | ||
| 107 | -1, | ||
| 108 | -1, | ||
| 109 | -1, | ||
| 110 | -1, | ||
| 111 | -1, | ||
| 112 | -1, | ||
| 113 | -1, | ||
| 114 | -1, | ||
| 115 | -1, | ||
| 116 | -1, | ||
| 117 | -1, | ||
| 118 | -1, | ||
| 119 | -1, | ||
| 120 | -1, | ||
| 121 | -1, | ||
| 122 | -1, | ||
| 123 | -1, | ||
| 124 | -1, | ||
| 125 | -1, | ||
| 126 | -1, | ||
| 127 | -1, | ||
| 128 | -1, | ||
| 129 | -1, | ||
| 130 | -1, | ||
| 131 | -1, | ||
| 132 | -1, | ||
| 133 | -1, | ||
| 134 | -1, | ||
| 135 | -1, | ||
| 136 | -1, | ||
| 137 | -1, | ||
| 138 | -1, | ||
| 139 | -1, | ||
| 140 | -1, | ||
| 141 | -1, | ||
| 142 | -1, | ||
| 143 | -1, | ||
| 144 | -1, | ||
| 145 | -1, | ||
| 146 | -1, | ||
| 147 | -1, | ||
| 148 | -1, | ||
| 149 | -1, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1 | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | 0xFFFFFFFFU, 0x00000000U, 0x00000000U, 0x80000000U, | ||
| 168 | 0xFFFFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 169 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 170 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 171 | 0x00000000U, 0x00000300U, 0x00000000U, 0x00000000U, | ||
| 172 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 173 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 174 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U | ||
| 175 | } | ||
| 176 | }; | ||
diff --git a/gl/unictype/ctype_digit.c b/gl/unictype/ctype_digit.c new file mode 100644 index 00000000..a82b3bb0 --- /dev/null +++ b/gl/unictype/ctype_digit.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_digit table. */ | ||
| 26 | #include "ctype_digit.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_digit (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_digit, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_digit.h b/gl/unictype/ctype_digit.h new file mode 100644 index 00000000..2f7d1822 --- /dev/null +++ b/gl/unictype/ctype_digit.h | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[1]; | ||
| 29 | short level2[1 << 7]; | ||
| 30 | unsigned int level3[1 << 4]; | ||
| 31 | } | ||
| 32 | u_is_digit = | ||
| 33 | { | ||
| 34 | { 1 }, | ||
| 35 | { 2 * sizeof (int) / sizeof (short) + 0 }, | ||
| 36 | { | ||
| 37 | 2 + 128 * sizeof (short) / sizeof (int) + 0, | ||
| 38 | -1, | ||
| 39 | -1, | ||
| 40 | -1, | ||
| 41 | -1, | ||
| 42 | -1, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | -1, | ||
| 49 | -1, | ||
| 50 | -1, | ||
| 51 | -1, | ||
| 52 | -1, | ||
| 53 | -1, | ||
| 54 | -1, | ||
| 55 | -1, | ||
| 56 | -1, | ||
| 57 | -1, | ||
| 58 | -1, | ||
| 59 | -1, | ||
| 60 | -1, | ||
| 61 | -1, | ||
| 62 | -1, | ||
| 63 | -1, | ||
| 64 | -1, | ||
| 65 | -1, | ||
| 66 | -1, | ||
| 67 | -1, | ||
| 68 | -1, | ||
| 69 | -1, | ||
| 70 | -1, | ||
| 71 | -1, | ||
| 72 | -1, | ||
| 73 | -1, | ||
| 74 | -1, | ||
| 75 | -1, | ||
| 76 | -1, | ||
| 77 | -1, | ||
| 78 | -1, | ||
| 79 | -1, | ||
| 80 | -1, | ||
| 81 | -1, | ||
| 82 | -1, | ||
| 83 | -1, | ||
| 84 | -1, | ||
| 85 | -1, | ||
| 86 | -1, | ||
| 87 | -1, | ||
| 88 | -1, | ||
| 89 | -1, | ||
| 90 | -1, | ||
| 91 | -1, | ||
| 92 | -1, | ||
| 93 | -1, | ||
| 94 | -1, | ||
| 95 | -1, | ||
| 96 | -1, | ||
| 97 | -1, | ||
| 98 | -1, | ||
| 99 | -1, | ||
| 100 | -1, | ||
| 101 | -1, | ||
| 102 | -1, | ||
| 103 | -1, | ||
| 104 | -1, | ||
| 105 | -1, | ||
| 106 | -1, | ||
| 107 | -1, | ||
| 108 | -1, | ||
| 109 | -1, | ||
| 110 | -1, | ||
| 111 | -1, | ||
| 112 | -1, | ||
| 113 | -1, | ||
| 114 | -1, | ||
| 115 | -1, | ||
| 116 | -1, | ||
| 117 | -1, | ||
| 118 | -1, | ||
| 119 | -1, | ||
| 120 | -1, | ||
| 121 | -1, | ||
| 122 | -1, | ||
| 123 | -1, | ||
| 124 | -1, | ||
| 125 | -1, | ||
| 126 | -1, | ||
| 127 | -1, | ||
| 128 | -1, | ||
| 129 | -1, | ||
| 130 | -1, | ||
| 131 | -1, | ||
| 132 | -1, | ||
| 133 | -1, | ||
| 134 | -1, | ||
| 135 | -1, | ||
| 136 | -1, | ||
| 137 | -1, | ||
| 138 | -1, | ||
| 139 | -1, | ||
| 140 | -1, | ||
| 141 | -1, | ||
| 142 | -1, | ||
| 143 | -1, | ||
| 144 | -1, | ||
| 145 | -1, | ||
| 146 | -1, | ||
| 147 | -1, | ||
| 148 | -1, | ||
| 149 | -1, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1 | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | 0x00000000U, 0x03FF0000U, 0x00000000U, 0x00000000U, | ||
| 168 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 169 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 170 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U | ||
| 171 | } | ||
| 172 | }; | ||
diff --git a/gl/unictype/ctype_graph.c b/gl/unictype/ctype_graph.c new file mode 100644 index 00000000..2c41c794 --- /dev/null +++ b/gl/unictype/ctype_graph.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_graph table. */ | ||
| 26 | #include "ctype_graph.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_graph (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_graph, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_graph.h b/gl/unictype/ctype_graph.h new file mode 100644 index 00000000..5627ad0f --- /dev/null +++ b/gl/unictype/ctype_graph.h | |||
| @@ -0,0 +1,1202 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[17]; | ||
| 29 | short level2[6 << 7]; | ||
| 30 | unsigned int level3[94 << 4]; | ||
| 31 | } | ||
| 32 | u_is_graph = | ||
| 33 | { | ||
| 34 | { 17 }, | ||
| 35 | { | ||
| 36 | 18 * sizeof (int) / sizeof (short) + 0, | ||
| 37 | 18 * sizeof (int) / sizeof (short) + 128, | ||
| 38 | 18 * sizeof (int) / sizeof (short) + 256, | ||
| 39 | 18 * sizeof (int) / sizeof (short) + 384, | ||
| 40 | -1, | ||
| 41 | -1, | ||
| 42 | -1, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | -1, | ||
| 49 | -1, | ||
| 50 | 18 * sizeof (int) / sizeof (short) + 512, | ||
| 51 | 18 * sizeof (int) / sizeof (short) + 640, | ||
| 52 | 18 * sizeof (int) / sizeof (short) + 640 | ||
| 53 | }, | ||
| 54 | { | ||
| 55 | 18 + 768 * sizeof (short) / sizeof (int) + 0, | ||
| 56 | 18 + 768 * sizeof (short) / sizeof (int) + 16, | ||
| 57 | 18 + 768 * sizeof (short) / sizeof (int) + 32, | ||
| 58 | 18 + 768 * sizeof (short) / sizeof (int) + 48, | ||
| 59 | 18 + 768 * sizeof (short) / sizeof (int) + 64, | ||
| 60 | 18 + 768 * sizeof (short) / sizeof (int) + 80, | ||
| 61 | 18 + 768 * sizeof (short) / sizeof (int) + 96, | ||
| 62 | 18 + 768 * sizeof (short) / sizeof (int) + 112, | ||
| 63 | 18 + 768 * sizeof (short) / sizeof (int) + 128, | ||
| 64 | 18 + 768 * sizeof (short) / sizeof (int) + 144, | ||
| 65 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 66 | 18 + 768 * sizeof (short) / sizeof (int) + 176, | ||
| 67 | 18 + 768 * sizeof (short) / sizeof (int) + 192, | ||
| 68 | 18 + 768 * sizeof (short) / sizeof (int) + 208, | ||
| 69 | 18 + 768 * sizeof (short) / sizeof (int) + 224, | ||
| 70 | 18 + 768 * sizeof (short) / sizeof (int) + 240, | ||
| 71 | 18 + 768 * sizeof (short) / sizeof (int) + 256, | ||
| 72 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 73 | 18 + 768 * sizeof (short) / sizeof (int) + 272, | ||
| 74 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 75 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 76 | 18 + 768 * sizeof (short) / sizeof (int) + 288, | ||
| 77 | 18 + 768 * sizeof (short) / sizeof (int) + 304, | ||
| 78 | 18 + 768 * sizeof (short) / sizeof (int) + 320, | ||
| 79 | 18 + 768 * sizeof (short) / sizeof (int) + 336, | ||
| 80 | 18 + 768 * sizeof (short) / sizeof (int) + 352, | ||
| 81 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 82 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 83 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 84 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 85 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 86 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 87 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 88 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 89 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 90 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 91 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 92 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 93 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 94 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 95 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 96 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 97 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 98 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 99 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 100 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 101 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 102 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 103 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 104 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 105 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 106 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 107 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 108 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 109 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 110 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 111 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 112 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 113 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 114 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 115 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 116 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 117 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 118 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 119 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 120 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 121 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 122 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 123 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 124 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 125 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 126 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 127 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 128 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 129 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 130 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 131 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 132 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 133 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 134 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 135 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 136 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 137 | 18 + 768 * sizeof (short) / sizeof (int) + 368, | ||
| 138 | 18 + 768 * sizeof (short) / sizeof (int) + 384, | ||
| 139 | 18 + 768 * sizeof (short) / sizeof (int) + 400, | ||
| 140 | 18 + 768 * sizeof (short) / sizeof (int) + 416, | ||
| 141 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 142 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 143 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 144 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 145 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 146 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 147 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 148 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 149 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 150 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 151 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 152 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 153 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 154 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 155 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 156 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 157 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 158 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 159 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 160 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 161 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 162 | 18 + 768 * sizeof (short) / sizeof (int) + 432, | ||
| 163 | -1, | ||
| 164 | -1, | ||
| 165 | -1, | ||
| 166 | -1, | ||
| 167 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 168 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 169 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 170 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 171 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 172 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 173 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 174 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 175 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 176 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 177 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 178 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 179 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 180 | 18 + 768 * sizeof (short) / sizeof (int) + 448, | ||
| 181 | 18 + 768 * sizeof (short) / sizeof (int) + 464, | ||
| 182 | 18 + 768 * sizeof (short) / sizeof (int) + 480, | ||
| 183 | 18 + 768 * sizeof (short) / sizeof (int) + 496, | ||
| 184 | 18 + 768 * sizeof (short) / sizeof (int) + 512, | ||
| 185 | 18 + 768 * sizeof (short) / sizeof (int) + 528, | ||
| 186 | 18 + 768 * sizeof (short) / sizeof (int) + 544, | ||
| 187 | 18 + 768 * sizeof (short) / sizeof (int) + 560, | ||
| 188 | 18 + 768 * sizeof (short) / sizeof (int) + 576, | ||
| 189 | 18 + 768 * sizeof (short) / sizeof (int) + 592, | ||
| 190 | 18 + 768 * sizeof (short) / sizeof (int) + 608, | ||
| 191 | 18 + 768 * sizeof (short) / sizeof (int) + 624, | ||
| 192 | 18 + 768 * sizeof (short) / sizeof (int) + 640, | ||
| 193 | 18 + 768 * sizeof (short) / sizeof (int) + 656, | ||
| 194 | 18 + 768 * sizeof (short) / sizeof (int) + 672, | ||
| 195 | 18 + 768 * sizeof (short) / sizeof (int) + 688, | ||
| 196 | 18 + 768 * sizeof (short) / sizeof (int) + 704, | ||
| 197 | 18 + 768 * sizeof (short) / sizeof (int) + 720, | ||
| 198 | 18 + 768 * sizeof (short) / sizeof (int) + 736, | ||
| 199 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 200 | 18 + 768 * sizeof (short) / sizeof (int) + 752, | ||
| 201 | 18 + 768 * sizeof (short) / sizeof (int) + 768, | ||
| 202 | -1, | ||
| 203 | -1, | ||
| 204 | -1, | ||
| 205 | -1, | ||
| 206 | 18 + 768 * sizeof (short) / sizeof (int) + 784, | ||
| 207 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 208 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 209 | 18 + 768 * sizeof (short) / sizeof (int) + 800, | ||
| 210 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 211 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 212 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 213 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 214 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 215 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 216 | 18 + 768 * sizeof (short) / sizeof (int) + 816, | ||
| 217 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 218 | 18 + 768 * sizeof (short) / sizeof (int) + 832, | ||
| 219 | -1, | ||
| 220 | -1, | ||
| 221 | -1, | ||
| 222 | -1, | ||
| 223 | -1, | ||
| 224 | -1, | ||
| 225 | -1, | ||
| 226 | -1, | ||
| 227 | -1, | ||
| 228 | -1, | ||
| 229 | -1, | ||
| 230 | -1, | ||
| 231 | 18 + 768 * sizeof (short) / sizeof (int) + 848, | ||
| 232 | -1, | ||
| 233 | -1, | ||
| 234 | -1, | ||
| 235 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 236 | 18 + 768 * sizeof (short) / sizeof (int) + 864, | ||
| 237 | 18 + 768 * sizeof (short) / sizeof (int) + 880, | ||
| 238 | 18 + 768 * sizeof (short) / sizeof (int) + 896, | ||
| 239 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 240 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 241 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 242 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 243 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 244 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 245 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 246 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 247 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 248 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 249 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 250 | 18 + 768 * sizeof (short) / sizeof (int) + 912, | ||
| 251 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 252 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 253 | 18 + 768 * sizeof (short) / sizeof (int) + 928, | ||
| 254 | -1, | ||
| 255 | -1, | ||
| 256 | -1, | ||
| 257 | -1, | ||
| 258 | -1, | ||
| 259 | -1, | ||
| 260 | -1, | ||
| 261 | -1, | ||
| 262 | -1, | ||
| 263 | -1, | ||
| 264 | -1, | ||
| 265 | -1, | ||
| 266 | -1, | ||
| 267 | -1, | ||
| 268 | -1, | ||
| 269 | -1, | ||
| 270 | 18 + 768 * sizeof (short) / sizeof (int) + 944, | ||
| 271 | 18 + 768 * sizeof (short) / sizeof (int) + 960, | ||
| 272 | 18 + 768 * sizeof (short) / sizeof (int) + 976, | ||
| 273 | -1, | ||
| 274 | -1, | ||
| 275 | -1, | ||
| 276 | -1, | ||
| 277 | 18 + 768 * sizeof (short) / sizeof (int) + 992, | ||
| 278 | -1, | ||
| 279 | -1, | ||
| 280 | -1, | ||
| 281 | -1, | ||
| 282 | -1, | ||
| 283 | -1, | ||
| 284 | -1, | ||
| 285 | 18 + 768 * sizeof (short) / sizeof (int) + 1008, | ||
| 286 | 18 + 768 * sizeof (short) / sizeof (int) + 1024, | ||
| 287 | 18 + 768 * sizeof (short) / sizeof (int) + 1040, | ||
| 288 | 18 + 768 * sizeof (short) / sizeof (int) + 1056, | ||
| 289 | 18 + 768 * sizeof (short) / sizeof (int) + 1072, | ||
| 290 | 18 + 768 * sizeof (short) / sizeof (int) + 1088, | ||
| 291 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 292 | 18 + 768 * sizeof (short) / sizeof (int) + 1104, | ||
| 293 | -1, | ||
| 294 | 18 + 768 * sizeof (short) / sizeof (int) + 1120, | ||
| 295 | 18 + 768 * sizeof (short) / sizeof (int) + 1136, | ||
| 296 | 18 + 768 * sizeof (short) / sizeof (int) + 1152, | ||
| 297 | 18 + 768 * sizeof (short) / sizeof (int) + 1168, | ||
| 298 | 18 + 768 * sizeof (short) / sizeof (int) + 1184, | ||
| 299 | 18 + 768 * sizeof (short) / sizeof (int) + 1200, | ||
| 300 | -1, | ||
| 301 | 18 + 768 * sizeof (short) / sizeof (int) + 1216, | ||
| 302 | 18 + 768 * sizeof (short) / sizeof (int) + 1232, | ||
| 303 | 18 + 768 * sizeof (short) / sizeof (int) + 1248, | ||
| 304 | 18 + 768 * sizeof (short) / sizeof (int) + 1264, | ||
| 305 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 306 | 18 + 768 * sizeof (short) / sizeof (int) + 1280, | ||
| 307 | 18 + 768 * sizeof (short) / sizeof (int) + 1296, | ||
| 308 | 18 + 768 * sizeof (short) / sizeof (int) + 1312, | ||
| 309 | -1, | ||
| 310 | -1, | ||
| 311 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 312 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 313 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 314 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 315 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 316 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 317 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 318 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 319 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 320 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 321 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 322 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 323 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 324 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 325 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 326 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 327 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 328 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 329 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 330 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 331 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 332 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 333 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 334 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 335 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 336 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 337 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 338 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 339 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 340 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 341 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 342 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 343 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 344 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 345 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 346 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 347 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 348 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 349 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 350 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 351 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 352 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 353 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 354 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 355 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 356 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 357 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 358 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 359 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 360 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 361 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 362 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 363 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 364 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 365 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 366 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 367 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 368 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 369 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 370 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 371 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 372 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 373 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 374 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 375 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 376 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 377 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 378 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 379 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 380 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 381 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 382 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 383 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 384 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 385 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 386 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 387 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 388 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 389 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 390 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 391 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 392 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 393 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 394 | 18 + 768 * sizeof (short) / sizeof (int) + 1328, | ||
| 395 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 396 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 397 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 398 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 399 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 400 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 401 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 402 | 18 + 768 * sizeof (short) / sizeof (int) + 1344, | ||
| 403 | 18 + 768 * sizeof (short) / sizeof (int) + 1360, | ||
| 404 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 405 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 406 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 407 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 408 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 409 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 410 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 411 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 412 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 413 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 414 | 18 + 768 * sizeof (short) / sizeof (int) + 1376, | ||
| 415 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 416 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 417 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 418 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 419 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 420 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 421 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 422 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 423 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 424 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 425 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 426 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 427 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 428 | 18 + 768 * sizeof (short) / sizeof (int) + 1392, | ||
| 429 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 430 | 18 + 768 * sizeof (short) / sizeof (int) + 1408, | ||
| 431 | -1, | ||
| 432 | -1, | ||
| 433 | -1, | ||
| 434 | -1, | ||
| 435 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 436 | 18 + 768 * sizeof (short) / sizeof (int) + 1424, | ||
| 437 | -1, | ||
| 438 | -1, | ||
| 439 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 440 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 441 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 442 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 443 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 444 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 445 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 446 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 447 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 448 | 18 + 768 * sizeof (short) / sizeof (int) + 1440, | ||
| 449 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 450 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 451 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 452 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 453 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 454 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 455 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 456 | 18 + 768 * sizeof (short) / sizeof (int) + 1456, | ||
| 457 | -1, | ||
| 458 | -1, | ||
| 459 | -1, | ||
| 460 | -1, | ||
| 461 | -1, | ||
| 462 | -1, | ||
| 463 | -1, | ||
| 464 | -1, | ||
| 465 | -1, | ||
| 466 | -1, | ||
| 467 | -1, | ||
| 468 | -1, | ||
| 469 | -1, | ||
| 470 | -1, | ||
| 471 | -1, | ||
| 472 | -1, | ||
| 473 | -1, | ||
| 474 | -1, | ||
| 475 | -1, | ||
| 476 | -1, | ||
| 477 | -1, | ||
| 478 | -1, | ||
| 479 | -1, | ||
| 480 | -1, | ||
| 481 | -1, | ||
| 482 | -1, | ||
| 483 | -1, | ||
| 484 | -1, | ||
| 485 | -1, | ||
| 486 | -1, | ||
| 487 | -1, | ||
| 488 | -1, | ||
| 489 | -1, | ||
| 490 | -1, | ||
| 491 | -1, | ||
| 492 | -1, | ||
| 493 | -1, | ||
| 494 | -1, | ||
| 495 | -1, | ||
| 496 | -1, | ||
| 497 | -1, | ||
| 498 | -1, | ||
| 499 | -1, | ||
| 500 | -1, | ||
| 501 | -1, | ||
| 502 | -1, | ||
| 503 | -1, | ||
| 504 | -1, | ||
| 505 | -1, | ||
| 506 | -1, | ||
| 507 | -1, | ||
| 508 | -1, | ||
| 509 | -1, | ||
| 510 | -1, | ||
| 511 | -1, | ||
| 512 | -1, | ||
| 513 | -1, | ||
| 514 | -1, | ||
| 515 | -1, | ||
| 516 | -1, | ||
| 517 | -1, | ||
| 518 | -1, | ||
| 519 | -1, | ||
| 520 | -1, | ||
| 521 | -1, | ||
| 522 | -1, | ||
| 523 | -1, | ||
| 524 | -1, | ||
| 525 | -1, | ||
| 526 | -1, | ||
| 527 | -1, | ||
| 528 | -1, | ||
| 529 | -1, | ||
| 530 | -1, | ||
| 531 | -1, | ||
| 532 | -1, | ||
| 533 | -1, | ||
| 534 | -1, | ||
| 535 | -1, | ||
| 536 | -1, | ||
| 537 | -1, | ||
| 538 | -1, | ||
| 539 | -1, | ||
| 540 | -1, | ||
| 541 | -1, | ||
| 542 | -1, | ||
| 543 | -1, | ||
| 544 | -1, | ||
| 545 | -1, | ||
| 546 | -1, | ||
| 547 | -1, | ||
| 548 | -1, | ||
| 549 | -1, | ||
| 550 | -1, | ||
| 551 | -1, | ||
| 552 | -1, | ||
| 553 | -1, | ||
| 554 | -1, | ||
| 555 | -1, | ||
| 556 | -1, | ||
| 557 | -1, | ||
| 558 | -1, | ||
| 559 | -1, | ||
| 560 | -1, | ||
| 561 | -1, | ||
| 562 | -1, | ||
| 563 | -1, | ||
| 564 | -1, | ||
| 565 | -1, | ||
| 566 | -1, | ||
| 567 | 18 + 768 * sizeof (short) / sizeof (int) + 1472, | ||
| 568 | -1, | ||
| 569 | -1, | ||
| 570 | -1, | ||
| 571 | -1, | ||
| 572 | -1, | ||
| 573 | -1, | ||
| 574 | -1, | ||
| 575 | -1, | ||
| 576 | -1, | ||
| 577 | -1, | ||
| 578 | -1, | ||
| 579 | -1, | ||
| 580 | -1, | ||
| 581 | -1, | ||
| 582 | -1, | ||
| 583 | -1, | ||
| 584 | -1, | ||
| 585 | -1, | ||
| 586 | -1, | ||
| 587 | -1, | ||
| 588 | -1, | ||
| 589 | -1, | ||
| 590 | -1, | ||
| 591 | -1, | ||
| 592 | -1, | ||
| 593 | -1, | ||
| 594 | -1, | ||
| 595 | -1, | ||
| 596 | -1, | ||
| 597 | -1, | ||
| 598 | -1, | ||
| 599 | -1, | ||
| 600 | -1, | ||
| 601 | -1, | ||
| 602 | -1, | ||
| 603 | -1, | ||
| 604 | -1, | ||
| 605 | -1, | ||
| 606 | -1, | ||
| 607 | -1, | ||
| 608 | -1, | ||
| 609 | -1, | ||
| 610 | -1, | ||
| 611 | -1, | ||
| 612 | -1, | ||
| 613 | -1, | ||
| 614 | -1, | ||
| 615 | -1, | ||
| 616 | -1, | ||
| 617 | -1, | ||
| 618 | -1, | ||
| 619 | -1, | ||
| 620 | -1, | ||
| 621 | -1, | ||
| 622 | -1, | ||
| 623 | -1, | ||
| 624 | -1, | ||
| 625 | -1, | ||
| 626 | -1, | ||
| 627 | -1, | ||
| 628 | -1, | ||
| 629 | -1, | ||
| 630 | -1, | ||
| 631 | -1, | ||
| 632 | -1, | ||
| 633 | -1, | ||
| 634 | -1, | ||
| 635 | -1, | ||
| 636 | -1, | ||
| 637 | -1, | ||
| 638 | -1, | ||
| 639 | -1, | ||
| 640 | -1, | ||
| 641 | -1, | ||
| 642 | -1, | ||
| 643 | -1, | ||
| 644 | -1, | ||
| 645 | -1, | ||
| 646 | -1, | ||
| 647 | -1, | ||
| 648 | -1, | ||
| 649 | -1, | ||
| 650 | -1, | ||
| 651 | -1, | ||
| 652 | -1, | ||
| 653 | -1, | ||
| 654 | -1, | ||
| 655 | -1, | ||
| 656 | -1, | ||
| 657 | -1, | ||
| 658 | -1, | ||
| 659 | -1, | ||
| 660 | -1, | ||
| 661 | -1, | ||
| 662 | -1, | ||
| 663 | -1, | ||
| 664 | -1, | ||
| 665 | -1, | ||
| 666 | -1, | ||
| 667 | -1, | ||
| 668 | -1, | ||
| 669 | -1, | ||
| 670 | -1, | ||
| 671 | -1, | ||
| 672 | -1, | ||
| 673 | -1, | ||
| 674 | -1, | ||
| 675 | -1, | ||
| 676 | -1, | ||
| 677 | -1, | ||
| 678 | -1, | ||
| 679 | -1, | ||
| 680 | -1, | ||
| 681 | -1, | ||
| 682 | -1, | ||
| 683 | -1, | ||
| 684 | -1, | ||
| 685 | -1, | ||
| 686 | -1, | ||
| 687 | -1, | ||
| 688 | -1, | ||
| 689 | -1, | ||
| 690 | -1, | ||
| 691 | -1, | ||
| 692 | -1, | ||
| 693 | -1, | ||
| 694 | -1, | ||
| 695 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 696 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 697 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 698 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 699 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 700 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 701 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 702 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 703 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 704 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 705 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 706 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 707 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 708 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 709 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 710 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 711 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 712 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 713 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 714 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 715 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 716 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 717 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 718 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 719 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 720 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 721 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 722 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 723 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 724 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 725 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 726 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 727 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 728 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 729 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 730 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 731 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 732 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 733 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 734 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 735 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 736 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 737 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 738 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 739 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 740 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 741 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 742 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 743 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 744 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 745 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 746 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 747 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 748 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 749 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 750 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 751 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 752 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 753 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 754 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 755 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 756 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 757 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 758 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 759 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 760 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 761 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 762 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 763 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 764 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 765 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 766 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 767 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 768 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 769 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 770 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 771 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 772 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 773 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 774 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 775 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 776 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 777 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 778 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 779 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 780 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 781 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 782 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 783 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 784 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 785 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 786 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 787 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 788 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 789 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 790 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 791 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 792 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 793 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 794 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 795 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 796 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 797 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 798 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 799 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 800 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 801 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 802 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 803 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 804 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 805 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 806 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 807 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 808 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 809 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 810 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 811 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 812 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 813 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 814 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 815 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 816 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 817 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 818 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 819 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 820 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 821 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 822 | 18 + 768 * sizeof (short) / sizeof (int) + 1488 | ||
| 823 | }, | ||
| 824 | { | ||
| 825 | 0x00000000U, 0xFFFFFFFEU, 0xFFFFFFFFU, 0x7FFFFFFFU, | ||
| 826 | 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 827 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 828 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 829 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 830 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 831 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFCFFFFFFU, | ||
| 832 | 0xFFFFD7F0U, 0xFFFFFFFBU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 833 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 834 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 835 | 0xFFFFFFFFU, 0xFFFEFFFFU, 0xFE7FFFFFU, 0xFFFFFFFFU, | ||
| 836 | 0xFFFEE7FFU, 0xFFFFFFFFU, 0xFFFF00FFU, 0x001F87FFU, | ||
| 837 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 838 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 839 | 0xFFFFBFFFU, 0xFFFFFFFFU, 0xFFFFE7FFU, 0xFFFFFFFFU, | ||
| 840 | 0xFFFFFFFFU, 0x0003FFFFU, 0xFFFFFFFFU, 0xE7FFFFFFU, | ||
| 841 | 0xFFFFFFFFU, 0x7FFF3FFFU, 0x4FFFFFFFU, 0xFFFF07FFU, | ||
| 842 | 0xFF837FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 843 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 844 | 0xFFF99FEFU, 0xF3C5FDFFU, 0xB080799FU, 0x7FFFFFCFU, | ||
| 845 | 0xFFF987EEU, 0xD36DFDFFU, 0x5E023987U, 0x007FFFC0U, | ||
| 846 | 0xFFFBBFEEU, 0xF3EDFDFFU, 0x00013BBFU, 0xFE03FFCFU, | ||
| 847 | 0xFFF99FEEU, 0xF3EDFDFFU, 0xB0E0399FU, 0x00FFFFCFU, | ||
| 848 | 0xD63DC7ECU, 0xC3FFC718U, 0x00813DC7U, 0x07FFFFC0U, | ||
| 849 | 0xFFFDDFFFU, 0xF3FFFDFFU, 0x27603DDFU, 0xFF80FFCFU, | ||
| 850 | 0xFFFDDFFFU, 0xF3EFFDFFU, 0x60603DDFU, 0x000EFFCFU, | ||
| 851 | 0xFFFDDFFFU, 0xFFFFFFFFU, 0xFFF0FDDFU, 0xFFFFFFCFU, | ||
| 852 | 0xFC7FFFEEU, 0x2FFBFFFFU, 0xFF5F847FU, 0x001CFFC0U, | ||
| 853 | 0xFFFFFFFEU, 0x87FFFFFFU, 0x0FFFFFFFU, 0x00000000U, | ||
| 854 | 0xFFFFF7D6U, 0x3FFFFFAFU, 0xF3FF7F5FU, 0x00000000U, | ||
| 855 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFEFFU, 0xFFFE1FFFU, | ||
| 856 | 0xFEFFFFFFU, 0xDFFFFFFFU, 0x07FFDFFFU, 0x00000000U, | ||
| 857 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 858 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF20BFU, 0xFFFFFFFFU, | ||
| 859 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 860 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 861 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3D7F3DFFU, 0xFFFFFFFFU, | ||
| 862 | 0xFFFF3DFFU, 0x7F3DFFFFU, 0xFF7FFF3DU, 0xFFFFFFFFU, | ||
| 863 | 0xFF3DFFFFU, 0xFFFFFFFFU, 0xE7FFFFFFU, 0x1FFFFFFFU, | ||
| 864 | 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3F3FFFFFU, | ||
| 865 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 866 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 867 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 868 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 869 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 870 | 0x1FFFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 871 | 0x803FFFFFU, 0x007FFFFFU, 0x000FFFFFU, 0x000DDFFFU, | ||
| 872 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU, 0x03FF03FFU, | ||
| 873 | 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 874 | 0xFFFFFFFFU, 0xFFFF07FFU, 0xFFFFFFFFU, 0x003FFFFFU, | ||
| 875 | 0x7FFFFFFFU, 0x0FFF0FFFU, 0xFFFFFFF1U, 0x001F3FFFU, | ||
| 876 | 0xFFFFFFFFU, 0xFFFF0FFFU, 0xC7FF03FFU, 0xFFFFFFFFU, | ||
| 877 | 0xCFFFFFFFU, 0xFFFFFFFFU, 0x7FFFFFFFU, 0x9FFFFFFFU, | ||
| 878 | 0x03FF03FFU, 0xFFFF3FFFU, 0x00007FFFU, 0x00000000U, | ||
| 879 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFDFFFU, 0xFFFFFFFFU, | ||
| 880 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF00FFFFFU, | ||
| 881 | 0xFFFFFFFFU, 0xF8FFFFFFU, 0xFFFFE3FFU, 0xFFFFFFFFU, | ||
| 882 | 0xFFFF07FFU, 0xE7FFFFFFU, 0xFFFF00FFU, 0x07FFFFFFU, | ||
| 883 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 884 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 885 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 886 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 887 | 0x3F3FFFFFU, 0xFFFFFFFFU, 0xAAFF3F3FU, 0x3FFFFFFFU, | ||
| 888 | 0xFFFFFFFFU, 0xFFDFFFFFU, 0xEFCFFFDFU, 0x7FDCFFFFU, | ||
| 889 | 0xFFFFF880U, 0xFFFFFCFFU, 0x7FFFFFFFU, 0xFFF3FFDFU, | ||
| 890 | 0x1FFF7FFFU, 0xFFFFFFFFU, 0xFFFF0001U, 0x0001FFFFU, | ||
| 891 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 892 | 0xFFFF0FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 893 | 0xFFFFFFFFU, 0x000003FFU, 0x000007FFU, 0xFFFFFFFFU, | ||
| 894 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 895 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 896 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 897 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 898 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 899 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFCFFFFFU, | ||
| 900 | 0xFFBFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 901 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 902 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFE0FFFFFU, | ||
| 903 | 0xFFFFFFFFU, 0xFFFF20BFU, 0xFFFFFFFFU, 0x800180FFU, | ||
| 904 | 0x007FFFFFU, 0x7F7F7F7FU, 0x7F7F7F7FU, 0xFFFFFFFFU, | ||
| 905 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU, 0x00000000U, | ||
| 906 | 0xFBFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000FFFFFU, | ||
| 907 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 908 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0xFFFF0000U, | ||
| 909 | 0xFFFFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFEU, 0xFFFFFFFFU, | ||
| 910 | 0xFE7FFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 911 | 0xFFFFFFE0U, 0xFFFEFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 912 | 0xFFFF7FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF803FU, | ||
| 913 | 0x7FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 914 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 915 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 916 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 917 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 918 | 0xFFFF1FFFU, 0xFFFFFFFFU, 0xFFFF007FU, 0xFFFFFFFFU, | ||
| 919 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 920 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 921 | 0xFFFFFFFFU, 0x00000FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 922 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00FFFFFFU, | ||
| 923 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 924 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x1FEB3FFFU, 0xFFFC0000U, | ||
| 925 | 0xFFFFFFFFU, 0x03FF1FFFU, 0xFFFFFFFFU, 0x00FFFFFFU, | ||
| 926 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFC03FU, 0xFFFFFFFFU, | ||
| 927 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x800FFFFFU, 0x1FFFFFFFU, | ||
| 928 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xC3FFBFFFU, 0x7FFFFFFFU, | ||
| 929 | 0xFFFFFFFFU, 0x007FFFFFU, 0xF3FF3FFFU, 0xFFFFFFFFU, | ||
| 930 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF8000007U, 0x007FFFFFU, | ||
| 931 | 0x007E7E7EU, 0xFFFF7F7FU, 0xFFFFFFFFU, 0xFFFF0FFFU, | ||
| 932 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF3FFFU, | ||
| 933 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 934 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 935 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 936 | 0xFFFFFFFFU, 0xFFFF000FU, 0xFFFFF87FU, 0x0FFFFFFFU, | ||
| 937 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF3FFFU, | ||
| 938 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, 0x00000000U, | ||
| 939 | 0xE0F8007FU, 0x5F7FFFFFU, 0xFFFFFFDBU, 0xFFFFFFFFU, | ||
| 940 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFF80007U, 0xFFFFFFFFU, | ||
| 941 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 942 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 943 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 944 | 0xFFFCFFFFU, 0xFFFFFFFFU, 0x000080FFU, 0xFFFF0000U, | ||
| 945 | 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFF7FFFFU, 0xFFDF0F7FU, | ||
| 946 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x9FFFFFFFU, | ||
| 947 | 0xFFFFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 948 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0x1CFCFCFCU, 0x3E007F7FU, | ||
| 949 | 0xFFFFEFFFU, 0xB7FFFF7FU, 0x3FFF3FFFU, 0x00000000U, | ||
| 950 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, | ||
| 951 | 0xFFFFFF87U, 0xFF8FFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 952 | 0x1FFF7FFFU, 0x00000001U, 0xFFFF0000U, 0x3FFFFFFFU, | ||
| 953 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 954 | 0x1FFFFFFFU, 0xFFFFFFFFU, 0x0001FFFFU, 0x0FFFFFFFU, | ||
| 955 | 0xFFFFFFFFU, 0xFFFFE00FU, 0xFFFF07FFU, 0x07FFFFFFU, | ||
| 956 | 0xBFFFFFFFU, 0xFFFFFFFFU, 0x003FFF0FU, 0x00000000U, | ||
| 957 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 958 | 0x3FFFFFFFU, 0xFFFF03FFU, 0xFF0FFFFFU, 0x0FFFFFFFU, | ||
| 959 | 0xFFFFFFFFU, 0xFFFF00FFU, 0xFFFFFFFFU, 0xF7FF800FU, | ||
| 960 | 0xFFB7F7FFU, 0x1BFBFFFBU, 0xFFFFFFFFU, 0x000FFFFFU, | ||
| 961 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 962 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 963 | 0xFFFFFFFFU, 0x007FFFFFU, 0x003FFFFFU, 0x000000FFU, | ||
| 964 | 0xFFFFFFBFU, 0x07FDFFFFU, 0x00000000U, 0x00000000U, | ||
| 965 | 0xFFFFFD3FU, 0x91BFFFFFU, 0xFFBFFFFFU, 0xFFFFFFFFU, | ||
| 966 | 0x7FFFFFFFU, 0x0000FF80U, 0x00000000U, 0xF837FFFFU, | ||
| 967 | 0x8FFFFFFFU, 0x83FFFFFFU, 0x00000000U, 0x00000000U, | ||
| 968 | 0xFFFFFFFFU, 0xF0FFFFFFU, 0xFFFCFFFFU, 0xFFFFFFFFU, | ||
| 969 | 0xFEEFF06FU, 0x873FFFFFU, 0x01FF01FFU, 0xFFFFFFFFU, | ||
| 970 | 0xFFFFFFFFU, 0x00000000U, 0xFFFFFFFFU, 0x007FF87FU, | ||
| 971 | 0xFFFFFFFFU, 0xFE3FFFFFU, 0xFF3FFFFFU, 0xFF07FFFFU, | ||
| 972 | 0x1E03FFFFU, 0x0000FE00U, 0x00000000U, 0x00000000U, | ||
| 973 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000001FFU, 0x00000000U, | ||
| 974 | 0xFFFFFFFFU, 0x0007FFFFU, 0xFFFFFFFFU, 0xFC07FFFFU, | ||
| 975 | 0xFFFFFFFFU, 0x03FF00FFU, 0xFFFFFFFFU, 0xFFFFFE3FU, | ||
| 976 | 0x0000C03FU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 977 | 0x00000000U, 0x00000000U, 0x00000000U, 0x7FFFFFFFU, | ||
| 978 | 0xFFFFFFFFU, 0x00033BFFU, 0x0000001CU, 0xF0000000U, | ||
| 979 | 0xFFFFFFFFU, 0xFFFF00FFU, 0x03FFFFFFU, 0xFFFF0000U, | ||
| 980 | 0x000003FFU, 0xFFFF0000U, 0x00000FFFU, 0x007FFFFFU, | ||
| 981 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFC3FFFU, 0x803FFFFFU, | ||
| 982 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF2007U, 0x03FF01FFU, | ||
| 983 | 0xFFFFFFFFU, 0xFFDFFFFFU, 0xFFFF00FFU, 0x007FFFFFU, | ||
| 984 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x001FFFFEU, | ||
| 985 | 0xFFFBFFFFU, 0xFFFFFFFFU, 0x00000003U, 0x00000000U, | ||
| 986 | 0xBFFFBD7FU, 0xFFFF03FFU, 0xFFFFFFFFU, 0x03FF07FFU, | ||
| 987 | 0xFFF99FEFU, 0xFBEDFDFFU, 0xE081399FU, 0x001F1FCFU, | ||
| 988 | 0xFFFF4BFFU, 0xFFBFFFFFU, 0x01BFF7A5U, 0x00000006U, | ||
| 989 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xEFFFFFFFU, 0x00000003U, | ||
| 990 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF00FFU, 0x00000000U, | ||
| 991 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 992 | 0xFFFFFFFFU, 0xFF3FFFFFU, 0x3FFFFFFFU, 0x00000000U, | ||
| 993 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF001FU, 0x00001FFFU, | ||
| 994 | 0xFFFFFFFFU, 0x03FFFFFFU, 0xFFFF03FFU, 0x0000000FU, | ||
| 995 | 0xE7FFFFFFU, 0xFFFF0FFFU, 0x0000007FU, 0x00000000U, | ||
| 996 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 997 | 0xFFFFFFFFU, 0x0FFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 998 | 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x8007FFFFU, | ||
| 999 | 0xFF6FF27FU, 0xF9BFFFFFU, 0x03FF007FU, 0x00000000U, | ||
| 1000 | 0x00000000U, 0xFFFFFCFFU, 0xFCFFFFFFU, 0x0000001FU, | ||
| 1001 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF00FFU, 0xFFFFFFFFU, | ||
| 1002 | 0xFFFFFFFFU, 0xFFFF0007U, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 1003 | 0x000003FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1004 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x03FF0003U, | ||
| 1005 | 0xFFFFFDFFU, 0xFF7FFFFFU, 0xFFFF003FU, 0xFFFF1FFFU, | ||
| 1006 | 0xFFFCFFFFU, 0x007FFEFFU, 0x00000000U, 0x00000000U, | ||
| 1007 | 0xFFFFFB7FU, 0xB47FFFFFU, 0x03FF00FFU, 0xFFFFFDBFU, | ||
| 1008 | 0x01FB7FFFU, 0x000003FFU, 0x00000000U, 0x00000000U, | ||
| 1009 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1010 | 0x00000000U, 0x00000000U, 0x00000000U, 0x01FFFFFFU, | ||
| 1011 | 0xFFFDFFFFU, 0xC7FFFFFFU, 0x07FFFFFFU, 0x00000000U, | ||
| 1012 | 0x00000000U, 0x00010000U, 0xFFFFFFFFU, 0x8003FFFFU, | ||
| 1013 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1014 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1015 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1016 | 0x03FFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1017 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x001F7FFFU, | ||
| 1018 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1019 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, | ||
| 1020 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1021 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1022 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1023 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1024 | 0xFFFF0000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0007FFFFU, | ||
| 1025 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0xFFFFFFFFU, | ||
| 1026 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1027 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1028 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1029 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1030 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1031 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1032 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, | ||
| 1033 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000007FU, 0x00000000U, | ||
| 1034 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1035 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1036 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1037 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1038 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1039 | 0xFFFFFFFFU, 0x03FFFFFFU, 0x00000000U, 0x00000000U, | ||
| 1040 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1041 | 0xFFFFFFFFU, 0x01FFFFFFU, 0x7FFFFFFFU, 0xFFFFC3FFU, | ||
| 1042 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0xFFFF03FFU, 0x003F3FFFU, | ||
| 1043 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFBFF003FU, 0xE0FFFFFBU, | ||
| 1044 | 0x0000FFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1045 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1046 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1047 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x03FFFFFFU, | ||
| 1048 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1049 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1050 | 0x07FFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1051 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF87FFU, 0xFFFFFFFFU, | ||
| 1052 | 0xFFFF80FFU, 0x00000000U, 0x00000000U, 0x0003001FU, | ||
| 1053 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1054 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1055 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1056 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00FFFFFFU, | ||
| 1057 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1058 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0x80000000U, | ||
| 1059 | 0x000001FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1060 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1061 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1062 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1063 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1064 | 0x00000000U, 0x00000000U, 0x00000000U, 0x6FEF0000U, | ||
| 1065 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1066 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1067 | 0xFFFFFFFFU, 0x00040007U, 0x00270000U, 0xFFFF00F0U, | ||
| 1068 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1069 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1070 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0FFFFFFFU, | ||
| 1071 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1072 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1073 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x1FFF07FFU, | ||
| 1074 | 0xF3FF01FFU, 0x0000000FU, 0x00000000U, 0x00000000U, | ||
| 1075 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1076 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1077 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1078 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, | ||
| 1079 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1080 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1081 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1082 | 0xFFFFFFFFU, 0x000FFFFFU, 0x00000000U, 0x00000000U, | ||
| 1083 | 0xFFFFFFFFU, 0xFFFF3FFFU, 0xFFFF007FU, 0xFFFFFFFFU, | ||
| 1084 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, | ||
| 1085 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1086 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, | ||
| 1087 | 0xFFFFFFFFU, 0xFFFFFE7FU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1088 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000007FFU, | ||
| 1089 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000003FU, 0x00000000U, | ||
| 1090 | 0x00000000U, 0x00000000U, 0x000FFFFFU, 0x000FFFFFU, | ||
| 1091 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x007FFFFFU, 0x01FFFFFFU, | ||
| 1092 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1093 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFDFFFFFU, 0xFFFFFFFFU, | ||
| 1094 | 0xDFFFFFFFU, 0xEBFFDE64U, 0xFFFFFFEFU, 0xFFFFFFFFU, | ||
| 1095 | 0xDFDFE7BFU, 0x7BFFFFFFU, 0xFFFDFC5FU, 0xFFFFFFFFU, | ||
| 1096 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1097 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1098 | 0xFFFFFFFFU, 0xFFFFFF3FU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1099 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1100 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFCFFFU, 0xFFFFFFFFU, | ||
| 1101 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1102 | 0xF8000FFFU, 0x0000FFFEU, 0x00000000U, 0x00000000U, | ||
| 1103 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1104 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1105 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1106 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1107 | 0x7FFFFFFFU, 0x000007E0U, 0x00000000U, 0x00000000U, | ||
| 1108 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1109 | 0xF9FFFF7FU, 0xFFFF07DBU, 0xFFFFFFFFU, 0x00003FFFU, | ||
| 1110 | 0x00008000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1111 | 0xFFFFFFFFU, 0x3FFF1FFFU, 0x0000C3FFU, 0x00000000U, | ||
| 1112 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1113 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1114 | 0xFFFF0000U, 0x00007FFFU, 0xFFFFFFFFU, 0x83FFFFFFU, | ||
| 1115 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1116 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1117 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1118 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x03FFFFFFU, | ||
| 1119 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1120 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x87FFFFFFU, | ||
| 1121 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1122 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1123 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1124 | 0x00000000U, 0x00000000U, 0x00000000U, 0x7FFF6F7FU, | ||
| 1125 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1126 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x007FFF9FU, 0x00000000U, | ||
| 1127 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xC3FF0FFFU, 0x00000000U, | ||
| 1128 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1129 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFFFE0000U, | ||
| 1130 | 0xFFFFFFFFU, 0x001FFFFFU, 0x00000000U, 0x00000000U, | ||
| 1131 | 0xFFFFFFFEU, 0x3FFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 1132 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1133 | 0xFFFFFFEFU, 0x0AF7FE96U, 0xAA96EA84U, 0x5EF7F796U, | ||
| 1134 | 0x0FFFFBFFU, 0x0FFFFBEEU, 0x00000000U, 0x00030000U, | ||
| 1135 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1136 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1137 | 0xFFFFFFFFU, 0xFFFF0FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1138 | 0x000FFFFFU, 0xFFFE7FFFU, 0xFFFEFFFEU, 0x003FFFFFU, | ||
| 1139 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1140 | 0xFFFFFFFFU, 0x00003FFFU, 0x00000000U, 0xFFFFFFC0U, | ||
| 1141 | 0xFFFF0007U, 0x0FFFFFFFU, 0x000301FFU, 0x0000003FU, | ||
| 1142 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1143 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1144 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1145 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1146 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF0FFFFFFU, 0x1FFF1FFFU, | ||
| 1147 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF87FFFFFU, | ||
| 1148 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, 0x00010FFFU, | ||
| 1149 | 0xFFFF0FFFU, 0xFFFFFFFFU, 0x03FF00FFU, 0xFFFFFFFFU, | ||
| 1150 | 0xFFFF00FFU, 0x0FFF3FFFU, 0x00000003U, 0x00000000U, | ||
| 1151 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1152 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1153 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000FFFFFU, 0x1FFF3FFFU, | ||
| 1154 | 0xFFFF83FFU, 0xFFFFFFFFU, 0x9FFFC07FU, 0x01FF03FFU, | ||
| 1155 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1156 | 0xFFF7FFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, | ||
| 1157 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1158 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, | ||
| 1159 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1160 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1161 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1162 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1163 | 0xFFFFFFFFU, 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1164 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1165 | 0x3FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1166 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1167 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1168 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1169 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1170 | 0xFFFFFFFFU, 0xFFFF0003U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1171 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1172 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1173 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1174 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1175 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1176 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF0001U, | ||
| 1177 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU, 0x00000000U, | ||
| 1178 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1179 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1180 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1181 | 0x3FFFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1182 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1183 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1184 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1185 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1186 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1187 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF07FFU, 0xFFFFFFFFU, | ||
| 1188 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1189 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1190 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1191 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1192 | 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, 0x00000000U, | ||
| 1193 | 0x00000002U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1194 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1195 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1196 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, | ||
| 1197 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1198 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1199 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1200 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU | ||
| 1201 | } | ||
| 1202 | }; | ||
diff --git a/gl/unictype/ctype_lower.c b/gl/unictype/ctype_lower.c new file mode 100644 index 00000000..99a05e09 --- /dev/null +++ b/gl/unictype/ctype_lower.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_lower table. */ | ||
| 26 | #include "ctype_lower.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_lower (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_lower, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_lower.h b/gl/unictype/ctype_lower.h new file mode 100644 index 00000000..cbf7d26d --- /dev/null +++ b/gl/unictype/ctype_lower.h | |||
| @@ -0,0 +1,371 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[2]; | ||
| 29 | short level2[2 << 7]; | ||
| 30 | unsigned int level3[18 << 4]; | ||
| 31 | } | ||
| 32 | u_is_lower = | ||
| 33 | { | ||
| 34 | { 2 }, | ||
| 35 | { | ||
| 36 | 3 * sizeof (int) / sizeof (short) + 0, | ||
| 37 | 3 * sizeof (int) / sizeof (short) + 128 | ||
| 38 | }, | ||
| 39 | { | ||
| 40 | 3 + 256 * sizeof (short) / sizeof (int) + 0, | ||
| 41 | 3 + 256 * sizeof (short) / sizeof (int) + 16, | ||
| 42 | 3 + 256 * sizeof (short) / sizeof (int) + 32, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | 3 + 256 * sizeof (short) / sizeof (int) + 48, | ||
| 49 | 3 + 256 * sizeof (short) / sizeof (int) + 64, | ||
| 50 | -1, | ||
| 51 | -1, | ||
| 52 | -1, | ||
| 53 | -1, | ||
| 54 | 3 + 256 * sizeof (short) / sizeof (int) + 80, | ||
| 55 | 3 + 256 * sizeof (short) / sizeof (int) + 96, | ||
| 56 | 3 + 256 * sizeof (short) / sizeof (int) + 112, | ||
| 57 | -1, | ||
| 58 | 3 + 256 * sizeof (short) / sizeof (int) + 128, | ||
| 59 | -1, | ||
| 60 | -1, | ||
| 61 | -1, | ||
| 62 | 3 + 256 * sizeof (short) / sizeof (int) + 144, | ||
| 63 | -1, | ||
| 64 | -1, | ||
| 65 | -1, | ||
| 66 | -1, | ||
| 67 | -1, | ||
| 68 | -1, | ||
| 69 | -1, | ||
| 70 | -1, | ||
| 71 | -1, | ||
| 72 | -1, | ||
| 73 | -1, | ||
| 74 | -1, | ||
| 75 | -1, | ||
| 76 | -1, | ||
| 77 | -1, | ||
| 78 | -1, | ||
| 79 | -1, | ||
| 80 | -1, | ||
| 81 | -1, | ||
| 82 | -1, | ||
| 83 | -1, | ||
| 84 | -1, | ||
| 85 | -1, | ||
| 86 | -1, | ||
| 87 | -1, | ||
| 88 | -1, | ||
| 89 | -1, | ||
| 90 | -1, | ||
| 91 | -1, | ||
| 92 | -1, | ||
| 93 | -1, | ||
| 94 | -1, | ||
| 95 | -1, | ||
| 96 | -1, | ||
| 97 | -1, | ||
| 98 | -1, | ||
| 99 | -1, | ||
| 100 | -1, | ||
| 101 | -1, | ||
| 102 | -1, | ||
| 103 | -1, | ||
| 104 | -1, | ||
| 105 | -1, | ||
| 106 | -1, | ||
| 107 | -1, | ||
| 108 | -1, | ||
| 109 | -1, | ||
| 110 | -1, | ||
| 111 | -1, | ||
| 112 | -1, | ||
| 113 | -1, | ||
| 114 | -1, | ||
| 115 | -1, | ||
| 116 | -1, | ||
| 117 | -1, | ||
| 118 | -1, | ||
| 119 | -1, | ||
| 120 | -1, | ||
| 121 | -1, | ||
| 122 | -1, | ||
| 123 | 3 + 256 * sizeof (short) / sizeof (int) + 160, | ||
| 124 | -1, | ||
| 125 | 3 + 256 * sizeof (short) / sizeof (int) + 176, | ||
| 126 | -1, | ||
| 127 | -1, | ||
| 128 | -1, | ||
| 129 | -1, | ||
| 130 | -1, | ||
| 131 | -1, | ||
| 132 | -1, | ||
| 133 | -1, | ||
| 134 | -1, | ||
| 135 | -1, | ||
| 136 | -1, | ||
| 137 | -1, | ||
| 138 | -1, | ||
| 139 | -1, | ||
| 140 | -1, | ||
| 141 | -1, | ||
| 142 | -1, | ||
| 143 | -1, | ||
| 144 | -1, | ||
| 145 | -1, | ||
| 146 | -1, | ||
| 147 | -1, | ||
| 148 | -1, | ||
| 149 | -1, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1, | ||
| 165 | -1, | ||
| 166 | -1, | ||
| 167 | 3 + 256 * sizeof (short) / sizeof (int) + 192, | ||
| 168 | -1, | ||
| 169 | -1, | ||
| 170 | 3 + 256 * sizeof (short) / sizeof (int) + 208, | ||
| 171 | -1, | ||
| 172 | -1, | ||
| 173 | -1, | ||
| 174 | 3 + 256 * sizeof (short) / sizeof (int) + 224, | ||
| 175 | -1, | ||
| 176 | -1, | ||
| 177 | -1, | ||
| 178 | -1, | ||
| 179 | -1, | ||
| 180 | 3 + 256 * sizeof (short) / sizeof (int) + 240, | ||
| 181 | -1, | ||
| 182 | -1, | ||
| 183 | -1, | ||
| 184 | -1, | ||
| 185 | -1, | ||
| 186 | -1, | ||
| 187 | -1, | ||
| 188 | -1, | ||
| 189 | -1, | ||
| 190 | -1, | ||
| 191 | -1, | ||
| 192 | -1, | ||
| 193 | -1, | ||
| 194 | -1, | ||
| 195 | -1, | ||
| 196 | -1, | ||
| 197 | -1, | ||
| 198 | -1, | ||
| 199 | -1, | ||
| 200 | -1, | ||
| 201 | -1, | ||
| 202 | -1, | ||
| 203 | -1, | ||
| 204 | -1, | ||
| 205 | -1, | ||
| 206 | -1, | ||
| 207 | -1, | ||
| 208 | -1, | ||
| 209 | -1, | ||
| 210 | -1, | ||
| 211 | -1, | ||
| 212 | -1, | ||
| 213 | -1, | ||
| 214 | -1, | ||
| 215 | -1, | ||
| 216 | -1, | ||
| 217 | -1, | ||
| 218 | -1, | ||
| 219 | -1, | ||
| 220 | -1, | ||
| 221 | -1, | ||
| 222 | -1, | ||
| 223 | 3 + 256 * sizeof (short) / sizeof (int) + 256, | ||
| 224 | -1, | ||
| 225 | -1, | ||
| 226 | -1, | ||
| 227 | -1, | ||
| 228 | -1, | ||
| 229 | -1, | ||
| 230 | -1, | ||
| 231 | -1, | ||
| 232 | -1, | ||
| 233 | -1, | ||
| 234 | -1, | ||
| 235 | -1, | ||
| 236 | -1, | ||
| 237 | -1, | ||
| 238 | -1, | ||
| 239 | -1, | ||
| 240 | -1, | ||
| 241 | -1, | ||
| 242 | -1, | ||
| 243 | -1, | ||
| 244 | -1, | ||
| 245 | -1, | ||
| 246 | -1, | ||
| 247 | -1, | ||
| 248 | -1, | ||
| 249 | -1, | ||
| 250 | -1, | ||
| 251 | -1, | ||
| 252 | -1, | ||
| 253 | -1, | ||
| 254 | -1, | ||
| 255 | -1, | ||
| 256 | -1, | ||
| 257 | -1, | ||
| 258 | -1, | ||
| 259 | -1, | ||
| 260 | -1, | ||
| 261 | -1, | ||
| 262 | -1, | ||
| 263 | -1, | ||
| 264 | -1, | ||
| 265 | -1, | ||
| 266 | -1, | ||
| 267 | -1, | ||
| 268 | -1, | ||
| 269 | -1, | ||
| 270 | -1, | ||
| 271 | -1, | ||
| 272 | -1, | ||
| 273 | -1, | ||
| 274 | -1, | ||
| 275 | -1, | ||
| 276 | -1, | ||
| 277 | -1, | ||
| 278 | -1, | ||
| 279 | -1, | ||
| 280 | -1, | ||
| 281 | -1, | ||
| 282 | -1, | ||
| 283 | -1, | ||
| 284 | 3 + 256 * sizeof (short) / sizeof (int) + 272, | ||
| 285 | -1, | ||
| 286 | -1, | ||
| 287 | -1, | ||
| 288 | -1, | ||
| 289 | -1, | ||
| 290 | -1, | ||
| 291 | -1, | ||
| 292 | -1, | ||
| 293 | -1, | ||
| 294 | -1, | ||
| 295 | -1 | ||
| 296 | }, | ||
| 297 | { | ||
| 298 | 0x00000000U, 0x00000000U, 0x00000000U, 0x07FFFFFEU, | ||
| 299 | 0x00000000U, 0x00200000U, 0x80000000U, 0xFF7FFFFFU, | ||
| 300 | 0xAAAAAAAAU, 0x54AAAAAAU, 0xAAAAA955U, 0xD4AAAAAAU, | ||
| 301 | 0x4E241129U, 0xA251212AU, 0xB5555B60U, 0xAA2CAAAAU, | ||
| 302 | 0xAAAAAAAAU, 0x900AAAA8U, 0x1ADFAA85U, 0x20269F7BU, | ||
| 303 | 0x60041F8DU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 304 | 0x00000000U, 0x00000000U, 0x00000020U, 0x388A0000U, | ||
| 305 | 0x00000000U, 0xFFFEF000U, 0xAAE37FFFU, 0x092FAAAAU, | ||
| 306 | 0x00000000U, 0xFFFF0000U, 0xFFFFFFFFU, 0xAAAAAAAAU, | ||
| 307 | 0xAAAAA802U, 0xAAAAAAAAU, 0xAAAAD554U, 0xAAAAAAAAU, | ||
| 308 | 0xAAAAAAAAU, 0x0000AAAAU, 0x00000000U, 0xFFFFFFFEU, | ||
| 309 | 0x0000007FU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 310 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 311 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0xE7FFFFFFU, | ||
| 312 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 313 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 314 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 315 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 316 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 317 | 0x00000000U, 0x00000000U, 0x00000000U, 0x3F000000U, | ||
| 318 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 319 | 0x000005FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 320 | 0x00000000U, 0x00000000U, 0x00000000U, 0x22000000U, | ||
| 321 | 0x00004000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 322 | 0xAAAAAAAAU, 0xAAAAAAAAU, 0xAAAAAAAAU, 0xAAAAAAAAU, | ||
| 323 | 0x082AAAAAU, 0xAAAAAAAAU, 0xAAAAAAAAU, 0xAAAAAAAAU, | ||
| 324 | 0x003F00FFU, 0x00FF00FFU, 0x00AA003FU, 0x3FFF00FFU, | ||
| 325 | 0x00FF00FFU, 0x400B00FFU, 0x00030008U, 0x00080023U, | ||
| 326 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 327 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 328 | 0x00000000U, 0x00000000U, 0x00004000U, 0xFFFF0000U, | ||
| 329 | 0x00000010U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 330 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 331 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x000003FFU, | ||
| 332 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 333 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 334 | 0x00000000U, 0xFFFF0000U, 0xFFFFFFFFU, 0x00481562U, | ||
| 335 | 0xAAAAAAAAU, 0xAAAAAAAAU, 0xAAAAAAAAU, 0x0008500AU, | ||
| 336 | 0xFFFFFFFFU, 0x000020BFU, 0x00000000U, 0x00000000U, | ||
| 337 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 338 | 0x00000000U, 0x00000000U, 0xAAAAAAAAU, 0x00002AAAU, | ||
| 339 | 0x0AAAAAAAU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 340 | 0x00000000U, 0xAAA8AAA8U, 0xAAAAAAAAU, 0x9400AAAAU, | ||
| 341 | 0xAA9A10AAU, 0xAAA002AAU, 0x0A82250AU, 0x00400000U, | ||
| 342 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 343 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 344 | 0x00000000U, 0x00000000U, 0x00080000U, 0xFFFF0000U, | ||
| 345 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 346 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 347 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 348 | 0x00000000U, 0x00000000U, 0x07FFFFFEU, 0x00000000U, | ||
| 349 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 350 | 0x00000000U, 0xFFFFFF00U, 0x0000FFFFU, 0x00000000U, | ||
| 351 | 0x00000000U, 0x00000000U, 0xFF000000U, 0x0FFFFFFFU, | ||
| 352 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 353 | 0xFF800000U, 0x1BFBFFFBU, 0x00000000U, 0x00000000U, | ||
| 354 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 355 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x0007FFFFU, | ||
| 356 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFFFF0000U, | ||
| 357 | 0x0000003FU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 358 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 359 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x00000000U, | ||
| 360 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 361 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 362 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFFFFFFFFU, | ||
| 363 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 364 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 365 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 366 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 367 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 368 | 0x00000000U, 0xFFFFFFFCU, 0x0000000FU, 0x00000000U, | ||
| 369 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U | ||
| 370 | } | ||
| 371 | }; | ||
diff --git a/gl/unictype/ctype_print.c b/gl/unictype/ctype_print.c new file mode 100644 index 00000000..0197d496 --- /dev/null +++ b/gl/unictype/ctype_print.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_print table. */ | ||
| 26 | #include "ctype_print.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_print (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_print, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_print.h b/gl/unictype/ctype_print.h new file mode 100644 index 00000000..b7007828 --- /dev/null +++ b/gl/unictype/ctype_print.h | |||
| @@ -0,0 +1,1202 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[17]; | ||
| 29 | short level2[6 << 7]; | ||
| 30 | unsigned int level3[94 << 4]; | ||
| 31 | } | ||
| 32 | u_is_print = | ||
| 33 | { | ||
| 34 | { 17 }, | ||
| 35 | { | ||
| 36 | 18 * sizeof (int) / sizeof (short) + 0, | ||
| 37 | 18 * sizeof (int) / sizeof (short) + 128, | ||
| 38 | 18 * sizeof (int) / sizeof (short) + 256, | ||
| 39 | 18 * sizeof (int) / sizeof (short) + 384, | ||
| 40 | -1, | ||
| 41 | -1, | ||
| 42 | -1, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | -1, | ||
| 49 | -1, | ||
| 50 | 18 * sizeof (int) / sizeof (short) + 512, | ||
| 51 | 18 * sizeof (int) / sizeof (short) + 640, | ||
| 52 | 18 * sizeof (int) / sizeof (short) + 640 | ||
| 53 | }, | ||
| 54 | { | ||
| 55 | 18 + 768 * sizeof (short) / sizeof (int) + 0, | ||
| 56 | 18 + 768 * sizeof (short) / sizeof (int) + 16, | ||
| 57 | 18 + 768 * sizeof (short) / sizeof (int) + 32, | ||
| 58 | 18 + 768 * sizeof (short) / sizeof (int) + 48, | ||
| 59 | 18 + 768 * sizeof (short) / sizeof (int) + 64, | ||
| 60 | 18 + 768 * sizeof (short) / sizeof (int) + 80, | ||
| 61 | 18 + 768 * sizeof (short) / sizeof (int) + 96, | ||
| 62 | 18 + 768 * sizeof (short) / sizeof (int) + 112, | ||
| 63 | 18 + 768 * sizeof (short) / sizeof (int) + 128, | ||
| 64 | 18 + 768 * sizeof (short) / sizeof (int) + 144, | ||
| 65 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 66 | 18 + 768 * sizeof (short) / sizeof (int) + 176, | ||
| 67 | 18 + 768 * sizeof (short) / sizeof (int) + 192, | ||
| 68 | 18 + 768 * sizeof (short) / sizeof (int) + 208, | ||
| 69 | 18 + 768 * sizeof (short) / sizeof (int) + 224, | ||
| 70 | 18 + 768 * sizeof (short) / sizeof (int) + 240, | ||
| 71 | 18 + 768 * sizeof (short) / sizeof (int) + 256, | ||
| 72 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 73 | 18 + 768 * sizeof (short) / sizeof (int) + 272, | ||
| 74 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 75 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 76 | 18 + 768 * sizeof (short) / sizeof (int) + 288, | ||
| 77 | 18 + 768 * sizeof (short) / sizeof (int) + 304, | ||
| 78 | 18 + 768 * sizeof (short) / sizeof (int) + 320, | ||
| 79 | 18 + 768 * sizeof (short) / sizeof (int) + 336, | ||
| 80 | 18 + 768 * sizeof (short) / sizeof (int) + 352, | ||
| 81 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 82 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 83 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 84 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 85 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 86 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 87 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 88 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 89 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 90 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 91 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 92 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 93 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 94 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 95 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 96 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 97 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 98 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 99 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 100 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 101 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 102 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 103 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 104 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 105 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 106 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 107 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 108 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 109 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 110 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 111 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 112 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 113 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 114 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 115 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 116 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 117 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 118 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 119 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 120 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 121 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 122 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 123 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 124 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 125 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 126 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 127 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 128 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 129 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 130 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 131 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 132 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 133 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 134 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 135 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 136 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 137 | 18 + 768 * sizeof (short) / sizeof (int) + 368, | ||
| 138 | 18 + 768 * sizeof (short) / sizeof (int) + 384, | ||
| 139 | 18 + 768 * sizeof (short) / sizeof (int) + 400, | ||
| 140 | 18 + 768 * sizeof (short) / sizeof (int) + 416, | ||
| 141 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 142 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 143 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 144 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 145 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 146 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 147 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 148 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 149 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 150 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 151 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 152 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 153 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 154 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 155 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 156 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 157 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 158 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 159 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 160 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 161 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 162 | 18 + 768 * sizeof (short) / sizeof (int) + 432, | ||
| 163 | -1, | ||
| 164 | -1, | ||
| 165 | -1, | ||
| 166 | -1, | ||
| 167 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 168 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 169 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 170 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 171 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 172 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 173 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 174 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 175 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 176 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 177 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 178 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 179 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 180 | 18 + 768 * sizeof (short) / sizeof (int) + 448, | ||
| 181 | 18 + 768 * sizeof (short) / sizeof (int) + 464, | ||
| 182 | 18 + 768 * sizeof (short) / sizeof (int) + 480, | ||
| 183 | 18 + 768 * sizeof (short) / sizeof (int) + 496, | ||
| 184 | 18 + 768 * sizeof (short) / sizeof (int) + 512, | ||
| 185 | 18 + 768 * sizeof (short) / sizeof (int) + 528, | ||
| 186 | 18 + 768 * sizeof (short) / sizeof (int) + 544, | ||
| 187 | 18 + 768 * sizeof (short) / sizeof (int) + 560, | ||
| 188 | 18 + 768 * sizeof (short) / sizeof (int) + 576, | ||
| 189 | 18 + 768 * sizeof (short) / sizeof (int) + 592, | ||
| 190 | 18 + 768 * sizeof (short) / sizeof (int) + 608, | ||
| 191 | 18 + 768 * sizeof (short) / sizeof (int) + 624, | ||
| 192 | 18 + 768 * sizeof (short) / sizeof (int) + 640, | ||
| 193 | 18 + 768 * sizeof (short) / sizeof (int) + 656, | ||
| 194 | 18 + 768 * sizeof (short) / sizeof (int) + 672, | ||
| 195 | 18 + 768 * sizeof (short) / sizeof (int) + 688, | ||
| 196 | 18 + 768 * sizeof (short) / sizeof (int) + 704, | ||
| 197 | 18 + 768 * sizeof (short) / sizeof (int) + 720, | ||
| 198 | 18 + 768 * sizeof (short) / sizeof (int) + 736, | ||
| 199 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 200 | 18 + 768 * sizeof (short) / sizeof (int) + 752, | ||
| 201 | 18 + 768 * sizeof (short) / sizeof (int) + 768, | ||
| 202 | -1, | ||
| 203 | -1, | ||
| 204 | -1, | ||
| 205 | -1, | ||
| 206 | 18 + 768 * sizeof (short) / sizeof (int) + 784, | ||
| 207 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 208 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 209 | 18 + 768 * sizeof (short) / sizeof (int) + 800, | ||
| 210 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 211 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 212 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 213 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 214 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 215 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 216 | 18 + 768 * sizeof (short) / sizeof (int) + 816, | ||
| 217 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 218 | 18 + 768 * sizeof (short) / sizeof (int) + 832, | ||
| 219 | -1, | ||
| 220 | -1, | ||
| 221 | -1, | ||
| 222 | -1, | ||
| 223 | -1, | ||
| 224 | -1, | ||
| 225 | -1, | ||
| 226 | -1, | ||
| 227 | -1, | ||
| 228 | -1, | ||
| 229 | -1, | ||
| 230 | -1, | ||
| 231 | 18 + 768 * sizeof (short) / sizeof (int) + 848, | ||
| 232 | -1, | ||
| 233 | -1, | ||
| 234 | -1, | ||
| 235 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 236 | 18 + 768 * sizeof (short) / sizeof (int) + 864, | ||
| 237 | 18 + 768 * sizeof (short) / sizeof (int) + 880, | ||
| 238 | 18 + 768 * sizeof (short) / sizeof (int) + 896, | ||
| 239 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 240 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 241 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 242 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 243 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 244 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 245 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 246 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 247 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 248 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 249 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 250 | 18 + 768 * sizeof (short) / sizeof (int) + 912, | ||
| 251 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 252 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 253 | 18 + 768 * sizeof (short) / sizeof (int) + 928, | ||
| 254 | -1, | ||
| 255 | -1, | ||
| 256 | -1, | ||
| 257 | -1, | ||
| 258 | -1, | ||
| 259 | -1, | ||
| 260 | -1, | ||
| 261 | -1, | ||
| 262 | -1, | ||
| 263 | -1, | ||
| 264 | -1, | ||
| 265 | -1, | ||
| 266 | -1, | ||
| 267 | -1, | ||
| 268 | -1, | ||
| 269 | -1, | ||
| 270 | 18 + 768 * sizeof (short) / sizeof (int) + 944, | ||
| 271 | 18 + 768 * sizeof (short) / sizeof (int) + 960, | ||
| 272 | 18 + 768 * sizeof (short) / sizeof (int) + 976, | ||
| 273 | -1, | ||
| 274 | -1, | ||
| 275 | -1, | ||
| 276 | -1, | ||
| 277 | 18 + 768 * sizeof (short) / sizeof (int) + 992, | ||
| 278 | -1, | ||
| 279 | -1, | ||
| 280 | -1, | ||
| 281 | -1, | ||
| 282 | -1, | ||
| 283 | -1, | ||
| 284 | -1, | ||
| 285 | 18 + 768 * sizeof (short) / sizeof (int) + 1008, | ||
| 286 | 18 + 768 * sizeof (short) / sizeof (int) + 1024, | ||
| 287 | 18 + 768 * sizeof (short) / sizeof (int) + 1040, | ||
| 288 | 18 + 768 * sizeof (short) / sizeof (int) + 1056, | ||
| 289 | 18 + 768 * sizeof (short) / sizeof (int) + 1072, | ||
| 290 | 18 + 768 * sizeof (short) / sizeof (int) + 1088, | ||
| 291 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 292 | 18 + 768 * sizeof (short) / sizeof (int) + 1104, | ||
| 293 | -1, | ||
| 294 | 18 + 768 * sizeof (short) / sizeof (int) + 1120, | ||
| 295 | 18 + 768 * sizeof (short) / sizeof (int) + 1136, | ||
| 296 | 18 + 768 * sizeof (short) / sizeof (int) + 1152, | ||
| 297 | 18 + 768 * sizeof (short) / sizeof (int) + 1168, | ||
| 298 | 18 + 768 * sizeof (short) / sizeof (int) + 1184, | ||
| 299 | 18 + 768 * sizeof (short) / sizeof (int) + 1200, | ||
| 300 | -1, | ||
| 301 | 18 + 768 * sizeof (short) / sizeof (int) + 1216, | ||
| 302 | 18 + 768 * sizeof (short) / sizeof (int) + 1232, | ||
| 303 | 18 + 768 * sizeof (short) / sizeof (int) + 1248, | ||
| 304 | 18 + 768 * sizeof (short) / sizeof (int) + 1264, | ||
| 305 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 306 | 18 + 768 * sizeof (short) / sizeof (int) + 1280, | ||
| 307 | 18 + 768 * sizeof (short) / sizeof (int) + 1296, | ||
| 308 | 18 + 768 * sizeof (short) / sizeof (int) + 1312, | ||
| 309 | -1, | ||
| 310 | -1, | ||
| 311 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 312 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 313 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 314 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 315 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 316 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 317 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 318 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 319 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 320 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 321 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 322 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 323 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 324 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 325 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 326 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 327 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 328 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 329 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 330 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 331 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 332 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 333 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 334 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 335 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 336 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 337 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 338 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 339 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 340 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 341 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 342 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 343 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 344 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 345 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 346 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 347 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 348 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 349 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 350 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 351 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 352 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 353 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 354 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 355 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 356 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 357 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 358 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 359 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 360 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 361 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 362 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 363 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 364 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 365 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 366 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 367 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 368 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 369 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 370 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 371 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 372 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 373 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 374 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 375 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 376 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 377 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 378 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 379 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 380 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 381 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 382 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 383 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 384 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 385 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 386 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 387 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 388 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 389 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 390 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 391 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 392 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 393 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 394 | 18 + 768 * sizeof (short) / sizeof (int) + 1328, | ||
| 395 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 396 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 397 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 398 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 399 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 400 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 401 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 402 | 18 + 768 * sizeof (short) / sizeof (int) + 1344, | ||
| 403 | 18 + 768 * sizeof (short) / sizeof (int) + 1360, | ||
| 404 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 405 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 406 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 407 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 408 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 409 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 410 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 411 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 412 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 413 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 414 | 18 + 768 * sizeof (short) / sizeof (int) + 1376, | ||
| 415 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 416 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 417 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 418 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 419 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 420 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 421 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 422 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 423 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 424 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 425 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 426 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 427 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 428 | 18 + 768 * sizeof (short) / sizeof (int) + 1392, | ||
| 429 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 430 | 18 + 768 * sizeof (short) / sizeof (int) + 1408, | ||
| 431 | -1, | ||
| 432 | -1, | ||
| 433 | -1, | ||
| 434 | -1, | ||
| 435 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 436 | 18 + 768 * sizeof (short) / sizeof (int) + 1424, | ||
| 437 | -1, | ||
| 438 | -1, | ||
| 439 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 440 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 441 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 442 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 443 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 444 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 445 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 446 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 447 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 448 | 18 + 768 * sizeof (short) / sizeof (int) + 1440, | ||
| 449 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 450 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 451 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 452 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 453 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 454 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 455 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 456 | 18 + 768 * sizeof (short) / sizeof (int) + 1456, | ||
| 457 | -1, | ||
| 458 | -1, | ||
| 459 | -1, | ||
| 460 | -1, | ||
| 461 | -1, | ||
| 462 | -1, | ||
| 463 | -1, | ||
| 464 | -1, | ||
| 465 | -1, | ||
| 466 | -1, | ||
| 467 | -1, | ||
| 468 | -1, | ||
| 469 | -1, | ||
| 470 | -1, | ||
| 471 | -1, | ||
| 472 | -1, | ||
| 473 | -1, | ||
| 474 | -1, | ||
| 475 | -1, | ||
| 476 | -1, | ||
| 477 | -1, | ||
| 478 | -1, | ||
| 479 | -1, | ||
| 480 | -1, | ||
| 481 | -1, | ||
| 482 | -1, | ||
| 483 | -1, | ||
| 484 | -1, | ||
| 485 | -1, | ||
| 486 | -1, | ||
| 487 | -1, | ||
| 488 | -1, | ||
| 489 | -1, | ||
| 490 | -1, | ||
| 491 | -1, | ||
| 492 | -1, | ||
| 493 | -1, | ||
| 494 | -1, | ||
| 495 | -1, | ||
| 496 | -1, | ||
| 497 | -1, | ||
| 498 | -1, | ||
| 499 | -1, | ||
| 500 | -1, | ||
| 501 | -1, | ||
| 502 | -1, | ||
| 503 | -1, | ||
| 504 | -1, | ||
| 505 | -1, | ||
| 506 | -1, | ||
| 507 | -1, | ||
| 508 | -1, | ||
| 509 | -1, | ||
| 510 | -1, | ||
| 511 | -1, | ||
| 512 | -1, | ||
| 513 | -1, | ||
| 514 | -1, | ||
| 515 | -1, | ||
| 516 | -1, | ||
| 517 | -1, | ||
| 518 | -1, | ||
| 519 | -1, | ||
| 520 | -1, | ||
| 521 | -1, | ||
| 522 | -1, | ||
| 523 | -1, | ||
| 524 | -1, | ||
| 525 | -1, | ||
| 526 | -1, | ||
| 527 | -1, | ||
| 528 | -1, | ||
| 529 | -1, | ||
| 530 | -1, | ||
| 531 | -1, | ||
| 532 | -1, | ||
| 533 | -1, | ||
| 534 | -1, | ||
| 535 | -1, | ||
| 536 | -1, | ||
| 537 | -1, | ||
| 538 | -1, | ||
| 539 | -1, | ||
| 540 | -1, | ||
| 541 | -1, | ||
| 542 | -1, | ||
| 543 | -1, | ||
| 544 | -1, | ||
| 545 | -1, | ||
| 546 | -1, | ||
| 547 | -1, | ||
| 548 | -1, | ||
| 549 | -1, | ||
| 550 | -1, | ||
| 551 | -1, | ||
| 552 | -1, | ||
| 553 | -1, | ||
| 554 | -1, | ||
| 555 | -1, | ||
| 556 | -1, | ||
| 557 | -1, | ||
| 558 | -1, | ||
| 559 | -1, | ||
| 560 | -1, | ||
| 561 | -1, | ||
| 562 | -1, | ||
| 563 | -1, | ||
| 564 | -1, | ||
| 565 | -1, | ||
| 566 | -1, | ||
| 567 | 18 + 768 * sizeof (short) / sizeof (int) + 1472, | ||
| 568 | -1, | ||
| 569 | -1, | ||
| 570 | -1, | ||
| 571 | -1, | ||
| 572 | -1, | ||
| 573 | -1, | ||
| 574 | -1, | ||
| 575 | -1, | ||
| 576 | -1, | ||
| 577 | -1, | ||
| 578 | -1, | ||
| 579 | -1, | ||
| 580 | -1, | ||
| 581 | -1, | ||
| 582 | -1, | ||
| 583 | -1, | ||
| 584 | -1, | ||
| 585 | -1, | ||
| 586 | -1, | ||
| 587 | -1, | ||
| 588 | -1, | ||
| 589 | -1, | ||
| 590 | -1, | ||
| 591 | -1, | ||
| 592 | -1, | ||
| 593 | -1, | ||
| 594 | -1, | ||
| 595 | -1, | ||
| 596 | -1, | ||
| 597 | -1, | ||
| 598 | -1, | ||
| 599 | -1, | ||
| 600 | -1, | ||
| 601 | -1, | ||
| 602 | -1, | ||
| 603 | -1, | ||
| 604 | -1, | ||
| 605 | -1, | ||
| 606 | -1, | ||
| 607 | -1, | ||
| 608 | -1, | ||
| 609 | -1, | ||
| 610 | -1, | ||
| 611 | -1, | ||
| 612 | -1, | ||
| 613 | -1, | ||
| 614 | -1, | ||
| 615 | -1, | ||
| 616 | -1, | ||
| 617 | -1, | ||
| 618 | -1, | ||
| 619 | -1, | ||
| 620 | -1, | ||
| 621 | -1, | ||
| 622 | -1, | ||
| 623 | -1, | ||
| 624 | -1, | ||
| 625 | -1, | ||
| 626 | -1, | ||
| 627 | -1, | ||
| 628 | -1, | ||
| 629 | -1, | ||
| 630 | -1, | ||
| 631 | -1, | ||
| 632 | -1, | ||
| 633 | -1, | ||
| 634 | -1, | ||
| 635 | -1, | ||
| 636 | -1, | ||
| 637 | -1, | ||
| 638 | -1, | ||
| 639 | -1, | ||
| 640 | -1, | ||
| 641 | -1, | ||
| 642 | -1, | ||
| 643 | -1, | ||
| 644 | -1, | ||
| 645 | -1, | ||
| 646 | -1, | ||
| 647 | -1, | ||
| 648 | -1, | ||
| 649 | -1, | ||
| 650 | -1, | ||
| 651 | -1, | ||
| 652 | -1, | ||
| 653 | -1, | ||
| 654 | -1, | ||
| 655 | -1, | ||
| 656 | -1, | ||
| 657 | -1, | ||
| 658 | -1, | ||
| 659 | -1, | ||
| 660 | -1, | ||
| 661 | -1, | ||
| 662 | -1, | ||
| 663 | -1, | ||
| 664 | -1, | ||
| 665 | -1, | ||
| 666 | -1, | ||
| 667 | -1, | ||
| 668 | -1, | ||
| 669 | -1, | ||
| 670 | -1, | ||
| 671 | -1, | ||
| 672 | -1, | ||
| 673 | -1, | ||
| 674 | -1, | ||
| 675 | -1, | ||
| 676 | -1, | ||
| 677 | -1, | ||
| 678 | -1, | ||
| 679 | -1, | ||
| 680 | -1, | ||
| 681 | -1, | ||
| 682 | -1, | ||
| 683 | -1, | ||
| 684 | -1, | ||
| 685 | -1, | ||
| 686 | -1, | ||
| 687 | -1, | ||
| 688 | -1, | ||
| 689 | -1, | ||
| 690 | -1, | ||
| 691 | -1, | ||
| 692 | -1, | ||
| 693 | -1, | ||
| 694 | -1, | ||
| 695 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 696 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 697 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 698 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 699 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 700 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 701 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 702 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 703 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 704 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 705 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 706 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 707 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 708 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 709 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 710 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 711 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 712 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 713 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 714 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 715 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 716 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 717 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 718 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 719 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 720 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 721 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 722 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 723 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 724 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 725 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 726 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 727 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 728 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 729 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 730 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 731 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 732 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 733 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 734 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 735 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 736 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 737 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 738 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 739 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 740 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 741 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 742 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 743 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 744 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 745 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 746 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 747 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 748 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 749 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 750 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 751 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 752 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 753 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 754 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 755 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 756 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 757 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 758 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 759 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 760 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 761 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 762 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 763 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 764 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 765 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 766 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 767 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 768 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 769 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 770 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 771 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 772 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 773 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 774 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 775 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 776 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 777 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 778 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 779 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 780 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 781 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 782 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 783 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 784 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 785 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 786 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 787 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 788 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 789 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 790 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 791 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 792 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 793 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 794 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 795 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 796 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 797 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 798 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 799 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 800 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 801 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 802 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 803 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 804 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 805 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 806 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 807 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 808 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 809 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 810 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 811 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 812 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 813 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 814 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 815 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 816 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 817 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 818 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 819 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 820 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 821 | 18 + 768 * sizeof (short) / sizeof (int) + 160, | ||
| 822 | 18 + 768 * sizeof (short) / sizeof (int) + 1488 | ||
| 823 | }, | ||
| 824 | { | ||
| 825 | 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFFFFFFU, | ||
| 826 | 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 827 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 828 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 829 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 830 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 831 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFCFFFFFFU, | ||
| 832 | 0xFFFFD7F0U, 0xFFFFFFFBU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 833 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 834 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 835 | 0xFFFFFFFFU, 0xFFFEFFFFU, 0xFE7FFFFFU, 0xFFFFFFFFU, | ||
| 836 | 0xFFFEE7FFU, 0xFFFFFFFFU, 0xFFFF00FFU, 0x001F87FFU, | ||
| 837 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 838 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 839 | 0xFFFFBFFFU, 0xFFFFFFFFU, 0xFFFFE7FFU, 0xFFFFFFFFU, | ||
| 840 | 0xFFFFFFFFU, 0x0003FFFFU, 0xFFFFFFFFU, 0xE7FFFFFFU, | ||
| 841 | 0xFFFFFFFFU, 0x7FFF3FFFU, 0x4FFFFFFFU, 0xFFFF07FFU, | ||
| 842 | 0xFF837FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 843 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 844 | 0xFFF99FEFU, 0xF3C5FDFFU, 0xB080799FU, 0x7FFFFFCFU, | ||
| 845 | 0xFFF987EEU, 0xD36DFDFFU, 0x5E023987U, 0x007FFFC0U, | ||
| 846 | 0xFFFBBFEEU, 0xF3EDFDFFU, 0x00013BBFU, 0xFE03FFCFU, | ||
| 847 | 0xFFF99FEEU, 0xF3EDFDFFU, 0xB0E0399FU, 0x00FFFFCFU, | ||
| 848 | 0xD63DC7ECU, 0xC3FFC718U, 0x00813DC7U, 0x07FFFFC0U, | ||
| 849 | 0xFFFDDFFFU, 0xF3FFFDFFU, 0x27603DDFU, 0xFF80FFCFU, | ||
| 850 | 0xFFFDDFFFU, 0xF3EFFDFFU, 0x60603DDFU, 0x000EFFCFU, | ||
| 851 | 0xFFFDDFFFU, 0xFFFFFFFFU, 0xFFF0FDDFU, 0xFFFFFFCFU, | ||
| 852 | 0xFC7FFFEEU, 0x2FFBFFFFU, 0xFF5F847FU, 0x001CFFC0U, | ||
| 853 | 0xFFFFFFFEU, 0x87FFFFFFU, 0x0FFFFFFFU, 0x00000000U, | ||
| 854 | 0xFFFFF7D6U, 0x3FFFFFAFU, 0xF3FF7F5FU, 0x00000000U, | ||
| 855 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFEFFU, 0xFFFE1FFFU, | ||
| 856 | 0xFEFFFFFFU, 0xDFFFFFFFU, 0x07FFDFFFU, 0x00000000U, | ||
| 857 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 858 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF20BFU, 0xFFFFFFFFU, | ||
| 859 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 860 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 861 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3D7F3DFFU, 0xFFFFFFFFU, | ||
| 862 | 0xFFFF3DFFU, 0x7F3DFFFFU, 0xFF7FFF3DU, 0xFFFFFFFFU, | ||
| 863 | 0xFF3DFFFFU, 0xFFFFFFFFU, 0xE7FFFFFFU, 0x1FFFFFFFU, | ||
| 864 | 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3F3FFFFFU, | ||
| 865 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 866 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 867 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 868 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 869 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 870 | 0x1FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 871 | 0x803FFFFFU, 0x007FFFFFU, 0x000FFFFFU, 0x000DDFFFU, | ||
| 872 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU, 0x03FF03FFU, | ||
| 873 | 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 874 | 0xFFFFFFFFU, 0xFFFF07FFU, 0xFFFFFFFFU, 0x003FFFFFU, | ||
| 875 | 0x7FFFFFFFU, 0x0FFF0FFFU, 0xFFFFFFF1U, 0x001F3FFFU, | ||
| 876 | 0xFFFFFFFFU, 0xFFFF0FFFU, 0xC7FF03FFU, 0xFFFFFFFFU, | ||
| 877 | 0xCFFFFFFFU, 0xFFFFFFFFU, 0x7FFFFFFFU, 0x9FFFFFFFU, | ||
| 878 | 0x03FF03FFU, 0xFFFF3FFFU, 0x00007FFFU, 0x00000000U, | ||
| 879 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFDFFFU, 0xFFFFFFFFU, | ||
| 880 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF00FFFFFU, | ||
| 881 | 0xFFFFFFFFU, 0xF8FFFFFFU, 0xFFFFE3FFU, 0xFFFFFFFFU, | ||
| 882 | 0xFFFF07FFU, 0xE7FFFFFFU, 0xFFFF00FFU, 0x07FFFFFFU, | ||
| 883 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 884 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 885 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 886 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 887 | 0x3F3FFFFFU, 0xFFFFFFFFU, 0xAAFF3F3FU, 0x3FFFFFFFU, | ||
| 888 | 0xFFFFFFFFU, 0xFFDFFFFFU, 0xEFCFFFDFU, 0x7FDCFFFFU, | ||
| 889 | 0xFFFFFFFFU, 0xFFFFFCFFU, 0xFFFFFFFFU, 0xFFF3FFDFU, | ||
| 890 | 0x1FFF7FFFU, 0xFFFFFFFFU, 0xFFFF0001U, 0x0001FFFFU, | ||
| 891 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 892 | 0xFFFF0FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 893 | 0xFFFFFFFFU, 0x000003FFU, 0x000007FFU, 0xFFFFFFFFU, | ||
| 894 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 895 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 896 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 897 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 898 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 899 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFCFFFFFU, | ||
| 900 | 0xFFBFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 901 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 902 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFE0FFFFFU, | ||
| 903 | 0xFFFFFFFFU, 0xFFFF20BFU, 0xFFFFFFFFU, 0x800180FFU, | ||
| 904 | 0x007FFFFFU, 0x7F7F7F7FU, 0x7F7F7F7FU, 0xFFFFFFFFU, | ||
| 905 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU, 0x00000000U, | ||
| 906 | 0xFBFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000FFFFFU, | ||
| 907 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 908 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0xFFFF0000U, | ||
| 909 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFEU, 0xFFFFFFFFU, | ||
| 910 | 0xFE7FFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 911 | 0xFFFFFFE0U, 0xFFFEFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 912 | 0xFFFF7FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF803FU, | ||
| 913 | 0x7FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 914 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 915 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 916 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 917 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 918 | 0xFFFF1FFFU, 0xFFFFFFFFU, 0xFFFF007FU, 0xFFFFFFFFU, | ||
| 919 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 920 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 921 | 0xFFFFFFFFU, 0x00000FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 922 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00FFFFFFU, | ||
| 923 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 924 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x1FEB3FFFU, 0xFFFC0000U, | ||
| 925 | 0xFFFFFFFFU, 0x03FF1FFFU, 0xFFFFFFFFU, 0x00FFFFFFU, | ||
| 926 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFC03FU, 0xFFFFFFFFU, | ||
| 927 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x800FFFFFU, 0x1FFFFFFFU, | ||
| 928 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xC3FFBFFFU, 0x7FFFFFFFU, | ||
| 929 | 0xFFFFFFFFU, 0x007FFFFFU, 0xF3FF3FFFU, 0xFFFFFFFFU, | ||
| 930 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF8000007U, 0x007FFFFFU, | ||
| 931 | 0x007E7E7EU, 0xFFFF7F7FU, 0xFFFFFFFFU, 0xFFFF0FFFU, | ||
| 932 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF3FFFU, | ||
| 933 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 934 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 935 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 936 | 0xFFFFFFFFU, 0xFFFF000FU, 0xFFFFF87FU, 0x0FFFFFFFU, | ||
| 937 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF3FFFU, | ||
| 938 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, 0x00000000U, | ||
| 939 | 0xE0F8007FU, 0x5F7FFFFFU, 0xFFFFFFDBU, 0xFFFFFFFFU, | ||
| 940 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFF80007U, 0xFFFFFFFFU, | ||
| 941 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 942 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 943 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 944 | 0xFFFCFFFFU, 0xFFFFFFFFU, 0x000080FFU, 0xFFFF0000U, | ||
| 945 | 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFF7FFFFU, 0xFFDF0F7FU, | ||
| 946 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x9FFFFFFFU, | ||
| 947 | 0xFFFFFFFEU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 948 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0x1CFCFCFCU, 0x3E007F7FU, | ||
| 949 | 0xFFFFEFFFU, 0xB7FFFF7FU, 0x3FFF3FFFU, 0x00000000U, | ||
| 950 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, | ||
| 951 | 0xFFFFFF87U, 0xFF8FFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 952 | 0x1FFF7FFFU, 0x00000001U, 0xFFFF0000U, 0x3FFFFFFFU, | ||
| 953 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 954 | 0x1FFFFFFFU, 0xFFFFFFFFU, 0x0001FFFFU, 0x0FFFFFFFU, | ||
| 955 | 0xFFFFFFFFU, 0xFFFFE00FU, 0xFFFF07FFU, 0x07FFFFFFU, | ||
| 956 | 0xBFFFFFFFU, 0xFFFFFFFFU, 0x003FFF0FU, 0x00000000U, | ||
| 957 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 958 | 0x3FFFFFFFU, 0xFFFF03FFU, 0xFF0FFFFFU, 0x0FFFFFFFU, | ||
| 959 | 0xFFFFFFFFU, 0xFFFF00FFU, 0xFFFFFFFFU, 0xF7FF800FU, | ||
| 960 | 0xFFB7F7FFU, 0x1BFBFFFBU, 0xFFFFFFFFU, 0x000FFFFFU, | ||
| 961 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 962 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 963 | 0xFFFFFFFFU, 0x007FFFFFU, 0x003FFFFFU, 0x000000FFU, | ||
| 964 | 0xFFFFFFBFU, 0x07FDFFFFU, 0x00000000U, 0x00000000U, | ||
| 965 | 0xFFFFFD3FU, 0x91BFFFFFU, 0xFFBFFFFFU, 0xFFFFFFFFU, | ||
| 966 | 0x7FFFFFFFU, 0x0000FF80U, 0x00000000U, 0xF837FFFFU, | ||
| 967 | 0x8FFFFFFFU, 0x83FFFFFFU, 0x00000000U, 0x00000000U, | ||
| 968 | 0xFFFFFFFFU, 0xF0FFFFFFU, 0xFFFCFFFFU, 0xFFFFFFFFU, | ||
| 969 | 0xFEEFF06FU, 0x873FFFFFU, 0x01FF01FFU, 0xFFFFFFFFU, | ||
| 970 | 0xFFFFFFFFU, 0x00000000U, 0xFFFFFFFFU, 0x007FF87FU, | ||
| 971 | 0xFFFFFFFFU, 0xFE3FFFFFU, 0xFF3FFFFFU, 0xFF07FFFFU, | ||
| 972 | 0x1E03FFFFU, 0x0000FE00U, 0x00000000U, 0x00000000U, | ||
| 973 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000001FFU, 0x00000000U, | ||
| 974 | 0xFFFFFFFFU, 0x0007FFFFU, 0xFFFFFFFFU, 0xFC07FFFFU, | ||
| 975 | 0xFFFFFFFFU, 0x03FF00FFU, 0xFFFFFFFFU, 0xFFFFFE3FU, | ||
| 976 | 0x0000C03FU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 977 | 0x00000000U, 0x00000000U, 0x00000000U, 0x7FFFFFFFU, | ||
| 978 | 0xFFFFFFFFU, 0x00033BFFU, 0x0000001CU, 0xF0000000U, | ||
| 979 | 0xFFFFFFFFU, 0xFFFF00FFU, 0x03FFFFFFU, 0xFFFF0000U, | ||
| 980 | 0x000003FFU, 0xFFFF0000U, 0x00000FFFU, 0x007FFFFFU, | ||
| 981 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFC3FFFU, 0x803FFFFFU, | ||
| 982 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF2007U, 0x03FF01FFU, | ||
| 983 | 0xFFFFFFFFU, 0xFFDFFFFFU, 0xFFFF00FFU, 0x007FFFFFU, | ||
| 984 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x001FFFFEU, | ||
| 985 | 0xFFFBFFFFU, 0xFFFFFFFFU, 0x00000003U, 0x00000000U, | ||
| 986 | 0xBFFFBD7FU, 0xFFFF03FFU, 0xFFFFFFFFU, 0x03FF07FFU, | ||
| 987 | 0xFFF99FEFU, 0xFBEDFDFFU, 0xE081399FU, 0x001F1FCFU, | ||
| 988 | 0xFFFF4BFFU, 0xFFBFFFFFU, 0x01BFF7A5U, 0x00000006U, | ||
| 989 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xEFFFFFFFU, 0x00000003U, | ||
| 990 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF00FFU, 0x00000000U, | ||
| 991 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 992 | 0xFFFFFFFFU, 0xFF3FFFFFU, 0x3FFFFFFFU, 0x00000000U, | ||
| 993 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FF001FU, 0x00001FFFU, | ||
| 994 | 0xFFFFFFFFU, 0x03FFFFFFU, 0xFFFF03FFU, 0x0000000FU, | ||
| 995 | 0xE7FFFFFFU, 0xFFFF0FFFU, 0x0000007FU, 0x00000000U, | ||
| 996 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 997 | 0xFFFFFFFFU, 0x0FFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 998 | 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x8007FFFFU, | ||
| 999 | 0xFF6FF27FU, 0xF9BFFFFFU, 0x03FF007FU, 0x00000000U, | ||
| 1000 | 0x00000000U, 0xFFFFFCFFU, 0xFCFFFFFFU, 0x0000001FU, | ||
| 1001 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF00FFU, 0xFFFFFFFFU, | ||
| 1002 | 0xFFFFFFFFU, 0xFFFF0007U, 0xFFFFFFFFU, 0x01FFFFFFU, | ||
| 1003 | 0x000003FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1004 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x03FF0003U, | ||
| 1005 | 0xFFFFFDFFU, 0xFF7FFFFFU, 0xFFFF003FU, 0xFFFF1FFFU, | ||
| 1006 | 0xFFFCFFFFU, 0x007FFEFFU, 0x00000000U, 0x00000000U, | ||
| 1007 | 0xFFFFFB7FU, 0xB47FFFFFU, 0x03FF00FFU, 0xFFFFFDBFU, | ||
| 1008 | 0x01FB7FFFU, 0x000003FFU, 0x00000000U, 0x00000000U, | ||
| 1009 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1010 | 0x00000000U, 0x00000000U, 0x00000000U, 0x01FFFFFFU, | ||
| 1011 | 0xFFFDFFFFU, 0xC7FFFFFFU, 0x07FFFFFFU, 0x00000000U, | ||
| 1012 | 0x00000000U, 0x00010000U, 0xFFFFFFFFU, 0x8003FFFFU, | ||
| 1013 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1014 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1015 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1016 | 0x03FFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1017 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x001F7FFFU, | ||
| 1018 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1019 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, | ||
| 1020 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1021 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1022 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1023 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1024 | 0xFFFF0000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0007FFFFU, | ||
| 1025 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0xFFFFFFFFU, | ||
| 1026 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1027 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1028 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1029 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1030 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1031 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1032 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x07FFFFFFU, | ||
| 1033 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000007FU, 0x00000000U, | ||
| 1034 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1035 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1036 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1037 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1038 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1039 | 0xFFFFFFFFU, 0x03FFFFFFU, 0x00000000U, 0x00000000U, | ||
| 1040 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1041 | 0xFFFFFFFFU, 0x01FFFFFFU, 0x7FFFFFFFU, 0xFFFFC3FFU, | ||
| 1042 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0xFFFF03FFU, 0x003F3FFFU, | ||
| 1043 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFBFF003FU, 0xE0FFFFFBU, | ||
| 1044 | 0x0000FFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1045 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1046 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1047 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x03FFFFFFU, | ||
| 1048 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1049 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1050 | 0x07FFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1051 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF87FFU, 0xFFFFFFFFU, | ||
| 1052 | 0xFFFF80FFU, 0x00000000U, 0x00000000U, 0x0003001FU, | ||
| 1053 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1054 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1055 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1056 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00FFFFFFU, | ||
| 1057 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1058 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0x80000000U, | ||
| 1059 | 0x000001FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1060 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1061 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1062 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1063 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1064 | 0x00000000U, 0x00000000U, 0x00000000U, 0x6FEF0000U, | ||
| 1065 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1066 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1067 | 0xFFFFFFFFU, 0x00040007U, 0x00270000U, 0xFFFF00F0U, | ||
| 1068 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1069 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1070 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0FFFFFFFU, | ||
| 1071 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1072 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1073 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x1FFF07FFU, | ||
| 1074 | 0xF3FF01FFU, 0x0000000FU, 0x00000000U, 0x00000000U, | ||
| 1075 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1076 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1077 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1078 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, | ||
| 1079 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1080 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1081 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1082 | 0xFFFFFFFFU, 0x000FFFFFU, 0x00000000U, 0x00000000U, | ||
| 1083 | 0xFFFFFFFFU, 0xFFFF3FFFU, 0xFFFF007FU, 0xFFFFFFFFU, | ||
| 1084 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, | ||
| 1085 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1086 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, | ||
| 1087 | 0xFFFFFFFFU, 0xFFFFFE7FU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1088 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000007FFU, | ||
| 1089 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000003FU, 0x00000000U, | ||
| 1090 | 0x00000000U, 0x00000000U, 0x000FFFFFU, 0x000FFFFFU, | ||
| 1091 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x007FFFFFU, 0x01FFFFFFU, | ||
| 1092 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1093 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFDFFFFFU, 0xFFFFFFFFU, | ||
| 1094 | 0xDFFFFFFFU, 0xEBFFDE64U, 0xFFFFFFEFU, 0xFFFFFFFFU, | ||
| 1095 | 0xDFDFE7BFU, 0x7BFFFFFFU, 0xFFFDFC5FU, 0xFFFFFFFFU, | ||
| 1096 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1097 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1098 | 0xFFFFFFFFU, 0xFFFFFF3FU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1099 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1100 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFCFFFU, 0xFFFFFFFFU, | ||
| 1101 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1102 | 0xF8000FFFU, 0x0000FFFEU, 0x00000000U, 0x00000000U, | ||
| 1103 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1104 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1105 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1106 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1107 | 0x7FFFFFFFU, 0x000007E0U, 0x00000000U, 0x00000000U, | ||
| 1108 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1109 | 0xF9FFFF7FU, 0xFFFF07DBU, 0xFFFFFFFFU, 0x00003FFFU, | ||
| 1110 | 0x00008000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1111 | 0xFFFFFFFFU, 0x3FFF1FFFU, 0x0000C3FFU, 0x00000000U, | ||
| 1112 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1113 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1114 | 0xFFFF0000U, 0x00007FFFU, 0xFFFFFFFFU, 0x83FFFFFFU, | ||
| 1115 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1116 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1117 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1118 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x03FFFFFFU, | ||
| 1119 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1120 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x87FFFFFFU, | ||
| 1121 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1122 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1123 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1124 | 0x00000000U, 0x00000000U, 0x00000000U, 0x7FFF6F7FU, | ||
| 1125 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1126 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x007FFF9FU, 0x00000000U, | ||
| 1127 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xC3FF0FFFU, 0x00000000U, | ||
| 1128 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1129 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFFFE0000U, | ||
| 1130 | 0xFFFFFFFFU, 0x001FFFFFU, 0x00000000U, 0x00000000U, | ||
| 1131 | 0xFFFFFFFEU, 0x3FFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 1132 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1133 | 0xFFFFFFEFU, 0x0AF7FE96U, 0xAA96EA84U, 0x5EF7F796U, | ||
| 1134 | 0x0FFFFBFFU, 0x0FFFFBEEU, 0x00000000U, 0x00030000U, | ||
| 1135 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1136 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1137 | 0xFFFFFFFFU, 0xFFFF0FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1138 | 0x000FFFFFU, 0xFFFE7FFFU, 0xFFFEFFFEU, 0x003FFFFFU, | ||
| 1139 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1140 | 0xFFFFFFFFU, 0x00003FFFU, 0x00000000U, 0xFFFFFFC0U, | ||
| 1141 | 0xFFFF0007U, 0x0FFFFFFFU, 0x000301FFU, 0x0000003FU, | ||
| 1142 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1143 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1144 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1145 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1146 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF0FFFFFFU, 0x1FFF1FFFU, | ||
| 1147 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF87FFFFFU, | ||
| 1148 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, 0x00010FFFU, | ||
| 1149 | 0xFFFF0FFFU, 0xFFFFFFFFU, 0x03FF00FFU, 0xFFFFFFFFU, | ||
| 1150 | 0xFFFF00FFU, 0x0FFF3FFFU, 0x00000003U, 0x00000000U, | ||
| 1151 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1152 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1153 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000FFFFFU, 0x1FFF3FFFU, | ||
| 1154 | 0xFFFF83FFU, 0xFFFFFFFFU, 0x9FFFC07FU, 0x01FF03FFU, | ||
| 1155 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1156 | 0xFFF7FFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, | ||
| 1157 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1158 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, | ||
| 1159 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1160 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1161 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1162 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1163 | 0xFFFFFFFFU, 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1164 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1165 | 0x3FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1166 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1167 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1168 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1169 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1170 | 0xFFFFFFFFU, 0xFFFF0003U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1171 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1172 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1173 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1174 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1175 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1176 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF0001U, | ||
| 1177 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU, 0x00000000U, | ||
| 1178 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1179 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1180 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1181 | 0x3FFFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1182 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1183 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1184 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1185 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1186 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1187 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF07FFU, 0xFFFFFFFFU, | ||
| 1188 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1189 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1190 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1191 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1192 | 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, 0x00000000U, | ||
| 1193 | 0x00000002U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1194 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 1195 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1196 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, | ||
| 1197 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1198 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1199 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 1200 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU | ||
| 1201 | } | ||
| 1202 | }; | ||
diff --git a/gl/unictype/ctype_punct.c b/gl/unictype/ctype_punct.c new file mode 100644 index 00000000..f2d647de --- /dev/null +++ b/gl/unictype/ctype_punct.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_punct table. */ | ||
| 26 | #include "ctype_punct.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_punct (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_punct, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_punct.h b/gl/unictype/ctype_punct.h new file mode 100644 index 00000000..cb252114 --- /dev/null +++ b/gl/unictype/ctype_punct.h | |||
| @@ -0,0 +1,870 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[17]; | ||
| 29 | short level2[4 << 7]; | ||
| 30 | unsigned int level3[75 << 4]; | ||
| 31 | } | ||
| 32 | u_is_punct = | ||
| 33 | { | ||
| 34 | { 17 }, | ||
| 35 | { | ||
| 36 | 18 * sizeof (int) / sizeof (short) + 0, | ||
| 37 | 18 * sizeof (int) / sizeof (short) + 128, | ||
| 38 | -1, | ||
| 39 | -1, | ||
| 40 | -1, | ||
| 41 | -1, | ||
| 42 | -1, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | -1, | ||
| 49 | -1, | ||
| 50 | 18 * sizeof (int) / sizeof (short) + 256, | ||
| 51 | 18 * sizeof (int) / sizeof (short) + 384, | ||
| 52 | 18 * sizeof (int) / sizeof (short) + 384 | ||
| 53 | }, | ||
| 54 | { | ||
| 55 | 18 + 512 * sizeof (short) / sizeof (int) + 0, | ||
| 56 | 18 + 512 * sizeof (short) / sizeof (int) + 16, | ||
| 57 | 18 + 512 * sizeof (short) / sizeof (int) + 32, | ||
| 58 | 18 + 512 * sizeof (short) / sizeof (int) + 48, | ||
| 59 | 18 + 512 * sizeof (short) / sizeof (int) + 64, | ||
| 60 | 18 + 512 * sizeof (short) / sizeof (int) + 80, | ||
| 61 | 18 + 512 * sizeof (short) / sizeof (int) + 96, | ||
| 62 | 18 + 512 * sizeof (short) / sizeof (int) + 112, | ||
| 63 | 18 + 512 * sizeof (short) / sizeof (int) + 128, | ||
| 64 | 18 + 512 * sizeof (short) / sizeof (int) + 144, | ||
| 65 | 18 + 512 * sizeof (short) / sizeof (int) + 160, | ||
| 66 | 18 + 512 * sizeof (short) / sizeof (int) + 176, | ||
| 67 | 18 + 512 * sizeof (short) / sizeof (int) + 192, | ||
| 68 | 18 + 512 * sizeof (short) / sizeof (int) + 208, | ||
| 69 | 18 + 512 * sizeof (short) / sizeof (int) + 224, | ||
| 70 | 18 + 512 * sizeof (short) / sizeof (int) + 240, | ||
| 71 | 18 + 512 * sizeof (short) / sizeof (int) + 256, | ||
| 72 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 73 | 18 + 512 * sizeof (short) / sizeof (int) + 288, | ||
| 74 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 75 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 76 | 18 + 512 * sizeof (short) / sizeof (int) + 304, | ||
| 77 | 18 + 512 * sizeof (short) / sizeof (int) + 320, | ||
| 78 | 18 + 512 * sizeof (short) / sizeof (int) + 336, | ||
| 79 | 18 + 512 * sizeof (short) / sizeof (int) + 352, | ||
| 80 | 18 + 512 * sizeof (short) / sizeof (int) + 368, | ||
| 81 | -1, | ||
| 82 | -1, | ||
| 83 | -1, | ||
| 84 | -1, | ||
| 85 | -1, | ||
| 86 | -1, | ||
| 87 | -1, | ||
| 88 | -1, | ||
| 89 | -1, | ||
| 90 | -1, | ||
| 91 | -1, | ||
| 92 | -1, | ||
| 93 | 18 + 512 * sizeof (short) / sizeof (int) + 384, | ||
| 94 | -1, | ||
| 95 | -1, | ||
| 96 | -1, | ||
| 97 | -1, | ||
| 98 | -1, | ||
| 99 | -1, | ||
| 100 | -1, | ||
| 101 | -1, | ||
| 102 | -1, | ||
| 103 | -1, | ||
| 104 | -1, | ||
| 105 | -1, | ||
| 106 | -1, | ||
| 107 | -1, | ||
| 108 | -1, | ||
| 109 | -1, | ||
| 110 | -1, | ||
| 111 | -1, | ||
| 112 | -1, | ||
| 113 | -1, | ||
| 114 | -1, | ||
| 115 | -1, | ||
| 116 | -1, | ||
| 117 | -1, | ||
| 118 | -1, | ||
| 119 | -1, | ||
| 120 | -1, | ||
| 121 | -1, | ||
| 122 | -1, | ||
| 123 | -1, | ||
| 124 | -1, | ||
| 125 | -1, | ||
| 126 | -1, | ||
| 127 | -1, | ||
| 128 | -1, | ||
| 129 | -1, | ||
| 130 | -1, | ||
| 131 | -1, | ||
| 132 | -1, | ||
| 133 | -1, | ||
| 134 | -1, | ||
| 135 | -1, | ||
| 136 | -1, | ||
| 137 | 18 + 512 * sizeof (short) / sizeof (int) + 400, | ||
| 138 | 18 + 512 * sizeof (short) / sizeof (int) + 416, | ||
| 139 | 18 + 512 * sizeof (short) / sizeof (int) + 432, | ||
| 140 | 18 + 512 * sizeof (short) / sizeof (int) + 448, | ||
| 141 | -1, | ||
| 142 | -1, | ||
| 143 | -1, | ||
| 144 | -1, | ||
| 145 | -1, | ||
| 146 | -1, | ||
| 147 | -1, | ||
| 148 | -1, | ||
| 149 | -1, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1, | ||
| 165 | -1, | ||
| 166 | -1, | ||
| 167 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 168 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 169 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 170 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 171 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 172 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 173 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 174 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 175 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 176 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 177 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 178 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 179 | 18 + 512 * sizeof (short) / sizeof (int) + 464, | ||
| 180 | 18 + 512 * sizeof (short) / sizeof (int) + 480, | ||
| 181 | 18 + 512 * sizeof (short) / sizeof (int) + 496, | ||
| 182 | 18 + 512 * sizeof (short) / sizeof (int) + 512, | ||
| 183 | 18 + 512 * sizeof (short) / sizeof (int) + 528, | ||
| 184 | 18 + 512 * sizeof (short) / sizeof (int) + 544, | ||
| 185 | 18 + 512 * sizeof (short) / sizeof (int) + 560, | ||
| 186 | -1, | ||
| 187 | 18 + 512 * sizeof (short) / sizeof (int) + 576, | ||
| 188 | 18 + 512 * sizeof (short) / sizeof (int) + 592, | ||
| 189 | 18 + 512 * sizeof (short) / sizeof (int) + 608, | ||
| 190 | 18 + 512 * sizeof (short) / sizeof (int) + 624, | ||
| 191 | 18 + 512 * sizeof (short) / sizeof (int) + 640, | ||
| 192 | 18 + 512 * sizeof (short) / sizeof (int) + 656, | ||
| 193 | 18 + 512 * sizeof (short) / sizeof (int) + 672, | ||
| 194 | 18 + 512 * sizeof (short) / sizeof (int) + 688, | ||
| 195 | 18 + 512 * sizeof (short) / sizeof (int) + 704, | ||
| 196 | 18 + 512 * sizeof (short) / sizeof (int) + 720, | ||
| 197 | 18 + 512 * sizeof (short) / sizeof (int) + 736, | ||
| 198 | 18 + 512 * sizeof (short) / sizeof (int) + 752, | ||
| 199 | -1, | ||
| 200 | -1, | ||
| 201 | 18 + 512 * sizeof (short) / sizeof (int) + 768, | ||
| 202 | -1, | ||
| 203 | -1, | ||
| 204 | -1, | ||
| 205 | -1, | ||
| 206 | 18 + 512 * sizeof (short) / sizeof (int) + 784, | ||
| 207 | -1, | ||
| 208 | -1, | ||
| 209 | 18 + 512 * sizeof (short) / sizeof (int) + 800, | ||
| 210 | -1, | ||
| 211 | -1, | ||
| 212 | -1, | ||
| 213 | -1, | ||
| 214 | -1, | ||
| 215 | -1, | ||
| 216 | -1, | ||
| 217 | -1, | ||
| 218 | -1, | ||
| 219 | -1, | ||
| 220 | -1, | ||
| 221 | -1, | ||
| 222 | -1, | ||
| 223 | -1, | ||
| 224 | -1, | ||
| 225 | -1, | ||
| 226 | -1, | ||
| 227 | -1, | ||
| 228 | -1, | ||
| 229 | -1, | ||
| 230 | -1, | ||
| 231 | 18 + 512 * sizeof (short) / sizeof (int) + 816, | ||
| 232 | -1, | ||
| 233 | -1, | ||
| 234 | -1, | ||
| 235 | -1, | ||
| 236 | 18 + 512 * sizeof (short) / sizeof (int) + 832, | ||
| 237 | 18 + 512 * sizeof (short) / sizeof (int) + 848, | ||
| 238 | 18 + 512 * sizeof (short) / sizeof (int) + 864, | ||
| 239 | -1, | ||
| 240 | -1, | ||
| 241 | -1, | ||
| 242 | -1, | ||
| 243 | -1, | ||
| 244 | -1, | ||
| 245 | -1, | ||
| 246 | -1, | ||
| 247 | -1, | ||
| 248 | -1, | ||
| 249 | -1, | ||
| 250 | -1, | ||
| 251 | -1, | ||
| 252 | -1, | ||
| 253 | -1, | ||
| 254 | -1, | ||
| 255 | -1, | ||
| 256 | -1, | ||
| 257 | -1, | ||
| 258 | -1, | ||
| 259 | -1, | ||
| 260 | -1, | ||
| 261 | -1, | ||
| 262 | -1, | ||
| 263 | -1, | ||
| 264 | -1, | ||
| 265 | -1, | ||
| 266 | -1, | ||
| 267 | -1, | ||
| 268 | -1, | ||
| 269 | -1, | ||
| 270 | -1, | ||
| 271 | -1, | ||
| 272 | -1, | ||
| 273 | -1, | ||
| 274 | -1, | ||
| 275 | -1, | ||
| 276 | -1, | ||
| 277 | 18 + 512 * sizeof (short) / sizeof (int) + 880, | ||
| 278 | -1, | ||
| 279 | -1, | ||
| 280 | -1, | ||
| 281 | -1, | ||
| 282 | -1, | ||
| 283 | -1, | ||
| 284 | -1, | ||
| 285 | 18 + 512 * sizeof (short) / sizeof (int) + 896, | ||
| 286 | 18 + 512 * sizeof (short) / sizeof (int) + 912, | ||
| 287 | 18 + 512 * sizeof (short) / sizeof (int) + 928, | ||
| 288 | 18 + 512 * sizeof (short) / sizeof (int) + 944, | ||
| 289 | -1, | ||
| 290 | 18 + 512 * sizeof (short) / sizeof (int) + 960, | ||
| 291 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 292 | 18 + 512 * sizeof (short) / sizeof (int) + 976, | ||
| 293 | -1, | ||
| 294 | -1, | ||
| 295 | 18 + 512 * sizeof (short) / sizeof (int) + 992, | ||
| 296 | 18 + 512 * sizeof (short) / sizeof (int) + 1008, | ||
| 297 | 18 + 512 * sizeof (short) / sizeof (int) + 1024, | ||
| 298 | -1, | ||
| 299 | 18 + 512 * sizeof (short) / sizeof (int) + 1040, | ||
| 300 | -1, | ||
| 301 | 18 + 512 * sizeof (short) / sizeof (int) + 1056, | ||
| 302 | 18 + 512 * sizeof (short) / sizeof (int) + 1072, | ||
| 303 | 18 + 512 * sizeof (short) / sizeof (int) + 1088, | ||
| 304 | 18 + 512 * sizeof (short) / sizeof (int) + 1104, | ||
| 305 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 306 | 18 + 512 * sizeof (short) / sizeof (int) + 1120, | ||
| 307 | 18 + 512 * sizeof (short) / sizeof (int) + 1136, | ||
| 308 | 18 + 512 * sizeof (short) / sizeof (int) + 1152, | ||
| 309 | -1, | ||
| 310 | -1, | ||
| 311 | 18 + 512 * sizeof (short) / sizeof (int) + 1168, | ||
| 312 | -1, | ||
| 313 | -1, | ||
| 314 | -1, | ||
| 315 | -1, | ||
| 316 | -1, | ||
| 317 | -1, | ||
| 318 | -1, | ||
| 319 | -1, | ||
| 320 | -1, | ||
| 321 | -1, | ||
| 322 | -1, | ||
| 323 | -1, | ||
| 324 | -1, | ||
| 325 | -1, | ||
| 326 | -1, | ||
| 327 | -1, | ||
| 328 | -1, | ||
| 329 | -1, | ||
| 330 | -1, | ||
| 331 | -1, | ||
| 332 | -1, | ||
| 333 | -1, | ||
| 334 | -1, | ||
| 335 | -1, | ||
| 336 | -1, | ||
| 337 | -1, | ||
| 338 | -1, | ||
| 339 | -1, | ||
| 340 | -1, | ||
| 341 | -1, | ||
| 342 | -1, | ||
| 343 | -1, | ||
| 344 | -1, | ||
| 345 | -1, | ||
| 346 | -1, | ||
| 347 | -1, | ||
| 348 | -1, | ||
| 349 | -1, | ||
| 350 | -1, | ||
| 351 | -1, | ||
| 352 | -1, | ||
| 353 | -1, | ||
| 354 | -1, | ||
| 355 | -1, | ||
| 356 | -1, | ||
| 357 | -1, | ||
| 358 | -1, | ||
| 359 | -1, | ||
| 360 | -1, | ||
| 361 | -1, | ||
| 362 | -1, | ||
| 363 | -1, | ||
| 364 | -1, | ||
| 365 | -1, | ||
| 366 | -1, | ||
| 367 | -1, | ||
| 368 | -1, | ||
| 369 | -1, | ||
| 370 | -1, | ||
| 371 | -1, | ||
| 372 | -1, | ||
| 373 | -1, | ||
| 374 | -1, | ||
| 375 | -1, | ||
| 376 | -1, | ||
| 377 | -1, | ||
| 378 | -1, | ||
| 379 | -1, | ||
| 380 | -1, | ||
| 381 | -1, | ||
| 382 | -1, | ||
| 383 | -1, | ||
| 384 | -1, | ||
| 385 | -1, | ||
| 386 | -1, | ||
| 387 | -1, | ||
| 388 | -1, | ||
| 389 | -1, | ||
| 390 | -1, | ||
| 391 | -1, | ||
| 392 | -1, | ||
| 393 | -1, | ||
| 394 | -1, | ||
| 395 | -1, | ||
| 396 | -1, | ||
| 397 | -1, | ||
| 398 | -1, | ||
| 399 | -1, | ||
| 400 | -1, | ||
| 401 | -1, | ||
| 402 | -1, | ||
| 403 | -1, | ||
| 404 | -1, | ||
| 405 | -1, | ||
| 406 | -1, | ||
| 407 | -1, | ||
| 408 | -1, | ||
| 409 | -1, | ||
| 410 | -1, | ||
| 411 | -1, | ||
| 412 | -1, | ||
| 413 | -1, | ||
| 414 | -1, | ||
| 415 | -1, | ||
| 416 | -1, | ||
| 417 | -1, | ||
| 418 | -1, | ||
| 419 | -1, | ||
| 420 | -1, | ||
| 421 | -1, | ||
| 422 | -1, | ||
| 423 | -1, | ||
| 424 | -1, | ||
| 425 | -1, | ||
| 426 | -1, | ||
| 427 | -1, | ||
| 428 | -1, | ||
| 429 | -1, | ||
| 430 | -1, | ||
| 431 | -1, | ||
| 432 | -1, | ||
| 433 | -1, | ||
| 434 | -1, | ||
| 435 | -1, | ||
| 436 | -1, | ||
| 437 | -1, | ||
| 438 | -1, | ||
| 439 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 440 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 441 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 442 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 443 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 444 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 445 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 446 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 447 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 448 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 449 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 450 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 451 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 452 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 453 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 454 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 455 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 456 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 457 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 458 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 459 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 460 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 461 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 462 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 463 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 464 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 465 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 466 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 467 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 468 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 469 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 470 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 471 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 472 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 473 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 474 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 475 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 476 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 477 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 478 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 479 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 480 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 481 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 482 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 483 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 484 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 485 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 486 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 487 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 488 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 489 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 490 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 491 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 492 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 493 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 494 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 495 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 496 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 497 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 498 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 499 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 500 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 501 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 502 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 503 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 504 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 505 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 506 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 507 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 508 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 509 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 510 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 511 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 512 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 513 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 514 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 515 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 516 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 517 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 518 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 519 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 520 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 521 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 522 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 523 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 524 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 525 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 526 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 527 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 528 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 529 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 530 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 531 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 532 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 533 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 534 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 535 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 536 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 537 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 538 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 539 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 540 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 541 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 542 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 543 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 544 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 545 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 546 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 547 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 548 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 549 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 550 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 551 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 552 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 553 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 554 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 555 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 556 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 557 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 558 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 559 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 560 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 561 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 562 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 563 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 564 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 565 | 18 + 512 * sizeof (short) / sizeof (int) + 272, | ||
| 566 | 18 + 512 * sizeof (short) / sizeof (int) + 1184 | ||
| 567 | }, | ||
| 568 | { | ||
| 569 | 0x00000000U, 0xFC00FFFEU, 0xF8000001U, 0x78000001U, | ||
| 570 | 0x00000000U, 0xFBDFFBFFU, 0x00800000U, 0x00800000U, | ||
| 571 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 572 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 573 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 574 | 0x00000000U, 0x00000000U, 0xFFFC003CU, 0xFFFFAFE0U, | ||
| 575 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFDFU, 0x4020FFFFU, | ||
| 576 | 0x000000B0U, 0x00000000U, 0x00000000U, 0x00400000U, | ||
| 577 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 578 | 0x000003FCU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 579 | 0x00000000U, 0x00000000U, 0xFC000000U, 0x00000000U, | ||
| 580 | 0xFFFEE600U, 0xFFFFFFFFU, 0x000000FFU, 0x00180000U, | ||
| 581 | 0xFFFFFFFFU, 0x00000000U, 0xFFFFF800U, 0x00013C00U, | ||
| 582 | 0x00000000U, 0x00000000U, 0xFFD00000U, 0x60003F9FU, | ||
| 583 | 0x0002BFFFU, 0xFFFF0000U, 0x000007FFU, 0x00000000U, | ||
| 584 | 0x00000000U, 0x0001FFC0U, 0x00000000U, 0xE3CFF800U, | ||
| 585 | 0xFBC00000U, 0x7FFF3EEFU, 0x4E000000U, 0x00000000U, | ||
| 586 | 0xFF830100U, 0x00000000U, 0xFFFFFC00U, 0xFFFFFFFFU, | ||
| 587 | 0x0000000FU, 0xDC000000U, 0x00FEFFFFU, 0x0001003CU, | ||
| 588 | 0x0000000EU, 0xD0000000U, 0x0080399FU, 0x6FFC000CU, | ||
| 589 | 0x0000000EU, 0xD0000000U, 0x00023987U, 0x00630000U, | ||
| 590 | 0x0000000EU, 0xD0000000U, 0x00003BBFU, 0xFC03000CU, | ||
| 591 | 0x0000000EU, 0xD0000000U, 0x00E0399FU, 0x00FD000CU, | ||
| 592 | 0x00000004U, 0xC0000000U, 0x00803DC7U, 0x07FF0000U, | ||
| 593 | 0x0000001FU, 0xD0000000U, 0x00603DDFU, 0xFF80000CU, | ||
| 594 | 0x0000001EU, 0xD0000000U, 0x00603DDFU, 0x0008000CU, | ||
| 595 | 0x0000000FU, 0xD8000000U, 0x7F80BDDFU, 0x03FF000CU, | ||
| 596 | 0x0000000EU, 0x00000000U, 0xFF5F8400U, 0x001C0000U, | ||
| 597 | 0x00000000U, 0x80008000U, 0x0C008040U, 0x00000000U, | ||
| 598 | 0x00000000U, 0x1FF20000U, 0x00007F00U, 0x00000000U, | ||
| 599 | 0xFFFFFFFEU, 0xFFFFFC00U, 0x00000000U, 0xFFFE0000U, | ||
| 600 | 0xFEFFE0FFU, 0xDFFFFFFFU, 0x07FFDFFFU, 0x00000000U, | ||
| 601 | 0x00000000U, 0x7FFFF800U, 0xC3C0FC00U, 0x001E3F9DU, | ||
| 602 | 0xFC00BFFCU, 0x00000000U, 0x00000000U, 0x08000000U, | ||
| 603 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 604 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 605 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 606 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 607 | 0x00000000U, 0x00000000U, 0xE0000000U, 0x1FFFFFFFU, | ||
| 608 | 0x03FF0000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 609 | 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 610 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 611 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 612 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 613 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00006000U, | ||
| 614 | 0x18000000U, 0x00000000U, 0x00000000U, 0x00003800U, | ||
| 615 | 0x003C0000U, 0x007C0000U, 0x000C0000U, 0x000C0000U, | ||
| 616 | 0x00000000U, 0xFFF00000U, 0x2F7FFFFFU, 0x03FF0000U, | ||
| 617 | 0x0000FFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 618 | 0x00000060U, 0x00000200U, 0x00000000U, 0x00000000U, | ||
| 619 | 0x00000000U, 0x0FFF0FFFU, 0x00000031U, 0x00000000U, | ||
| 620 | 0x00000000U, 0x00000000U, 0xC4000000U, 0xFFFFFFFFU, | ||
| 621 | 0xCF800000U, 0x00000000U, 0x7FE00000U, 0x9FFFFFFFU, | ||
| 622 | 0x00000000U, 0xFFFF3F7FU, 0x00007FFFU, 0x00000000U, | ||
| 623 | 0x0000001FU, 0xFFF00000U, 0xFC00C01FU, 0xFFFFFFFFU, | ||
| 624 | 0x00000007U, 0x00003FFEU, 0x00000000U, 0xF00FFFC0U, | ||
| 625 | 0x00000000U, 0xF8FFFFF0U, 0x00000000U, 0xC0000000U, | ||
| 626 | 0x00000000U, 0x00000000U, 0xFFFF00FFU, 0x039021FFU, | ||
| 627 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 628 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 629 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 630 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 631 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 632 | 0x00000000U, 0xA0000000U, 0xE000E003U, 0x6000E000U, | ||
| 633 | 0xFFFFF880U, 0xFFFFFCFFU, 0x7FFFFFFFU, 0x7FF1FFDFU, | ||
| 634 | 0x00007FFFU, 0xFFFFFFFFU, 0xFFFF0001U, 0x0001FFFFU, | ||
| 635 | 0xC1D0037BU, 0x0C0040AFU, 0xFFFFBC1FU, 0x00000000U, | ||
| 636 | 0xFFFF0E00U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 637 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 638 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 639 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 640 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 641 | 0xFFFFFFFFU, 0x000003FFU, 0x000007FFU, 0xFFFFFFFFU, | ||
| 642 | 0x0FFFFFFFU, 0x00000000U, 0x00000000U, 0xFFFFFC00U, | ||
| 643 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 644 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 645 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 646 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 647 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFCFFFFFU, | ||
| 648 | 0xFFBFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 649 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 650 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFE0387E0U, | ||
| 651 | 0x00000000U, 0x00000000U, 0x00000000U, 0x80010000U, | ||
| 652 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFFFFFFFFU, | ||
| 653 | 0xFFFFFFFFU, 0xFFFF7FFFU, 0x3FFFFFFFU, 0x00000000U, | ||
| 654 | 0xFBFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000FFFFFU, | ||
| 655 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 656 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0xFFFF0000U, | ||
| 657 | 0xFFFFFF1EU, 0xE0C1FC01U, 0x00000000U, 0x00000000U, | ||
| 658 | 0x1E000000U, 0x00000001U, 0x00000000U, 0x08000000U, | ||
| 659 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 660 | 0xFFFF0000U, 0x00000000U, 0xFFFFFFFFU, 0x0000803FU, | ||
| 661 | 0x7FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 662 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 663 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 664 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 665 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 666 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 667 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 668 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 669 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 670 | 0xFFFF0000U, 0xFFFFFFFFU, 0x0000007FU, 0xC0000000U, | ||
| 671 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 672 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 673 | 0x0000E000U, 0x00000000U, 0x00000000U, 0x7FFF8000U, | ||
| 674 | 0xC0000000U, 0x00000000U, 0x00000000U, 0x00FF0000U, | ||
| 675 | 0x007FFFFFU, 0x00000003U, 0x00000000U, 0x00000000U, | ||
| 676 | 0x00000600U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 677 | 0x00000844U, 0x03FF1FF8U, 0x00000000U, 0x00F00000U, | ||
| 678 | 0x00000003U, 0xFFF00000U, 0x0000C03FU, 0x9703FFFFU, | ||
| 679 | 0x00000000U, 0x0000FFC0U, 0x800FFF80U, 0x00000000U, | ||
| 680 | 0x0000000FU, 0xFFF80000U, 0xC0003FFFU, 0x00000020U, | ||
| 681 | 0x00000000U, 0x007FFE00U, 0xF0003008U, 0x3B800000U, | ||
| 682 | 0x00000000U, 0xC19D0000U, 0xC0000002U, 0x0063F800U, | ||
| 683 | 0x00000000U, 0x00000000U, 0x08000000U, 0x00000C00U, | ||
| 684 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00003FF8U, | ||
| 685 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 686 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 687 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 688 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 689 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 690 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 691 | 0x40000000U, 0x00000200U, 0x00000000U, 0x00000000U, | ||
| 692 | 0x00000000U, 0xFFFC0000U, 0x00000007U, 0x00000000U, | ||
| 693 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 694 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 695 | 0x00000000U, 0xC0000000U, 0x0000FFFFU, 0x00000000U, | ||
| 696 | 0x00000000U, 0x00000000U, 0x00008000U, 0xF0000000U, | ||
| 697 | 0x03FFFFFFU, 0xFFFFFFFFU, 0xFFF7FFFFU, 0x00000F7FU, | ||
| 698 | 0x00000000U, 0x00000000U, 0x00000000U, 0x80000000U, | ||
| 699 | 0xFC00FFFEU, 0xF8000001U, 0xF8000001U, 0x0000003FU, | ||
| 700 | 0x00000000U, 0x00000000U, 0x00000000U, 0x3E007F7FU, | ||
| 701 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 702 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 703 | 0xFFFFFF87U, 0xFF8FFFFFU, 0x00000000U, 0xFFE00000U, | ||
| 704 | 0x1FFF7FFFU, 0x00000001U, 0xFFFF0000U, 0x3FFFFFFFU, | ||
| 705 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 706 | 0x00000000U, 0x00000000U, 0x00000000U, 0x0FFFFFFFU, | ||
| 707 | 0x00000000U, 0x0000000FU, 0x00000000U, 0x07C00000U, | ||
| 708 | 0x80000000U, 0x00000000U, 0x00010000U, 0x00000000U, | ||
| 709 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 710 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 711 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00008000U, | ||
| 712 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 713 | 0x00000000U, 0x00000000U, 0xFF800000U, 0xFF800000U, | ||
| 714 | 0x00000000U, 0x0000FF80U, 0x00000000U, 0xF8000000U, | ||
| 715 | 0x8FC00000U, 0x80000000U, 0x00000000U, 0x00000000U, | ||
| 716 | 0x00000000U, 0x30000000U, 0xFFFCFFFFU, 0xFFFFFFFFU, | ||
| 717 | 0x0000F06EU, 0x87000000U, 0x01FF01FFU, 0xE0000000U, | ||
| 718 | 0xE0000000U, 0x00000000U, 0x00000100U, 0x007FF860U, | ||
| 719 | 0x00000000U, 0xFE000000U, 0xFF000000U, 0xFF000000U, | ||
| 720 | 0x1E000000U, 0x0000FE00U, 0x00000000U, 0x00000000U, | ||
| 721 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 722 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFC000000U, | ||
| 723 | 0x00000000U, 0x000000F0U, 0x00000000U, 0x00007E00U, | ||
| 724 | 0x0000C000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 725 | 0x00000000U, 0x00000000U, 0x00000000U, 0x7FFFFFFFU, | ||
| 726 | 0x00000000U, 0x00003800U, 0x00000000U, 0xF0000000U, | ||
| 727 | 0xE0000000U, 0x0000007FU, 0x03FFFFC0U, 0x00000000U, | ||
| 728 | 0x000003FCU, 0x00000000U, 0x00000FE0U, 0x00000000U, | ||
| 729 | 0x00000007U, 0xFF000000U, 0xFFFC3FFFU, 0x8019003FU, | ||
| 730 | 0x00000007U, 0xFFFF0000U, 0x00002007U, 0x00000000U, | ||
| 731 | 0x00000007U, 0x001FFF80U, 0x0000006FU, 0x00380000U, | ||
| 732 | 0x00000007U, 0xFFF80000U, 0xE800FFE1U, 0x001FFFFEU, | ||
| 733 | 0x00000000U, 0x7FFFF000U, 0x00000002U, 0x00000000U, | ||
| 734 | 0x00000000U, 0x00000200U, 0x80000000U, 0x000007FFU, | ||
| 735 | 0x0000000FU, 0xD8000000U, 0x0080399FU, 0x001F1FCCU, | ||
| 736 | 0x00000000U, 0xFF000000U, 0x01B5F7A5U, 0x00000006U, | ||
| 737 | 0x00000000U, 0xFFE00000U, 0x6C00F87FU, 0x00000000U, | ||
| 738 | 0x00000000U, 0xFFFF0000U, 0x0000004FU, 0x00000000U, | ||
| 739 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 740 | 0x00000000U, 0xFF3F8000U, 0x30FFFFFFU, 0x00000000U, | ||
| 741 | 0x00000000U, 0xFFFF0000U, 0x0000000FU, 0x00001FFFU, | ||
| 742 | 0x00000000U, 0x02FFF800U, 0x00000000U, 0x00000000U, | ||
| 743 | 0xE0000000U, 0xFC000FFFU, 0x00000000U, 0x00000000U, | ||
| 744 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 745 | 0x00000000U, 0x0FFFF000U, 0x00000000U, 0x00000000U, | ||
| 746 | 0x00000000U, 0x00000000U, 0x00000000U, 0x0007FC00U, | ||
| 747 | 0x00000000U, 0x79BF0000U, 0x0000007DU, 0x00000000U, | ||
| 748 | 0x00000000U, 0x00000000U, 0xFCFE0000U, 0x00000015U, | ||
| 749 | 0x000007FEU, 0xFBF80000U, 0x0FFE00FFU, 0x00000000U, | ||
| 750 | 0xDFFFFC00U, 0x00000007U, 0x00000000U, 0x00000000U, | ||
| 751 | 0x000003FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 752 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000002U, | ||
| 753 | 0x00000000U, 0xFF7F8000U, 0xFC00003EU, 0x00031FFFU, | ||
| 754 | 0xFFFC0000U, 0x007FFEFFU, 0x00000000U, 0x00000000U, | ||
| 755 | 0x00000000U, 0xB47E0000U, 0x000000BFU, 0x00000000U, | ||
| 756 | 0x00FB7C00U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 757 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 758 | 0x00000000U, 0x00000000U, 0x00000000U, 0x01F80000U, | ||
| 759 | 0x0000000BU, 0xC7F00000U, 0x0400FFFFU, 0x00000000U, | ||
| 760 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x8003FFFFU, | ||
| 761 | 0x00000000U, 0x00000000U, 0x00000000U, 0x001F0000U, | ||
| 762 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 763 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 764 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 765 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 766 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 767 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 768 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00060000U, | ||
| 769 | 0x00000000U, 0xFFFF0000U, 0x003FFF81U, 0x00000000U, | ||
| 770 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 771 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 772 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 773 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 774 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 775 | 0xC0000000U, 0x0000FFFFU, 0x00000000U, 0x00000000U, | ||
| 776 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 777 | 0x00000000U, 0x00000000U, 0x00000000U, 0x0000C000U, | ||
| 778 | 0x00000000U, 0x00000000U, 0x00000000U, 0x003F0000U, | ||
| 779 | 0x00000000U, 0xFFFF0000U, 0xF8000030U, 0x00000003U, | ||
| 780 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 781 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 782 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 783 | 0x00000000U, 0x00000000U, 0x00000000U, 0x0000E000U, | ||
| 784 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 785 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 786 | 0x07FFFFFFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 787 | 0x00000000U, 0x00000000U, 0xFFFE8000U, 0xFFFFFFFFU, | ||
| 788 | 0x000780FFU, 0x00000000U, 0x00000000U, 0x00030014U, | ||
| 789 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 790 | 0xF0000000U, 0x0000000FU, 0x00000000U, 0x00000000U, | ||
| 791 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 792 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 793 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 794 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0x00000000U, | ||
| 795 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 796 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 797 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 798 | 0xFFFFFFFFU, 0x000FFFFFU, 0x00000000U, 0x00000000U, | ||
| 799 | 0xFFFFFFFFU, 0xFFFF3FFFU, 0xFFFF007FU, 0xFFFFFFFFU, | ||
| 800 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, | ||
| 801 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 802 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, | ||
| 803 | 0xFFFFFFFFU, 0xFFFFFE7FU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 804 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000007FFU, | ||
| 805 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000003FU, 0x00000000U, | ||
| 806 | 0x00000000U, 0x00000000U, 0x000FFFFFU, 0x000FFFFFU, | ||
| 807 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x007FFFFFU, 0x01FFFFFFU, | ||
| 808 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 809 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 810 | 0x00000000U, 0x00000000U, 0x08000002U, 0x08000000U, | ||
| 811 | 0x00200000U, 0x00200000U, 0x00008000U, 0x00008000U, | ||
| 812 | 0x00000200U, 0x00000200U, 0x00000008U, 0x00000000U, | ||
| 813 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 814 | 0xF8000FFFU, 0x0000FFFEU, 0x00000000U, 0x00000000U, | ||
| 815 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 816 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 817 | 0xF9FFFF7FU, 0x000007DBU, 0x00000000U, 0x00000000U, | ||
| 818 | 0x00008000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 819 | 0x00000000U, 0x007F0000U, 0x00008000U, 0x00000000U, | ||
| 820 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 821 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 822 | 0x00000000U, 0x00004000U, 0x00000000U, 0x8000F000U, | ||
| 823 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 824 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 825 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 826 | 0x00000000U, 0x00000000U, 0x00000000U, 0x0000F000U, | ||
| 827 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 828 | 0x00000000U, 0x00000000U, 0x00000000U, 0x8000C000U, | ||
| 829 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 830 | 0x00000000U, 0x00000000U, 0x007FFF80U, 0x00000000U, | ||
| 831 | 0x00000000U, 0x00000000U, 0xC00007F0U, 0x00000000U, | ||
| 832 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 833 | 0x00000000U, 0x00000000U, 0x00000000U, 0xFFFE0000U, | ||
| 834 | 0xFFFFFFFFU, 0x001FFFFFU, 0x00000000U, 0x00000000U, | ||
| 835 | 0xFFFFFFFEU, 0x3FFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 836 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 837 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 838 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00030000U, | ||
| 839 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 840 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 841 | 0xFFFFFFFFU, 0xFFFF0FFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 842 | 0x000FFFFFU, 0xFFFE7FFFU, 0xFFFEFFFEU, 0x003FFFFFU, | ||
| 843 | 0x0000FFFFU, 0x0000E000U, 0x0000FC00U, 0x0000FC00U, | ||
| 844 | 0xFFFFF800U, 0x00003FDFU, 0x00000000U, 0x00000000U, | ||
| 845 | 0xFFFF0007U, 0x0FFFFFFFU, 0x000301FFU, 0x0000003FU, | ||
| 846 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 847 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 848 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 849 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 850 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF0FFFFFFU, 0x1FFF1FFFU, | ||
| 851 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xF87FFFFFU, | ||
| 852 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x03FFFFFFU, 0x00010FFFU, | ||
| 853 | 0xFFFF0FFFU, 0xFFFFFFFFU, 0x03FF00FFU, 0xFFFFFFFFU, | ||
| 854 | 0xFFFF00FFU, 0x0FFF3FFFU, 0x00000003U, 0x00000000U, | ||
| 855 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 856 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 857 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x000FFFFFU, 0x1FFF3FFFU, | ||
| 858 | 0xFFFF83FFU, 0xFFFFFFFFU, 0x9FFFC07FU, 0x01FF03FFU, | ||
| 859 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 860 | 0xFFF7FFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, | ||
| 861 | 0x00000002U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 862 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 863 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 864 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, | ||
| 865 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 866 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 867 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 868 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x3FFFFFFFU | ||
| 869 | } | ||
| 870 | }; | ||
diff --git a/gl/unictype/ctype_space.c b/gl/unictype/ctype_space.c new file mode 100644 index 00000000..4c032398 --- /dev/null +++ b/gl/unictype/ctype_space.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_space table. */ | ||
| 26 | #include "ctype_space.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_space (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_space, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_space.h b/gl/unictype/ctype_space.h new file mode 100644 index 00000000..93ed2467 --- /dev/null +++ b/gl/unictype/ctype_space.h | |||
| @@ -0,0 +1,184 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[1]; | ||
| 29 | short level2[1 << 7]; | ||
| 30 | unsigned int level3[4 << 4]; | ||
| 31 | } | ||
| 32 | u_is_space = | ||
| 33 | { | ||
| 34 | { 1 }, | ||
| 35 | { 2 * sizeof (int) / sizeof (short) + 0 }, | ||
| 36 | { | ||
| 37 | 2 + 128 * sizeof (short) / sizeof (int) + 0, | ||
| 38 | -1, | ||
| 39 | -1, | ||
| 40 | -1, | ||
| 41 | -1, | ||
| 42 | -1, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | 2 + 128 * sizeof (short) / sizeof (int) + 16, | ||
| 49 | -1, | ||
| 50 | -1, | ||
| 51 | -1, | ||
| 52 | -1, | ||
| 53 | 2 + 128 * sizeof (short) / sizeof (int) + 32, | ||
| 54 | -1, | ||
| 55 | -1, | ||
| 56 | -1, | ||
| 57 | -1, | ||
| 58 | -1, | ||
| 59 | -1, | ||
| 60 | -1, | ||
| 61 | 2 + 128 * sizeof (short) / sizeof (int) + 48, | ||
| 62 | -1, | ||
| 63 | -1, | ||
| 64 | -1, | ||
| 65 | -1, | ||
| 66 | -1, | ||
| 67 | -1, | ||
| 68 | -1, | ||
| 69 | -1, | ||
| 70 | -1, | ||
| 71 | -1, | ||
| 72 | -1, | ||
| 73 | -1, | ||
| 74 | -1, | ||
| 75 | -1, | ||
| 76 | -1, | ||
| 77 | -1, | ||
| 78 | -1, | ||
| 79 | -1, | ||
| 80 | -1, | ||
| 81 | -1, | ||
| 82 | -1, | ||
| 83 | -1, | ||
| 84 | -1, | ||
| 85 | -1, | ||
| 86 | -1, | ||
| 87 | -1, | ||
| 88 | -1, | ||
| 89 | -1, | ||
| 90 | -1, | ||
| 91 | -1, | ||
| 92 | -1, | ||
| 93 | -1, | ||
| 94 | -1, | ||
| 95 | -1, | ||
| 96 | -1, | ||
| 97 | -1, | ||
| 98 | -1, | ||
| 99 | -1, | ||
| 100 | -1, | ||
| 101 | -1, | ||
| 102 | -1, | ||
| 103 | -1, | ||
| 104 | -1, | ||
| 105 | -1, | ||
| 106 | -1, | ||
| 107 | -1, | ||
| 108 | -1, | ||
| 109 | -1, | ||
| 110 | -1, | ||
| 111 | -1, | ||
| 112 | -1, | ||
| 113 | -1, | ||
| 114 | -1, | ||
| 115 | -1, | ||
| 116 | -1, | ||
| 117 | -1, | ||
| 118 | -1, | ||
| 119 | -1, | ||
| 120 | -1, | ||
| 121 | -1, | ||
| 122 | -1, | ||
| 123 | -1, | ||
| 124 | -1, | ||
| 125 | -1, | ||
| 126 | -1, | ||
| 127 | -1, | ||
| 128 | -1, | ||
| 129 | -1, | ||
| 130 | -1, | ||
| 131 | -1, | ||
| 132 | -1, | ||
| 133 | -1, | ||
| 134 | -1, | ||
| 135 | -1, | ||
| 136 | -1, | ||
| 137 | -1, | ||
| 138 | -1, | ||
| 139 | -1, | ||
| 140 | -1, | ||
| 141 | -1, | ||
| 142 | -1, | ||
| 143 | -1, | ||
| 144 | -1, | ||
| 145 | -1, | ||
| 146 | -1, | ||
| 147 | -1, | ||
| 148 | -1, | ||
| 149 | -1, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1 | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | 0x00003E00U, 0x00000001U, 0x00000000U, 0x00000000U, | ||
| 168 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 169 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 170 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 171 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 172 | 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 173 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 174 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 175 | 0x0000077FU, 0x00000300U, 0x80000000U, 0x00000000U, | ||
| 176 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 177 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 178 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 179 | 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 180 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 181 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 182 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U | ||
| 183 | } | ||
| 184 | }; | ||
diff --git a/gl/unictype/ctype_upper.c b/gl/unictype/ctype_upper.c new file mode 100644 index 00000000..af2c3fe6 --- /dev/null +++ b/gl/unictype/ctype_upper.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_upper table. */ | ||
| 26 | #include "ctype_upper.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_upper (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_upper, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_upper.h b/gl/unictype/ctype_upper.h new file mode 100644 index 00000000..ef527809 --- /dev/null +++ b/gl/unictype/ctype_upper.h | |||
| @@ -0,0 +1,367 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[2]; | ||
| 29 | short level2[2 << 7]; | ||
| 30 | unsigned int level3[17 << 4]; | ||
| 31 | } | ||
| 32 | u_is_upper = | ||
| 33 | { | ||
| 34 | { 2 }, | ||
| 35 | { | ||
| 36 | 3 * sizeof (int) / sizeof (short) + 0, | ||
| 37 | 3 * sizeof (int) / sizeof (short) + 128 | ||
| 38 | }, | ||
| 39 | { | ||
| 40 | 3 + 256 * sizeof (short) / sizeof (int) + 0, | ||
| 41 | 3 + 256 * sizeof (short) / sizeof (int) + 16, | ||
| 42 | 3 + 256 * sizeof (short) / sizeof (int) + 32, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | 3 + 256 * sizeof (short) / sizeof (int) + 48, | ||
| 49 | 3 + 256 * sizeof (short) / sizeof (int) + 64, | ||
| 50 | -1, | ||
| 51 | -1, | ||
| 52 | -1, | ||
| 53 | -1, | ||
| 54 | 3 + 256 * sizeof (short) / sizeof (int) + 80, | ||
| 55 | 3 + 256 * sizeof (short) / sizeof (int) + 96, | ||
| 56 | 3 + 256 * sizeof (short) / sizeof (int) + 112, | ||
| 57 | -1, | ||
| 58 | 3 + 256 * sizeof (short) / sizeof (int) + 128, | ||
| 59 | -1, | ||
| 60 | -1, | ||
| 61 | -1, | ||
| 62 | 3 + 256 * sizeof (short) / sizeof (int) + 144, | ||
| 63 | -1, | ||
| 64 | -1, | ||
| 65 | -1, | ||
| 66 | -1, | ||
| 67 | -1, | ||
| 68 | -1, | ||
| 69 | -1, | ||
| 70 | -1, | ||
| 71 | -1, | ||
| 72 | -1, | ||
| 73 | -1, | ||
| 74 | -1, | ||
| 75 | -1, | ||
| 76 | -1, | ||
| 77 | -1, | ||
| 78 | -1, | ||
| 79 | -1, | ||
| 80 | -1, | ||
| 81 | -1, | ||
| 82 | -1, | ||
| 83 | -1, | ||
| 84 | -1, | ||
| 85 | -1, | ||
| 86 | -1, | ||
| 87 | -1, | ||
| 88 | -1, | ||
| 89 | -1, | ||
| 90 | -1, | ||
| 91 | -1, | ||
| 92 | -1, | ||
| 93 | -1, | ||
| 94 | -1, | ||
| 95 | -1, | ||
| 96 | -1, | ||
| 97 | -1, | ||
| 98 | -1, | ||
| 99 | -1, | ||
| 100 | -1, | ||
| 101 | -1, | ||
| 102 | -1, | ||
| 103 | -1, | ||
| 104 | -1, | ||
| 105 | -1, | ||
| 106 | -1, | ||
| 107 | -1, | ||
| 108 | -1, | ||
| 109 | -1, | ||
| 110 | -1, | ||
| 111 | -1, | ||
| 112 | -1, | ||
| 113 | -1, | ||
| 114 | -1, | ||
| 115 | -1, | ||
| 116 | -1, | ||
| 117 | -1, | ||
| 118 | -1, | ||
| 119 | -1, | ||
| 120 | -1, | ||
| 121 | -1, | ||
| 122 | -1, | ||
| 123 | 3 + 256 * sizeof (short) / sizeof (int) + 160, | ||
| 124 | -1, | ||
| 125 | -1, | ||
| 126 | -1, | ||
| 127 | -1, | ||
| 128 | -1, | ||
| 129 | -1, | ||
| 130 | -1, | ||
| 131 | -1, | ||
| 132 | -1, | ||
| 133 | -1, | ||
| 134 | -1, | ||
| 135 | -1, | ||
| 136 | -1, | ||
| 137 | -1, | ||
| 138 | -1, | ||
| 139 | -1, | ||
| 140 | -1, | ||
| 141 | -1, | ||
| 142 | -1, | ||
| 143 | -1, | ||
| 144 | -1, | ||
| 145 | -1, | ||
| 146 | -1, | ||
| 147 | -1, | ||
| 148 | -1, | ||
| 149 | -1, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1, | ||
| 165 | -1, | ||
| 166 | -1, | ||
| 167 | 3 + 256 * sizeof (short) / sizeof (int) + 176, | ||
| 168 | -1, | ||
| 169 | -1, | ||
| 170 | 3 + 256 * sizeof (short) / sizeof (int) + 192, | ||
| 171 | -1, | ||
| 172 | -1, | ||
| 173 | -1, | ||
| 174 | 3 + 256 * sizeof (short) / sizeof (int) + 208, | ||
| 175 | -1, | ||
| 176 | -1, | ||
| 177 | -1, | ||
| 178 | -1, | ||
| 179 | -1, | ||
| 180 | 3 + 256 * sizeof (short) / sizeof (int) + 224, | ||
| 181 | -1, | ||
| 182 | -1, | ||
| 183 | -1, | ||
| 184 | -1, | ||
| 185 | -1, | ||
| 186 | -1, | ||
| 187 | -1, | ||
| 188 | -1, | ||
| 189 | -1, | ||
| 190 | -1, | ||
| 191 | -1, | ||
| 192 | -1, | ||
| 193 | -1, | ||
| 194 | -1, | ||
| 195 | -1, | ||
| 196 | -1, | ||
| 197 | -1, | ||
| 198 | -1, | ||
| 199 | -1, | ||
| 200 | -1, | ||
| 201 | -1, | ||
| 202 | -1, | ||
| 203 | -1, | ||
| 204 | -1, | ||
| 205 | -1, | ||
| 206 | -1, | ||
| 207 | -1, | ||
| 208 | -1, | ||
| 209 | -1, | ||
| 210 | -1, | ||
| 211 | -1, | ||
| 212 | -1, | ||
| 213 | -1, | ||
| 214 | -1, | ||
| 215 | -1, | ||
| 216 | -1, | ||
| 217 | -1, | ||
| 218 | -1, | ||
| 219 | -1, | ||
| 220 | -1, | ||
| 221 | -1, | ||
| 222 | -1, | ||
| 223 | 3 + 256 * sizeof (short) / sizeof (int) + 240, | ||
| 224 | -1, | ||
| 225 | -1, | ||
| 226 | -1, | ||
| 227 | -1, | ||
| 228 | -1, | ||
| 229 | -1, | ||
| 230 | -1, | ||
| 231 | -1, | ||
| 232 | -1, | ||
| 233 | -1, | ||
| 234 | -1, | ||
| 235 | -1, | ||
| 236 | -1, | ||
| 237 | -1, | ||
| 238 | -1, | ||
| 239 | -1, | ||
| 240 | -1, | ||
| 241 | -1, | ||
| 242 | -1, | ||
| 243 | -1, | ||
| 244 | -1, | ||
| 245 | -1, | ||
| 246 | -1, | ||
| 247 | -1, | ||
| 248 | -1, | ||
| 249 | -1, | ||
| 250 | -1, | ||
| 251 | -1, | ||
| 252 | -1, | ||
| 253 | -1, | ||
| 254 | -1, | ||
| 255 | -1, | ||
| 256 | -1, | ||
| 257 | -1, | ||
| 258 | -1, | ||
| 259 | -1, | ||
| 260 | -1, | ||
| 261 | -1, | ||
| 262 | -1, | ||
| 263 | -1, | ||
| 264 | -1, | ||
| 265 | -1, | ||
| 266 | -1, | ||
| 267 | -1, | ||
| 268 | -1, | ||
| 269 | -1, | ||
| 270 | -1, | ||
| 271 | -1, | ||
| 272 | -1, | ||
| 273 | -1, | ||
| 274 | -1, | ||
| 275 | -1, | ||
| 276 | -1, | ||
| 277 | -1, | ||
| 278 | -1, | ||
| 279 | -1, | ||
| 280 | -1, | ||
| 281 | -1, | ||
| 282 | -1, | ||
| 283 | -1, | ||
| 284 | 3 + 256 * sizeof (short) / sizeof (int) + 256, | ||
| 285 | -1, | ||
| 286 | -1, | ||
| 287 | -1, | ||
| 288 | -1, | ||
| 289 | -1, | ||
| 290 | -1, | ||
| 291 | -1, | ||
| 292 | -1, | ||
| 293 | -1, | ||
| 294 | -1, | ||
| 295 | -1 | ||
| 296 | }, | ||
| 297 | { | ||
| 298 | 0x00000000U, 0x00000000U, 0x07FFFFFEU, 0x00000000U, | ||
| 299 | 0x00000000U, 0x00000000U, 0x7F7FFFFFU, 0x00000000U, | ||
| 300 | 0x55555555U, 0xAA555555U, 0x555554AAU, 0x2B555555U, | ||
| 301 | 0xB1DBCED6U, 0x11AED2D5U, 0x4AAAADB0U, 0x55D65555U, | ||
| 302 | 0x55555555U, 0x6C055555U, 0x0000557AU, 0x00000000U, | ||
| 303 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 304 | 0x00000000U, 0x00000000U, 0x00000000U, 0x80450000U, | ||
| 305 | 0xFFFED740U, 0x00000FFBU, 0x55008000U, 0xE6905555U, | ||
| 306 | 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, 0x55555555U, | ||
| 307 | 0x55555401U, 0x55555555U, 0x55552AABU, 0x55555555U, | ||
| 308 | 0x55555555U, 0xFFFE5555U, 0x007FFFFFU, 0x00000000U, | ||
| 309 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 310 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 311 | 0x00000000U, 0xFFFFFFFFU, 0x000020BFU, 0x00000000U, | ||
| 312 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 313 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 314 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 315 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 316 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 317 | 0x00000000U, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, | ||
| 318 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 319 | 0xFFFF0200U, 0xE7FFFFFFU, 0x00000000U, 0x00000000U, | ||
| 320 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 321 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 322 | 0x55555555U, 0x55555555U, 0x55555555U, 0x55555555U, | ||
| 323 | 0x40155555U, 0x55555555U, 0x55555555U, 0x55555555U, | ||
| 324 | 0x3F00FF00U, 0xFF00FF00U, 0xAA003F00U, 0x0000FF00U, | ||
| 325 | 0xFF00FF00U, 0x1F00FF00U, 0x0F001F00U, 0x1F001F00U, | ||
| 326 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 327 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 328 | 0x00000000U, 0x00040C40U, 0x00000000U, 0x0000FFFFU, | ||
| 329 | 0x00000008U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 330 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 331 | 0x00000000U, 0xFFC00000U, 0x0000FFFFU, 0x00000000U, | ||
| 332 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 333 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 334 | 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, 0xC025EA9DU, | ||
| 335 | 0x55555555U, 0x55555555U, 0x55555555U, 0x00042805U, | ||
| 336 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 337 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 338 | 0x00000000U, 0x00000000U, 0x55555555U, 0x00001555U, | ||
| 339 | 0x05555555U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 340 | 0x00000000U, 0x55545554U, 0x55555555U, 0x6A005555U, | ||
| 341 | 0x55452855U, 0x555F7D55U, 0x15411AF5U, 0x00200000U, | ||
| 342 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 343 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 344 | 0x00000000U, 0x07FFFFFEU, 0x00000000U, 0x00000000U, | ||
| 345 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 346 | 0xFFFFFFFFU, 0x000000FFU, 0x00000000U, 0x00000000U, | ||
| 347 | 0x00000000U, 0xFFFF0000U, 0x000FFFFFU, 0x00000000U, | ||
| 348 | 0x00000000U, 0x00000000U, 0x00000000U, 0xF7FF0000U, | ||
| 349 | 0x0037F7FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 350 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 351 | 0xFFFFFFFFU, 0x0007FFFFU, 0x00000000U, 0x00000000U, | ||
| 352 | 0x00000000U, 0x00000000U, 0xFFFF0000U, 0x0000003FU, | ||
| 353 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 354 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 355 | 0x00000000U, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 356 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 357 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 358 | 0x00000000U, 0x00000000U, 0xFFFFFFFFU, 0x00000000U, | ||
| 359 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 360 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 361 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 362 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 363 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 364 | 0xFFFFFFFFU, 0x00000003U, 0x00000000U, 0x00000000U, | ||
| 365 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U | ||
| 366 | } | ||
| 367 | }; | ||
diff --git a/gl/unictype/ctype_xdigit.c b/gl/unictype/ctype_xdigit.c new file mode 100644 index 00000000..ee4b2ea4 --- /dev/null +++ b/gl/unictype/ctype_xdigit.c | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* ISO C <ctype.h> like properties of Unicode characters. | ||
| 2 | Copyright (C) 2002, 2006-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "unictype.h" | ||
| 22 | |||
| 23 | #include "bitmap.h" | ||
| 24 | |||
| 25 | /* Define u_is_xdigit table. */ | ||
| 26 | #include "ctype_xdigit.h" | ||
| 27 | |||
| 28 | bool | ||
| 29 | uc_is_xdigit (ucs4_t uc) | ||
| 30 | { | ||
| 31 | return bitmap_lookup (&u_is_xdigit, uc); | ||
| 32 | } | ||
diff --git a/gl/unictype/ctype_xdigit.h b/gl/unictype/ctype_xdigit.h new file mode 100644 index 00000000..c0b2ac05 --- /dev/null +++ b/gl/unictype/ctype_xdigit.h | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* ISO C <ctype.h> like properties of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[1]; | ||
| 29 | short level2[1 << 7]; | ||
| 30 | unsigned int level3[1 << 4]; | ||
| 31 | } | ||
| 32 | u_is_xdigit = | ||
| 33 | { | ||
| 34 | { 1 }, | ||
| 35 | { 2 * sizeof (int) / sizeof (short) + 0 }, | ||
| 36 | { | ||
| 37 | 2 + 128 * sizeof (short) / sizeof (int) + 0, | ||
| 38 | -1, | ||
| 39 | -1, | ||
| 40 | -1, | ||
| 41 | -1, | ||
| 42 | -1, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | -1, | ||
| 49 | -1, | ||
| 50 | -1, | ||
| 51 | -1, | ||
| 52 | -1, | ||
| 53 | -1, | ||
| 54 | -1, | ||
| 55 | -1, | ||
| 56 | -1, | ||
| 57 | -1, | ||
| 58 | -1, | ||
| 59 | -1, | ||
| 60 | -1, | ||
| 61 | -1, | ||
| 62 | -1, | ||
| 63 | -1, | ||
| 64 | -1, | ||
| 65 | -1, | ||
| 66 | -1, | ||
| 67 | -1, | ||
| 68 | -1, | ||
| 69 | -1, | ||
| 70 | -1, | ||
| 71 | -1, | ||
| 72 | -1, | ||
| 73 | -1, | ||
| 74 | -1, | ||
| 75 | -1, | ||
| 76 | -1, | ||
| 77 | -1, | ||
| 78 | -1, | ||
| 79 | -1, | ||
| 80 | -1, | ||
| 81 | -1, | ||
| 82 | -1, | ||
| 83 | -1, | ||
| 84 | -1, | ||
| 85 | -1, | ||
| 86 | -1, | ||
| 87 | -1, | ||
| 88 | -1, | ||
| 89 | -1, | ||
| 90 | -1, | ||
| 91 | -1, | ||
| 92 | -1, | ||
| 93 | -1, | ||
| 94 | -1, | ||
| 95 | -1, | ||
| 96 | -1, | ||
| 97 | -1, | ||
| 98 | -1, | ||
| 99 | -1, | ||
| 100 | -1, | ||
| 101 | -1, | ||
| 102 | -1, | ||
| 103 | -1, | ||
| 104 | -1, | ||
| 105 | -1, | ||
| 106 | -1, | ||
| 107 | -1, | ||
| 108 | -1, | ||
| 109 | -1, | ||
| 110 | -1, | ||
| 111 | -1, | ||
| 112 | -1, | ||
| 113 | -1, | ||
| 114 | -1, | ||
| 115 | -1, | ||
| 116 | -1, | ||
| 117 | -1, | ||
| 118 | -1, | ||
| 119 | -1, | ||
| 120 | -1, | ||
| 121 | -1, | ||
| 122 | -1, | ||
| 123 | -1, | ||
| 124 | -1, | ||
| 125 | -1, | ||
| 126 | -1, | ||
| 127 | -1, | ||
| 128 | -1, | ||
| 129 | -1, | ||
| 130 | -1, | ||
| 131 | -1, | ||
| 132 | -1, | ||
| 133 | -1, | ||
| 134 | -1, | ||
| 135 | -1, | ||
| 136 | -1, | ||
| 137 | -1, | ||
| 138 | -1, | ||
| 139 | -1, | ||
| 140 | -1, | ||
| 141 | -1, | ||
| 142 | -1, | ||
| 143 | -1, | ||
| 144 | -1, | ||
| 145 | -1, | ||
| 146 | -1, | ||
| 147 | -1, | ||
| 148 | -1, | ||
| 149 | -1, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1 | ||
| 165 | }, | ||
| 166 | { | ||
| 167 | 0x00000000U, 0x03FF0000U, 0x0000007EU, 0x0000007EU, | ||
| 168 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 169 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 170 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U | ||
| 171 | } | ||
| 172 | }; | ||
diff --git a/gl/uninorm.h b/gl/uninorm.h new file mode 100644 index 00000000..f6815c49 --- /dev/null +++ b/gl/uninorm.h | |||
| @@ -0,0 +1,256 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* Normalization forms (composition and decomposition) of Unicode strings. | ||
| 3 | Copyright (C) 2001-2002, 2009-2025 Free Software Foundation, Inc. | ||
| 4 | Written by Bruno Haible <bruno@clisp.org>, 2009. | ||
| 5 | |||
| 6 | This file is free software: you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU Lesser General Public License as | ||
| 8 | published by the Free Software Foundation; either version 2.1 of the | ||
| 9 | License, or (at your option) any later version. | ||
| 10 | |||
| 11 | This file is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU Lesser General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU Lesser General Public License | ||
| 17 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _UNINORM_H | ||
| 20 | #define _UNINORM_H | ||
| 21 | |||
| 22 | /* Get size_t. */ | ||
| 23 | #include <stddef.h> | ||
| 24 | |||
| 25 | #include "unitypes.h" | ||
| 26 | |||
| 27 | #if 0 | ||
| 28 | # include <unistring/woe32dll.h> | ||
| 29 | #else | ||
| 30 | # define LIBUNISTRING_DLL_VARIABLE | ||
| 31 | #endif | ||
| 32 | |||
| 33 | |||
| 34 | #ifdef __cplusplus | ||
| 35 | extern "C" { | ||
| 36 | #endif | ||
| 37 | |||
| 38 | |||
| 39 | /* Conventions: | ||
| 40 | |||
| 41 | All functions prefixed with u8_ operate on UTF-8 encoded strings. | ||
| 42 | Their unit is an uint8_t (1 byte). | ||
| 43 | |||
| 44 | All functions prefixed with u16_ operate on UTF-16 encoded strings. | ||
| 45 | Their unit is an uint16_t (a 2-byte word). | ||
| 46 | |||
| 47 | All functions prefixed with u32_ operate on UCS-4 encoded strings. | ||
| 48 | Their unit is an uint32_t (a 4-byte word). | ||
| 49 | |||
| 50 | All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly | ||
| 51 | n units. | ||
| 52 | |||
| 53 | Functions returning a string result take a (resultbuf, lengthp) argument | ||
| 54 | pair. If resultbuf is not NULL and the result fits into *lengthp units, | ||
| 55 | it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly | ||
| 56 | allocated string is returned. In both cases, *lengthp is set to the | ||
| 57 | length (number of units) of the returned string. In case of error, | ||
| 58 | NULL is returned and errno is set. */ | ||
| 59 | |||
| 60 | |||
| 61 | enum | ||
| 62 | { | ||
| 63 | UC_DECOMP_CANONICAL,/* Canonical decomposition. */ | ||
| 64 | UC_DECOMP_FONT, /* <font> A font variant (e.g. a blackletter form). */ | ||
| 65 | UC_DECOMP_NOBREAK, /* <noBreak> A no-break version of a space or hyphen. */ | ||
| 66 | UC_DECOMP_INITIAL, /* <initial> An initial presentation form (Arabic). */ | ||
| 67 | UC_DECOMP_MEDIAL, /* <medial> A medial presentation form (Arabic). */ | ||
| 68 | UC_DECOMP_FINAL, /* <final> A final presentation form (Arabic). */ | ||
| 69 | UC_DECOMP_ISOLATED,/* <isolated> An isolated presentation form (Arabic). */ | ||
| 70 | UC_DECOMP_CIRCLE, /* <circle> An encircled form. */ | ||
| 71 | UC_DECOMP_SUPER, /* <super> A superscript form. */ | ||
| 72 | UC_DECOMP_SUB, /* <sub> A subscript form. */ | ||
| 73 | UC_DECOMP_VERTICAL,/* <vertical> A vertical layout presentation form. */ | ||
| 74 | UC_DECOMP_WIDE, /* <wide> A wide (or zenkaku) compatibility character. */ | ||
| 75 | UC_DECOMP_NARROW, /* <narrow> A narrow (or hankaku) compatibility character. */ | ||
| 76 | UC_DECOMP_SMALL, /* <small> A small variant form (CNS compatibility). */ | ||
| 77 | UC_DECOMP_SQUARE, /* <square> A CJK squared font variant. */ | ||
| 78 | UC_DECOMP_FRACTION,/* <fraction> A vulgar fraction form. */ | ||
| 79 | UC_DECOMP_COMPAT /* <compat> Otherwise unspecified compatibility character. */ | ||
| 80 | }; | ||
| 81 | |||
| 82 | /* Maximum size of decomposition of a single Unicode character. */ | ||
| 83 | #define UC_DECOMPOSITION_MAX_LENGTH 32 | ||
| 84 | |||
| 85 | /* Return the character decomposition mapping of a Unicode character. | ||
| 86 | DECOMPOSITION must point to an array of at least UC_DECOMPOSITION_MAX_LENGTH | ||
| 87 | ucs_t elements. | ||
| 88 | When a decomposition exists, DECOMPOSITION[0..N-1] and *DECOMP_TAG are | ||
| 89 | filled and N is returned. Otherwise -1 is returned. */ | ||
| 90 | extern int | ||
| 91 | uc_decomposition (ucs4_t uc, int *decomp_tag, ucs4_t *decomposition); | ||
| 92 | |||
| 93 | /* Return the canonical character decomposition mapping of a Unicode character. | ||
| 94 | DECOMPOSITION must point to an array of at least UC_DECOMPOSITION_MAX_LENGTH | ||
| 95 | ucs_t elements. | ||
| 96 | When a decomposition exists, DECOMPOSITION[0..N-1] is filled and N is | ||
| 97 | returned. Otherwise -1 is returned. */ | ||
| 98 | extern int | ||
| 99 | uc_canonical_decomposition (ucs4_t uc, ucs4_t *decomposition); | ||
| 100 | |||
| 101 | |||
| 102 | /* Attempt to combine the Unicode characters uc1, uc2. | ||
| 103 | uc1 is known to have canonical combining class 0. | ||
| 104 | Return the combination of uc1 and uc2, if it exists. | ||
| 105 | Return 0 otherwise. | ||
| 106 | Not all decompositions can be recombined using this function. See the | ||
| 107 | Unicode file CompositionExclusions.txt for details. */ | ||
| 108 | extern ucs4_t | ||
| 109 | uc_composition (ucs4_t uc1, ucs4_t uc2) | ||
| 110 | _UC_ATTRIBUTE_CONST; | ||
| 111 | |||
| 112 | |||
| 113 | /* An object of type uninorm_t denotes a Unicode normalization form. */ | ||
| 114 | struct unicode_normalization_form; | ||
| 115 | typedef const struct unicode_normalization_form *uninorm_t; | ||
| 116 | |||
| 117 | /* UNINORM_NFD: Normalization form D: canonical decomposition. */ | ||
| 118 | extern LIBUNISTRING_DLL_VARIABLE const struct unicode_normalization_form uninorm_nfd; | ||
| 119 | #define UNINORM_NFD (&uninorm_nfd) | ||
| 120 | |||
| 121 | /* UNINORM_NFC: Normalization form C: canonical decomposition, then | ||
| 122 | canonical composition. */ | ||
| 123 | extern LIBUNISTRING_DLL_VARIABLE const struct unicode_normalization_form uninorm_nfc; | ||
| 124 | #define UNINORM_NFC (&uninorm_nfc) | ||
| 125 | |||
| 126 | /* UNINORM_NFKD: Normalization form KD: compatibility decomposition. */ | ||
| 127 | extern LIBUNISTRING_DLL_VARIABLE const struct unicode_normalization_form uninorm_nfkd; | ||
| 128 | #define UNINORM_NFKD (&uninorm_nfkd) | ||
| 129 | |||
| 130 | /* UNINORM_NFKC: Normalization form KC: compatibility decomposition, then | ||
| 131 | canonical composition. */ | ||
| 132 | extern LIBUNISTRING_DLL_VARIABLE const struct unicode_normalization_form uninorm_nfkc; | ||
| 133 | #define UNINORM_NFKC (&uninorm_nfkc) | ||
| 134 | |||
| 135 | /* Test whether a normalization form does compatibility decomposition. */ | ||
| 136 | #define uninorm_is_compat_decomposing(nf) \ | ||
| 137 | ((* (const unsigned int *) (nf) >> 0) & 1) | ||
| 138 | |||
| 139 | /* Test whether a normalization form includes canonical composition. */ | ||
| 140 | #define uninorm_is_composing(nf) \ | ||
| 141 | ((* (const unsigned int *) (nf) >> 1) & 1) | ||
| 142 | |||
| 143 | /* Return the decomposing variant of a normalization form. | ||
| 144 | This maps NFC,NFD -> NFD and NFKC,NFKD -> NFKD. */ | ||
| 145 | extern uninorm_t | ||
| 146 | uninorm_decomposing_form (uninorm_t nf) | ||
| 147 | _UC_ATTRIBUTE_PURE; | ||
| 148 | |||
| 149 | |||
| 150 | /* Return the specified normalization form of a string. */ | ||
| 151 | extern uint8_t * | ||
| 152 | u8_normalize (uninorm_t nf, const uint8_t *s, size_t n, | ||
| 153 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 154 | extern uint16_t * | ||
| 155 | u16_normalize (uninorm_t nf, const uint16_t *s, size_t n, | ||
| 156 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 157 | extern uint32_t * | ||
| 158 | u32_normalize (uninorm_t nf, const uint32_t *s, size_t n, | ||
| 159 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 160 | |||
| 161 | |||
| 162 | /* Compare S1 and S2, ignoring differences in normalization. | ||
| 163 | NF must be either UNINORM_NFD or UNINORM_NFKD. | ||
| 164 | If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and | ||
| 165 | return 0. Upon failure, return -1 with errno set. */ | ||
| 166 | extern int | ||
| 167 | u8_normcmp (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2, | ||
| 168 | uninorm_t nf, int *resultp); | ||
| 169 | extern int | ||
| 170 | u16_normcmp (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2, | ||
| 171 | uninorm_t nf, int *resultp); | ||
| 172 | extern int | ||
| 173 | u32_normcmp (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2, | ||
| 174 | uninorm_t nf, int *resultp); | ||
| 175 | |||
| 176 | |||
| 177 | /* Converts the string S of length N to a NUL-terminated byte sequence, in such | ||
| 178 | a way that comparing uN_normxfrm (S1) and uN_normxfrm (S2) with uN_cmp2() is | ||
| 179 | equivalent to comparing S1 and S2 with uN_normcoll(). | ||
| 180 | NF must be either UNINORM_NFC or UNINORM_NFKC. */ | ||
| 181 | extern char * | ||
| 182 | u8_normxfrm (const uint8_t *s, size_t n, uninorm_t nf, | ||
| 183 | char *resultbuf, size_t *lengthp); | ||
| 184 | extern char * | ||
| 185 | u16_normxfrm (const uint16_t *s, size_t n, uninorm_t nf, | ||
| 186 | char *resultbuf, size_t *lengthp); | ||
| 187 | extern char * | ||
| 188 | u32_normxfrm (const uint32_t *s, size_t n, uninorm_t nf, | ||
| 189 | char *resultbuf, size_t *lengthp); | ||
| 190 | |||
| 191 | |||
| 192 | /* Compare S1 and S2, ignoring differences in normalization, using the | ||
| 193 | collation rules of the current locale. | ||
| 194 | NF must be either UNINORM_NFC or UNINORM_NFKC. | ||
| 195 | If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and | ||
| 196 | return 0. Upon failure, return -1 with errno set. */ | ||
| 197 | extern int | ||
| 198 | u8_normcoll (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2, | ||
| 199 | uninorm_t nf, int *resultp); | ||
| 200 | extern int | ||
| 201 | u16_normcoll (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2, | ||
| 202 | uninorm_t nf, int *resultp); | ||
| 203 | extern int | ||
| 204 | u32_normcoll (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2, | ||
| 205 | uninorm_t nf, int *resultp); | ||
| 206 | |||
| 207 | |||
| 208 | /* Normalization of a stream of Unicode characters. | ||
| 209 | |||
| 210 | A "stream of Unicode characters" is essentially a function that accepts an | ||
| 211 | ucs4_t argument repeatedly, optionally combined with a function that | ||
| 212 | "flushes" the stream. */ | ||
| 213 | |||
| 214 | /* Data type of a stream of Unicode characters that normalizes its input | ||
| 215 | according to a given normalization form and passes the normalized character | ||
| 216 | sequence to the encapsulated stream of Unicode characters. */ | ||
| 217 | struct uninorm_filter; | ||
| 218 | |||
| 219 | /* Bring data buffered in the filter to its destination, the encapsulated | ||
| 220 | stream, then close and free the filter. | ||
| 221 | Return 0 if successful, or -1 with errno set upon failure. */ | ||
| 222 | extern int | ||
| 223 | uninorm_filter_free (struct uninorm_filter *filter); | ||
| 224 | |||
| 225 | /* Create and return a normalization filter for Unicode characters. | ||
| 226 | The pair (stream_func, stream_data) is the encapsulated stream. | ||
| 227 | stream_func (stream_data, uc) receives the Unicode character uc | ||
| 228 | and returns 0 if successful, or -1 with errno set upon failure. | ||
| 229 | Return the new filter, or NULL with errno set upon failure. */ | ||
| 230 | extern struct uninorm_filter * | ||
| 231 | uninorm_filter_create (uninorm_t nf, | ||
| 232 | int (*stream_func) (void *stream_data, ucs4_t uc), | ||
| 233 | void *stream_data) | ||
| 234 | _GL_ATTRIBUTE_DEALLOC (uninorm_filter_free, 1); | ||
| 235 | |||
| 236 | /* Stuff a Unicode character into a normalizing filter. | ||
| 237 | Return 0 if successful, or -1 with errno set upon failure. */ | ||
| 238 | extern int | ||
| 239 | uninorm_filter_write (struct uninorm_filter *filter, ucs4_t uc); | ||
| 240 | |||
| 241 | /* Bring data buffered in the filter to its destination, the encapsulated | ||
| 242 | stream. | ||
| 243 | Return 0 if successful, or -1 with errno set upon failure. | ||
| 244 | Note! If after calling this function, additional characters are written | ||
| 245 | into the filter, the resulting character sequence in the encapsulated stream | ||
| 246 | will not necessarily be normalized. */ | ||
| 247 | extern int | ||
| 248 | uninorm_filter_flush (struct uninorm_filter *filter); | ||
| 249 | |||
| 250 | |||
| 251 | #ifdef __cplusplus | ||
| 252 | } | ||
| 253 | #endif | ||
| 254 | |||
| 255 | |||
| 256 | #endif /* _UNINORM_H */ | ||
diff --git a/gl/uninorm.in.h b/gl/uninorm.in.h new file mode 100644 index 00000000..76ab32b6 --- /dev/null +++ b/gl/uninorm.in.h | |||
| @@ -0,0 +1,255 @@ | |||
| 1 | /* Normalization forms (composition and decomposition) of Unicode strings. | ||
| 2 | Copyright (C) 2001-2002, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2009. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #ifndef _UNINORM_H | ||
| 19 | #define _UNINORM_H | ||
| 20 | |||
| 21 | /* Get size_t. */ | ||
| 22 | #include <stddef.h> | ||
| 23 | |||
| 24 | #include "unitypes.h" | ||
| 25 | |||
| 26 | #if @HAVE_UNISTRING_WOE32DLL_H@ | ||
| 27 | # include <unistring/woe32dll.h> | ||
| 28 | #else | ||
| 29 | # define LIBUNISTRING_DLL_VARIABLE | ||
| 30 | #endif | ||
| 31 | |||
| 32 | |||
| 33 | #ifdef __cplusplus | ||
| 34 | extern "C" { | ||
| 35 | #endif | ||
| 36 | |||
| 37 | |||
| 38 | /* Conventions: | ||
| 39 | |||
| 40 | All functions prefixed with u8_ operate on UTF-8 encoded strings. | ||
| 41 | Their unit is an uint8_t (1 byte). | ||
| 42 | |||
| 43 | All functions prefixed with u16_ operate on UTF-16 encoded strings. | ||
| 44 | Their unit is an uint16_t (a 2-byte word). | ||
| 45 | |||
| 46 | All functions prefixed with u32_ operate on UCS-4 encoded strings. | ||
| 47 | Their unit is an uint32_t (a 4-byte word). | ||
| 48 | |||
| 49 | All argument pairs (s, n) denote a Unicode string s[0..n-1] with exactly | ||
| 50 | n units. | ||
| 51 | |||
| 52 | Functions returning a string result take a (resultbuf, lengthp) argument | ||
| 53 | pair. If resultbuf is not NULL and the result fits into *lengthp units, | ||
| 54 | it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly | ||
| 55 | allocated string is returned. In both cases, *lengthp is set to the | ||
| 56 | length (number of units) of the returned string. In case of error, | ||
| 57 | NULL is returned and errno is set. */ | ||
| 58 | |||
| 59 | |||
| 60 | enum | ||
| 61 | { | ||
| 62 | UC_DECOMP_CANONICAL,/* Canonical decomposition. */ | ||
| 63 | UC_DECOMP_FONT, /* <font> A font variant (e.g. a blackletter form). */ | ||
| 64 | UC_DECOMP_NOBREAK, /* <noBreak> A no-break version of a space or hyphen. */ | ||
| 65 | UC_DECOMP_INITIAL, /* <initial> An initial presentation form (Arabic). */ | ||
| 66 | UC_DECOMP_MEDIAL, /* <medial> A medial presentation form (Arabic). */ | ||
| 67 | UC_DECOMP_FINAL, /* <final> A final presentation form (Arabic). */ | ||
| 68 | UC_DECOMP_ISOLATED,/* <isolated> An isolated presentation form (Arabic). */ | ||
| 69 | UC_DECOMP_CIRCLE, /* <circle> An encircled form. */ | ||
| 70 | UC_DECOMP_SUPER, /* <super> A superscript form. */ | ||
| 71 | UC_DECOMP_SUB, /* <sub> A subscript form. */ | ||
| 72 | UC_DECOMP_VERTICAL,/* <vertical> A vertical layout presentation form. */ | ||
| 73 | UC_DECOMP_WIDE, /* <wide> A wide (or zenkaku) compatibility character. */ | ||
| 74 | UC_DECOMP_NARROW, /* <narrow> A narrow (or hankaku) compatibility character. */ | ||
| 75 | UC_DECOMP_SMALL, /* <small> A small variant form (CNS compatibility). */ | ||
| 76 | UC_DECOMP_SQUARE, /* <square> A CJK squared font variant. */ | ||
| 77 | UC_DECOMP_FRACTION,/* <fraction> A vulgar fraction form. */ | ||
| 78 | UC_DECOMP_COMPAT /* <compat> Otherwise unspecified compatibility character. */ | ||
| 79 | }; | ||
| 80 | |||
| 81 | /* Maximum size of decomposition of a single Unicode character. */ | ||
| 82 | #define UC_DECOMPOSITION_MAX_LENGTH 32 | ||
| 83 | |||
| 84 | /* Return the character decomposition mapping of a Unicode character. | ||
| 85 | DECOMPOSITION must point to an array of at least UC_DECOMPOSITION_MAX_LENGTH | ||
| 86 | ucs_t elements. | ||
| 87 | When a decomposition exists, DECOMPOSITION[0..N-1] and *DECOMP_TAG are | ||
| 88 | filled and N is returned. Otherwise -1 is returned. */ | ||
| 89 | extern int | ||
| 90 | uc_decomposition (ucs4_t uc, int *decomp_tag, ucs4_t *decomposition); | ||
| 91 | |||
| 92 | /* Return the canonical character decomposition mapping of a Unicode character. | ||
| 93 | DECOMPOSITION must point to an array of at least UC_DECOMPOSITION_MAX_LENGTH | ||
| 94 | ucs_t elements. | ||
| 95 | When a decomposition exists, DECOMPOSITION[0..N-1] is filled and N is | ||
| 96 | returned. Otherwise -1 is returned. */ | ||
| 97 | extern int | ||
| 98 | uc_canonical_decomposition (ucs4_t uc, ucs4_t *decomposition); | ||
| 99 | |||
| 100 | |||
| 101 | /* Attempt to combine the Unicode characters uc1, uc2. | ||
| 102 | uc1 is known to have canonical combining class 0. | ||
| 103 | Return the combination of uc1 and uc2, if it exists. | ||
| 104 | Return 0 otherwise. | ||
| 105 | Not all decompositions can be recombined using this function. See the | ||
| 106 | Unicode file CompositionExclusions.txt for details. */ | ||
| 107 | extern ucs4_t | ||
| 108 | uc_composition (ucs4_t uc1, ucs4_t uc2) | ||
| 109 | _UC_ATTRIBUTE_CONST; | ||
| 110 | |||
| 111 | |||
| 112 | /* An object of type uninorm_t denotes a Unicode normalization form. */ | ||
| 113 | struct unicode_normalization_form; | ||
| 114 | typedef const struct unicode_normalization_form *uninorm_t; | ||
| 115 | |||
| 116 | /* UNINORM_NFD: Normalization form D: canonical decomposition. */ | ||
| 117 | extern @GNULIB_UNINORM_NFD_DLL_VARIABLE@ const struct unicode_normalization_form uninorm_nfd; | ||
| 118 | #define UNINORM_NFD (&uninorm_nfd) | ||
| 119 | |||
| 120 | /* UNINORM_NFC: Normalization form C: canonical decomposition, then | ||
| 121 | canonical composition. */ | ||
| 122 | extern @GNULIB_UNINORM_NFC_DLL_VARIABLE@ const struct unicode_normalization_form uninorm_nfc; | ||
| 123 | #define UNINORM_NFC (&uninorm_nfc) | ||
| 124 | |||
| 125 | /* UNINORM_NFKD: Normalization form KD: compatibility decomposition. */ | ||
| 126 | extern @GNULIB_UNINORM_NFKD_DLL_VARIABLE@ const struct unicode_normalization_form uninorm_nfkd; | ||
| 127 | #define UNINORM_NFKD (&uninorm_nfkd) | ||
| 128 | |||
| 129 | /* UNINORM_NFKC: Normalization form KC: compatibility decomposition, then | ||
| 130 | canonical composition. */ | ||
| 131 | extern @GNULIB_UNINORM_NFKC_DLL_VARIABLE@ const struct unicode_normalization_form uninorm_nfkc; | ||
| 132 | #define UNINORM_NFKC (&uninorm_nfkc) | ||
| 133 | |||
| 134 | /* Test whether a normalization form does compatibility decomposition. */ | ||
| 135 | #define uninorm_is_compat_decomposing(nf) \ | ||
| 136 | ((* (const unsigned int *) (nf) >> 0) & 1) | ||
| 137 | |||
| 138 | /* Test whether a normalization form includes canonical composition. */ | ||
| 139 | #define uninorm_is_composing(nf) \ | ||
| 140 | ((* (const unsigned int *) (nf) >> 1) & 1) | ||
| 141 | |||
| 142 | /* Return the decomposing variant of a normalization form. | ||
| 143 | This maps NFC,NFD -> NFD and NFKC,NFKD -> NFKD. */ | ||
| 144 | extern uninorm_t | ||
| 145 | uninorm_decomposing_form (uninorm_t nf) | ||
| 146 | _UC_ATTRIBUTE_PURE; | ||
| 147 | |||
| 148 | |||
| 149 | /* Return the specified normalization form of a string. */ | ||
| 150 | extern uint8_t * | ||
| 151 | u8_normalize (uninorm_t nf, const uint8_t *s, size_t n, | ||
| 152 | uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 153 | extern uint16_t * | ||
| 154 | u16_normalize (uninorm_t nf, const uint16_t *s, size_t n, | ||
| 155 | uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 156 | extern uint32_t * | ||
| 157 | u32_normalize (uninorm_t nf, const uint32_t *s, size_t n, | ||
| 158 | uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp); | ||
| 159 | |||
| 160 | |||
| 161 | /* Compare S1 and S2, ignoring differences in normalization. | ||
| 162 | NF must be either UNINORM_NFD or UNINORM_NFKD. | ||
| 163 | If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and | ||
| 164 | return 0. Upon failure, return -1 with errno set. */ | ||
| 165 | extern int | ||
| 166 | u8_normcmp (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2, | ||
| 167 | uninorm_t nf, int *resultp); | ||
| 168 | extern int | ||
| 169 | u16_normcmp (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2, | ||
| 170 | uninorm_t nf, int *resultp); | ||
| 171 | extern int | ||
| 172 | u32_normcmp (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2, | ||
| 173 | uninorm_t nf, int *resultp); | ||
| 174 | |||
| 175 | |||
| 176 | /* Converts the string S of length N to a NUL-terminated byte sequence, in such | ||
| 177 | a way that comparing uN_normxfrm (S1) and uN_normxfrm (S2) with uN_cmp2() is | ||
| 178 | equivalent to comparing S1 and S2 with uN_normcoll(). | ||
| 179 | NF must be either UNINORM_NFC or UNINORM_NFKC. */ | ||
| 180 | extern char * | ||
| 181 | u8_normxfrm (const uint8_t *s, size_t n, uninorm_t nf, | ||
| 182 | char *resultbuf, size_t *lengthp); | ||
| 183 | extern char * | ||
| 184 | u16_normxfrm (const uint16_t *s, size_t n, uninorm_t nf, | ||
| 185 | char *resultbuf, size_t *lengthp); | ||
| 186 | extern char * | ||
| 187 | u32_normxfrm (const uint32_t *s, size_t n, uninorm_t nf, | ||
| 188 | char *resultbuf, size_t *lengthp); | ||
| 189 | |||
| 190 | |||
| 191 | /* Compare S1 and S2, ignoring differences in normalization, using the | ||
| 192 | collation rules of the current locale. | ||
| 193 | NF must be either UNINORM_NFC or UNINORM_NFKC. | ||
| 194 | If successful, set *RESULTP to -1 if S1 < S2, 0 if S1 = S2, 1 if S1 > S2, and | ||
| 195 | return 0. Upon failure, return -1 with errno set. */ | ||
| 196 | extern int | ||
| 197 | u8_normcoll (const uint8_t *s1, size_t n1, const uint8_t *s2, size_t n2, | ||
| 198 | uninorm_t nf, int *resultp); | ||
| 199 | extern int | ||
| 200 | u16_normcoll (const uint16_t *s1, size_t n1, const uint16_t *s2, size_t n2, | ||
| 201 | uninorm_t nf, int *resultp); | ||
| 202 | extern int | ||
| 203 | u32_normcoll (const uint32_t *s1, size_t n1, const uint32_t *s2, size_t n2, | ||
| 204 | uninorm_t nf, int *resultp); | ||
| 205 | |||
| 206 | |||
| 207 | /* Normalization of a stream of Unicode characters. | ||
| 208 | |||
| 209 | A "stream of Unicode characters" is essentially a function that accepts an | ||
| 210 | ucs4_t argument repeatedly, optionally combined with a function that | ||
| 211 | "flushes" the stream. */ | ||
| 212 | |||
| 213 | /* Data type of a stream of Unicode characters that normalizes its input | ||
| 214 | according to a given normalization form and passes the normalized character | ||
| 215 | sequence to the encapsulated stream of Unicode characters. */ | ||
| 216 | struct uninorm_filter; | ||
| 217 | |||
| 218 | /* Bring data buffered in the filter to its destination, the encapsulated | ||
| 219 | stream, then close and free the filter. | ||
| 220 | Return 0 if successful, or -1 with errno set upon failure. */ | ||
| 221 | extern int | ||
| 222 | uninorm_filter_free (struct uninorm_filter *filter); | ||
| 223 | |||
| 224 | /* Create and return a normalization filter for Unicode characters. | ||
| 225 | The pair (stream_func, stream_data) is the encapsulated stream. | ||
| 226 | stream_func (stream_data, uc) receives the Unicode character uc | ||
| 227 | and returns 0 if successful, or -1 with errno set upon failure. | ||
| 228 | Return the new filter, or NULL with errno set upon failure. */ | ||
| 229 | extern struct uninorm_filter * | ||
| 230 | uninorm_filter_create (uninorm_t nf, | ||
| 231 | int (*stream_func) (void *stream_data, ucs4_t uc), | ||
| 232 | void *stream_data) | ||
| 233 | _GL_ATTRIBUTE_DEALLOC (uninorm_filter_free, 1); | ||
| 234 | |||
| 235 | /* Stuff a Unicode character into a normalizing filter. | ||
| 236 | Return 0 if successful, or -1 with errno set upon failure. */ | ||
| 237 | extern int | ||
| 238 | uninorm_filter_write (struct uninorm_filter *filter, ucs4_t uc); | ||
| 239 | |||
| 240 | /* Bring data buffered in the filter to its destination, the encapsulated | ||
| 241 | stream. | ||
| 242 | Return 0 if successful, or -1 with errno set upon failure. | ||
| 243 | Note! If after calling this function, additional characters are written | ||
| 244 | into the filter, the resulting character sequence in the encapsulated stream | ||
| 245 | will not necessarily be normalized. */ | ||
| 246 | extern int | ||
| 247 | uninorm_filter_flush (struct uninorm_filter *filter); | ||
| 248 | |||
| 249 | |||
| 250 | #ifdef __cplusplus | ||
| 251 | } | ||
| 252 | #endif | ||
| 253 | |||
| 254 | |||
| 255 | #endif /* _UNINORM_H */ | ||
diff --git a/gl/unistd.c b/gl/unistd.c index f3b3f7bd..e6625589 100644 --- a/gl/unistd.c +++ b/gl/unistd.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Inline functions for <unistd.h>. | 1 | /* Inline functions for <unistd.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2012-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -15,8 +15,8 @@ | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | 15 | You should have received a copy of the GNU Lesser General Public License |
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
| 17 | 17 | ||
| 18 | #define _GL_UNISTD_INLINE _GL_EXTERN_INLINE | ||
| 18 | #include <config.h> | 19 | #include <config.h> |
| 19 | 20 | ||
| 20 | #define _GL_UNISTD_INLINE _GL_EXTERN_INLINE | ||
| 21 | #include <unistd.h> | 21 | #include <unistd.h> |
| 22 | typedef int dummy; | 22 | typedef int dummy; |
diff --git a/gl/unistd.in.h b/gl/unistd.in.h index b4129663..9f057d30 100644 --- a/gl/unistd.in.h +++ b/gl/unistd.in.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Substitute for and wrapper around <unistd.h>. | 1 | /* Substitute for and wrapper around <unistd.h>. |
| 2 | Copyright (C) 2003-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2003-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -69,8 +69,8 @@ | |||
| 69 | #if !defined _@GUARD_PREFIX@_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H | 69 | #if !defined _@GUARD_PREFIX@_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H |
| 70 | #define _@GUARD_PREFIX@_UNISTD_H | 70 | #define _@GUARD_PREFIX@_UNISTD_H |
| 71 | 71 | ||
| 72 | /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, GNULIB_POSIXCHECK, | 72 | /* This file uses _GL_ATTRIBUTE_NODISCARD, _GL_INLINE_HEADER_BEGIN, _GL_INLINE, |
| 73 | HAVE_RAW_DECL_*. */ | 73 | GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */ |
| 74 | #if !_GL_CONFIG_H_INCLUDED | 74 | #if !_GL_CONFIG_H_INCLUDED |
| 75 | #error "Please include config.h first." | 75 | #error "Please include config.h first." |
| 76 | #endif | 76 | #endif |
| @@ -95,12 +95,24 @@ | |||
| 95 | # include <stdio.h> | 95 | # include <stdio.h> |
| 96 | #endif | 96 | #endif |
| 97 | 97 | ||
| 98 | /* Native Windows platforms declare _chdir, _getcwd, _rmdir in | ||
| 99 | <io.h> and/or <direct.h>, not in <unistd.h>. | ||
| 100 | They also declare _access(), _chmod(), _close(), _dup(), _dup2(), _isatty(), | ||
| 101 | _lseek(), _read(), _unlink(), _write() in <io.h>. */ | ||
| 102 | #if defined _WIN32 && !defined __CYGWIN__ | ||
| 103 | # include <io.h> | ||
| 104 | # include <direct.h> | ||
| 105 | #endif | ||
| 106 | |||
| 107 | /* FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, Solaris 11.4, and glibc 2.41 | ||
| 108 | do not define O_CLOEXEC in <unistd.h>. */ | ||
| 98 | /* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in | 109 | /* Cygwin 1.7.1 and Android 4.3 declare unlinkat in <fcntl.h>, not in |
| 99 | <unistd.h>. */ | 110 | <unistd.h>. */ |
| 100 | /* But avoid namespace pollution on glibc systems. */ | 111 | /* But avoid namespace pollution on glibc systems. */ |
| 101 | #if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \ | 112 | #if ! defined O_CLOEXEC \ |
| 102 | && (defined __CYGWIN__ || defined __ANDROID__) \ | 113 | || ((@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \ |
| 103 | && ! defined __GLIBC__ | 114 | && (defined __CYGWIN__ || defined __ANDROID__) \ |
| 115 | && ! defined __GLIBC__) | ||
| 104 | # include <fcntl.h> | 116 | # include <fcntl.h> |
| 105 | #endif | 117 | #endif |
| 106 | 118 | ||
| @@ -117,15 +129,6 @@ | |||
| 117 | # undef __need_system_stdlib_h | 129 | # undef __need_system_stdlib_h |
| 118 | #endif | 130 | #endif |
| 119 | 131 | ||
| 120 | /* Native Windows platforms declare _chdir, _getcwd, _rmdir in | ||
| 121 | <io.h> and/or <direct.h>, not in <unistd.h>. | ||
| 122 | They also declare _access(), _chmod(), _close(), _dup(), _dup2(), _isatty(), | ||
| 123 | _lseek(), _read(), _unlink(), _write() in <io.h>. */ | ||
| 124 | #if defined _WIN32 && !defined __CYGWIN__ | ||
| 125 | # include <io.h> | ||
| 126 | # include <direct.h> | ||
| 127 | #endif | ||
| 128 | |||
| 129 | /* Native Windows platforms declare _execl*, _execv* in <process.h>. */ | 132 | /* Native Windows platforms declare _execl*, _execv* in <process.h>. */ |
| 130 | #if defined _WIN32 && !defined __CYGWIN__ | 133 | #if defined _WIN32 && !defined __CYGWIN__ |
| 131 | # include <process.h> | 134 | # include <process.h> |
| @@ -159,8 +162,9 @@ | |||
| 159 | #endif | 162 | #endif |
| 160 | 163 | ||
| 161 | /* MSVC defines off_t in <sys/types.h>. | 164 | /* MSVC defines off_t in <sys/types.h>. |
| 162 | May also define off_t to a 64-bit type on native Windows. */ | 165 | May also define off_t to a 64-bit type on native Windows. |
| 163 | /* Get off_t, ssize_t, mode_t. */ | 166 | Also defines off64_t on macOS, NetBSD, OpenBSD, MSVC, Cygwin, Haiku. */ |
| 167 | /* Get off_t, off64_t, ssize_t, mode_t. */ | ||
| 164 | #include <sys/types.h> | 168 | #include <sys/types.h> |
| 165 | 169 | ||
| 166 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ | 170 | /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ |
| @@ -180,6 +184,9 @@ _GL_INLINE_HEADER_BEGIN | |||
| 180 | #ifndef _GL_UNISTD_INLINE | 184 | #ifndef _GL_UNISTD_INLINE |
| 181 | # define _GL_UNISTD_INLINE _GL_INLINE | 185 | # define _GL_UNISTD_INLINE _GL_INLINE |
| 182 | #endif | 186 | #endif |
| 187 | #ifndef _GL_GETPAGESIZE_INLINE | ||
| 188 | # define _GL_GETPAGESIZE_INLINE _GL_INLINE | ||
| 189 | #endif | ||
| 183 | 190 | ||
| 184 | /* Hide some function declarations from <winsock2.h>. */ | 191 | /* Hide some function declarations from <winsock2.h>. */ |
| 185 | 192 | ||
| @@ -286,7 +293,7 @@ _GL_INLINE_HEADER_BEGIN | |||
| 286 | # undef access | 293 | # undef access |
| 287 | # define access rpl_access | 294 | # define access rpl_access |
| 288 | # endif | 295 | # endif |
| 289 | _GL_FUNCDECL_RPL (access, int, (const char *file, int mode) | 296 | _GL_FUNCDECL_RPL (access, int, (const char *file, int mode), |
| 290 | _GL_ARG_NONNULL ((1))); | 297 | _GL_ARG_NONNULL ((1))); |
| 291 | _GL_CXXALIAS_RPL (access, int, (const char *file, int mode)); | 298 | _GL_CXXALIAS_RPL (access, int, (const char *file, int mode)); |
| 292 | # elif defined _WIN32 && !defined __CYGWIN__ | 299 | # elif defined _WIN32 && !defined __CYGWIN__ |
| @@ -339,7 +346,7 @@ _GL_CXXALIASWARN (chdir); | |||
| 339 | #elif defined GNULIB_POSIXCHECK | 346 | #elif defined GNULIB_POSIXCHECK |
| 340 | # undef chdir | 347 | # undef chdir |
| 341 | # if HAVE_RAW_DECL_CHDIR | 348 | # if HAVE_RAW_DECL_CHDIR |
| 342 | _GL_WARN_ON_USE (chown, "chdir is not always in <unistd.h> - " | 349 | _GL_WARN_ON_USE (chdir, "chdir is not always in <unistd.h> - " |
| 343 | "use gnulib module chdir for portability"); | 350 | "use gnulib module chdir for portability"); |
| 344 | # endif | 351 | # endif |
| 345 | #elif @GNULIB_MDA_CHDIR@ | 352 | #elif @GNULIB_MDA_CHDIR@ |
| @@ -370,13 +377,13 @@ _GL_CXXALIASWARN (chdir); | |||
| 370 | # undef chown | 377 | # undef chown |
| 371 | # define chown rpl_chown | 378 | # define chown rpl_chown |
| 372 | # endif | 379 | # endif |
| 373 | _GL_FUNCDECL_RPL (chown, int, (const char *file, uid_t uid, gid_t gid) | 380 | _GL_FUNCDECL_RPL (chown, int, (const char *file, uid_t uid, gid_t gid), |
| 374 | _GL_ARG_NONNULL ((1))); | 381 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 375 | _GL_CXXALIAS_RPL (chown, int, (const char *file, uid_t uid, gid_t gid)); | 382 | _GL_CXXALIAS_RPL (chown, int, (const char *file, uid_t uid, gid_t gid)); |
| 376 | # else | 383 | # else |
| 377 | # if !@HAVE_CHOWN@ | 384 | # if !@HAVE_CHOWN@ |
| 378 | _GL_FUNCDECL_SYS (chown, int, (const char *file, uid_t uid, gid_t gid) | 385 | _GL_FUNCDECL_SYS (chown, int, (const char *file, uid_t uid, gid_t gid), |
| 379 | _GL_ARG_NONNULL ((1))); | 386 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 380 | # endif | 387 | # endif |
| 381 | _GL_CXXALIAS_SYS (chown, int, (const char *file, uid_t uid, gid_t gid)); | 388 | _GL_CXXALIAS_SYS (chown, int, (const char *file, uid_t uid, gid_t gid)); |
| 382 | # endif | 389 | # endif |
| @@ -398,7 +405,7 @@ _GL_WARN_ON_USE (chown, "chown fails to follow symlinks on some systems and " | |||
| 398 | # undef close | 405 | # undef close |
| 399 | # define close rpl_close | 406 | # define close rpl_close |
| 400 | # endif | 407 | # endif |
| 401 | _GL_FUNCDECL_RPL (close, int, (int fd)); | 408 | _GL_FUNCDECL_RPL (close, int, (int fd), ); |
| 402 | _GL_CXXALIAS_RPL (close, int, (int fd)); | 409 | _GL_CXXALIAS_RPL (close, int, (int fd)); |
| 403 | # elif defined _WIN32 && !defined __CYGWIN__ | 410 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 404 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 411 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -411,8 +418,10 @@ _GL_CXXALIAS_SYS (close, int, (int fd)); | |||
| 411 | # endif | 418 | # endif |
| 412 | _GL_CXXALIASWARN (close); | 419 | _GL_CXXALIASWARN (close); |
| 413 | #elif @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ | 420 | #elif @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@ |
| 414 | # undef close | 421 | # if !GNULIB_CLOSE |
| 415 | # define close close_used_without_requesting_gnulib_module_close | 422 | # undef close |
| 423 | # define close close_used_without_requesting_gnulib_module_close | ||
| 424 | # endif | ||
| 416 | #elif defined GNULIB_POSIXCHECK | 425 | #elif defined GNULIB_POSIXCHECK |
| 417 | # undef close | 426 | # undef close |
| 418 | /* Assume close is always declared. */ | 427 | /* Assume close is always declared. */ |
| @@ -443,7 +452,7 @@ _GL_CXXALIASWARN (close); | |||
| 443 | # endif | 452 | # endif |
| 444 | _GL_FUNCDECL_RPL (copy_file_range, ssize_t, (int ifd, off_t *ipos, | 453 | _GL_FUNCDECL_RPL (copy_file_range, ssize_t, (int ifd, off_t *ipos, |
| 445 | int ofd, off_t *opos, | 454 | int ofd, off_t *opos, |
| 446 | size_t len, unsigned flags)); | 455 | size_t len, unsigned flags), ); |
| 447 | _GL_CXXALIAS_RPL (copy_file_range, ssize_t, (int ifd, off_t *ipos, | 456 | _GL_CXXALIAS_RPL (copy_file_range, ssize_t, (int ifd, off_t *ipos, |
| 448 | int ofd, off_t *opos, | 457 | int ofd, off_t *opos, |
| 449 | size_t len, unsigned flags)); | 458 | size_t len, unsigned flags)); |
| @@ -451,13 +460,15 @@ _GL_CXXALIAS_RPL (copy_file_range, ssize_t, (int ifd, off_t *ipos, | |||
| 451 | # if !@HAVE_COPY_FILE_RANGE@ | 460 | # if !@HAVE_COPY_FILE_RANGE@ |
| 452 | _GL_FUNCDECL_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos, | 461 | _GL_FUNCDECL_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos, |
| 453 | int ofd, off_t *opos, | 462 | int ofd, off_t *opos, |
| 454 | size_t len, unsigned flags)); | 463 | size_t len, unsigned flags), ); |
| 455 | # endif | 464 | # endif |
| 456 | _GL_CXXALIAS_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos, | 465 | _GL_CXXALIAS_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos, |
| 457 | int ofd, off_t *opos, | 466 | int ofd, off_t *opos, |
| 458 | size_t len, unsigned flags)); | 467 | size_t len, unsigned flags)); |
| 459 | # endif | 468 | # endif |
| 469 | # if __GLIBC__ >= 2 | ||
| 460 | _GL_CXXALIASWARN (copy_file_range); | 470 | _GL_CXXALIASWARN (copy_file_range); |
| 471 | # endif | ||
| 461 | #elif defined GNULIB_POSIXCHECK | 472 | #elif defined GNULIB_POSIXCHECK |
| 462 | # undef copy_file_range | 473 | # undef copy_file_range |
| 463 | # if HAVE_RAW_DECL_COPY_FILE_RANGE | 474 | # if HAVE_RAW_DECL_COPY_FILE_RANGE |
| @@ -473,7 +484,7 @@ _GL_WARN_ON_USE (copy_file_range, | |||
| 473 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 484 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 474 | # define dup rpl_dup | 485 | # define dup rpl_dup |
| 475 | # endif | 486 | # endif |
| 476 | _GL_FUNCDECL_RPL (dup, int, (int oldfd)); | 487 | _GL_FUNCDECL_RPL (dup, int, (int oldfd), _GL_ATTRIBUTE_NODISCARD); |
| 477 | _GL_CXXALIAS_RPL (dup, int, (int oldfd)); | 488 | _GL_CXXALIAS_RPL (dup, int, (int oldfd)); |
| 478 | # elif defined _WIN32 && !defined __CYGWIN__ | 489 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 479 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 490 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -518,7 +529,7 @@ _GL_CXXALIASWARN (dup); | |||
| 518 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 529 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 519 | # define dup2 rpl_dup2 | 530 | # define dup2 rpl_dup2 |
| 520 | # endif | 531 | # endif |
| 521 | _GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd)); | 532 | _GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd), ); |
| 522 | _GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd)); | 533 | _GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd)); |
| 523 | # elif defined _WIN32 && !defined __CYGWIN__ | 534 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 524 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 535 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -567,11 +578,11 @@ _GL_CXXALIASWARN (dup2); | |||
| 567 | # undef dup3 | 578 | # undef dup3 |
| 568 | # define dup3 rpl_dup3 | 579 | # define dup3 rpl_dup3 |
| 569 | # endif | 580 | # endif |
| 570 | _GL_FUNCDECL_RPL (dup3, int, (int oldfd, int newfd, int flags)); | 581 | _GL_FUNCDECL_RPL (dup3, int, (int oldfd, int newfd, int flags), ); |
| 571 | _GL_CXXALIAS_RPL (dup3, int, (int oldfd, int newfd, int flags)); | 582 | _GL_CXXALIAS_RPL (dup3, int, (int oldfd, int newfd, int flags)); |
| 572 | # else | 583 | # else |
| 573 | # if !@HAVE_DUP3@ | 584 | # if !@HAVE_DUP3@ |
| 574 | _GL_FUNCDECL_SYS (dup3, int, (int oldfd, int newfd, int flags)); | 585 | _GL_FUNCDECL_SYS (dup3, int, (int oldfd, int newfd, int flags), ); |
| 575 | # endif | 586 | # endif |
| 576 | _GL_CXXALIAS_SYS (dup3, int, (int oldfd, int newfd, int flags)); | 587 | _GL_CXXALIAS_SYS (dup3, int, (int oldfd, int newfd, int flags)); |
| 577 | # endif | 588 | # endif |
| @@ -636,7 +647,7 @@ rpl_environ (void) | |||
| 636 | /* Like access(), except that it uses the effective user id and group id of | 647 | /* Like access(), except that it uses the effective user id and group id of |
| 637 | the current process. */ | 648 | the current process. */ |
| 638 | # if !@HAVE_EUIDACCESS@ | 649 | # if !@HAVE_EUIDACCESS@ |
| 639 | _GL_FUNCDECL_SYS (euidaccess, int, (const char *filename, int mode) | 650 | _GL_FUNCDECL_SYS (euidaccess, int, (const char *filename, int mode), |
| 640 | _GL_ARG_NONNULL ((1))); | 651 | _GL_ARG_NONNULL ((1))); |
| 641 | # endif | 652 | # endif |
| 642 | _GL_CXXALIAS_SYS (euidaccess, int, (const char *filename, int mode)); | 653 | _GL_CXXALIAS_SYS (euidaccess, int, (const char *filename, int mode)); |
| @@ -661,7 +672,7 @@ _GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - " | |||
| 661 | # undef execl | 672 | # undef execl |
| 662 | # define execl rpl_execl | 673 | # define execl rpl_execl |
| 663 | # endif | 674 | # endif |
| 664 | _GL_FUNCDECL_RPL (execl, int, (const char *program, const char *arg, ...) | 675 | _GL_FUNCDECL_RPL (execl, int, (const char *program, const char *arg, ...), |
| 665 | _GL_ARG_NONNULL ((1))); | 676 | _GL_ARG_NONNULL ((1))); |
| 666 | _GL_CXXALIAS_RPL (execl, int, (const char *program, const char *arg, ...)); | 677 | _GL_CXXALIAS_RPL (execl, int, (const char *program, const char *arg, ...)); |
| 667 | # else | 678 | # else |
| @@ -696,7 +707,7 @@ _GL_CXXALIASWARN (execl); | |||
| 696 | # undef execle | 707 | # undef execle |
| 697 | # define execle rpl_execle | 708 | # define execle rpl_execle |
| 698 | # endif | 709 | # endif |
| 699 | _GL_FUNCDECL_RPL (execle, int, (const char *program, const char *arg, ...) | 710 | _GL_FUNCDECL_RPL (execle, int, (const char *program, const char *arg, ...), |
| 700 | _GL_ARG_NONNULL ((1))); | 711 | _GL_ARG_NONNULL ((1))); |
| 701 | _GL_CXXALIAS_RPL (execle, int, (const char *program, const char *arg, ...)); | 712 | _GL_CXXALIAS_RPL (execle, int, (const char *program, const char *arg, ...)); |
| 702 | # else | 713 | # else |
| @@ -732,7 +743,7 @@ _GL_CXXALIASWARN (execle); | |||
| 732 | # undef execlp | 743 | # undef execlp |
| 733 | # define execlp rpl_execlp | 744 | # define execlp rpl_execlp |
| 734 | # endif | 745 | # endif |
| 735 | _GL_FUNCDECL_RPL (execlp, int, (const char *program, const char *arg, ...) | 746 | _GL_FUNCDECL_RPL (execlp, int, (const char *program, const char *arg, ...), |
| 736 | _GL_ARG_NONNULL ((1))); | 747 | _GL_ARG_NONNULL ((1))); |
| 737 | _GL_CXXALIAS_RPL (execlp, int, (const char *program, const char *arg, ...)); | 748 | _GL_CXXALIAS_RPL (execlp, int, (const char *program, const char *arg, ...)); |
| 738 | # else | 749 | # else |
| @@ -769,7 +780,7 @@ _GL_CXXALIASWARN (execlp); | |||
| 769 | # undef execv | 780 | # undef execv |
| 770 | # define execv rpl_execv | 781 | # define execv rpl_execv |
| 771 | # endif | 782 | # endif |
| 772 | _GL_FUNCDECL_RPL (execv, int, (const char *program, char * const *argv) | 783 | _GL_FUNCDECL_RPL (execv, int, (const char *program, char * const *argv), |
| 773 | _GL_ARG_NONNULL ((1, 2))); | 784 | _GL_ARG_NONNULL ((1, 2))); |
| 774 | _GL_CXXALIAS_RPL (execv, int, (const char *program, char * const *argv)); | 785 | _GL_CXXALIAS_RPL (execv, int, (const char *program, char * const *argv)); |
| 775 | # else | 786 | # else |
| @@ -806,7 +817,7 @@ _GL_CXXALIASWARN (execv); | |||
| 806 | # define execve rpl_execve | 817 | # define execve rpl_execve |
| 807 | # endif | 818 | # endif |
| 808 | _GL_FUNCDECL_RPL (execve, int, | 819 | _GL_FUNCDECL_RPL (execve, int, |
| 809 | (const char *program, char * const *argv, char * const *env) | 820 | (const char *program, char * const *argv, char * const *env), |
| 810 | _GL_ARG_NONNULL ((1, 2))); | 821 | _GL_ARG_NONNULL ((1, 2))); |
| 811 | _GL_CXXALIAS_RPL (execve, int, | 822 | _GL_CXXALIAS_RPL (execve, int, |
| 812 | (const char *program, char * const *argv, char * const *env)); | 823 | (const char *program, char * const *argv, char * const *env)); |
| @@ -846,7 +857,7 @@ _GL_CXXALIASWARN (execve); | |||
| 846 | # undef execvp | 857 | # undef execvp |
| 847 | # define execvp rpl_execvp | 858 | # define execvp rpl_execvp |
| 848 | # endif | 859 | # endif |
| 849 | _GL_FUNCDECL_RPL (execvp, int, (const char *program, char * const *argv) | 860 | _GL_FUNCDECL_RPL (execvp, int, (const char *program, char * const *argv), |
| 850 | _GL_ARG_NONNULL ((1, 2))); | 861 | _GL_ARG_NONNULL ((1, 2))); |
| 851 | _GL_CXXALIAS_RPL (execvp, int, (const char *program, char * const *argv)); | 862 | _GL_CXXALIAS_RPL (execvp, int, (const char *program, char * const *argv)); |
| 852 | # else | 863 | # else |
| @@ -883,14 +894,14 @@ _GL_CXXALIASWARN (execvp); | |||
| 883 | # define execvpe rpl_execvpe | 894 | # define execvpe rpl_execvpe |
| 884 | # endif | 895 | # endif |
| 885 | _GL_FUNCDECL_RPL (execvpe, int, | 896 | _GL_FUNCDECL_RPL (execvpe, int, |
| 886 | (const char *program, char * const *argv, char * const *env) | 897 | (const char *program, char * const *argv, char * const *env), |
| 887 | _GL_ARG_NONNULL ((1, 2))); | 898 | _GL_ARG_NONNULL ((1, 2))); |
| 888 | _GL_CXXALIAS_RPL (execvpe, int, | 899 | _GL_CXXALIAS_RPL (execvpe, int, |
| 889 | (const char *program, char * const *argv, char * const *env)); | 900 | (const char *program, char * const *argv, char * const *env)); |
| 890 | # else | 901 | # else |
| 891 | # if !@HAVE_DECL_EXECVPE@ | 902 | # if !@HAVE_DECL_EXECVPE@ |
| 892 | _GL_FUNCDECL_SYS (execvpe, int, | 903 | _GL_FUNCDECL_SYS (execvpe, int, |
| 893 | (const char *program, char * const *argv, char * const *env) | 904 | (const char *program, char * const *argv, char * const *env), |
| 894 | _GL_ARG_NONNULL ((1, 2))); | 905 | _GL_ARG_NONNULL ((1, 2))); |
| 895 | # endif | 906 | # endif |
| 896 | _GL_CXXALIAS_SYS (execvpe, int, | 907 | _GL_CXXALIAS_SYS (execvpe, int, |
| @@ -921,7 +932,7 @@ _GL_CXXALIAS_MDA_CAST (execvpe, intptr_t, | |||
| 921 | # elif @HAVE_EXECVPE@ | 932 | # elif @HAVE_EXECVPE@ |
| 922 | # if !@HAVE_DECL_EXECVPE@ | 933 | # if !@HAVE_DECL_EXECVPE@ |
| 923 | _GL_FUNCDECL_SYS (execvpe, int, | 934 | _GL_FUNCDECL_SYS (execvpe, int, |
| 924 | (const char *program, char * const *argv, char * const *env) | 935 | (const char *program, char * const *argv, char * const *env), |
| 925 | _GL_ARG_NONNULL ((1, 2))); | 936 | _GL_ARG_NONNULL ((1, 2))); |
| 926 | # endif | 937 | # endif |
| 927 | _GL_CXXALIAS_SYS (execvpe, int, | 938 | _GL_CXXALIAS_SYS (execvpe, int, |
| @@ -940,15 +951,15 @@ _GL_CXXALIASWARN (execvpe); | |||
| 940 | # define faccessat rpl_faccessat | 951 | # define faccessat rpl_faccessat |
| 941 | # endif | 952 | # endif |
| 942 | _GL_FUNCDECL_RPL (faccessat, int, | 953 | _GL_FUNCDECL_RPL (faccessat, int, |
| 943 | (int fd, char const *name, int mode, int flag) | 954 | (int fd, char const *name, int mode, int flag), |
| 944 | _GL_ARG_NONNULL ((2))); | 955 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 945 | _GL_CXXALIAS_RPL (faccessat, int, | 956 | _GL_CXXALIAS_RPL (faccessat, int, |
| 946 | (int fd, char const *name, int mode, int flag)); | 957 | (int fd, char const *name, int mode, int flag)); |
| 947 | # else | 958 | # else |
| 948 | # if !@HAVE_FACCESSAT@ | 959 | # if !@HAVE_FACCESSAT@ |
| 949 | _GL_FUNCDECL_SYS (faccessat, int, | 960 | _GL_FUNCDECL_SYS (faccessat, int, |
| 950 | (int fd, char const *file, int mode, int flag) | 961 | (int fd, char const *file, int mode, int flag), |
| 951 | _GL_ARG_NONNULL ((2))); | 962 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 952 | # endif | 963 | # endif |
| 953 | _GL_CXXALIAS_SYS (faccessat, int, | 964 | _GL_CXXALIAS_SYS (faccessat, int, |
| 954 | (int fd, char const *file, int mode, int flag)); | 965 | (int fd, char const *file, int mode, int flag)); |
| @@ -976,11 +987,11 @@ _GL_WARN_ON_USE (faccessat, "faccessat is not portable - " | |||
| 976 | # undef fchdir | 987 | # undef fchdir |
| 977 | # define fchdir rpl_fchdir | 988 | # define fchdir rpl_fchdir |
| 978 | # endif | 989 | # endif |
| 979 | _GL_FUNCDECL_RPL (fchdir, int, (int /*fd*/)); | 990 | _GL_FUNCDECL_RPL (fchdir, int, (int /*fd*/), _GL_ATTRIBUTE_NODISCARD); |
| 980 | _GL_CXXALIAS_RPL (fchdir, int, (int /*fd*/)); | 991 | _GL_CXXALIAS_RPL (fchdir, int, (int /*fd*/)); |
| 981 | # else | 992 | # else |
| 982 | # if !@HAVE_FCHDIR@ || !@HAVE_DECL_FCHDIR@ | 993 | # if !@HAVE_FCHDIR@ || !@HAVE_DECL_FCHDIR@ |
| 983 | _GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/)); | 994 | _GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/), _GL_ATTRIBUTE_NODISCARD); |
| 984 | # endif | 995 | # endif |
| 985 | _GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/)); | 996 | _GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/)); |
| 986 | # endif | 997 | # endif |
| @@ -1009,15 +1020,15 @@ _GL_WARN_ON_USE (fchdir, "fchdir is unportable - " | |||
| 1009 | # define fchownat rpl_fchownat | 1020 | # define fchownat rpl_fchownat |
| 1010 | # endif | 1021 | # endif |
| 1011 | _GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file, | 1022 | _GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file, |
| 1012 | uid_t owner, gid_t group, int flag) | 1023 | uid_t owner, gid_t group, int flag), |
| 1013 | _GL_ARG_NONNULL ((2))); | 1024 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 1014 | _GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file, | 1025 | _GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file, |
| 1015 | uid_t owner, gid_t group, int flag)); | 1026 | uid_t owner, gid_t group, int flag)); |
| 1016 | # else | 1027 | # else |
| 1017 | # if !@HAVE_FCHOWNAT@ | 1028 | # if !@HAVE_FCHOWNAT@ |
| 1018 | _GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file, | 1029 | _GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file, |
| 1019 | uid_t owner, gid_t group, int flag) | 1030 | uid_t owner, gid_t group, int flag), |
| 1020 | _GL_ARG_NONNULL ((2))); | 1031 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 1021 | # endif | 1032 | # endif |
| 1022 | _GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file, | 1033 | _GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file, |
| 1023 | uid_t owner, gid_t group, int flag)); | 1034 | uid_t owner, gid_t group, int flag)); |
| @@ -1042,11 +1053,11 @@ _GL_WARN_ON_USE (fchownat, "fchownat is not portable - " | |||
| 1042 | # undef fdatasync | 1053 | # undef fdatasync |
| 1043 | # define fdatasync rpl_fdatasync | 1054 | # define fdatasync rpl_fdatasync |
| 1044 | # endif | 1055 | # endif |
| 1045 | _GL_FUNCDECL_RPL (fdatasync, int, (int fd)); | 1056 | _GL_FUNCDECL_RPL (fdatasync, int, (int fd), ); |
| 1046 | _GL_CXXALIAS_RPL (fdatasync, int, (int fd)); | 1057 | _GL_CXXALIAS_RPL (fdatasync, int, (int fd)); |
| 1047 | # else | 1058 | # else |
| 1048 | # if !@HAVE_FDATASYNC@|| !@HAVE_DECL_FDATASYNC@ | 1059 | # if !@HAVE_FDATASYNC@|| !@HAVE_DECL_FDATASYNC@ |
| 1049 | _GL_FUNCDECL_SYS (fdatasync, int, (int fd)); | 1060 | _GL_FUNCDECL_SYS (fdatasync, int, (int fd), ); |
| 1050 | # endif | 1061 | # endif |
| 1051 | _GL_CXXALIAS_SYS (fdatasync, int, (int fd)); | 1062 | _GL_CXXALIAS_SYS (fdatasync, int, (int fd)); |
| 1052 | # endif | 1063 | # endif |
| @@ -1068,7 +1079,7 @@ _GL_WARN_ON_USE (fdatasync, "fdatasync is unportable - " | |||
| 1068 | See POSIX:2008 specification | 1079 | See POSIX:2008 specification |
| 1069 | <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html>. */ | 1080 | <https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html>. */ |
| 1070 | # if !@HAVE_FSYNC@ | 1081 | # if !@HAVE_FSYNC@ |
| 1071 | _GL_FUNCDECL_SYS (fsync, int, (int fd)); | 1082 | _GL_FUNCDECL_SYS (fsync, int, (int fd), ); |
| 1072 | # endif | 1083 | # endif |
| 1073 | _GL_CXXALIAS_SYS (fsync, int, (int fd)); | 1084 | _GL_CXXALIAS_SYS (fsync, int, (int fd)); |
| 1074 | _GL_CXXALIASWARN (fsync); | 1085 | _GL_CXXALIASWARN (fsync); |
| @@ -1091,13 +1102,17 @@ _GL_WARN_ON_USE (fsync, "fsync is unportable - " | |||
| 1091 | # undef ftruncate | 1102 | # undef ftruncate |
| 1092 | # define ftruncate rpl_ftruncate | 1103 | # define ftruncate rpl_ftruncate |
| 1093 | # endif | 1104 | # endif |
| 1094 | _GL_FUNCDECL_RPL (ftruncate, int, (int fd, off_t length)); | 1105 | _GL_FUNCDECL_RPL (ftruncate, int, |
| 1095 | _GL_CXXALIAS_RPL (ftruncate, int, (int fd, off_t length)); | 1106 | (int fd, off_t length), _GL_ATTRIBUTE_NODISCARD); |
| 1107 | _GL_CXXALIAS_RPL (ftruncate, int, | ||
| 1108 | (int fd, off_t length)); | ||
| 1096 | # else | 1109 | # else |
| 1097 | # if !@HAVE_FTRUNCATE@ | 1110 | # if !@HAVE_FTRUNCATE@ |
| 1098 | _GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length)); | 1111 | _GL_FUNCDECL_SYS (ftruncate, int, |
| 1112 | (int fd, off_t length), _GL_ATTRIBUTE_NODISCARD); | ||
| 1099 | # endif | 1113 | # endif |
| 1100 | _GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length)); | 1114 | _GL_CXXALIAS_SYS (ftruncate, int, |
| 1115 | (int fd, off_t length)); | ||
| 1101 | # endif | 1116 | # endif |
| 1102 | # if __GLIBC__ >= 2 | 1117 | # if __GLIBC__ >= 2 |
| 1103 | _GL_CXXALIASWARN (ftruncate); | 1118 | _GL_CXXALIASWARN (ftruncate); |
| @@ -1126,7 +1141,8 @@ _GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - " | |||
| 1126 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1141 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1127 | # define getcwd rpl_getcwd | 1142 | # define getcwd rpl_getcwd |
| 1128 | # endif | 1143 | # endif |
| 1129 | _GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size)); | 1144 | _GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size), |
| 1145 | _GL_ATTRIBUTE_NODISCARD); | ||
| 1130 | _GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size)); | 1146 | _GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size)); |
| 1131 | # elif defined _WIN32 && !defined __CYGWIN__ | 1147 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 1132 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1148 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -1181,15 +1197,19 @@ _GL_CXXALIASWARN (getcwd); | |||
| 1181 | # undef getdomainname | 1197 | # undef getdomainname |
| 1182 | # define getdomainname rpl_getdomainname | 1198 | # define getdomainname rpl_getdomainname |
| 1183 | # endif | 1199 | # endif |
| 1184 | _GL_FUNCDECL_RPL (getdomainname, int, (char *name, size_t len) | 1200 | _GL_FUNCDECL_RPL (getdomainname, int, |
| 1185 | _GL_ARG_NONNULL ((1))); | 1201 | (char *name, size_t len), |
| 1186 | _GL_CXXALIAS_RPL (getdomainname, int, (char *name, size_t len)); | 1202 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 1203 | _GL_CXXALIAS_RPL (getdomainname, int, | ||
| 1204 | (char *name, size_t len)); | ||
| 1187 | # else | 1205 | # else |
| 1188 | # if !@HAVE_DECL_GETDOMAINNAME@ | 1206 | # if !@HAVE_DECL_GETDOMAINNAME@ |
| 1189 | _GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len) | 1207 | _GL_FUNCDECL_SYS (getdomainname, int, |
| 1190 | _GL_ARG_NONNULL ((1))); | 1208 | (char *name, size_t len), |
| 1209 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 1191 | # endif | 1210 | # endif |
| 1192 | _GL_CXXALIAS_SYS (getdomainname, int, (char *name, size_t len)); | 1211 | _GL_CXXALIAS_SYS (getdomainname, int, |
| 1212 | (char *name, size_t len)); | ||
| 1193 | # endif | 1213 | # endif |
| 1194 | # if __GLIBC__ >= 2 | 1214 | # if __GLIBC__ >= 2 |
| 1195 | _GL_CXXALIASWARN (getdomainname); | 1215 | _GL_CXXALIASWARN (getdomainname); |
| @@ -1211,11 +1231,11 @@ _GL_WARN_ON_USE (getdomainname, "getdomainname is unportable - " | |||
| 1211 | # undef getdtablesize | 1231 | # undef getdtablesize |
| 1212 | # define getdtablesize rpl_getdtablesize | 1232 | # define getdtablesize rpl_getdtablesize |
| 1213 | # endif | 1233 | # endif |
| 1214 | _GL_FUNCDECL_RPL (getdtablesize, int, (void)); | 1234 | _GL_FUNCDECL_RPL (getdtablesize, int, (void), ); |
| 1215 | _GL_CXXALIAS_RPL (getdtablesize, int, (void)); | 1235 | _GL_CXXALIAS_RPL (getdtablesize, int, (void)); |
| 1216 | # else | 1236 | # else |
| 1217 | # if !@HAVE_GETDTABLESIZE@ | 1237 | # if !@HAVE_GETDTABLESIZE@ |
| 1218 | _GL_FUNCDECL_SYS (getdtablesize, int, (void)); | 1238 | _GL_FUNCDECL_SYS (getdtablesize, int, (void), ); |
| 1219 | # endif | 1239 | # endif |
| 1220 | /* Need to cast, because on AIX, the parameter list is | 1240 | /* Need to cast, because on AIX, the parameter list is |
| 1221 | (...). */ | 1241 | (...). */ |
| @@ -1238,13 +1258,17 @@ _GL_WARN_ON_USE (getdtablesize, "getdtablesize is unportable - " | |||
| 1238 | # undef getentropy | 1258 | # undef getentropy |
| 1239 | # define getentropy rpl_getentropy | 1259 | # define getentropy rpl_getentropy |
| 1240 | # endif | 1260 | # endif |
| 1241 | _GL_FUNCDECL_RPL (getentropy, int, (void *buffer, size_t length)); | 1261 | _GL_FUNCDECL_RPL (getentropy, int, |
| 1242 | _GL_CXXALIAS_RPL (getentropy, int, (void *buffer, size_t length)); | 1262 | (void *buffer, size_t length), _GL_ATTRIBUTE_NODISCARD); |
| 1263 | _GL_CXXALIAS_RPL (getentropy, int, | ||
| 1264 | (void *buffer, size_t length)); | ||
| 1243 | # else | 1265 | # else |
| 1244 | # if !@HAVE_GETENTROPY@ | 1266 | # if !@HAVE_GETENTROPY@ |
| 1245 | _GL_FUNCDECL_SYS (getentropy, int, (void *buffer, size_t length)); | 1267 | _GL_FUNCDECL_SYS (getentropy, int, |
| 1268 | (void *buffer, size_t length), _GL_ATTRIBUTE_NODISCARD); | ||
| 1246 | # endif | 1269 | # endif |
| 1247 | _GL_CXXALIAS_SYS (getentropy, int, (void *buffer, size_t length)); | 1270 | _GL_CXXALIAS_SYS (getentropy, int, |
| 1271 | (void *buffer, size_t length)); | ||
| 1248 | # endif | 1272 | # endif |
| 1249 | # if __GLIBC__ >= 2 | 1273 | # if __GLIBC__ >= 2 |
| 1250 | _GL_CXXALIASWARN (getentropy); | 1274 | _GL_CXXALIASWARN (getentropy); |
| @@ -1269,13 +1293,17 @@ _GL_WARN_ON_USE (getentropy, "getentropy is unportable - " | |||
| 1269 | # undef getgroups | 1293 | # undef getgroups |
| 1270 | # define getgroups rpl_getgroups | 1294 | # define getgroups rpl_getgroups |
| 1271 | # endif | 1295 | # endif |
| 1272 | _GL_FUNCDECL_RPL (getgroups, int, (int n, gid_t *groups)); | 1296 | _GL_FUNCDECL_RPL (getgroups, int, |
| 1273 | _GL_CXXALIAS_RPL (getgroups, int, (int n, gid_t *groups)); | 1297 | (int n, gid_t *groups), _GL_ATTRIBUTE_NODISCARD); |
| 1298 | _GL_CXXALIAS_RPL (getgroups, int, | ||
| 1299 | (int n, gid_t *groups)); | ||
| 1274 | # else | 1300 | # else |
| 1275 | # if !@HAVE_GETGROUPS@ | 1301 | # if !@HAVE_GETGROUPS@ |
| 1276 | _GL_FUNCDECL_SYS (getgroups, int, (int n, gid_t *groups)); | 1302 | _GL_FUNCDECL_SYS (getgroups, int, |
| 1303 | (int n, gid_t *groups), _GL_ATTRIBUTE_NODISCARD); | ||
| 1277 | # endif | 1304 | # endif |
| 1278 | _GL_CXXALIAS_SYS (getgroups, int, (int n, gid_t *groups)); | 1305 | _GL_CXXALIAS_SYS (getgroups, int, |
| 1306 | (int n, gid_t *groups)); | ||
| 1279 | # endif | 1307 | # endif |
| 1280 | _GL_CXXALIASWARN (getgroups); | 1308 | _GL_CXXALIASWARN (getgroups); |
| 1281 | #elif defined GNULIB_POSIXCHECK | 1309 | #elif defined GNULIB_POSIXCHECK |
| @@ -1300,12 +1328,12 @@ _GL_WARN_ON_USE (getgroups, "getgroups is unportable - " | |||
| 1300 | # undef gethostname | 1328 | # undef gethostname |
| 1301 | # define gethostname rpl_gethostname | 1329 | # define gethostname rpl_gethostname |
| 1302 | # endif | 1330 | # endif |
| 1303 | _GL_FUNCDECL_RPL (gethostname, int, (char *name, size_t len) | 1331 | _GL_FUNCDECL_RPL (gethostname, int, (char *name, size_t len), |
| 1304 | _GL_ARG_NONNULL ((1))); | 1332 | _GL_ARG_NONNULL ((1))); |
| 1305 | _GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len)); | 1333 | _GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len)); |
| 1306 | # else | 1334 | # else |
| 1307 | # if !@HAVE_GETHOSTNAME@ | 1335 | # if !@HAVE_GETHOSTNAME@ |
| 1308 | _GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len) | 1336 | _GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len), |
| 1309 | _GL_ARG_NONNULL ((1))); | 1337 | _GL_ARG_NONNULL ((1))); |
| 1310 | # endif | 1338 | # endif |
| 1311 | /* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second | 1339 | /* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second |
| @@ -1315,8 +1343,10 @@ _GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len)); | |||
| 1315 | # endif | 1343 | # endif |
| 1316 | _GL_CXXALIASWARN (gethostname); | 1344 | _GL_CXXALIASWARN (gethostname); |
| 1317 | #elif @UNISTD_H_HAVE_WINSOCK2_H@ | 1345 | #elif @UNISTD_H_HAVE_WINSOCK2_H@ |
| 1318 | # undef gethostname | 1346 | # if !GNULIB_GETHOSTNAME |
| 1319 | # define gethostname gethostname_used_without_requesting_gnulib_module_gethostname | 1347 | # undef gethostname |
| 1348 | # define gethostname gethostname_used_without_requesting_gnulib_module_gethostname | ||
| 1349 | # endif | ||
| 1320 | #elif defined GNULIB_POSIXCHECK | 1350 | #elif defined GNULIB_POSIXCHECK |
| 1321 | # undef gethostname | 1351 | # undef gethostname |
| 1322 | # if HAVE_RAW_DECL_GETHOSTNAME | 1352 | # if HAVE_RAW_DECL_GETHOSTNAME |
| @@ -1337,11 +1367,21 @@ _GL_WARN_ON_USE (gethostname, "gethostname is unportable - " | |||
| 1337 | ${LOGNAME-$USER} on Unix platforms, | 1367 | ${LOGNAME-$USER} on Unix platforms, |
| 1338 | $USERNAME on native Windows platforms. | 1368 | $USERNAME on native Windows platforms. |
| 1339 | */ | 1369 | */ |
| 1340 | # if !@HAVE_DECL_GETLOGIN@ | 1370 | # if @REPLACE_GETLOGIN@ |
| 1341 | _GL_FUNCDECL_SYS (getlogin, char *, (void)); | 1371 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1342 | # endif | 1372 | # define getlogin rpl_getlogin |
| 1373 | # endif | ||
| 1374 | _GL_FUNCDECL_RPL (getlogin, char *, (void), ); | ||
| 1375 | _GL_CXXALIAS_RPL (getlogin, char *, (void)); | ||
| 1376 | # else | ||
| 1377 | # if !@HAVE_DECL_GETLOGIN@ | ||
| 1378 | _GL_FUNCDECL_SYS (getlogin, char *, (void), ); | ||
| 1379 | # endif | ||
| 1343 | _GL_CXXALIAS_SYS (getlogin, char *, (void)); | 1380 | _GL_CXXALIAS_SYS (getlogin, char *, (void)); |
| 1381 | # endif | ||
| 1382 | # if __GLIBC__ >= 2 | ||
| 1344 | _GL_CXXALIASWARN (getlogin); | 1383 | _GL_CXXALIASWARN (getlogin); |
| 1384 | # endif | ||
| 1345 | #elif defined GNULIB_POSIXCHECK | 1385 | #elif defined GNULIB_POSIXCHECK |
| 1346 | # undef getlogin | 1386 | # undef getlogin |
| 1347 | # if HAVE_RAW_DECL_GETLOGIN | 1387 | # if HAVE_RAW_DECL_GETLOGIN |
| @@ -1370,12 +1410,12 @@ _GL_WARN_ON_USE (getlogin, "getlogin is unportable - " | |||
| 1370 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1410 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1371 | # define getlogin_r rpl_getlogin_r | 1411 | # define getlogin_r rpl_getlogin_r |
| 1372 | # endif | 1412 | # endif |
| 1373 | _GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size) | 1413 | _GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size), |
| 1374 | _GL_ARG_NONNULL ((1))); | 1414 | _GL_ARG_NONNULL ((1))); |
| 1375 | _GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size)); | 1415 | _GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size)); |
| 1376 | # else | 1416 | # else |
| 1377 | # if !@HAVE_DECL_GETLOGIN_R@ | 1417 | # if !@HAVE_DECL_GETLOGIN_R@ |
| 1378 | _GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size) | 1418 | _GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size), |
| 1379 | _GL_ARG_NONNULL ((1))); | 1419 | _GL_ARG_NONNULL ((1))); |
| 1380 | # endif | 1420 | # endif |
| 1381 | /* Need to cast, because on Solaris 10 systems, the second argument is | 1421 | /* Need to cast, because on Solaris 10 systems, the second argument is |
| @@ -1399,13 +1439,13 @@ _GL_WARN_ON_USE (getlogin_r, "getlogin_r is unportable - " | |||
| 1399 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1439 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1400 | # define getpagesize rpl_getpagesize | 1440 | # define getpagesize rpl_getpagesize |
| 1401 | # endif | 1441 | # endif |
| 1402 | _GL_FUNCDECL_RPL (getpagesize, int, (void)); | 1442 | _GL_FUNCDECL_RPL (getpagesize, int, (void), ); |
| 1403 | _GL_CXXALIAS_RPL (getpagesize, int, (void)); | 1443 | _GL_CXXALIAS_RPL (getpagesize, int, (void)); |
| 1404 | # else | 1444 | # else |
| 1405 | /* On HP-UX, getpagesize exists, but it is not declared in <unistd.h> even if | 1445 | /* On HP-UX, getpagesize exists, but it is not declared in <unistd.h> even if |
| 1406 | the compiler options -D_HPUX_SOURCE -D_XOPEN_SOURCE=600 are used. */ | 1446 | the compiler options -D_HPUX_SOURCE -D_XOPEN_SOURCE=600 are used. */ |
| 1407 | # if defined __hpux | 1447 | # if defined __hpux |
| 1408 | _GL_FUNCDECL_SYS (getpagesize, int, (void)); | 1448 | _GL_FUNCDECL_SYS (getpagesize, int, (void), ); |
| 1409 | # endif | 1449 | # endif |
| 1410 | # if !@HAVE_GETPAGESIZE@ | 1450 | # if !@HAVE_GETPAGESIZE@ |
| 1411 | # if !defined getpagesize | 1451 | # if !defined getpagesize |
| @@ -1456,7 +1496,7 @@ _GL_FUNCDECL_SYS (getpagesize, int, (void)); | |||
| 1456 | # define getpagesize() _gl_getpagesize () | 1496 | # define getpagesize() _gl_getpagesize () |
| 1457 | # else | 1497 | # else |
| 1458 | # if !GNULIB_defined_getpagesize_function | 1498 | # if !GNULIB_defined_getpagesize_function |
| 1459 | _GL_UNISTD_INLINE int | 1499 | _GL_GETPAGESIZE_INLINE int |
| 1460 | getpagesize () | 1500 | getpagesize () |
| 1461 | { | 1501 | { |
| 1462 | return _gl_getpagesize (); | 1502 | return _gl_getpagesize (); |
| @@ -1492,12 +1532,12 @@ _GL_WARN_ON_USE (getpagesize, "getpagesize is unportable - " | |||
| 1492 | # undef getpass | 1532 | # undef getpass |
| 1493 | # define getpass rpl_getpass | 1533 | # define getpass rpl_getpass |
| 1494 | # endif | 1534 | # endif |
| 1495 | _GL_FUNCDECL_RPL (getpass, char *, (const char *prompt) | 1535 | _GL_FUNCDECL_RPL (getpass, char *, (const char *prompt), |
| 1496 | _GL_ARG_NONNULL ((1))); | 1536 | _GL_ARG_NONNULL ((1))); |
| 1497 | _GL_CXXALIAS_RPL (getpass, char *, (const char *prompt)); | 1537 | _GL_CXXALIAS_RPL (getpass, char *, (const char *prompt)); |
| 1498 | # else | 1538 | # else |
| 1499 | # if !@HAVE_GETPASS@ | 1539 | # if !@HAVE_GETPASS@ |
| 1500 | _GL_FUNCDECL_SYS (getpass, char *, (const char *prompt) | 1540 | _GL_FUNCDECL_SYS (getpass, char *, (const char *prompt), |
| 1501 | _GL_ARG_NONNULL ((1))); | 1541 | _GL_ARG_NONNULL ((1))); |
| 1502 | # endif | 1542 | # endif |
| 1503 | _GL_CXXALIAS_SYS (getpass, char *, (const char *prompt)); | 1543 | _GL_CXXALIAS_SYS (getpass, char *, (const char *prompt)); |
| @@ -1530,12 +1570,21 @@ _GL_CXXALIASWARN (getpid); | |||
| 1530 | 1570 | ||
| 1531 | 1571 | ||
| 1532 | #if @GNULIB_GETUSERSHELL@ | 1572 | #if @GNULIB_GETUSERSHELL@ |
| 1573 | # if @REPLACE_GETUSERSHELL@ | ||
| 1533 | /* Return the next valid login shell on the system, or NULL when the end of | 1574 | /* Return the next valid login shell on the system, or NULL when the end of |
| 1534 | the list has been reached. */ | 1575 | the list has been reached. */ |
| 1535 | # if !@HAVE_DECL_GETUSERSHELL@ | 1576 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1536 | _GL_FUNCDECL_SYS (getusershell, char *, (void)); | 1577 | # undef getusershell |
| 1537 | # endif | 1578 | # define getusershell rpl_getusershell |
| 1579 | # endif | ||
| 1580 | _GL_FUNCDECL_RPL (getusershell, char *, (void), ); | ||
| 1581 | _GL_CXXALIAS_RPL (getusershell, char *, (void)); | ||
| 1582 | # else | ||
| 1583 | # if !@HAVE_DECL_GETUSERSHELL@ | ||
| 1584 | _GL_FUNCDECL_SYS (getusershell, char *, (void), ); | ||
| 1585 | # endif | ||
| 1538 | _GL_CXXALIAS_SYS (getusershell, char *, (void)); | 1586 | _GL_CXXALIAS_SYS (getusershell, char *, (void)); |
| 1587 | # endif | ||
| 1539 | _GL_CXXALIASWARN (getusershell); | 1588 | _GL_CXXALIASWARN (getusershell); |
| 1540 | #elif defined GNULIB_POSIXCHECK | 1589 | #elif defined GNULIB_POSIXCHECK |
| 1541 | # undef getusershell | 1590 | # undef getusershell |
| @@ -1547,10 +1596,19 @@ _GL_WARN_ON_USE (getusershell, "getusershell is unportable - " | |||
| 1547 | 1596 | ||
| 1548 | #if @GNULIB_GETUSERSHELL@ | 1597 | #if @GNULIB_GETUSERSHELL@ |
| 1549 | /* Rewind to pointer that is advanced at each getusershell() call. */ | 1598 | /* Rewind to pointer that is advanced at each getusershell() call. */ |
| 1550 | # if !@HAVE_DECL_GETUSERSHELL@ | 1599 | # if @REPLACE_GETUSERSHELL@ |
| 1551 | _GL_FUNCDECL_SYS (setusershell, void, (void)); | 1600 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1552 | # endif | 1601 | # undef setusershell |
| 1602 | # define setusershell rpl_setusershell | ||
| 1603 | # endif | ||
| 1604 | _GL_FUNCDECL_RPL (setusershell, void, (void), ); | ||
| 1605 | _GL_CXXALIAS_RPL (setusershell, void, (void)); | ||
| 1606 | # else | ||
| 1607 | # if !@HAVE_DECL_GETUSERSHELL@ | ||
| 1608 | _GL_FUNCDECL_SYS (setusershell, void, (void), ); | ||
| 1609 | # endif | ||
| 1553 | _GL_CXXALIAS_SYS (setusershell, void, (void)); | 1610 | _GL_CXXALIAS_SYS (setusershell, void, (void)); |
| 1611 | # endif | ||
| 1554 | _GL_CXXALIASWARN (setusershell); | 1612 | _GL_CXXALIASWARN (setusershell); |
| 1555 | #elif defined GNULIB_POSIXCHECK | 1613 | #elif defined GNULIB_POSIXCHECK |
| 1556 | # undef setusershell | 1614 | # undef setusershell |
| @@ -1563,10 +1621,19 @@ _GL_WARN_ON_USE (setusershell, "setusershell is unportable - " | |||
| 1563 | #if @GNULIB_GETUSERSHELL@ | 1621 | #if @GNULIB_GETUSERSHELL@ |
| 1564 | /* Free the pointer that is advanced at each getusershell() call and | 1622 | /* Free the pointer that is advanced at each getusershell() call and |
| 1565 | associated resources. */ | 1623 | associated resources. */ |
| 1566 | # if !@HAVE_DECL_GETUSERSHELL@ | 1624 | # if @REPLACE_GETUSERSHELL@ |
| 1567 | _GL_FUNCDECL_SYS (endusershell, void, (void)); | 1625 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1568 | # endif | 1626 | # undef endusershell |
| 1627 | # define endusershell rpl_endusershell | ||
| 1628 | # endif | ||
| 1629 | _GL_FUNCDECL_RPL (endusershell, void, (void), ); | ||
| 1630 | _GL_CXXALIAS_RPL (endusershell, void, (void)); | ||
| 1631 | # else | ||
| 1632 | # if !@HAVE_DECL_GETUSERSHELL@ | ||
| 1633 | _GL_FUNCDECL_SYS (endusershell, void, (void), ); | ||
| 1634 | # endif | ||
| 1569 | _GL_CXXALIAS_SYS (endusershell, void, (void)); | 1635 | _GL_CXXALIAS_SYS (endusershell, void, (void)); |
| 1636 | # endif | ||
| 1570 | _GL_CXXALIASWARN (endusershell); | 1637 | _GL_CXXALIASWARN (endusershell); |
| 1571 | #elif defined GNULIB_POSIXCHECK | 1638 | #elif defined GNULIB_POSIXCHECK |
| 1572 | # undef endusershell | 1639 | # undef endusershell |
| @@ -1580,7 +1647,7 @@ _GL_WARN_ON_USE (endusershell, "endusershell is unportable - " | |||
| 1580 | #if @GNULIB_GROUP_MEMBER@ | 1647 | #if @GNULIB_GROUP_MEMBER@ |
| 1581 | /* Determine whether group id is in calling user's group list. */ | 1648 | /* Determine whether group id is in calling user's group list. */ |
| 1582 | # if !@HAVE_GROUP_MEMBER@ | 1649 | # if !@HAVE_GROUP_MEMBER@ |
| 1583 | _GL_FUNCDECL_SYS (group_member, int, (gid_t gid)); | 1650 | _GL_FUNCDECL_SYS (group_member, int, (gid_t gid), ); |
| 1584 | # endif | 1651 | # endif |
| 1585 | _GL_CXXALIAS_SYS (group_member, int, (gid_t gid)); | 1652 | _GL_CXXALIAS_SYS (group_member, int, (gid_t gid)); |
| 1586 | _GL_CXXALIASWARN (group_member); | 1653 | _GL_CXXALIASWARN (group_member); |
| @@ -1600,7 +1667,7 @@ _GL_WARN_ON_USE (group_member, "group_member is unportable - " | |||
| 1600 | # define isatty rpl_isatty | 1667 | # define isatty rpl_isatty |
| 1601 | # endif | 1668 | # endif |
| 1602 | # define GNULIB_defined_isatty 1 | 1669 | # define GNULIB_defined_isatty 1 |
| 1603 | _GL_FUNCDECL_RPL (isatty, int, (int fd)); | 1670 | _GL_FUNCDECL_RPL (isatty, int, (int fd), ); |
| 1604 | _GL_CXXALIAS_RPL (isatty, int, (int fd)); | 1671 | _GL_CXXALIAS_RPL (isatty, int, (int fd)); |
| 1605 | # elif defined _WIN32 && !defined __CYGWIN__ | 1672 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 1606 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1673 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -1646,13 +1713,13 @@ _GL_CXXALIASWARN (isatty); | |||
| 1646 | # undef lchown | 1713 | # undef lchown |
| 1647 | # define lchown rpl_lchown | 1714 | # define lchown rpl_lchown |
| 1648 | # endif | 1715 | # endif |
| 1649 | _GL_FUNCDECL_RPL (lchown, int, (char const *file, uid_t owner, gid_t group) | 1716 | _GL_FUNCDECL_RPL (lchown, int, (char const *file, uid_t owner, gid_t group), |
| 1650 | _GL_ARG_NONNULL ((1))); | 1717 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 1651 | _GL_CXXALIAS_RPL (lchown, int, (char const *file, uid_t owner, gid_t group)); | 1718 | _GL_CXXALIAS_RPL (lchown, int, (char const *file, uid_t owner, gid_t group)); |
| 1652 | # else | 1719 | # else |
| 1653 | # if !@HAVE_LCHOWN@ | 1720 | # if !@HAVE_LCHOWN@ |
| 1654 | _GL_FUNCDECL_SYS (lchown, int, (char const *file, uid_t owner, gid_t group) | 1721 | _GL_FUNCDECL_SYS (lchown, int, (char const *file, uid_t owner, gid_t group), |
| 1655 | _GL_ARG_NONNULL ((1))); | 1722 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 1656 | # endif | 1723 | # endif |
| 1657 | _GL_CXXALIAS_SYS (lchown, int, (char const *file, uid_t owner, gid_t group)); | 1724 | _GL_CXXALIAS_SYS (lchown, int, (char const *file, uid_t owner, gid_t group)); |
| 1658 | # endif | 1725 | # endif |
| @@ -1675,13 +1742,13 @@ _GL_WARN_ON_USE (lchown, "lchown is unportable to pre-POSIX.1-2001 systems - " | |||
| 1675 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1742 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1676 | # define link rpl_link | 1743 | # define link rpl_link |
| 1677 | # endif | 1744 | # endif |
| 1678 | _GL_FUNCDECL_RPL (link, int, (const char *path1, const char *path2) | 1745 | _GL_FUNCDECL_RPL (link, int, (const char *path1, const char *path2), |
| 1679 | _GL_ARG_NONNULL ((1, 2))); | 1746 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_NODISCARD); |
| 1680 | _GL_CXXALIAS_RPL (link, int, (const char *path1, const char *path2)); | 1747 | _GL_CXXALIAS_RPL (link, int, (const char *path1, const char *path2)); |
| 1681 | # else | 1748 | # else |
| 1682 | # if !@HAVE_LINK@ | 1749 | # if !@HAVE_LINK@ |
| 1683 | _GL_FUNCDECL_SYS (link, int, (const char *path1, const char *path2) | 1750 | _GL_FUNCDECL_SYS (link, int, (const char *path1, const char *path2), |
| 1684 | _GL_ARG_NONNULL ((1, 2))); | 1751 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_NODISCARD); |
| 1685 | # endif | 1752 | # endif |
| 1686 | _GL_CXXALIAS_SYS (link, int, (const char *path1, const char *path2)); | 1753 | _GL_CXXALIAS_SYS (link, int, (const char *path1, const char *path2)); |
| 1687 | # endif | 1754 | # endif |
| @@ -1706,8 +1773,8 @@ _GL_WARN_ON_USE (link, "link is unportable - " | |||
| 1706 | # endif | 1773 | # endif |
| 1707 | _GL_FUNCDECL_RPL (linkat, int, | 1774 | _GL_FUNCDECL_RPL (linkat, int, |
| 1708 | (int fd1, const char *path1, int fd2, const char *path2, | 1775 | (int fd1, const char *path1, int fd2, const char *path2, |
| 1709 | int flag) | 1776 | int flag), |
| 1710 | _GL_ARG_NONNULL ((2, 4))); | 1777 | _GL_ARG_NONNULL ((2, 4)) _GL_ATTRIBUTE_NODISCARD); |
| 1711 | _GL_CXXALIAS_RPL (linkat, int, | 1778 | _GL_CXXALIAS_RPL (linkat, int, |
| 1712 | (int fd1, const char *path1, int fd2, const char *path2, | 1779 | (int fd1, const char *path1, int fd2, const char *path2, |
| 1713 | int flag)); | 1780 | int flag)); |
| @@ -1715,8 +1782,8 @@ _GL_CXXALIAS_RPL (linkat, int, | |||
| 1715 | # if !@HAVE_LINKAT@ | 1782 | # if !@HAVE_LINKAT@ |
| 1716 | _GL_FUNCDECL_SYS (linkat, int, | 1783 | _GL_FUNCDECL_SYS (linkat, int, |
| 1717 | (int fd1, const char *path1, int fd2, const char *path2, | 1784 | (int fd1, const char *path1, int fd2, const char *path2, |
| 1718 | int flag) | 1785 | int flag), |
| 1719 | _GL_ARG_NONNULL ((2, 4))); | 1786 | _GL_ARG_NONNULL ((2, 4)) _GL_ATTRIBUTE_NODISCARD); |
| 1720 | # endif | 1787 | # endif |
| 1721 | _GL_CXXALIAS_SYS (linkat, int, | 1788 | _GL_CXXALIAS_SYS (linkat, int, |
| 1722 | (int fd1, const char *path1, int fd2, const char *path2, | 1789 | (int fd1, const char *path1, int fd2, const char *path2, |
| @@ -1743,7 +1810,7 @@ _GL_WARN_ON_USE (linkat, "linkat is unportable - " | |||
| 1743 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1810 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1744 | # define lseek rpl_lseek | 1811 | # define lseek rpl_lseek |
| 1745 | # endif | 1812 | # endif |
| 1746 | _GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence)); | 1813 | _GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence), ); |
| 1747 | _GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence)); | 1814 | _GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence)); |
| 1748 | # elif defined _WIN32 && !defined __CYGWIN__ | 1815 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 1749 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1816 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -1783,7 +1850,8 @@ _GL_CXXALIASWARN (lseek); | |||
| 1783 | Store the read-end as fd[0] and the write-end as fd[1]. | 1850 | Store the read-end as fd[0] and the write-end as fd[1]. |
| 1784 | Return 0 upon success, or -1 with errno set upon failure. */ | 1851 | Return 0 upon success, or -1 with errno set upon failure. */ |
| 1785 | # if !@HAVE_PIPE@ | 1852 | # if !@HAVE_PIPE@ |
| 1786 | _GL_FUNCDECL_SYS (pipe, int, (int fd[2]) _GL_ARG_NONNULL ((1))); | 1853 | _GL_FUNCDECL_SYS (pipe, int, (int fd[2]), |
| 1854 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 1787 | # endif | 1855 | # endif |
| 1788 | _GL_CXXALIAS_SYS (pipe, int, (int fd[2])); | 1856 | _GL_CXXALIAS_SYS (pipe, int, (int fd[2])); |
| 1789 | _GL_CXXALIASWARN (pipe); | 1857 | _GL_CXXALIASWARN (pipe); |
| @@ -1810,10 +1878,12 @@ _GL_WARN_ON_USE (pipe, "pipe is unportable - " | |||
| 1810 | # undef pipe2 | 1878 | # undef pipe2 |
| 1811 | # define pipe2 rpl_pipe2 | 1879 | # define pipe2 rpl_pipe2 |
| 1812 | # endif | 1880 | # endif |
| 1813 | _GL_FUNCDECL_RPL (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1))); | 1881 | _GL_FUNCDECL_RPL (pipe2, int, (int fd[2], int flags), |
| 1882 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 1814 | _GL_CXXALIAS_RPL (pipe2, int, (int fd[2], int flags)); | 1883 | _GL_CXXALIAS_RPL (pipe2, int, (int fd[2], int flags)); |
| 1815 | # else | 1884 | # else |
| 1816 | _GL_FUNCDECL_SYS (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1))); | 1885 | _GL_FUNCDECL_SYS (pipe2, int, (int fd[2], int flags), |
| 1886 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 1817 | _GL_CXXALIAS_SYS (pipe2, int, (int fd[2], int flags)); | 1887 | _GL_CXXALIAS_SYS (pipe2, int, (int fd[2], int flags)); |
| 1818 | # endif | 1888 | # endif |
| 1819 | # if __GLIBC__ >= 2 | 1889 | # if __GLIBC__ >= 2 |
| @@ -1840,15 +1910,15 @@ _GL_WARN_ON_USE (pipe2, "pipe2 is unportable - " | |||
| 1840 | # define pread rpl_pread | 1910 | # define pread rpl_pread |
| 1841 | # endif | 1911 | # endif |
| 1842 | _GL_FUNCDECL_RPL (pread, ssize_t, | 1912 | _GL_FUNCDECL_RPL (pread, ssize_t, |
| 1843 | (int fd, void *buf, size_t bufsize, off_t offset) | 1913 | (int fd, void *buf, size_t bufsize, off_t offset), |
| 1844 | _GL_ARG_NONNULL ((2))); | 1914 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 1845 | _GL_CXXALIAS_RPL (pread, ssize_t, | 1915 | _GL_CXXALIAS_RPL (pread, ssize_t, |
| 1846 | (int fd, void *buf, size_t bufsize, off_t offset)); | 1916 | (int fd, void *buf, size_t bufsize, off_t offset)); |
| 1847 | # else | 1917 | # else |
| 1848 | # if !@HAVE_PREAD@ | 1918 | # if !@HAVE_PREAD@ |
| 1849 | _GL_FUNCDECL_SYS (pread, ssize_t, | 1919 | _GL_FUNCDECL_SYS (pread, ssize_t, |
| 1850 | (int fd, void *buf, size_t bufsize, off_t offset) | 1920 | (int fd, void *buf, size_t bufsize, off_t offset), |
| 1851 | _GL_ARG_NONNULL ((2))); | 1921 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 1852 | # endif | 1922 | # endif |
| 1853 | _GL_CXXALIAS_SYS (pread, ssize_t, | 1923 | _GL_CXXALIAS_SYS (pread, ssize_t, |
| 1854 | (int fd, void *buf, size_t bufsize, off_t offset)); | 1924 | (int fd, void *buf, size_t bufsize, off_t offset)); |
| @@ -1877,15 +1947,15 @@ _GL_WARN_ON_USE (pread, "pread is unportable - " | |||
| 1877 | # define pwrite rpl_pwrite | 1947 | # define pwrite rpl_pwrite |
| 1878 | # endif | 1948 | # endif |
| 1879 | _GL_FUNCDECL_RPL (pwrite, ssize_t, | 1949 | _GL_FUNCDECL_RPL (pwrite, ssize_t, |
| 1880 | (int fd, const void *buf, size_t bufsize, off_t offset) | 1950 | (int fd, const void *buf, size_t bufsize, off_t offset), |
| 1881 | _GL_ARG_NONNULL ((2))); | 1951 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 1882 | _GL_CXXALIAS_RPL (pwrite, ssize_t, | 1952 | _GL_CXXALIAS_RPL (pwrite, ssize_t, |
| 1883 | (int fd, const void *buf, size_t bufsize, off_t offset)); | 1953 | (int fd, const void *buf, size_t bufsize, off_t offset)); |
| 1884 | # else | 1954 | # else |
| 1885 | # if !@HAVE_PWRITE@ | 1955 | # if !@HAVE_PWRITE@ |
| 1886 | _GL_FUNCDECL_SYS (pwrite, ssize_t, | 1956 | _GL_FUNCDECL_SYS (pwrite, ssize_t, |
| 1887 | (int fd, const void *buf, size_t bufsize, off_t offset) | 1957 | (int fd, const void *buf, size_t bufsize, off_t offset), |
| 1888 | _GL_ARG_NONNULL ((2))); | 1958 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 1889 | # endif | 1959 | # endif |
| 1890 | _GL_CXXALIAS_SYS (pwrite, ssize_t, | 1960 | _GL_CXXALIAS_SYS (pwrite, ssize_t, |
| 1891 | (int fd, const void *buf, size_t bufsize, off_t offset)); | 1961 | (int fd, const void *buf, size_t bufsize, off_t offset)); |
| @@ -1911,8 +1981,9 @@ _GL_WARN_ON_USE (pwrite, "pwrite is unportable - " | |||
| 1911 | # undef read | 1981 | # undef read |
| 1912 | # define read rpl_read | 1982 | # define read rpl_read |
| 1913 | # endif | 1983 | # endif |
| 1914 | _GL_FUNCDECL_RPL (read, ssize_t, (int fd, void *buf, size_t count) | 1984 | |
| 1915 | _GL_ARG_NONNULL ((2))); | 1985 | _GL_FUNCDECL_RPL (read, ssize_t, (int fd, void *buf, size_t count), |
| 1986 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); | ||
| 1916 | _GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, size_t count)); | 1987 | _GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, size_t count)); |
| 1917 | # elif defined _WIN32 && !defined __CYGWIN__ | 1988 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 1918 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 1989 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -1933,11 +2004,7 @@ _GL_CXXALIASWARN (read); | |||
| 1933 | # undef read | 2004 | # undef read |
| 1934 | # define read _read | 2005 | # define read _read |
| 1935 | # endif | 2006 | # endif |
| 1936 | # ifdef __MINGW32__ | 2007 | _GL_CXXALIAS_MDA_CAST (read, ssize_t, (int fd, void *buf, unsigned int count)); |
| 1937 | _GL_CXXALIAS_MDA (read, int, (int fd, void *buf, unsigned int count)); | ||
| 1938 | # else | ||
| 1939 | _GL_CXXALIAS_MDA (read, ssize_t, (int fd, void *buf, unsigned int count)); | ||
| 1940 | # endif | ||
| 1941 | # else | 2008 | # else |
| 1942 | _GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count)); | 2009 | _GL_CXXALIAS_SYS (read, ssize_t, (int fd, void *buf, size_t count)); |
| 1943 | # endif | 2010 | # endif |
| @@ -1957,8 +2024,8 @@ _GL_CXXALIASWARN (read); | |||
| 1957 | # endif | 2024 | # endif |
| 1958 | _GL_FUNCDECL_RPL (readlink, ssize_t, | 2025 | _GL_FUNCDECL_RPL (readlink, ssize_t, |
| 1959 | (const char *restrict file, | 2026 | (const char *restrict file, |
| 1960 | char *restrict buf, size_t bufsize) | 2027 | char *restrict buf, size_t bufsize), |
| 1961 | _GL_ARG_NONNULL ((1, 2))); | 2028 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_NODISCARD); |
| 1962 | _GL_CXXALIAS_RPL (readlink, ssize_t, | 2029 | _GL_CXXALIAS_RPL (readlink, ssize_t, |
| 1963 | (const char *restrict file, | 2030 | (const char *restrict file, |
| 1964 | char *restrict buf, size_t bufsize)); | 2031 | char *restrict buf, size_t bufsize)); |
| @@ -1966,8 +2033,8 @@ _GL_CXXALIAS_RPL (readlink, ssize_t, | |||
| 1966 | # if !@HAVE_READLINK@ | 2033 | # if !@HAVE_READLINK@ |
| 1967 | _GL_FUNCDECL_SYS (readlink, ssize_t, | 2034 | _GL_FUNCDECL_SYS (readlink, ssize_t, |
| 1968 | (const char *restrict file, | 2035 | (const char *restrict file, |
| 1969 | char *restrict buf, size_t bufsize) | 2036 | char *restrict buf, size_t bufsize), |
| 1970 | _GL_ARG_NONNULL ((1, 2))); | 2037 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_NODISCARD); |
| 1971 | # endif | 2038 | # endif |
| 1972 | _GL_CXXALIAS_SYS (readlink, ssize_t, | 2039 | _GL_CXXALIAS_SYS (readlink, ssize_t, |
| 1973 | (const char *restrict file, | 2040 | (const char *restrict file, |
| @@ -1990,8 +2057,8 @@ _GL_WARN_ON_USE (readlink, "readlink is unportable - " | |||
| 1990 | # endif | 2057 | # endif |
| 1991 | _GL_FUNCDECL_RPL (readlinkat, ssize_t, | 2058 | _GL_FUNCDECL_RPL (readlinkat, ssize_t, |
| 1992 | (int fd, char const *restrict file, | 2059 | (int fd, char const *restrict file, |
| 1993 | char *restrict buf, size_t len) | 2060 | char *restrict buf, size_t len), |
| 1994 | _GL_ARG_NONNULL ((2, 3))); | 2061 | _GL_ARG_NONNULL ((2, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 1995 | _GL_CXXALIAS_RPL (readlinkat, ssize_t, | 2062 | _GL_CXXALIAS_RPL (readlinkat, ssize_t, |
| 1996 | (int fd, char const *restrict file, | 2063 | (int fd, char const *restrict file, |
| 1997 | char *restrict buf, size_t len)); | 2064 | char *restrict buf, size_t len)); |
| @@ -1999,8 +2066,8 @@ _GL_CXXALIAS_RPL (readlinkat, ssize_t, | |||
| 1999 | # if !@HAVE_READLINKAT@ | 2066 | # if !@HAVE_READLINKAT@ |
| 2000 | _GL_FUNCDECL_SYS (readlinkat, ssize_t, | 2067 | _GL_FUNCDECL_SYS (readlinkat, ssize_t, |
| 2001 | (int fd, char const *restrict file, | 2068 | (int fd, char const *restrict file, |
| 2002 | char *restrict buf, size_t len) | 2069 | char *restrict buf, size_t len), |
| 2003 | _GL_ARG_NONNULL ((2, 3))); | 2070 | _GL_ARG_NONNULL ((2, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 2004 | # endif | 2071 | # endif |
| 2005 | _GL_CXXALIAS_SYS (readlinkat, ssize_t, | 2072 | _GL_CXXALIAS_SYS (readlinkat, ssize_t, |
| 2006 | (int fd, char const *restrict file, | 2073 | (int fd, char const *restrict file, |
| @@ -2024,7 +2091,7 @@ _GL_WARN_ON_USE (readlinkat, "readlinkat is not portable - " | |||
| 2024 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 2091 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 2025 | # define rmdir rpl_rmdir | 2092 | # define rmdir rpl_rmdir |
| 2026 | # endif | 2093 | # endif |
| 2027 | _GL_FUNCDECL_RPL (rmdir, int, (char const *name) _GL_ARG_NONNULL ((1))); | 2094 | _GL_FUNCDECL_RPL (rmdir, int, (char const *name), _GL_ARG_NONNULL ((1))); |
| 2028 | _GL_CXXALIAS_RPL (rmdir, int, (char const *name)); | 2095 | _GL_CXXALIAS_RPL (rmdir, int, (char const *name)); |
| 2029 | # elif defined _WIN32 && !defined __CYGWIN__ | 2096 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 2030 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 2097 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -2073,18 +2140,22 @@ _GL_CXXALIASWARN (rmdir); | |||
| 2073 | # undef sethostname | 2140 | # undef sethostname |
| 2074 | # define sethostname rpl_sethostname | 2141 | # define sethostname rpl_sethostname |
| 2075 | # endif | 2142 | # endif |
| 2076 | _GL_FUNCDECL_RPL (sethostname, int, (const char *name, size_t len) | 2143 | _GL_FUNCDECL_RPL (sethostname, int, |
| 2077 | _GL_ARG_NONNULL ((1))); | 2144 | (const char *name, size_t len), |
| 2078 | _GL_CXXALIAS_RPL (sethostname, int, (const char *name, size_t len)); | 2145 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 2146 | _GL_CXXALIAS_RPL (sethostname, int, | ||
| 2147 | (const char *name, size_t len)); | ||
| 2079 | # else | 2148 | # else |
| 2080 | # if !@HAVE_SETHOSTNAME@ || !@HAVE_DECL_SETHOSTNAME@ | 2149 | # if !@HAVE_SETHOSTNAME@ || !@HAVE_DECL_SETHOSTNAME@ |
| 2081 | _GL_FUNCDECL_SYS (sethostname, int, (const char *name, size_t len) | 2150 | _GL_FUNCDECL_SYS (sethostname, int, |
| 2082 | _GL_ARG_NONNULL ((1))); | 2151 | (const char *name, size_t len), |
| 2152 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); | ||
| 2083 | # endif | 2153 | # endif |
| 2084 | /* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, IRIX 6.5 | 2154 | /* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, IRIX 6.5 |
| 2085 | and FreeBSD 6.4 the second parameter is int. On Solaris 11 | 2155 | and FreeBSD 6.4 the second parameter is int. On Solaris 11 |
| 2086 | 2011-10, the first parameter is not const. */ | 2156 | 2011-10, the first parameter is not const. */ |
| 2087 | _GL_CXXALIAS_SYS_CAST (sethostname, int, (const char *name, size_t len)); | 2157 | _GL_CXXALIAS_SYS_CAST (sethostname, int, |
| 2158 | (const char *name, size_t len)); | ||
| 2088 | # endif | 2159 | # endif |
| 2089 | # if __GLIBC__ >= 2 | 2160 | # if __GLIBC__ >= 2 |
| 2090 | _GL_CXXALIASWARN (sethostname); | 2161 | _GL_CXXALIASWARN (sethostname); |
| @@ -2108,11 +2179,11 @@ _GL_WARN_ON_USE (sethostname, "sethostname is unportable - " | |||
| 2108 | # undef sleep | 2179 | # undef sleep |
| 2109 | # define sleep rpl_sleep | 2180 | # define sleep rpl_sleep |
| 2110 | # endif | 2181 | # endif |
| 2111 | _GL_FUNCDECL_RPL (sleep, unsigned int, (unsigned int n)); | 2182 | _GL_FUNCDECL_RPL (sleep, unsigned int, (unsigned int n), ); |
| 2112 | _GL_CXXALIAS_RPL (sleep, unsigned int, (unsigned int n)); | 2183 | _GL_CXXALIAS_RPL (sleep, unsigned int, (unsigned int n)); |
| 2113 | # else | 2184 | # else |
| 2114 | # if !@HAVE_SLEEP@ | 2185 | # if !@HAVE_SLEEP@ |
| 2115 | _GL_FUNCDECL_SYS (sleep, unsigned int, (unsigned int n)); | 2186 | _GL_FUNCDECL_SYS (sleep, unsigned int, (unsigned int n), ); |
| 2116 | # endif | 2187 | # endif |
| 2117 | _GL_CXXALIAS_SYS (sleep, unsigned int, (unsigned int n)); | 2188 | _GL_CXXALIAS_SYS (sleep, unsigned int, (unsigned int n)); |
| 2118 | # endif | 2189 | # endif |
| @@ -2157,15 +2228,19 @@ _GL_CXXALIASWARN (swab); | |||
| 2157 | # undef symlink | 2228 | # undef symlink |
| 2158 | # define symlink rpl_symlink | 2229 | # define symlink rpl_symlink |
| 2159 | # endif | 2230 | # endif |
| 2160 | _GL_FUNCDECL_RPL (symlink, int, (char const *contents, char const *file) | 2231 | _GL_FUNCDECL_RPL (symlink, int, |
| 2161 | _GL_ARG_NONNULL ((1, 2))); | 2232 | (char const *contents, char const *file), |
| 2162 | _GL_CXXALIAS_RPL (symlink, int, (char const *contents, char const *file)); | 2233 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_NODISCARD); |
| 2234 | _GL_CXXALIAS_RPL (symlink, int, | ||
| 2235 | (char const *contents, char const *file)); | ||
| 2163 | # else | 2236 | # else |
| 2164 | # if !@HAVE_SYMLINK@ | 2237 | # if !@HAVE_SYMLINK@ |
| 2165 | _GL_FUNCDECL_SYS (symlink, int, (char const *contents, char const *file) | 2238 | _GL_FUNCDECL_SYS (symlink, int, |
| 2166 | _GL_ARG_NONNULL ((1, 2))); | 2239 | (char const *contents, char const *file), |
| 2240 | _GL_ARG_NONNULL ((1, 2)) _GL_ATTRIBUTE_NODISCARD); | ||
| 2167 | # endif | 2241 | # endif |
| 2168 | _GL_CXXALIAS_SYS (symlink, int, (char const *contents, char const *file)); | 2242 | _GL_CXXALIAS_SYS (symlink, int, |
| 2243 | (char const *contents, char const *file)); | ||
| 2169 | # endif | 2244 | # endif |
| 2170 | _GL_CXXALIASWARN (symlink); | 2245 | _GL_CXXALIASWARN (symlink); |
| 2171 | #elif defined GNULIB_POSIXCHECK | 2246 | #elif defined GNULIB_POSIXCHECK |
| @@ -2184,15 +2259,15 @@ _GL_WARN_ON_USE (symlink, "symlink is not portable - " | |||
| 2184 | # define symlinkat rpl_symlinkat | 2259 | # define symlinkat rpl_symlinkat |
| 2185 | # endif | 2260 | # endif |
| 2186 | _GL_FUNCDECL_RPL (symlinkat, int, | 2261 | _GL_FUNCDECL_RPL (symlinkat, int, |
| 2187 | (char const *contents, int fd, char const *file) | 2262 | (char const *contents, int fd, char const *file), |
| 2188 | _GL_ARG_NONNULL ((1, 3))); | 2263 | _GL_ARG_NONNULL ((1, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 2189 | _GL_CXXALIAS_RPL (symlinkat, int, | 2264 | _GL_CXXALIAS_RPL (symlinkat, int, |
| 2190 | (char const *contents, int fd, char const *file)); | 2265 | (char const *contents, int fd, char const *file)); |
| 2191 | # else | 2266 | # else |
| 2192 | # if !@HAVE_SYMLINKAT@ | 2267 | # if !@HAVE_SYMLINKAT@ |
| 2193 | _GL_FUNCDECL_SYS (symlinkat, int, | 2268 | _GL_FUNCDECL_SYS (symlinkat, int, |
| 2194 | (char const *contents, int fd, char const *file) | 2269 | (char const *contents, int fd, char const *file), |
| 2195 | _GL_ARG_NONNULL ((1, 3))); | 2270 | _GL_ARG_NONNULL ((1, 3)) _GL_ATTRIBUTE_NODISCARD); |
| 2196 | # endif | 2271 | # endif |
| 2197 | _GL_CXXALIAS_SYS (symlinkat, int, | 2272 | _GL_CXXALIAS_SYS (symlinkat, int, |
| 2198 | (char const *contents, int fd, char const *file)); | 2273 | (char const *contents, int fd, char const *file)); |
| @@ -2219,13 +2294,13 @@ _GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - " | |||
| 2219 | # undef truncate | 2294 | # undef truncate |
| 2220 | # define truncate rpl_truncate | 2295 | # define truncate rpl_truncate |
| 2221 | # endif | 2296 | # endif |
| 2222 | _GL_FUNCDECL_RPL (truncate, int, (const char *filename, off_t length) | 2297 | _GL_FUNCDECL_RPL (truncate, int, (const char *filename, off_t length), |
| 2223 | _GL_ARG_NONNULL ((1))); | 2298 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 2224 | _GL_CXXALIAS_RPL (truncate, int, (const char *filename, off_t length)); | 2299 | _GL_CXXALIAS_RPL (truncate, int, (const char *filename, off_t length)); |
| 2225 | # else | 2300 | # else |
| 2226 | # if !@HAVE_DECL_TRUNCATE@ | 2301 | # if !@HAVE_DECL_TRUNCATE@ |
| 2227 | _GL_FUNCDECL_SYS (truncate, int, (const char *filename, off_t length) | 2302 | _GL_FUNCDECL_SYS (truncate, int, (const char *filename, off_t length), |
| 2228 | _GL_ARG_NONNULL ((1))); | 2303 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NODISCARD); |
| 2229 | # endif | 2304 | # endif |
| 2230 | _GL_CXXALIAS_SYS (truncate, int, (const char *filename, off_t length)); | 2305 | _GL_CXXALIAS_SYS (truncate, int, (const char *filename, off_t length)); |
| 2231 | # endif | 2306 | # endif |
| @@ -2250,13 +2325,15 @@ _GL_WARN_ON_USE (truncate, "truncate is unportable - " | |||
| 2250 | # define ttyname_r rpl_ttyname_r | 2325 | # define ttyname_r rpl_ttyname_r |
| 2251 | # endif | 2326 | # endif |
| 2252 | _GL_FUNCDECL_RPL (ttyname_r, int, | 2327 | _GL_FUNCDECL_RPL (ttyname_r, int, |
| 2253 | (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); | 2328 | (int fd, char *buf, size_t buflen), |
| 2329 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); | ||
| 2254 | _GL_CXXALIAS_RPL (ttyname_r, int, | 2330 | _GL_CXXALIAS_RPL (ttyname_r, int, |
| 2255 | (int fd, char *buf, size_t buflen)); | 2331 | (int fd, char *buf, size_t buflen)); |
| 2256 | # else | 2332 | # else |
| 2257 | # if !@HAVE_DECL_TTYNAME_R@ | 2333 | # if !@HAVE_DECL_TTYNAME_R@ |
| 2258 | _GL_FUNCDECL_SYS (ttyname_r, int, | 2334 | _GL_FUNCDECL_SYS (ttyname_r, int, |
| 2259 | (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); | 2335 | (int fd, char *buf, size_t buflen), |
| 2336 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); | ||
| 2260 | # endif | 2337 | # endif |
| 2261 | _GL_CXXALIAS_SYS (ttyname_r, int, | 2338 | _GL_CXXALIAS_SYS (ttyname_r, int, |
| 2262 | (int fd, char *buf, size_t buflen)); | 2339 | (int fd, char *buf, size_t buflen)); |
| @@ -2279,7 +2356,7 @@ _GL_WARN_ON_USE (ttyname_r, "ttyname_r is not portable - " | |||
| 2279 | # undef unlink | 2356 | # undef unlink |
| 2280 | # define unlink rpl_unlink | 2357 | # define unlink rpl_unlink |
| 2281 | # endif | 2358 | # endif |
| 2282 | _GL_FUNCDECL_RPL (unlink, int, (char const *file) _GL_ARG_NONNULL ((1))); | 2359 | _GL_FUNCDECL_RPL (unlink, int, (char const *file), _GL_ARG_NONNULL ((1))); |
| 2283 | _GL_CXXALIAS_RPL (unlink, int, (char const *file)); | 2360 | _GL_CXXALIAS_RPL (unlink, int, (char const *file)); |
| 2284 | # elif defined _WIN32 && !defined __CYGWIN__ | 2361 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 2285 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 2362 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| @@ -2320,12 +2397,12 @@ _GL_CXXALIASWARN (unlink); | |||
| 2320 | # undef unlinkat | 2397 | # undef unlinkat |
| 2321 | # define unlinkat rpl_unlinkat | 2398 | # define unlinkat rpl_unlinkat |
| 2322 | # endif | 2399 | # endif |
| 2323 | _GL_FUNCDECL_RPL (unlinkat, int, (int fd, char const *file, int flag) | 2400 | _GL_FUNCDECL_RPL (unlinkat, int, (int fd, char const *file, int flag), |
| 2324 | _GL_ARG_NONNULL ((2))); | 2401 | _GL_ARG_NONNULL ((2))); |
| 2325 | _GL_CXXALIAS_RPL (unlinkat, int, (int fd, char const *file, int flag)); | 2402 | _GL_CXXALIAS_RPL (unlinkat, int, (int fd, char const *file, int flag)); |
| 2326 | # else | 2403 | # else |
| 2327 | # if !@HAVE_UNLINKAT@ | 2404 | # if !@HAVE_UNLINKAT@ |
| 2328 | _GL_FUNCDECL_SYS (unlinkat, int, (int fd, char const *file, int flag) | 2405 | _GL_FUNCDECL_SYS (unlinkat, int, (int fd, char const *file, int flag), |
| 2329 | _GL_ARG_NONNULL ((2))); | 2406 | _GL_ARG_NONNULL ((2))); |
| 2330 | # endif | 2407 | # endif |
| 2331 | _GL_CXXALIAS_SYS (unlinkat, int, (int fd, char const *file, int flag)); | 2408 | _GL_CXXALIAS_SYS (unlinkat, int, (int fd, char const *file, int flag)); |
| @@ -2343,18 +2420,18 @@ _GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - " | |||
| 2343 | #if @GNULIB_USLEEP@ | 2420 | #if @GNULIB_USLEEP@ |
| 2344 | /* Pause the execution of the current thread for N microseconds. | 2421 | /* Pause the execution of the current thread for N microseconds. |
| 2345 | Returns 0 on completion, or -1 on range error. | 2422 | Returns 0 on completion, or -1 on range error. |
| 2346 | See the POSIX:2001 specification | 2423 | See the POSIX.1-2004 specification |
| 2347 | <https://pubs.opengroup.org/onlinepubs/009695399/functions/usleep.html>. */ | 2424 | <https://pubs.opengroup.org/onlinepubs/009695399/functions/usleep.html>. */ |
| 2348 | # if @REPLACE_USLEEP@ | 2425 | # if @REPLACE_USLEEP@ |
| 2349 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 2426 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 2350 | # undef usleep | 2427 | # undef usleep |
| 2351 | # define usleep rpl_usleep | 2428 | # define usleep rpl_usleep |
| 2352 | # endif | 2429 | # endif |
| 2353 | _GL_FUNCDECL_RPL (usleep, int, (useconds_t n)); | 2430 | _GL_FUNCDECL_RPL (usleep, int, (useconds_t n), ); |
| 2354 | _GL_CXXALIAS_RPL (usleep, int, (useconds_t n)); | 2431 | _GL_CXXALIAS_RPL (usleep, int, (useconds_t n)); |
| 2355 | # else | 2432 | # else |
| 2356 | # if !@HAVE_USLEEP@ | 2433 | # if !@HAVE_USLEEP@ |
| 2357 | _GL_FUNCDECL_SYS (usleep, int, (useconds_t n)); | 2434 | _GL_FUNCDECL_SYS (usleep, int, (useconds_t n), ); |
| 2358 | # endif | 2435 | # endif |
| 2359 | /* Need to cast, because on Haiku, the first parameter is | 2436 | /* Need to cast, because on Haiku, the first parameter is |
| 2360 | unsigned int n. */ | 2437 | unsigned int n. */ |
| @@ -2379,17 +2456,21 @@ _GL_WARN_ON_USE (usleep, "usleep is unportable - " | |||
| 2379 | # undef write | 2456 | # undef write |
| 2380 | # define write rpl_write | 2457 | # define write rpl_write |
| 2381 | # endif | 2458 | # endif |
| 2382 | _GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count) | 2459 | _GL_FUNCDECL_RPL (write, ssize_t, |
| 2383 | _GL_ARG_NONNULL ((2))); | 2460 | (int fd, const void *buf, size_t count), |
| 2384 | _GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count)); | 2461 | _GL_ARG_NONNULL ((2)) _GL_ATTRIBUTE_NODISCARD); |
| 2462 | _GL_CXXALIAS_RPL (write, ssize_t, | ||
| 2463 | (int fd, const void *buf, size_t count)); | ||
| 2385 | # elif defined _WIN32 && !defined __CYGWIN__ | 2464 | # elif defined _WIN32 && !defined __CYGWIN__ |
| 2386 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 2465 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 2387 | # undef write | 2466 | # undef write |
| 2388 | # define write _write | 2467 | # define write _write |
| 2389 | # endif | 2468 | # endif |
| 2390 | _GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, size_t count)); | 2469 | _GL_CXXALIAS_MDA (write, ssize_t, |
| 2470 | (int fd, const void *buf, size_t count)); | ||
| 2391 | # else | 2471 | # else |
| 2392 | _GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count)); | 2472 | _GL_CXXALIAS_SYS (write, ssize_t, |
| 2473 | (int fd, const void *buf, size_t count)); | ||
| 2393 | # endif | 2474 | # endif |
| 2394 | _GL_CXXALIASWARN (write); | 2475 | _GL_CXXALIASWARN (write); |
| 2395 | #elif @GNULIB_MDA_WRITE@ | 2476 | #elif @GNULIB_MDA_WRITE@ |
| @@ -2401,13 +2482,11 @@ _GL_CXXALIASWARN (write); | |||
| 2401 | # undef write | 2482 | # undef write |
| 2402 | # define write _write | 2483 | # define write _write |
| 2403 | # endif | 2484 | # endif |
| 2404 | # ifdef __MINGW32__ | 2485 | _GL_CXXALIAS_MDA_CAST (write, ssize_t, |
| 2405 | _GL_CXXALIAS_MDA (write, int, (int fd, const void *buf, unsigned int count)); | 2486 | (int fd, const void *buf, unsigned int count)); |
| 2406 | # else | ||
| 2407 | _GL_CXXALIAS_MDA (write, ssize_t, (int fd, const void *buf, unsigned int count)); | ||
| 2408 | # endif | ||
| 2409 | # else | 2487 | # else |
| 2410 | _GL_CXXALIAS_SYS (write, ssize_t, (int fd, const void *buf, size_t count)); | 2488 | _GL_CXXALIAS_SYS (write, ssize_t, |
| 2489 | (int fd, const void *buf, size_t count)); | ||
| 2411 | # endif | 2490 | # endif |
| 2412 | _GL_CXXALIASWARN (write); | 2491 | _GL_CXXALIASWARN (write); |
| 2413 | #endif | 2492 | #endif |
diff --git a/gl/unitypes.h b/gl/unitypes.h new file mode 100644 index 00000000..83a91750 --- /dev/null +++ b/gl/unitypes.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* Elementary types and macros for the GNU UniString library. | ||
| 3 | Copyright (C) 2002, 2005-2006, 2009-2025 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #ifndef _UNITYPES_H | ||
| 19 | #define _UNITYPES_H | ||
| 20 | |||
| 21 | /* Get uint8_t, uint16_t, uint32_t. */ | ||
| 22 | #include <stdint.h> | ||
| 23 | |||
| 24 | #ifdef __cplusplus | ||
| 25 | extern "C" { | ||
| 26 | #endif | ||
| 27 | |||
| 28 | |||
| 29 | /* Type representing a Unicode character. */ | ||
| 30 | typedef uint32_t ucs4_t; | ||
| 31 | |||
| 32 | /* Attribute of a function whose result depends only on the arguments | ||
| 33 | (not pointers!) and which has no side effects. */ | ||
| 34 | #ifndef _UC_ATTRIBUTE_CONST | ||
| 35 | # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) || defined __clang__ | ||
| 36 | # define _UC_ATTRIBUTE_CONST __attribute__ ((__const__)) | ||
| 37 | # else | ||
| 38 | # define _UC_ATTRIBUTE_CONST | ||
| 39 | # endif | ||
| 40 | #endif | ||
| 41 | |||
| 42 | /* Attribute of a function whose result depends only on the arguments | ||
| 43 | (possibly pointers) and global memory, and which has no side effects. */ | ||
| 44 | #ifndef _UC_ATTRIBUTE_PURE | ||
| 45 | # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ | ||
| 46 | # define _UC_ATTRIBUTE_PURE __attribute__ ((__pure__)) | ||
| 47 | # else | ||
| 48 | # define _UC_ATTRIBUTE_PURE | ||
| 49 | # endif | ||
| 50 | #endif | ||
| 51 | |||
| 52 | /* Qualifier in a function declaration, that asserts that the caller must | ||
| 53 | pass a pointer to a different object in the specified pointer argument | ||
| 54 | than in the other pointer arguments. */ | ||
| 55 | #ifndef _UC_RESTRICT | ||
| 56 | # if defined __restrict \ | ||
| 57 | || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \ | ||
| 58 | || __clang_major__ >= 3 | ||
| 59 | # define _UC_RESTRICT __restrict | ||
| 60 | # elif 199901L <= __STDC_VERSION__ || defined restrict | ||
| 61 | # define _UC_RESTRICT restrict | ||
| 62 | # else | ||
| 63 | # define _UC_RESTRICT | ||
| 64 | # endif | ||
| 65 | #endif | ||
| 66 | |||
| 67 | |||
| 68 | #ifdef __cplusplus | ||
| 69 | } | ||
| 70 | #endif | ||
| 71 | |||
| 72 | #endif /* _UNITYPES_H */ | ||
diff --git a/gl/unitypes.in.h b/gl/unitypes.in.h new file mode 100644 index 00000000..776d90e9 --- /dev/null +++ b/gl/unitypes.in.h | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | /* Elementary types and macros for the GNU UniString library. | ||
| 2 | Copyright (C) 2002, 2005-2006, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #ifndef _UNITYPES_H | ||
| 18 | #define _UNITYPES_H | ||
| 19 | |||
| 20 | /* Get uint8_t, uint16_t, uint32_t. */ | ||
| 21 | #include <stdint.h> | ||
| 22 | |||
| 23 | #ifdef __cplusplus | ||
| 24 | extern "C" { | ||
| 25 | #endif | ||
| 26 | |||
| 27 | |||
| 28 | /* Type representing a Unicode character. */ | ||
| 29 | typedef uint32_t ucs4_t; | ||
| 30 | |||
| 31 | /* Attribute of a function whose result depends only on the arguments | ||
| 32 | (not pointers!) and which has no side effects. */ | ||
| 33 | #ifndef _UC_ATTRIBUTE_CONST | ||
| 34 | # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) || defined __clang__ | ||
| 35 | # define _UC_ATTRIBUTE_CONST __attribute__ ((__const__)) | ||
| 36 | # else | ||
| 37 | # define _UC_ATTRIBUTE_CONST | ||
| 38 | # endif | ||
| 39 | #endif | ||
| 40 | |||
| 41 | /* Attribute of a function whose result depends only on the arguments | ||
| 42 | (possibly pointers) and global memory, and which has no side effects. */ | ||
| 43 | #ifndef _UC_ATTRIBUTE_PURE | ||
| 44 | # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ | ||
| 45 | # define _UC_ATTRIBUTE_PURE __attribute__ ((__pure__)) | ||
| 46 | # else | ||
| 47 | # define _UC_ATTRIBUTE_PURE | ||
| 48 | # endif | ||
| 49 | #endif | ||
| 50 | |||
| 51 | /* Qualifier in a function declaration, that asserts that the caller must | ||
| 52 | pass a pointer to a different object in the specified pointer argument | ||
| 53 | than in the other pointer arguments. */ | ||
| 54 | #ifndef _UC_RESTRICT | ||
| 55 | # if defined __restrict \ | ||
| 56 | || 2 < __GNUC__ + (95 <= __GNUC_MINOR__) \ | ||
| 57 | || __clang_major__ >= 3 | ||
| 58 | # define _UC_RESTRICT __restrict | ||
| 59 | # elif 199901L <= __STDC_VERSION__ || defined restrict | ||
| 60 | # define _UC_RESTRICT restrict | ||
| 61 | # else | ||
| 62 | # define _UC_RESTRICT | ||
| 63 | # endif | ||
| 64 | #endif | ||
| 65 | |||
| 66 | |||
| 67 | #ifdef __cplusplus | ||
| 68 | } | ||
| 69 | #endif | ||
| 70 | |||
| 71 | #endif /* _UNITYPES_H */ | ||
diff --git a/gl/uniwidth.h b/gl/uniwidth.h new file mode 100644 index 00000000..b88df2bf --- /dev/null +++ b/gl/uniwidth.h | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* Display width functions. | ||
| 3 | Copyright (C) 2001-2002, 2005, 2007, 2009-2025 Free Software Foundation, | ||
| 4 | Inc. | ||
| 5 | |||
| 6 | This file is free software: you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU Lesser General Public License as | ||
| 8 | published by the Free Software Foundation; either version 2.1 of the | ||
| 9 | License, or (at your option) any later version. | ||
| 10 | |||
| 11 | This file is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU Lesser General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU Lesser General Public License | ||
| 17 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef _UNIWIDTH_H | ||
| 20 | #define _UNIWIDTH_H | ||
| 21 | |||
| 22 | #include "unitypes.h" | ||
| 23 | |||
| 24 | /* Get size_t. */ | ||
| 25 | #include <stddef.h> | ||
| 26 | |||
| 27 | /* Get locale_charset() declaration. */ | ||
| 28 | #include "localcharset.h" | ||
| 29 | |||
| 30 | #ifdef __cplusplus | ||
| 31 | extern "C" { | ||
| 32 | #endif | ||
| 33 | |||
| 34 | |||
| 35 | /* Display width. */ | ||
| 36 | |||
| 37 | /* These functions are locale dependent. The encoding argument identifies | ||
| 38 | the encoding (e.g. "ISO-8859-2" for Polish). */ | ||
| 39 | |||
| 40 | /* Determine number of column positions required for UC. */ | ||
| 41 | extern int | ||
| 42 | uc_width (ucs4_t uc, const char *encoding) | ||
| 43 | _UC_ATTRIBUTE_PURE; | ||
| 44 | |||
| 45 | /* Determine number of column positions required for first N units | ||
| 46 | (or fewer if S ends before this) in S. */ | ||
| 47 | extern int | ||
| 48 | u8_width (const uint8_t *s, size_t n, const char *encoding) | ||
| 49 | _UC_ATTRIBUTE_PURE; | ||
| 50 | extern int | ||
| 51 | u16_width (const uint16_t *s, size_t n, const char *encoding) | ||
| 52 | _UC_ATTRIBUTE_PURE; | ||
| 53 | extern int | ||
| 54 | u32_width (const uint32_t *s, size_t n, const char *encoding) | ||
| 55 | _UC_ATTRIBUTE_PURE; | ||
| 56 | |||
| 57 | /* Determine number of column positions required for S. */ | ||
| 58 | extern int | ||
| 59 | u8_strwidth (const uint8_t *s, const char *encoding) | ||
| 60 | _UC_ATTRIBUTE_PURE; | ||
| 61 | extern int | ||
| 62 | u16_strwidth (const uint16_t *s, const char *encoding) | ||
| 63 | _UC_ATTRIBUTE_PURE; | ||
| 64 | extern int | ||
| 65 | u32_strwidth (const uint32_t *s, const char *encoding) | ||
| 66 | _UC_ATTRIBUTE_PURE; | ||
| 67 | |||
| 68 | |||
| 69 | #ifdef __cplusplus | ||
| 70 | } | ||
| 71 | #endif | ||
| 72 | |||
| 73 | #endif /* _UNIWIDTH_H */ | ||
diff --git a/gl/uniwidth.in.h b/gl/uniwidth.in.h new file mode 100644 index 00000000..49c7ce05 --- /dev/null +++ b/gl/uniwidth.in.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /* Display width functions. | ||
| 2 | Copyright (C) 2001-2002, 2005, 2007, 2009-2025 Free Software Foundation, | ||
| 3 | Inc. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #ifndef _UNIWIDTH_H | ||
| 19 | #define _UNIWIDTH_H | ||
| 20 | |||
| 21 | #include "unitypes.h" | ||
| 22 | |||
| 23 | /* Get size_t. */ | ||
| 24 | #include <stddef.h> | ||
| 25 | |||
| 26 | /* Get locale_charset() declaration. */ | ||
| 27 | #include "localcharset.h" | ||
| 28 | |||
| 29 | #ifdef __cplusplus | ||
| 30 | extern "C" { | ||
| 31 | #endif | ||
| 32 | |||
| 33 | |||
| 34 | /* Display width. */ | ||
| 35 | |||
| 36 | /* These functions are locale dependent. The encoding argument identifies | ||
| 37 | the encoding (e.g. "ISO-8859-2" for Polish). */ | ||
| 38 | |||
| 39 | /* Determine number of column positions required for UC. */ | ||
| 40 | extern int | ||
| 41 | uc_width (ucs4_t uc, const char *encoding) | ||
| 42 | _UC_ATTRIBUTE_PURE; | ||
| 43 | |||
| 44 | /* Determine number of column positions required for first N units | ||
| 45 | (or fewer if S ends before this) in S. */ | ||
| 46 | extern int | ||
| 47 | u8_width (const uint8_t *s, size_t n, const char *encoding) | ||
| 48 | _UC_ATTRIBUTE_PURE; | ||
| 49 | extern int | ||
| 50 | u16_width (const uint16_t *s, size_t n, const char *encoding) | ||
| 51 | _UC_ATTRIBUTE_PURE; | ||
| 52 | extern int | ||
| 53 | u32_width (const uint32_t *s, size_t n, const char *encoding) | ||
| 54 | _UC_ATTRIBUTE_PURE; | ||
| 55 | |||
| 56 | /* Determine number of column positions required for S. */ | ||
| 57 | extern int | ||
| 58 | u8_strwidth (const uint8_t *s, const char *encoding) | ||
| 59 | _UC_ATTRIBUTE_PURE; | ||
| 60 | extern int | ||
| 61 | u16_strwidth (const uint16_t *s, const char *encoding) | ||
| 62 | _UC_ATTRIBUTE_PURE; | ||
| 63 | extern int | ||
| 64 | u32_strwidth (const uint32_t *s, const char *encoding) | ||
| 65 | _UC_ATTRIBUTE_PURE; | ||
| 66 | |||
| 67 | |||
| 68 | #ifdef __cplusplus | ||
| 69 | } | ||
| 70 | #endif | ||
| 71 | |||
| 72 | #endif /* _UNIWIDTH_H */ | ||
diff --git a/gl/uniwidth/.deps/.dirstamp b/gl/uniwidth/.deps/.dirstamp new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/gl/uniwidth/.deps/.dirstamp | |||
diff --git a/gl/uniwidth/.deps/libgnu_a-width.Po b/gl/uniwidth/.deps/libgnu_a-width.Po new file mode 100644 index 00000000..f3f0e3fd --- /dev/null +++ b/gl/uniwidth/.deps/libgnu_a-width.Po | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | uniwidth/libgnu_a-width.o: uniwidth/width.c /usr/include/stdc-predef.h \ | ||
| 2 | ../config.h uniwidth.h unitypes.h \ | ||
| 3 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h /usr/include/stdint.h \ | ||
| 4 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ | ||
| 5 | /usr/include/features.h /usr/include/features-time64.h \ | ||
| 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ | ||
| 7 | /usr/include/x86_64-linux-gnu/bits/timesize.h \ | ||
| 8 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ | ||
| 9 | /usr/include/x86_64-linux-gnu/bits/long-double.h \ | ||
| 10 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ | ||
| 11 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | ||
| 12 | /usr/include/x86_64-linux-gnu/bits/types.h \ | ||
| 13 | /usr/include/x86_64-linux-gnu/bits/typesizes.h \ | ||
| 14 | /usr/include/x86_64-linux-gnu/bits/time64.h \ | ||
| 15 | /usr/include/x86_64-linux-gnu/bits/wchar.h \ | ||
| 16 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ | ||
| 17 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ | ||
| 18 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h stddef.h \ | ||
| 19 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h localcharset.h \ | ||
| 20 | uniwidth/cjk.h streq.h string.h /usr/include/string.h \ | ||
| 21 | /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ | ||
| 22 | /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h strings.h \ | ||
| 23 | /usr/include/strings.h uniwidth/width0.h uniwidth/width2.h \ | ||
| 24 | unictype/bitmap.h | ||
| 25 | /usr/include/stdc-predef.h: | ||
| 26 | ../config.h: | ||
| 27 | uniwidth.h: | ||
| 28 | unitypes.h: | ||
| 29 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: | ||
| 30 | /usr/include/stdint.h: | ||
| 31 | /usr/include/x86_64-linux-gnu/bits/libc-header-start.h: | ||
| 32 | /usr/include/features.h: | ||
| 33 | /usr/include/features-time64.h: | ||
| 34 | /usr/include/x86_64-linux-gnu/bits/wordsize.h: | ||
| 35 | /usr/include/x86_64-linux-gnu/bits/timesize.h: | ||
| 36 | /usr/include/x86_64-linux-gnu/sys/cdefs.h: | ||
| 37 | /usr/include/x86_64-linux-gnu/bits/long-double.h: | ||
| 38 | /usr/include/x86_64-linux-gnu/gnu/stubs.h: | ||
| 39 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h: | ||
| 40 | /usr/include/x86_64-linux-gnu/bits/types.h: | ||
| 41 | /usr/include/x86_64-linux-gnu/bits/typesizes.h: | ||
| 42 | /usr/include/x86_64-linux-gnu/bits/time64.h: | ||
| 43 | /usr/include/x86_64-linux-gnu/bits/wchar.h: | ||
| 44 | /usr/include/x86_64-linux-gnu/bits/stdint-intn.h: | ||
| 45 | /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: | ||
| 46 | /usr/include/x86_64-linux-gnu/bits/stdint-least.h: | ||
| 47 | stddef.h: | ||
| 48 | /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: | ||
| 49 | localcharset.h: | ||
| 50 | uniwidth/cjk.h: | ||
| 51 | streq.h: | ||
| 52 | string.h: | ||
| 53 | /usr/include/string.h: | ||
| 54 | /usr/include/x86_64-linux-gnu/bits/types/locale_t.h: | ||
| 55 | /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: | ||
| 56 | strings.h: | ||
| 57 | /usr/include/strings.h: | ||
| 58 | uniwidth/width0.h: | ||
| 59 | uniwidth/width2.h: | ||
| 60 | unictype/bitmap.h: | ||
diff --git a/gl/uniwidth/.dirstamp b/gl/uniwidth/.dirstamp new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/gl/uniwidth/.dirstamp | |||
diff --git a/gl/uniwidth/cjk.h b/gl/uniwidth/cjk.h new file mode 100644 index 00000000..af41f637 --- /dev/null +++ b/gl/uniwidth/cjk.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | /* Test for CJK encoding. | ||
| 2 | Copyright (C) 2001-2002, 2005-2007, 2009-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include "streq.h" | ||
| 19 | |||
| 20 | static int | ||
| 21 | is_cjk_encoding (const char *encoding) | ||
| 22 | { | ||
| 23 | if (0 | ||
| 24 | /* Legacy Japanese encodings */ | ||
| 25 | || STREQ_OPT (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0) | ||
| 26 | /* Legacy Chinese encodings */ | ||
| 27 | || STREQ_OPT (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) | ||
| 28 | || STREQ_OPT (encoding, "GBK", 'G', 'B', 'K', 0, 0, 0, 0, 0, 0) | ||
| 29 | || STREQ_OPT (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0) | ||
| 30 | || STREQ_OPT (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0) | ||
| 31 | /* Legacy Korean encodings */ | ||
| 32 | || STREQ_OPT (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) | ||
| 33 | || STREQ_OPT (encoding, "CP949", 'C', 'P', '9', '4', '9', 0, 0, 0, 0) | ||
| 34 | || STREQ_OPT (encoding, "JOHAB", 'J', 'O', 'H', 'A', 'B', 0, 0, 0, 0)) | ||
| 35 | return 1; | ||
| 36 | return 0; | ||
| 37 | } | ||
diff --git a/gl/uniwidth/width.c b/gl/uniwidth/width.c new file mode 100644 index 00000000..c99a74cb --- /dev/null +++ b/gl/uniwidth/width.c | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /* Determine display width of Unicode character. | ||
| 2 | Copyright (C) 2001-2002, 2006-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2002. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | /* Specification. */ | ||
| 21 | #include "uniwidth.h" | ||
| 22 | |||
| 23 | #include "cjk.h" | ||
| 24 | |||
| 25 | /* The non-spacing attribute table consists of: | ||
| 26 | * Non-spacing characters; generated from PropList.txt or | ||
| 27 | "grep '^[^;]*;[^;]*;[^;]*;[^;]*;NSM;' UnicodeData.txt" | ||
| 28 | * Format control characters; generated from | ||
| 29 | "grep '^[^;]*;[^;]*;Cf;' UnicodeData.txt" | ||
| 30 | * Zero width characters; generated from | ||
| 31 | "grep '^[^;]*;ZERO WIDTH ' UnicodeData.txt" | ||
| 32 | * Hangul Jamo characters that have conjoining behaviour: | ||
| 33 | - jungseong = syllable-middle vowels | ||
| 34 | - jongseong = syllable-final consonants | ||
| 35 | Rationale: | ||
| 36 | 1) These characters act like combining characters. They have no | ||
| 37 | equivalent in legacy character sets. Therefore the EastAsianWidth.txt | ||
| 38 | file does not really matter for them; UAX #11 East Asian Width | ||
| 39 | <https://www.unicode.org/reports/tr11/> makes it clear that it focus | ||
| 40 | is on compatibility with traditional Japanese layout. | ||
| 41 | By contrast, the same glyphs without conjoining behaviour are available | ||
| 42 | in the U+3130..U+318F block, and these characters are mapped to legacy | ||
| 43 | character sets, and traditional Japanese layout matters for them. | ||
| 44 | 2) glibc does the same thing, see | ||
| 45 | <https://sourceware.org/bugzilla/show_bug.cgi?id=21750> | ||
| 46 | <https://sourceware.org/bugzilla/show_bug.cgi?id=26120> | ||
| 47 | */ | ||
| 48 | #include "uniwidth/width0.h" | ||
| 49 | |||
| 50 | #include "uniwidth/width2.h" | ||
| 51 | #include "unictype/bitmap.h" | ||
| 52 | |||
| 53 | #define SIZEOF(a) (sizeof(a) / sizeof(a[0])) | ||
| 54 | |||
| 55 | |||
| 56 | /* Determine number of column positions required for UC. */ | ||
| 57 | int | ||
| 58 | uc_width (ucs4_t uc, const char *encoding) | ||
| 59 | { | ||
| 60 | /* Test for non-spacing or control character. */ | ||
| 61 | if ((uc >> 9) < SIZEOF (nonspacing_table_ind)) | ||
| 62 | { | ||
| 63 | int ind = nonspacing_table_ind[uc >> 9]; | ||
| 64 | if (ind >= 0) | ||
| 65 | if ((nonspacing_table_data[64*ind + ((uc >> 3) & 63)] >> (uc & 7)) & 1) | ||
| 66 | { | ||
| 67 | if (uc > 0 && uc < 0xa0) | ||
| 68 | return -1; | ||
| 69 | else | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | else if ((uc >> 9) == (0xe0000 >> 9)) | ||
| 74 | { | ||
| 75 | if (uc >= 0xe0100) | ||
| 76 | { | ||
| 77 | if (uc <= 0xe01ef) | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | else | ||
| 81 | { | ||
| 82 | if (uc >= 0xe0020 ? uc <= 0xe007f : uc == 0xe0001) | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | /* Test for double-width character. */ | ||
| 87 | if (bitmap_lookup (&u_width2, uc)) | ||
| 88 | return 2; | ||
| 89 | /* In ancient CJK encodings, Cyrillic and most other characters are | ||
| 90 | double-width as well. */ | ||
| 91 | if (uc >= 0x00A1 && uc < 0xFF61 && uc != 0x20A9 | ||
| 92 | && is_cjk_encoding (encoding)) | ||
| 93 | return 2; | ||
| 94 | return 1; | ||
| 95 | } | ||
diff --git a/gl/uniwidth/width0.h b/gl/uniwidth/width0.h new file mode 100644 index 00000000..2edbe240 --- /dev/null +++ b/gl/uniwidth/width0.h | |||
| @@ -0,0 +1,495 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* Table of non-spacing or control characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | static const unsigned char nonspacing_table_data[49*64] = { | ||
| 21 | /* 0x0000-0x01ff */ | ||
| 22 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0x0000-0x003f */ | ||
| 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x0040-0x007f */ | ||
| 24 | 0xff, 0xff, 0xff, 0xff, 0x00, 0x20, 0x00, 0x00, /* 0x0080-0x00bf */ | ||
| 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00c0-0x00ff */ | ||
| 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0100-0x013f */ | ||
| 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0140-0x017f */ | ||
| 28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0180-0x01bf */ | ||
| 29 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c0-0x01ff */ | ||
| 30 | /* 0x0200-0x03ff */ | ||
| 31 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0200-0x023f */ | ||
| 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0240-0x027f */ | ||
| 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0280-0x02bf */ | ||
| 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02c0-0x02ff */ | ||
| 35 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x0300-0x033f */ | ||
| 36 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, /* 0x0340-0x037f */ | ||
| 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0380-0x03bf */ | ||
| 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x03c0-0x03ff */ | ||
| 39 | /* 0x0400-0x05ff */ | ||
| 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0400-0x043f */ | ||
| 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0440-0x047f */ | ||
| 42 | 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0480-0x04bf */ | ||
| 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04c0-0x04ff */ | ||
| 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0500-0x053f */ | ||
| 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0540-0x057f */ | ||
| 46 | 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, /* 0x0580-0x05bf */ | ||
| 47 | 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x05c0-0x05ff */ | ||
| 48 | /* 0x0600-0x07ff */ | ||
| 49 | 0x00, 0x00, 0xff, 0x17, 0x00, 0x00, 0x00, 0x00, /* 0x0600-0x063f */ | ||
| 50 | 0x00, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, /* 0x0640-0x067f */ | ||
| 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0680-0x06bf */ | ||
| 52 | 0x00, 0x00, 0xc0, 0x9f, 0x9f, 0x3d, 0x00, 0x00, /* 0x06c0-0x06ff */ | ||
| 53 | 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0x0700-0x073f */ | ||
| 54 | 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0740-0x077f */ | ||
| 55 | 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, /* 0x0780-0x07bf */ | ||
| 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x20, /* 0x07c0-0x07ff */ | ||
| 57 | /* 0x0800-0x09ff */ | ||
| 58 | 0x00, 0x00, 0xc0, 0xfb, 0xef, 0x3e, 0x00, 0x00, /* 0x0800-0x083f */ | ||
| 59 | 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, /* 0x0840-0x087f */ | ||
| 60 | 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0x0880-0x08bf */ | ||
| 61 | 0x00, 0xfc, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, /* 0x08c0-0x08ff */ | ||
| 62 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, /* 0x0900-0x093f */ | ||
| 63 | 0xfe, 0x21, 0xfe, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0940-0x097f */ | ||
| 64 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0980-0x09bf */ | ||
| 65 | 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, /* 0x09c0-0x09ff */ | ||
| 66 | /* 0x0a00-0x0bff */ | ||
| 67 | 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a00-0x0a3f */ | ||
| 68 | 0x86, 0x39, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, /* 0x0a40-0x0a7f */ | ||
| 69 | 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a80-0x0abf */ | ||
| 70 | 0xbe, 0x21, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xfc, /* 0x0ac0-0x0aff */ | ||
| 71 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, /* 0x0b00-0x0b3f */ | ||
| 72 | 0x1e, 0x20, 0x60, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0b40-0x0b7f */ | ||
| 73 | 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b80-0x0bbf */ | ||
| 74 | 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0bc0-0x0bff */ | ||
| 75 | /* 0x0c00-0x0dff */ | ||
| 76 | 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, /* 0x0c00-0x0c3f */ | ||
| 77 | 0xc1, 0x3d, 0x60, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0c40-0x0c7f */ | ||
| 78 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0c80-0x0cbf */ | ||
| 79 | 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0cc0-0x0cff */ | ||
| 80 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, /* 0x0d00-0x0d3f */ | ||
| 81 | 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0d40-0x0d7f */ | ||
| 82 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d80-0x0dbf */ | ||
| 83 | 0x00, 0x04, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0dc0-0x0dff */ | ||
| 84 | /* 0x0e00-0x0fff */ | ||
| 85 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x07, /* 0x0e00-0x0e3f */ | ||
| 86 | 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e40-0x0e7f */ | ||
| 87 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x1f, /* 0x0e80-0x0ebf */ | ||
| 88 | 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0ec0-0x0eff */ | ||
| 89 | 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xa0, 0x02, /* 0x0f00-0x0f3f */ | ||
| 90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, /* 0x0f40-0x0f7f */ | ||
| 91 | 0xdf, 0xe0, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, /* 0x0f80-0x0fbf */ | ||
| 92 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0fc0-0x0fff */ | ||
| 93 | /* 0x1000-0x11ff */ | ||
| 94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0x66, /* 0x1000-0x103f */ | ||
| 95 | 0x00, 0x00, 0x00, 0xc3, 0x01, 0x00, 0x1e, 0x00, /* 0x1040-0x107f */ | ||
| 96 | 0x64, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x1080-0x10bf */ | ||
| 97 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c0-0x10ff */ | ||
| 98 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1100-0x113f */ | ||
| 99 | 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, /* 0x1140-0x117f */ | ||
| 100 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x1180-0x11bf */ | ||
| 101 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x11c0-0x11ff */ | ||
| 102 | /* 0x1200-0x13ff */ | ||
| 103 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1200-0x123f */ | ||
| 104 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1240-0x127f */ | ||
| 105 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1280-0x12bf */ | ||
| 106 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x12c0-0x12ff */ | ||
| 107 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1300-0x133f */ | ||
| 108 | 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, /* 0x1340-0x137f */ | ||
| 109 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1380-0x13bf */ | ||
| 110 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13c0-0x13ff */ | ||
| 111 | /* 0x1600-0x17ff */ | ||
| 112 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1600-0x163f */ | ||
| 113 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1640-0x167f */ | ||
| 114 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1680-0x16bf */ | ||
| 115 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16c0-0x16ff */ | ||
| 116 | 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0c, 0x00, /* 0x1700-0x173f */ | ||
| 117 | 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, /* 0x1740-0x177f */ | ||
| 118 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x3f, /* 0x1780-0x17bf */ | ||
| 119 | 0x40, 0xfe, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x17c0-0x17ff */ | ||
| 120 | /* 0x1800-0x19ff */ | ||
| 121 | 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1800-0x183f */ | ||
| 122 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1840-0x187f */ | ||
| 123 | 0x60, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x1880-0x18bf */ | ||
| 124 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18c0-0x18ff */ | ||
| 125 | 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x04, 0x0e, /* 0x1900-0x193f */ | ||
| 126 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1940-0x197f */ | ||
| 127 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1980-0x19bf */ | ||
| 128 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x19c0-0x19ff */ | ||
| 129 | /* 0x1a00-0x1bff */ | ||
| 130 | 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, /* 0x1a00-0x1a3f */ | ||
| 131 | 0x00, 0x00, 0x40, 0x7f, 0xe5, 0x1f, 0xf8, 0x9f, /* 0x1a40-0x1a7f */ | ||
| 132 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0x1a80-0x1abf */ | ||
| 133 | 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ac0-0x1aff */ | ||
| 134 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x17, /* 0x1b00-0x1b3f */ | ||
| 135 | 0x04, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x1b40-0x1b7f */ | ||
| 136 | 0x03, 0x00, 0x00, 0x00, 0x3c, 0x3b, 0x00, 0x00, /* 0x1b80-0x1bbf */ | ||
| 137 | 0x00, 0x00, 0x00, 0x00, 0x40, 0xa3, 0x03, 0x00, /* 0x1bc0-0x1bff */ | ||
| 138 | /* 0x1c00-0x1dff */ | ||
| 139 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xcf, 0x00, /* 0x1c00-0x1c3f */ | ||
| 140 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c40-0x1c7f */ | ||
| 141 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c80-0x1cbf */ | ||
| 142 | 0x00, 0x00, 0xf7, 0xff, 0xfd, 0x21, 0x10, 0x03, /* 0x1cc0-0x1cff */ | ||
| 143 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d00-0x1d3f */ | ||
| 144 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d40-0x1d7f */ | ||
| 145 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d80-0x1dbf */ | ||
| 146 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x1dc0-0x1dff */ | ||
| 147 | /* 0x2000-0x21ff */ | ||
| 148 | 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, /* 0x2000-0x203f */ | ||
| 149 | 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0x00, 0x00, /* 0x2040-0x207f */ | ||
| 150 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2080-0x20bf */ | ||
| 151 | 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, /* 0x20c0-0x20ff */ | ||
| 152 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2100-0x213f */ | ||
| 153 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2140-0x217f */ | ||
| 154 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2180-0x21bf */ | ||
| 155 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x21c0-0x21ff */ | ||
| 156 | /* 0x2c00-0x2dff */ | ||
| 157 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c00-0x2c3f */ | ||
| 158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c40-0x2c7f */ | ||
| 159 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c80-0x2cbf */ | ||
| 160 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, /* 0x2cc0-0x2cff */ | ||
| 161 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d00-0x2d3f */ | ||
| 162 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x2d40-0x2d7f */ | ||
| 163 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d80-0x2dbf */ | ||
| 164 | 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, /* 0x2dc0-0x2dff */ | ||
| 165 | /* 0x3000-0x31ff */ | ||
| 166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* 0x3000-0x303f */ | ||
| 167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3040-0x307f */ | ||
| 168 | 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, /* 0x3080-0x30bf */ | ||
| 169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30c0-0x30ff */ | ||
| 170 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3100-0x313f */ | ||
| 171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3140-0x317f */ | ||
| 172 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3180-0x31bf */ | ||
| 173 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x31c0-0x31ff */ | ||
| 174 | /* 0xa600-0xa7ff */ | ||
| 175 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa600-0xa63f */ | ||
| 176 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf7, 0x3f, /* 0xa640-0xa67f */ | ||
| 177 | 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, /* 0xa680-0xa6bf */ | ||
| 178 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* 0xa6c0-0xa6ff */ | ||
| 179 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa700-0xa73f */ | ||
| 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa740-0xa77f */ | ||
| 181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa780-0xa7bf */ | ||
| 182 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa7c0-0xa7ff */ | ||
| 183 | /* 0xa800-0xa9ff */ | ||
| 184 | 0x44, 0x08, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, /* 0xa800-0xa83f */ | ||
| 185 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa840-0xa87f */ | ||
| 186 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa880-0xa8bf */ | ||
| 187 | 0x30, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x80, /* 0xa8c0-0xa8ff */ | ||
| 188 | 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, /* 0xa900-0xa93f */ | ||
| 189 | 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa940-0xa97f */ | ||
| 190 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x33, /* 0xa980-0xa9bf */ | ||
| 191 | 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, /* 0xa9c0-0xa9ff */ | ||
| 192 | /* 0xaa00-0xabff */ | ||
| 193 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x66, 0x00, /* 0xaa00-0xaa3f */ | ||
| 194 | 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0xaa40-0xaa7f */ | ||
| 195 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xc1, /* 0xaa80-0xaabf */ | ||
| 196 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0x00, /* 0xaac0-0xaaff */ | ||
| 197 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab00-0xab3f */ | ||
| 198 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab40-0xab7f */ | ||
| 199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab80-0xabbf */ | ||
| 200 | 0x00, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x00, /* 0xabc0-0xabff */ | ||
| 201 | /* 0xd600-0xd7ff */ | ||
| 202 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd600-0xd63f */ | ||
| 203 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd640-0xd67f */ | ||
| 204 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd680-0xd6bf */ | ||
| 205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd6c0-0xd6ff */ | ||
| 206 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd700-0xd73f */ | ||
| 207 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd740-0xd77f */ | ||
| 208 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0xd780-0xd7bf */ | ||
| 209 | 0x7f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, /* 0xd7c0-0xd7ff */ | ||
| 210 | /* 0xfa00-0xfbff */ | ||
| 211 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa00-0xfa3f */ | ||
| 212 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa40-0xfa7f */ | ||
| 213 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa80-0xfabf */ | ||
| 214 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfac0-0xfaff */ | ||
| 215 | 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, /* 0xfb00-0xfb3f */ | ||
| 216 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb40-0xfb7f */ | ||
| 217 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb80-0xfbbf */ | ||
| 218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfbc0-0xfbff */ | ||
| 219 | /* 0xfe00-0xffff */ | ||
| 220 | 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, /* 0xfe00-0xfe3f */ | ||
| 221 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe40-0xfe7f */ | ||
| 222 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe80-0xfebf */ | ||
| 223 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xfec0-0xfeff */ | ||
| 224 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff00-0xff3f */ | ||
| 225 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff40-0xff7f */ | ||
| 226 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff80-0xffbf */ | ||
| 227 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, /* 0xffc0-0xffff */ | ||
| 228 | /* 0x10000-0x101ff */ | ||
| 229 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10000-0x1003f */ | ||
| 230 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10040-0x1007f */ | ||
| 231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10080-0x100bf */ | ||
| 232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x100c0-0x100ff */ | ||
| 233 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10100-0x1013f */ | ||
| 234 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10140-0x1017f */ | ||
| 235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10180-0x101bf */ | ||
| 236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* 0x101c0-0x101ff */ | ||
| 237 | /* 0x10200-0x103ff */ | ||
| 238 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10200-0x1023f */ | ||
| 239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10240-0x1027f */ | ||
| 240 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10280-0x102bf */ | ||
| 241 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* 0x102c0-0x102ff */ | ||
| 242 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10300-0x1033f */ | ||
| 243 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, /* 0x10340-0x1037f */ | ||
| 244 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10380-0x103bf */ | ||
| 245 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x103c0-0x103ff */ | ||
| 246 | /* 0x10a00-0x10bff */ | ||
| 247 | 0x6e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, /* 0x10a00-0x10a3f */ | ||
| 248 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a40-0x10a7f */ | ||
| 249 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a80-0x10abf */ | ||
| 250 | 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* 0x10ac0-0x10aff */ | ||
| 251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b00-0x10b3f */ | ||
| 252 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b40-0x10b7f */ | ||
| 253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b80-0x10bbf */ | ||
| 254 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10bc0-0x10bff */ | ||
| 255 | /* 0x10c00-0x10dff */ | ||
| 256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c00-0x10c3f */ | ||
| 257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c40-0x10c7f */ | ||
| 258 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c80-0x10cbf */ | ||
| 259 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10cc0-0x10cff */ | ||
| 260 | 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, /* 0x10d00-0x10d3f */ | ||
| 261 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, /* 0x10d40-0x10d7f */ | ||
| 262 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10d80-0x10dbf */ | ||
| 263 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10dc0-0x10dff */ | ||
| 264 | /* 0x10e00-0x10fff */ | ||
| 265 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10e00-0x10e3f */ | ||
| 266 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10e40-0x10e7f */ | ||
| 267 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, /* 0x10e80-0x10ebf */ | ||
| 268 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, /* 0x10ec0-0x10eff */ | ||
| 269 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10f00-0x10f3f */ | ||
| 270 | 0xc0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10f40-0x10f7f */ | ||
| 271 | 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10f80-0x10fbf */ | ||
| 272 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10fc0-0x10fff */ | ||
| 273 | /* 0x11000-0x111ff */ | ||
| 274 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0x11000-0x1103f */ | ||
| 275 | 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x80, /* 0x11040-0x1107f */ | ||
| 276 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x06, /* 0x11080-0x110bf */ | ||
| 277 | 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110c0-0x110ff */ | ||
| 278 | 0x07, 0x00, 0x00, 0x00, 0x80, 0xef, 0x1f, 0x00, /* 0x11100-0x1113f */ | ||
| 279 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, /* 0x11140-0x1117f */ | ||
| 280 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x7f, /* 0x11180-0x111bf */ | ||
| 281 | 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x111c0-0x111ff */ | ||
| 282 | /* 0x11200-0x113ff */ | ||
| 283 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd3, 0x40, /* 0x11200-0x1123f */ | ||
| 284 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11240-0x1127f */ | ||
| 285 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11280-0x112bf */ | ||
| 286 | 0x00, 0x00, 0x00, 0x80, 0xf8, 0x07, 0x00, 0x00, /* 0x112c0-0x112ff */ | ||
| 287 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, /* 0x11300-0x1133f */ | ||
| 288 | 0x01, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x1f, 0x00, /* 0x11340-0x1137f */ | ||
| 289 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, /* 0x11380-0x113bf */ | ||
| 290 | 0x01, 0x40, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, /* 0x113c0-0x113ff */ | ||
| 291 | /* 0x11400-0x115ff */ | ||
| 292 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0x11400-0x1143f */ | ||
| 293 | 0x5c, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, /* 0x11440-0x1147f */ | ||
| 294 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x85, /* 0x11480-0x114bf */ | ||
| 295 | 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x114c0-0x114ff */ | ||
| 296 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11500-0x1153f */ | ||
| 297 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11540-0x1157f */ | ||
| 298 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb0, /* 0x11580-0x115bf */ | ||
| 299 | 0x01, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, /* 0x115c0-0x115ff */ | ||
| 300 | /* 0x11600-0x117ff */ | ||
| 301 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa7, /* 0x11600-0x1163f */ | ||
| 302 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11640-0x1167f */ | ||
| 303 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xbf, 0x00, /* 0x11680-0x116bf */ | ||
| 304 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x116c0-0x116ff */ | ||
| 305 | 0x00, 0x00, 0x00, 0xa0, 0xbc, 0x0f, 0x00, 0x00, /* 0x11700-0x1173f */ | ||
| 306 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11740-0x1177f */ | ||
| 307 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11780-0x117bf */ | ||
| 308 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x117c0-0x117ff */ | ||
| 309 | /* 0x11800-0x119ff */ | ||
| 310 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x06, /* 0x11800-0x1183f */ | ||
| 311 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11840-0x1187f */ | ||
| 312 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11880-0x118bf */ | ||
| 313 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118c0-0x118ff */ | ||
| 314 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, /* 0x11900-0x1193f */ | ||
| 315 | 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11940-0x1197f */ | ||
| 316 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11980-0x119bf */ | ||
| 317 | 0x00, 0x00, 0xf0, 0x0c, 0x01, 0x00, 0x00, 0x00, /* 0x119c0-0x119ff */ | ||
| 318 | /* 0x11a00-0x11bff */ | ||
| 319 | 0x7e, 0x06, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x79, /* 0x11a00-0x11a3f */ | ||
| 320 | 0x80, 0x00, 0x7e, 0x0e, 0x00, 0x00, 0x00, 0x00, /* 0x11a40-0x11a7f */ | ||
| 321 | 0x00, 0xfc, 0x7f, 0x03, 0x00, 0x00, 0x00, 0x00, /* 0x11a80-0x11abf */ | ||
| 322 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11ac0-0x11aff */ | ||
| 323 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11b00-0x11b3f */ | ||
| 324 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11b40-0x11b7f */ | ||
| 325 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11b80-0x11bbf */ | ||
| 326 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11bc0-0x11bff */ | ||
| 327 | /* 0x11c00-0x11dff */ | ||
| 328 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x3f, /* 0x11c00-0x11c3f */ | ||
| 329 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11c40-0x11c7f */ | ||
| 330 | 0x00, 0x00, 0xfc, 0xff, 0xff, 0xfc, 0x6d, 0x00, /* 0x11c80-0x11cbf */ | ||
| 331 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11cc0-0x11cff */ | ||
| 332 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xb4, /* 0x11d00-0x11d3f */ | ||
| 333 | 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11d40-0x11d7f */ | ||
| 334 | 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11d80-0x11dbf */ | ||
| 335 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11dc0-0x11dff */ | ||
| 336 | /* 0x11e00-0x11fff */ | ||
| 337 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11e00-0x11e3f */ | ||
| 338 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11e40-0x11e7f */ | ||
| 339 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11e80-0x11ebf */ | ||
| 340 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, /* 0x11ec0-0x11eff */ | ||
| 341 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, /* 0x11f00-0x11f3f */ | ||
| 342 | 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, /* 0x11f40-0x11f7f */ | ||
| 343 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11f80-0x11fbf */ | ||
| 344 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11fc0-0x11fff */ | ||
| 345 | /* 0x13400-0x135ff */ | ||
| 346 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0x13400-0x1343f */ | ||
| 347 | 0x81, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13440-0x1347f */ | ||
| 348 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13480-0x134bf */ | ||
| 349 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x134c0-0x134ff */ | ||
| 350 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13500-0x1353f */ | ||
| 351 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13540-0x1357f */ | ||
| 352 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13580-0x135bf */ | ||
| 353 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x135c0-0x135ff */ | ||
| 354 | /* 0x16000-0x161ff */ | ||
| 355 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16000-0x1603f */ | ||
| 356 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16040-0x1607f */ | ||
| 357 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16080-0x160bf */ | ||
| 358 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x160c0-0x160ff */ | ||
| 359 | 0x00, 0x00, 0x00, 0xc0, 0xff, 0xe3, 0x00, 0x00, /* 0x16100-0x1613f */ | ||
| 360 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16140-0x1617f */ | ||
| 361 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16180-0x161bf */ | ||
| 362 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x161c0-0x161ff */ | ||
| 363 | /* 0x16a00-0x16bff */ | ||
| 364 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16a00-0x16a3f */ | ||
| 365 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16a40-0x16a7f */ | ||
| 366 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16a80-0x16abf */ | ||
| 367 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, /* 0x16ac0-0x16aff */ | ||
| 368 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, /* 0x16b00-0x16b3f */ | ||
| 369 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16b40-0x16b7f */ | ||
| 370 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16b80-0x16bbf */ | ||
| 371 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16bc0-0x16bff */ | ||
| 372 | /* 0x16e00-0x16fff */ | ||
| 373 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16e00-0x16e3f */ | ||
| 374 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16e40-0x16e7f */ | ||
| 375 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16e80-0x16ebf */ | ||
| 376 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16ec0-0x16eff */ | ||
| 377 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16f00-0x16f3f */ | ||
| 378 | 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16f40-0x16f7f */ | ||
| 379 | 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16f80-0x16fbf */ | ||
| 380 | 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, /* 0x16fc0-0x16fff */ | ||
| 381 | /* 0x1bc00-0x1bdff */ | ||
| 382 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bc00-0x1bc3f */ | ||
| 383 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bc40-0x1bc7f */ | ||
| 384 | 0x00, 0x00, 0x00, 0x60, 0x0f, 0x00, 0x00, 0x00, /* 0x1bc80-0x1bcbf */ | ||
| 385 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bcc0-0x1bcff */ | ||
| 386 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bd00-0x1bd3f */ | ||
| 387 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bd40-0x1bd7f */ | ||
| 388 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bd80-0x1bdbf */ | ||
| 389 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bdc0-0x1bdff */ | ||
| 390 | /* 0x1ce00-0x1cfff */ | ||
| 391 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ce00-0x1ce3f */ | ||
| 392 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ce40-0x1ce7f */ | ||
| 393 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ce80-0x1cebf */ | ||
| 394 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1cec0-0x1ceff */ | ||
| 395 | 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, /* 0x1cf00-0x1cf3f */ | ||
| 396 | 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1cf40-0x1cf7f */ | ||
| 397 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1cf80-0x1cfbf */ | ||
| 398 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1cfc0-0x1cfff */ | ||
| 399 | /* 0x1d000-0x1d1ff */ | ||
| 400 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d000-0x1d03f */ | ||
| 401 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d040-0x1d07f */ | ||
| 402 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d080-0x1d0bf */ | ||
| 403 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0c0-0x1d0ff */ | ||
| 404 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d100-0x1d13f */ | ||
| 405 | 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0xf8, 0xff, /* 0x1d140-0x1d17f */ | ||
| 406 | 0xe7, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* 0x1d180-0x1d1bf */ | ||
| 407 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d1c0-0x1d1ff */ | ||
| 408 | /* 0x1d200-0x1d3ff */ | ||
| 409 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d200-0x1d23f */ | ||
| 410 | 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d240-0x1d27f */ | ||
| 411 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d280-0x1d2bf */ | ||
| 412 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d2c0-0x1d2ff */ | ||
| 413 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d300-0x1d33f */ | ||
| 414 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d340-0x1d37f */ | ||
| 415 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d380-0x1d3bf */ | ||
| 416 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d3c0-0x1d3ff */ | ||
| 417 | /* 0x1da00-0x1dbff */ | ||
| 418 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf8, /* 0x1da00-0x1da3f */ | ||
| 419 | 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x20, 0x00, /* 0x1da40-0x1da7f */ | ||
| 420 | 0x10, 0x00, 0x00, 0xf8, 0xfe, 0xff, 0x00, 0x00, /* 0x1da80-0x1dabf */ | ||
| 421 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1dac0-0x1daff */ | ||
| 422 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1db00-0x1db3f */ | ||
| 423 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1db40-0x1db7f */ | ||
| 424 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1db80-0x1dbbf */ | ||
| 425 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1dbc0-0x1dbff */ | ||
| 426 | /* 0x1e000-0x1e1ff */ | ||
| 427 | 0x7f, 0xff, 0xff, 0xf9, 0xdb, 0x07, 0x00, 0x00, /* 0x1e000-0x1e03f */ | ||
| 428 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e040-0x1e07f */ | ||
| 429 | 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e080-0x1e0bf */ | ||
| 430 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e0c0-0x1e0ff */ | ||
| 431 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, /* 0x1e100-0x1e13f */ | ||
| 432 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e140-0x1e17f */ | ||
| 433 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e180-0x1e1bf */ | ||
| 434 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e1c0-0x1e1ff */ | ||
| 435 | /* 0x1e200-0x1e3ff */ | ||
| 436 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e200-0x1e23f */ | ||
| 437 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e240-0x1e27f */ | ||
| 438 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, /* 0x1e280-0x1e2bf */ | ||
| 439 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, /* 0x1e2c0-0x1e2ff */ | ||
| 440 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e300-0x1e33f */ | ||
| 441 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e340-0x1e37f */ | ||
| 442 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e380-0x1e3bf */ | ||
| 443 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e3c0-0x1e3ff */ | ||
| 444 | /* 0x1e400-0x1e5ff */ | ||
| 445 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e400-0x1e43f */ | ||
| 446 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e440-0x1e47f */ | ||
| 447 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e480-0x1e4bf */ | ||
| 448 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, /* 0x1e4c0-0x1e4ff */ | ||
| 449 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e500-0x1e53f */ | ||
| 450 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e540-0x1e57f */ | ||
| 451 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e580-0x1e5bf */ | ||
| 452 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x1e5c0-0x1e5ff */ | ||
| 453 | /* 0x1e800-0x1e9ff */ | ||
| 454 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e800-0x1e83f */ | ||
| 455 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e840-0x1e87f */ | ||
| 456 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e880-0x1e8bf */ | ||
| 457 | 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8c0-0x1e8ff */ | ||
| 458 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e900-0x1e93f */ | ||
| 459 | 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e940-0x1e97f */ | ||
| 460 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e980-0x1e9bf */ | ||
| 461 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x1e9c0-0x1e9ff */ | ||
| 462 | }; | ||
| 463 | static const signed char nonspacing_table_ind[248] = { | ||
| 464 | 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000-0x0fff */ | ||
| 465 | 8, 9, -1, 10, 11, 12, 13, -1, /* 0x1000-0x1fff */ | ||
| 466 | 14, -1, -1, -1, -1, -1, 15, -1, /* 0x2000-0x2fff */ | ||
| 467 | 16, -1, -1, -1, -1, -1, -1, -1, /* 0x3000-0x3fff */ | ||
| 468 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x4000-0x4fff */ | ||
| 469 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x5000-0x5fff */ | ||
| 470 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x6000-0x6fff */ | ||
| 471 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x7000-0x7fff */ | ||
| 472 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x8000-0x8fff */ | ||
| 473 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9000-0x9fff */ | ||
| 474 | -1, -1, -1, 17, 18, 19, -1, -1, /* 0xa000-0xafff */ | ||
| 475 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb000-0xbfff */ | ||
| 476 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc000-0xcfff */ | ||
| 477 | -1, -1, -1, 20, -1, -1, -1, -1, /* 0xd000-0xdfff */ | ||
| 478 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe000-0xefff */ | ||
| 479 | -1, -1, -1, -1, -1, 21, -1, 22, /* 0xf000-0xffff */ | ||
| 480 | 23, 24, -1, -1, -1, 25, 26, 27, /* 0x10000-0x10fff */ | ||
| 481 | 28, 29, 30, 31, 32, 33, 34, 35, /* 0x11000-0x11fff */ | ||
| 482 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x12000-0x12fff */ | ||
| 483 | -1, -1, 36, -1, -1, -1, -1, -1, /* 0x13000-0x13fff */ | ||
| 484 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x14000-0x14fff */ | ||
| 485 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x15000-0x15fff */ | ||
| 486 | 37, -1, -1, -1, -1, 38, -1, 39, /* 0x16000-0x16fff */ | ||
| 487 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x17000-0x17fff */ | ||
| 488 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x18000-0x18fff */ | ||
| 489 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x19000-0x19fff */ | ||
| 490 | -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1a000-0x1afff */ | ||
| 491 | -1, -1, -1, -1, -1, -1, 40, -1, /* 0x1b000-0x1bfff */ | ||
| 492 | -1, -1, -1, -1, -1, -1, -1, 41, /* 0x1c000-0x1cfff */ | ||
| 493 | 42, 43, -1, -1, -1, 44, -1, -1, /* 0x1d000-0x1dfff */ | ||
| 494 | 45, 46, 47, -1, 48, -1, -1, -1 /* 0x1e000-0x1efff */ | ||
| 495 | }; | ||
diff --git a/gl/uniwidth/width2.h b/gl/uniwidth/width2.h new file mode 100644 index 00000000..f919989b --- /dev/null +++ b/gl/uniwidth/width2.h | |||
| @@ -0,0 +1,541 @@ | |||
| 1 | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ | ||
| 2 | /* Width 2 property of Unicode characters. */ | ||
| 3 | /* Generated automatically by gen-uni-tables.c for Unicode 16.0.0. */ | ||
| 4 | |||
| 5 | /* Copyright (C) 2000-2024 Free Software Foundation, Inc. | ||
| 6 | |||
| 7 | This file is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU Lesser General Public License as | ||
| 9 | published by the Free Software Foundation; either version 2.1 of the | ||
| 10 | License, or (at your option) any later version. | ||
| 11 | |||
| 12 | This file is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU Lesser General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU Lesser General Public License | ||
| 18 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #define header_0 16 | ||
| 21 | #define header_2 9 | ||
| 22 | #define header_3 127 | ||
| 23 | #define header_4 15 | ||
| 24 | static const | ||
| 25 | struct | ||
| 26 | { | ||
| 27 | int header[1]; | ||
| 28 | int level1[4]; | ||
| 29 | short level2[3 << 7]; | ||
| 30 | unsigned int level3[28 << 4]; | ||
| 31 | } | ||
| 32 | u_width2 = | ||
| 33 | { | ||
| 34 | { 4 }, | ||
| 35 | { | ||
| 36 | 5 * sizeof (int) / sizeof (short) + 0, | ||
| 37 | 5 * sizeof (int) / sizeof (short) + 128, | ||
| 38 | 5 * sizeof (int) / sizeof (short) + 256, | ||
| 39 | 5 * sizeof (int) / sizeof (short) + 256 | ||
| 40 | }, | ||
| 41 | { | ||
| 42 | -1, | ||
| 43 | -1, | ||
| 44 | -1, | ||
| 45 | -1, | ||
| 46 | -1, | ||
| 47 | -1, | ||
| 48 | -1, | ||
| 49 | -1, | ||
| 50 | 5 + 384 * sizeof (short) / sizeof (int) + 0, | ||
| 51 | -1, | ||
| 52 | -1, | ||
| 53 | -1, | ||
| 54 | -1, | ||
| 55 | -1, | ||
| 56 | -1, | ||
| 57 | -1, | ||
| 58 | -1, | ||
| 59 | 5 + 384 * sizeof (short) / sizeof (int) + 16, | ||
| 60 | 5 + 384 * sizeof (short) / sizeof (int) + 32, | ||
| 61 | 5 + 384 * sizeof (short) / sizeof (int) + 48, | ||
| 62 | -1, | ||
| 63 | 5 + 384 * sizeof (short) / sizeof (int) + 64, | ||
| 64 | -1, | ||
| 65 | 5 + 384 * sizeof (short) / sizeof (int) + 80, | ||
| 66 | 5 + 384 * sizeof (short) / sizeof (int) + 96, | ||
| 67 | 5 + 384 * sizeof (short) / sizeof (int) + 112, | ||
| 68 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 69 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 70 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 71 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 72 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 73 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 74 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 75 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 76 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 77 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 78 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 79 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 80 | 5 + 384 * sizeof (short) / sizeof (int) + 144, | ||
| 81 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 82 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 83 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 84 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 85 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 86 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 87 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 88 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 89 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 90 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 91 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 92 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 93 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 94 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 95 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 96 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 97 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 98 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 99 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 100 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 101 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 102 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 103 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 104 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 105 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 106 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 107 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 108 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 109 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 110 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 111 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 112 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 113 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 114 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 115 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 116 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 117 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 118 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 119 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 120 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 121 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 122 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 123 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 124 | 5 + 384 * sizeof (short) / sizeof (int) + 160, | ||
| 125 | -1, | ||
| 126 | 5 + 384 * sizeof (short) / sizeof (int) + 176, | ||
| 127 | -1, | ||
| 128 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 129 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 130 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 131 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 132 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 133 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 134 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 135 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 136 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 137 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 138 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 139 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 140 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 141 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 142 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 143 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 144 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 145 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 146 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 147 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 148 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 149 | 5 + 384 * sizeof (short) / sizeof (int) + 192, | ||
| 150 | -1, | ||
| 151 | -1, | ||
| 152 | -1, | ||
| 153 | -1, | ||
| 154 | -1, | ||
| 155 | -1, | ||
| 156 | -1, | ||
| 157 | -1, | ||
| 158 | -1, | ||
| 159 | -1, | ||
| 160 | -1, | ||
| 161 | -1, | ||
| 162 | -1, | ||
| 163 | -1, | ||
| 164 | -1, | ||
| 165 | -1, | ||
| 166 | 5 + 384 * sizeof (short) / sizeof (int) + 208, | ||
| 167 | 5 + 384 * sizeof (short) / sizeof (int) + 224, | ||
| 168 | -1, | ||
| 169 | 5 + 384 * sizeof (short) / sizeof (int) + 240, | ||
| 170 | -1, | ||
| 171 | -1, | ||
| 172 | -1, | ||
| 173 | -1, | ||
| 174 | -1, | ||
| 175 | -1, | ||
| 176 | -1, | ||
| 177 | -1, | ||
| 178 | -1, | ||
| 179 | -1, | ||
| 180 | -1, | ||
| 181 | -1, | ||
| 182 | -1, | ||
| 183 | -1, | ||
| 184 | -1, | ||
| 185 | -1, | ||
| 186 | -1, | ||
| 187 | -1, | ||
| 188 | -1, | ||
| 189 | -1, | ||
| 190 | -1, | ||
| 191 | -1, | ||
| 192 | -1, | ||
| 193 | -1, | ||
| 194 | -1, | ||
| 195 | -1, | ||
| 196 | -1, | ||
| 197 | -1, | ||
| 198 | -1, | ||
| 199 | -1, | ||
| 200 | -1, | ||
| 201 | -1, | ||
| 202 | -1, | ||
| 203 | -1, | ||
| 204 | -1, | ||
| 205 | -1, | ||
| 206 | -1, | ||
| 207 | -1, | ||
| 208 | -1, | ||
| 209 | -1, | ||
| 210 | -1, | ||
| 211 | -1, | ||
| 212 | -1, | ||
| 213 | -1, | ||
| 214 | -1, | ||
| 215 | -1, | ||
| 216 | -1, | ||
| 217 | -1, | ||
| 218 | -1, | ||
| 219 | -1, | ||
| 220 | -1, | ||
| 221 | -1, | ||
| 222 | -1, | ||
| 223 | -1, | ||
| 224 | -1, | ||
| 225 | 5 + 384 * sizeof (short) / sizeof (int) + 256, | ||
| 226 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 227 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 228 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 229 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 230 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 231 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 232 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 233 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 234 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 235 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 236 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 237 | 5 + 384 * sizeof (short) / sizeof (int) + 272, | ||
| 238 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 239 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 240 | 5 + 384 * sizeof (short) / sizeof (int) + 288, | ||
| 241 | -1, | ||
| 242 | -1, | ||
| 243 | -1, | ||
| 244 | -1, | ||
| 245 | -1, | ||
| 246 | -1, | ||
| 247 | -1, | ||
| 248 | -1, | ||
| 249 | -1, | ||
| 250 | -1, | ||
| 251 | -1, | ||
| 252 | -1, | ||
| 253 | -1, | ||
| 254 | -1, | ||
| 255 | -1, | ||
| 256 | -1, | ||
| 257 | 5 + 384 * sizeof (short) / sizeof (int) + 304, | ||
| 258 | 5 + 384 * sizeof (short) / sizeof (int) + 320, | ||
| 259 | 5 + 384 * sizeof (short) / sizeof (int) + 336, | ||
| 260 | -1, | ||
| 261 | -1, | ||
| 262 | -1, | ||
| 263 | -1, | ||
| 264 | -1, | ||
| 265 | -1, | ||
| 266 | -1, | ||
| 267 | -1, | ||
| 268 | -1, | ||
| 269 | -1, | ||
| 270 | -1, | ||
| 271 | -1, | ||
| 272 | -1, | ||
| 273 | -1, | ||
| 274 | -1, | ||
| 275 | -1, | ||
| 276 | -1, | ||
| 277 | -1, | ||
| 278 | -1, | ||
| 279 | -1, | ||
| 280 | -1, | ||
| 281 | -1, | ||
| 282 | -1, | ||
| 283 | -1, | ||
| 284 | -1, | ||
| 285 | -1, | ||
| 286 | -1, | ||
| 287 | -1, | ||
| 288 | -1, | ||
| 289 | -1, | ||
| 290 | 5 + 384 * sizeof (short) / sizeof (int) + 352, | ||
| 291 | 5 + 384 * sizeof (short) / sizeof (int) + 368, | ||
| 292 | 5 + 384 * sizeof (short) / sizeof (int) + 384, | ||
| 293 | 5 + 384 * sizeof (short) / sizeof (int) + 400, | ||
| 294 | 5 + 384 * sizeof (short) / sizeof (int) + 416, | ||
| 295 | 5 + 384 * sizeof (short) / sizeof (int) + 432, | ||
| 296 | -1, | ||
| 297 | -1, | ||
| 298 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 299 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 300 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 301 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 302 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 303 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 304 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 305 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 306 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 307 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 308 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 309 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 310 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 311 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 312 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 313 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 314 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 315 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 316 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 317 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 318 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 319 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 320 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 321 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 322 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 323 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 324 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 325 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 326 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 327 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 328 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 329 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 330 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 331 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 332 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 333 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 334 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 335 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 336 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 337 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 338 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 339 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 340 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 341 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 342 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 343 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 344 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 345 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 346 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 347 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 348 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 349 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 350 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 351 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 352 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 353 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 354 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 355 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 356 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 357 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 358 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 359 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 360 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 361 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 362 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 363 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 364 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 365 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 366 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 367 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 368 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 369 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 370 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 371 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 372 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 373 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 374 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 375 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 376 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 377 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 378 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 379 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 380 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 381 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 382 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 383 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 384 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 385 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 386 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 387 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 388 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 389 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 390 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 391 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 392 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 393 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 394 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 395 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 396 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 397 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 398 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 399 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 400 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 401 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 402 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 403 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 404 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 405 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 406 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 407 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 408 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 409 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 410 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 411 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 412 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 413 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 414 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 415 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 416 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 417 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 418 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 419 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 420 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 421 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 422 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 423 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 424 | 5 + 384 * sizeof (short) / sizeof (int) + 128, | ||
| 425 | 5 + 384 * sizeof (short) / sizeof (int) + 128 | ||
| 426 | }, | ||
| 427 | { | ||
| 428 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 429 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 430 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, | ||
| 431 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 432 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 433 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 434 | 0x0C000000U, 0x00000600U, 0x00000000U, 0x00000000U, | ||
| 435 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00091E00U, | ||
| 436 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 437 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 438 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 439 | 0x00000000U, 0x00000000U, 0x00000000U, 0x60000000U, | ||
| 440 | 0x00300000U, 0x00000000U, 0x000FFF00U, 0x80000000U, | ||
| 441 | 0x00080000U, 0x60000C02U, 0x00104030U, 0x242C0400U, | ||
| 442 | 0x00000C20U, 0x00000100U, 0x00B85000U, 0x00000000U, | ||
| 443 | 0x00E00000U, 0x80010000U, 0x00000000U, 0x00000000U, | ||
| 444 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 445 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 446 | 0x18000000U, 0x00000000U, 0x00210000U, 0x00000000U, | ||
| 447 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 448 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 449 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 450 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 451 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 452 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 453 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 454 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 455 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 456 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFF00FFU, 0xFFFFFFFFU, | ||
| 457 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 458 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 459 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 460 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 461 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 462 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 463 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 464 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 465 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 466 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 467 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000000U, 0x00000000U, | ||
| 468 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 469 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, | ||
| 470 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 471 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 472 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 473 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 474 | 0x00000000U, 0x00000000U, 0x00000000U, 0x1FFFFFFFU, | ||
| 475 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 476 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 477 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 478 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 479 | 0xFFFFFFFFU, 0x0000000FU, 0x00000000U, 0x00000000U, | ||
| 480 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 481 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 482 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 483 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 484 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 485 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 486 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 487 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 488 | 0xFFFF0000U, 0xFFFF0000U, 0xFFFFFFFFU, 0x0000FFFFU, | ||
| 489 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 490 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00000001U, | ||
| 491 | 0x00000000U, 0x00000000U, 0x00000000U, 0x0000007FU, | ||
| 492 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 493 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 494 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 495 | 0x00000000U, 0x00000000U, 0x00000000U, 0x0003000FU, | ||
| 496 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 497 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 498 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 499 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x00FFFFFFU, | ||
| 500 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 501 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x003FFFFFU, 0x00000000U, | ||
| 502 | 0x000001FFU, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 503 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 504 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 505 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 506 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 507 | 0x00000000U, 0x00000000U, 0x00000000U, 0x6FEF0000U, | ||
| 508 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 509 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 510 | 0xFFFFFFFFU, 0x00000007U, 0x00070000U, 0xFFFF00F0U, | ||
| 511 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 512 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 513 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0FFFFFFFU, | ||
| 514 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 515 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 516 | 0x00000010U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 517 | 0x00000000U, 0x00000000U, 0x00008000U, 0x00000000U, | ||
| 518 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 519 | 0x07FE4000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 520 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 521 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 522 | 0xFFFFFFFFU, 0xFFBFE001U, 0xFFFFFFFFU, 0xDFFFFFFFU, | ||
| 523 | 0x000FFFFFU, 0xFFFFFFFFU, 0x000F87FFU, 0xFF11FFFFU, | ||
| 524 | 0xFFFFFFFFU, 0x7FFFFFFFU, 0xFFFFFFFDU, 0xFFFFFFFFU, | ||
| 525 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x9FFFFFFFU, | ||
| 526 | 0xFFFFFFFFU, 0x3FFFFFFFU, 0xFFFF7800U, 0x040000FFU, | ||
| 527 | 0x00600000U, 0x00000010U, 0x00000000U, 0xF8000000U, | ||
| 528 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0x0000FFFFU, 0x00000000U, | ||
| 529 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xE0E7103FU, 0x1FF01800U, | ||
| 530 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 531 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00010FFFU, | ||
| 532 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 533 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 534 | 0xFFFFF000U, 0xF7FFFFFFU, 0xFFFFFFBFU, 0xFFFFFFFFU, | ||
| 535 | 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, | ||
| 536 | 0x00000000U, 0x00000000U, 0x00000000U, 0x1F1F0000U, | ||
| 537 | 0xFFFF007FU, 0x07FF1FFFU, 0x03FF003FU, 0x007F00FFU, | ||
| 538 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, | ||
| 539 | 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U | ||
| 540 | } | ||
| 541 | }; | ||
diff --git a/gl/unlocked-io.h b/gl/unlocked-io.h index 0cd9bbf3..69ea6641 100644 --- a/gl/unlocked-io.h +++ b/gl/unlocked-io.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Prefer faster, non-thread-safe stdio functions if available. | 1 | /* Prefer faster, non-thread-safe stdio functions if available. |
| 2 | 2 | ||
| 3 | Copyright (C) 2001-2004, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2001-2004, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software: you can redistribute it and/or modify | 5 | This program is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
diff --git a/gl/unsetenv.c b/gl/unsetenv.c index d8ada2aa..d38ed37a 100644 --- a/gl/unsetenv.c +++ b/gl/unsetenv.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (C) 1992, 1995-2002, 2005-2024 Free Software Foundation, Inc. | 1 | /* Copyright (C) 1992, 1995-2002, 2005-2025 Free Software Foundation, Inc. |
| 2 | This file is part of the GNU C Library. | 2 | This file is part of the GNU C Library. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| @@ -57,7 +57,6 @@ int | |||
| 57 | unsetenv (const char *name) | 57 | unsetenv (const char *name) |
| 58 | { | 58 | { |
| 59 | size_t len; | 59 | size_t len; |
| 60 | char **ep; | ||
| 61 | 60 | ||
| 62 | if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) | 61 | if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) |
| 63 | { | 62 | { |
| @@ -67,9 +66,37 @@ unsetenv (const char *name) | |||
| 67 | 66 | ||
| 68 | len = strlen (name); | 67 | len = strlen (name); |
| 69 | 68 | ||
| 69 | #if HAVE_DECL__PUTENV /* native Windows */ | ||
| 70 | /* The Microsoft documentation | ||
| 71 | <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/putenv-wputenv> | ||
| 72 | says: | ||
| 73 | "Don't change an environment entry directly: instead, | ||
| 74 | use _putenv or _wputenv to change it." | ||
| 75 | Note: Microsoft's _putenv updates not only the contents of _environ but | ||
| 76 | also the contents of _wenviron, so that both are in kept in sync. | ||
| 77 | |||
| 78 | The way to remove an environment variable is to pass to _putenv a string | ||
| 79 | of the form "NAME=". (NB: This is a different convention than with glibc | ||
| 80 | putenv, which expects a string of the form "NAME"!) */ | ||
| 81 | { | ||
| 82 | int putenv_result; | ||
| 83 | char *name_ = malloc (len + 2); | ||
| 84 | if (name_ == NULL) | ||
| 85 | return -1; | ||
| 86 | memcpy (name_, name, len); | ||
| 87 | name_[len] = '='; | ||
| 88 | name_[len + 1] = 0; | ||
| 89 | putenv_result = _putenv (name_); | ||
| 90 | /* In this particular case it is OK to free() the argument passed to | ||
| 91 | _putenv. */ | ||
| 92 | free (name_); | ||
| 93 | return putenv_result; | ||
| 94 | } | ||
| 95 | #else | ||
| 96 | |||
| 70 | LOCK; | 97 | LOCK; |
| 71 | 98 | ||
| 72 | ep = __environ; | 99 | char **ep = __environ; |
| 73 | while (*ep != NULL) | 100 | while (*ep != NULL) |
| 74 | if (!strncmp (*ep, name, len) && (*ep)[len] == '=') | 101 | if (!strncmp (*ep, name, len) && (*ep)[len] == '=') |
| 75 | { | 102 | { |
| @@ -87,6 +114,7 @@ unsetenv (const char *name) | |||
| 87 | UNLOCK; | 114 | UNLOCK; |
| 88 | 115 | ||
| 89 | return 0; | 116 | return 0; |
| 117 | #endif | ||
| 90 | } | 118 | } |
| 91 | 119 | ||
| 92 | #ifdef _LIBC | 120 | #ifdef _LIBC |
diff --git a/gl/vasnprintf.c b/gl/vasnprintf.c index de204458..f46e8701 100644 --- a/gl/vasnprintf.c +++ b/gl/vasnprintf.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* vsprintf with automatic memory allocation. | 1 | /* vsprintf with automatic memory allocation. |
| 2 | Copyright (C) 1999, 2002-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2002-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -29,6 +29,7 @@ | |||
| 29 | Depends on FCHAR_T. | 29 | Depends on FCHAR_T. |
| 30 | DCHAR_CPY memcpy like function for DCHAR_T[] arrays. | 30 | DCHAR_CPY memcpy like function for DCHAR_T[] arrays. |
| 31 | DCHAR_SET memset like function for DCHAR_T[] arrays. | 31 | DCHAR_SET memset like function for DCHAR_T[] arrays. |
| 32 | DCHAR_STRLEN strlen like function for DCHAR_T[] arrays. | ||
| 32 | DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays. | 33 | DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays. |
| 33 | SNPRINTF The system's snprintf (or similar) function. | 34 | SNPRINTF The system's snprintf (or similar) function. |
| 34 | This may be either snprintf or swprintf. | 35 | This may be either snprintf or swprintf. |
| @@ -64,7 +65,7 @@ | |||
| 64 | /* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's | 65 | /* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's |
| 65 | use of CHECK macros expands to code that is too complicated for gcc | 66 | use of CHECK macros expands to code that is too complicated for gcc |
| 66 | -fanalyzer. Suppress the resulting bogus warnings. */ | 67 | -fanalyzer. Suppress the resulting bogus warnings. */ |
| 67 | #if 10 <= __GNUC__ | 68 | #if _GL_GNUC_PREREQ (10, 0) |
| 68 | # pragma GCC diagnostic ignored "-Wanalyzer-null-argument" | 69 | # pragma GCC diagnostic ignored "-Wanalyzer-null-argument" |
| 69 | #endif | 70 | #endif |
| 70 | 71 | ||
| @@ -80,14 +81,15 @@ | |||
| 80 | #endif | 81 | #endif |
| 81 | 82 | ||
| 82 | #include <locale.h> /* localeconv() */ | 83 | #include <locale.h> /* localeconv() */ |
| 84 | #include <stdint.h> /* PTRDIFF_MAX */ | ||
| 83 | #include <stdio.h> /* snprintf(), sprintf() */ | 85 | #include <stdio.h> /* snprintf(), sprintf() */ |
| 84 | #include <stdlib.h> /* abort(), malloc(), realloc(), free() */ | 86 | #include <stdlib.h> /* abort(), malloc(), realloc(), free() */ |
| 85 | #include <string.h> /* memcpy(), strlen() */ | 87 | #include <string.h> /* memcpy(), strlen() */ |
| 86 | #include <wchar.h> /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb(), mbszero() */ | 88 | #include <wchar.h> /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb(), mbszero() */ |
| 87 | #include <errno.h> /* errno */ | 89 | #include <errno.h> /* errno */ |
| 88 | #include <limits.h> /* CHAR_BIT, INT_WIDTH, LONG_WIDTH */ | 90 | #include <limits.h> /* CHAR_BIT, INT_MAX, INT_WIDTH, LONG_WIDTH */ |
| 89 | #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */ | 91 | #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP, LDBL_MANT_DIG */ |
| 90 | #if HAVE_NL_LANGINFO | 92 | #if HAVE_NL_LANGINFO || __GLIBC__ >= 2 || defined __CYGWIN__ |
| 91 | # include <langinfo.h> | 93 | # include <langinfo.h> |
| 92 | #endif | 94 | #endif |
| 93 | #ifndef VASNPRINTF | 95 | #ifndef VASNPRINTF |
| @@ -182,6 +184,20 @@ | |||
| 182 | # define TCHAR_T char | 184 | # define TCHAR_T char |
| 183 | # endif | 185 | # endif |
| 184 | #endif | 186 | #endif |
| 187 | #ifndef DCHAR_STRLEN | ||
| 188 | # if WIDE_CHAR_VERSION | ||
| 189 | # define DCHAR_STRLEN local_wcslen | ||
| 190 | # else | ||
| 191 | # define DCHAR_STRLEN strlen | ||
| 192 | # endif | ||
| 193 | #endif | ||
| 194 | #ifndef DCHAR_MBSNLEN | ||
| 195 | # if WIDE_CHAR_VERSION | ||
| 196 | # define DCHAR_MBSNLEN wcsnlen | ||
| 197 | # else | ||
| 198 | # define DCHAR_MBSNLEN mbsnlen | ||
| 199 | # endif | ||
| 200 | #endif | ||
| 185 | #if !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR | 201 | #if !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR |
| 186 | /* TCHAR_T is char. */ | 202 | /* TCHAR_T is char. */ |
| 187 | /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. | 203 | /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. |
| @@ -216,6 +232,12 @@ | |||
| 216 | /* Here we need to call the native sprintf, not rpl_sprintf. */ | 232 | /* Here we need to call the native sprintf, not rpl_sprintf. */ |
| 217 | #undef sprintf | 233 | #undef sprintf |
| 218 | 234 | ||
| 235 | /* macOS 12's "warning: 'sprintf' is deprecated" is pointless, | ||
| 236 | as sprintf is used safely here. */ | ||
| 237 | #if defined __APPLE__ && defined __MACH__ && _GL_GNUC_PREREQ (4, 2) | ||
| 238 | # pragma GCC diagnostic ignored "-Wdeprecated-declarations" | ||
| 239 | #endif | ||
| 240 | |||
| 219 | /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized" | 241 | /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized" |
| 220 | warnings in this file. Use -Dlint to suppress them. */ | 242 | warnings in this file. Use -Dlint to suppress them. */ |
| 221 | #if defined GCC_LINT || defined lint | 243 | #if defined GCC_LINT || defined lint |
| @@ -224,6 +246,11 @@ | |||
| 224 | # define IF_LINT(Code) /* empty */ | 246 | # define IF_LINT(Code) /* empty */ |
| 225 | #endif | 247 | #endif |
| 226 | 248 | ||
| 249 | /* Here we need only the most basic fields of 'struct lconv', and can | ||
| 250 | therefore use the system's localeconv() function, without needing a | ||
| 251 | dependency on module 'localeconv'. */ | ||
| 252 | #undef localeconv | ||
| 253 | |||
| 227 | /* Avoid some warnings from "gcc -Wshadow". | 254 | /* Avoid some warnings from "gcc -Wshadow". |
| 228 | This file doesn't use the exp() and remainder() functions. */ | 255 | This file doesn't use the exp() and remainder() functions. */ |
| 229 | #undef exp | 256 | #undef exp |
| @@ -231,7 +258,7 @@ | |||
| 231 | #undef remainder | 258 | #undef remainder |
| 232 | #define remainder rem | 259 | #define remainder rem |
| 233 | 260 | ||
| 234 | #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION | 261 | #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (PTRDIFF_MAX > INT_MAX)) && !WIDE_CHAR_VERSION |
| 235 | # if (HAVE_STRNLEN && !defined _AIX) | 262 | # if (HAVE_STRNLEN && !defined _AIX) |
| 236 | # define local_strnlen strnlen | 263 | # define local_strnlen strnlen |
| 237 | # else | 264 | # else |
| @@ -247,7 +274,7 @@ local_strnlen (const char *string, size_t maxlen) | |||
| 247 | # endif | 274 | # endif |
| 248 | #endif | 275 | #endif |
| 249 | 276 | ||
| 250 | #if (((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_WPRINTF_DIRECTIVE_LC) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T | 277 | #if ((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) |
| 251 | # if HAVE_WCSLEN | 278 | # if HAVE_WCSLEN |
| 252 | # define local_wcslen wcslen | 279 | # define local_wcslen wcslen |
| 253 | # else | 280 | # else |
| @@ -270,7 +297,7 @@ local_wcslen (const wchar_t *s) | |||
| 270 | # endif | 297 | # endif |
| 271 | #endif | 298 | #endif |
| 272 | 299 | ||
| 273 | #if (!USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION | 300 | #if (!USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION |
| 274 | # if HAVE_WCSNLEN && HAVE_DECL_WCSNLEN | 301 | # if HAVE_WCSNLEN && HAVE_DECL_WCSNLEN |
| 275 | # define local_wcsnlen wcsnlen | 302 | # define local_wcsnlen wcsnlen |
| 276 | # else | 303 | # else |
| @@ -289,7 +316,7 @@ local_wcsnlen (const wchar_t *s, size_t maxlen) | |||
| 289 | # endif | 316 | # endif |
| 290 | #endif | 317 | #endif |
| 291 | 318 | ||
| 292 | #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T)) && !WIDE_CHAR_VERSION | 319 | #if ((!USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T)) && !WIDE_CHAR_VERSION |
| 293 | # if ENABLE_WCHAR_FALLBACK | 320 | # if ENABLE_WCHAR_FALLBACK |
| 294 | static size_t | 321 | static size_t |
| 295 | wctomb_fallback (char *s, wchar_t wc) | 322 | wctomb_fallback (char *s, wchar_t wc) |
| @@ -357,7 +384,7 @@ local_wctomb (char *s, wchar_t wc) | |||
| 357 | # endif | 384 | # endif |
| 358 | #endif | 385 | #endif |
| 359 | 386 | ||
| 360 | #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) | 387 | #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) || (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT) |
| 361 | /* Determine the decimal-point character according to the current locale. */ | 388 | /* Determine the decimal-point character according to the current locale. */ |
| 362 | # ifndef decimal_point_char_defined | 389 | # ifndef decimal_point_char_defined |
| 363 | # define decimal_point_char_defined 1 | 390 | # define decimal_point_char_defined 1 |
| @@ -384,6 +411,217 @@ decimal_point_char (void) | |||
| 384 | # endif | 411 | # endif |
| 385 | #endif | 412 | #endif |
| 386 | 413 | ||
| 414 | #if (!WIDE_CHAR_VERSION && (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE)) || ((!WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR) && (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT)) | ||
| 415 | /* Determine the thousands-separator character according to the current | ||
| 416 | locale. | ||
| 417 | It is a single multibyte character. | ||
| 418 | In glibc: 35x ".", 90x ",", 23x U+202F, 1x U+2019, 1x U+066C, on other | ||
| 419 | systems also U+00A0. */ | ||
| 420 | # ifndef thousands_separator_char_defined | ||
| 421 | # define thousands_separator_char_defined 1 | ||
| 422 | static const char * | ||
| 423 | thousands_separator_char (char stackbuf[10]) | ||
| 424 | { | ||
| 425 | /* Determine it in a multithread-safe way. | ||
| 426 | We know nl_langinfo is multithread-safe on glibc systems, on Mac OS X | ||
| 427 | systems, and on NetBSD, but is not required to be multithread-safe by | ||
| 428 | POSIX. | ||
| 429 | localeconv() is not guaranteed to be multithread-safe by POSIX either; | ||
| 430 | however, on native Windows it is (cf. test-localeconv-mt). | ||
| 431 | sprintf(), however, is multithread-safe. */ | ||
| 432 | # if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__) || defined __NetBSD__) | ||
| 433 | return nl_langinfo (THOUSEP); | ||
| 434 | # elif defined _WIN32 && !defined __CYGWIN__ | ||
| 435 | return localeconv () -> thousands_sep; | ||
| 436 | # else | ||
| 437 | sprintf (stackbuf, "%'.0f", 1000.0); | ||
| 438 | /* Now stackbuf = "1<thousep>000". */ | ||
| 439 | stackbuf[strlen (stackbuf) - 3] = '\0'; | ||
| 440 | # if defined __sun | ||
| 441 | /* Solaris specific hack: Replace wrong result (0xC2 means U+00A0). */ | ||
| 442 | if (strcmp (&stackbuf[1], "\302") == 0) | ||
| 443 | strcpy (&stackbuf[1], MB_CUR_MAX > 1 ? "\302\240" : "\240"); | ||
| 444 | # endif | ||
| 445 | return &stackbuf[1]; | ||
| 446 | # endif | ||
| 447 | } | ||
| 448 | # endif | ||
| 449 | #endif | ||
| 450 | #if !WIDE_CHAR_VERSION && defined DCHAR_CONV_FROM_ENCODING && (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) | ||
| 451 | /* Determine the thousands-separator character, as a DCHAR_T[] array, | ||
| 452 | according to the current locale. | ||
| 453 | It is a single Unicode character. */ | ||
| 454 | # ifndef thousands_separator_DCHAR_defined | ||
| 455 | # define thousands_separator_DCHAR_defined 1 | ||
| 456 | static const DCHAR_T * | ||
| 457 | thousands_separator_DCHAR (DCHAR_T stackbuf[10]) | ||
| 458 | { | ||
| 459 | /* Determine it in a multithread-safe way. */ | ||
| 460 | char tmpbuf[10]; | ||
| 461 | const char *tmp = thousands_separator_char (tmpbuf); | ||
| 462 | if (*tmp != '\0') | ||
| 463 | { | ||
| 464 | /* Convert it from char[] to DCHAR_T[]. */ | ||
| 465 | size_t converted_len = 10; | ||
| 466 | DCHAR_T *converted = | ||
| 467 | DCHAR_CONV_FROM_ENCODING (locale_charset (), | ||
| 468 | iconveh_question_mark, | ||
| 469 | tmp, strlen (tmp) + 1, | ||
| 470 | NULL, | ||
| 471 | stackbuf, &converted_len); | ||
| 472 | if (converted != NULL) | ||
| 473 | { | ||
| 474 | if (converted != stackbuf) | ||
| 475 | /* It should not be so long. */ | ||
| 476 | abort (); | ||
| 477 | return stackbuf; | ||
| 478 | } | ||
| 479 | } | ||
| 480 | stackbuf[0] = 0; | ||
| 481 | return stackbuf; | ||
| 482 | } | ||
| 483 | # endif | ||
| 484 | #endif | ||
| 485 | /* Maximum number of 'char' in the char[] or DCHAR_T[] representation of the | ||
| 486 | thousands separator. */ | ||
| 487 | #define THOUSEP_CHAR_MAXLEN 3 | ||
| 488 | |||
| 489 | #if WIDE_CHAR_VERSION && ((NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) || ((NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT) && DCHAR_IS_TCHAR)) | ||
| 490 | /* Determine the thousands-separator character, as a wide character, according | ||
| 491 | to the current locale. | ||
| 492 | It is a single wide character. */ | ||
| 493 | # ifndef thousands_separator_wchar_defined | ||
| 494 | # define thousands_separator_wchar_defined 1 | ||
| 495 | static const wchar_t * | ||
| 496 | thousands_separator_wchar (wchar_t stackbuf[10]) | ||
| 497 | { | ||
| 498 | # if __GLIBC__ >= 2 || defined __CYGWIN__ | ||
| 499 | /* On glibc, in the unibyte locale fr_FR, the *wprintf routines use U+202F | ||
| 500 | as separator, which cannot be represented in the locale encoding. */ | ||
| 501 | stackbuf[0] = | ||
| 502 | (wchar_t) (unsigned long) nl_langinfo (_NL_NUMERIC_THOUSANDS_SEP_WC); | ||
| 503 | stackbuf[1] = L'\0'; | ||
| 504 | return stackbuf; | ||
| 505 | # elif defined _WIN32 && !defined __CYGWIN__ | ||
| 506 | const char *tmp = localeconv () -> thousands_sep; | ||
| 507 | if (*tmp != '\0') | ||
| 508 | { | ||
| 509 | mbstate_t state; | ||
| 510 | mbszero (&state); | ||
| 511 | if ((int) mbrtowc (&stackbuf[0], tmp, strlen (tmp), &state) > 0) | ||
| 512 | stackbuf[1] = L'\0'; | ||
| 513 | else | ||
| 514 | stackbuf[0] = L'\0'; | ||
| 515 | } | ||
| 516 | else | ||
| 517 | stackbuf[0] = L'\0'; | ||
| 518 | return stackbuf; | ||
| 519 | # elif defined __sun | ||
| 520 | /* Use sprintf, because swprintf retrieves a wrong value for the | ||
| 521 | thousands-separator wide character (e.g. (wchar_t) 0xffffffa0). */ | ||
| 522 | char tmp[10]; | ||
| 523 | sprintf (tmp, "%'.0f", 1000.0); | ||
| 524 | /* Now tmp = L"1<thousep>000". */ | ||
| 525 | tmp[strlen (tmp) - 3] = '\0'; | ||
| 526 | /* Solaris specific hack: Replace wrong result (0xC2 means U+00A0). */ | ||
| 527 | if (strcmp (&tmp[1], "\302") == 0) | ||
| 528 | strcpy (&tmp[1], MB_CUR_MAX > 1 ? "\302\240" : "\240"); | ||
| 529 | if (tmp[1] != '\0') | ||
| 530 | { | ||
| 531 | mbstate_t state; | ||
| 532 | mbszero (&state); | ||
| 533 | if ((int) mbrtowc (&stackbuf[0], &tmp[1], strlen (&tmp[1]), &state) > 0) | ||
| 534 | stackbuf[1] = L'\0'; | ||
| 535 | else | ||
| 536 | stackbuf[0] = L'\0'; | ||
| 537 | } | ||
| 538 | else | ||
| 539 | stackbuf[0] = L'\0'; | ||
| 540 | return stackbuf; | ||
| 541 | # else | ||
| 542 | swprintf (stackbuf, 10, L"%'.0f", 1000.0); | ||
| 543 | /* Now stackbuf = L"1<thousep>000". */ | ||
| 544 | stackbuf[local_wcslen (stackbuf) - 3] = '\0'; | ||
| 545 | return &stackbuf[1]; | ||
| 546 | # endif | ||
| 547 | } | ||
| 548 | # endif | ||
| 549 | #endif | ||
| 550 | /* Maximum number of 'wchar_t' in the wchar_t[] representation of the thousands | ||
| 551 | separator. */ | ||
| 552 | #define THOUSEP_WCHAR_MAXLEN 1 | ||
| 553 | |||
| 554 | #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) || (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT) | ||
| 555 | # ifndef grouping_rule_defined | ||
| 556 | # define grouping_rule_defined 1 | ||
| 557 | /* Determine the grouping rule. | ||
| 558 | * As specified in POSIX | ||
| 559 | * <https://pubs.opengroup.org/onlinepubs/9799919799/functions/localeconv.html> | ||
| 560 | * <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap07.html#tag_07_03_04> | ||
| 561 | * it is a string whose elements are 'signed char' values, where | ||
| 562 | * "Each integer specifies the number of digits in each group, with the initial | ||
| 563 | * integer defining the size of the group immediately preceding the decimal | ||
| 564 | * delimiter, and the following integers defining the preceding groups. If | ||
| 565 | * the last integer is not -1, then the size of the previous group (if any) | ||
| 566 | * shall be repeatedly used for the remainder of the digits. If the last | ||
| 567 | * integer is -1, then no further grouping shall be performed." | ||
| 568 | * Platforms that have locales with grouping: | ||
| 569 | * glibc, FreeBSD, NetBSD, AIX, Solaris, Cygwin, Haiku. | ||
| 570 | * Platforms that don't: | ||
| 571 | * musl libc, macOS, OpenBSD, Android, mingw, MSVC. | ||
| 572 | * Typical grouping rules on glibc: | ||
| 573 | * 136x 3 (fr_FR etc.) | ||
| 574 | * 4x 4 (cmn_TW etc.) | ||
| 575 | * 9x 3;2 (ta_IN etc.) | ||
| 576 | * 1x 2;2;2;3 (umn_US) | ||
| 577 | * 21x -1 (C etc.) | ||
| 578 | */ | ||
| 579 | static const signed char * | ||
| 580 | grouping_rule (void) | ||
| 581 | { | ||
| 582 | /* We know nl_langinfo is multithread-safe on glibc systems and on Cygwin, | ||
| 583 | but is not required to be multithread-safe by POSIX. | ||
| 584 | localeconv() is not guaranteed to be multithread-safe by POSIX either; | ||
| 585 | however, on all known systems it is (cf. test-localeconv-mt). */ | ||
| 586 | # if __GLIBC__ >= 2 | ||
| 587 | return (const signed char *) nl_langinfo (GROUPING); | ||
| 588 | # elif defined __CYGWIN__ | ||
| 589 | return (const signed char *) nl_langinfo (_NL_NUMERIC_GROUPING); | ||
| 590 | # else | ||
| 591 | return (const signed char *) localeconv () -> grouping; | ||
| 592 | # endif | ||
| 593 | } | ||
| 594 | /* Determines the number of thousands-separators to be inserted in a digit | ||
| 595 | sequence with ndigits digits (before the decimal point). */ | ||
| 596 | static size_t | ||
| 597 | num_thousands_separators (const signed char *grouping, size_t ndigits) | ||
| 598 | { | ||
| 599 | const signed char *g = grouping; | ||
| 600 | int h = *g; | ||
| 601 | if (h <= 0 || ndigits == 0) | ||
| 602 | return 0; | ||
| 603 | size_t insert = 0; | ||
| 604 | for (;;) | ||
| 605 | { | ||
| 606 | /* Invariant: here h == *g, h > 0, ndigits > 0. */ | ||
| 607 | if (g[1] == 0) | ||
| 608 | /* h repeats endlessly. */ | ||
| 609 | return insert + (ndigits - 1) / h; | ||
| 610 | /* h does not repeat. */ | ||
| 611 | if (ndigits <= h) | ||
| 612 | return insert; | ||
| 613 | ndigits -= h; | ||
| 614 | insert++; | ||
| 615 | g++; | ||
| 616 | h = *g; | ||
| 617 | if (h < 0) | ||
| 618 | /* No further grouping. */ | ||
| 619 | return insert; | ||
| 620 | } | ||
| 621 | } | ||
| 622 | # endif | ||
| 623 | #endif | ||
| 624 | |||
| 387 | #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE | 625 | #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE |
| 388 | 626 | ||
| 389 | /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ | 627 | /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ |
| @@ -406,8 +644,45 @@ is_infinite_or_zerol (long double x) | |||
| 406 | 644 | ||
| 407 | #endif | 645 | #endif |
| 408 | 646 | ||
| 647 | #if NEED_PRINTF_LONG_DOUBLE | ||
| 648 | |||
| 649 | /* Like frexpl, except that it supports even "unsupported" numbers. */ | ||
| 650 | # if (LDBL_MANT_DIG == 64 && (defined __ia64 || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))) && (defined __APPLE__ && defined __MACH__) | ||
| 651 | /* Don't assume that frexpl can handle pseudo-denormals; it does not on | ||
| 652 | macOS 12/x86_64. Therefore test for a pseudo-denormal explicitly. */ | ||
| 653 | |||
| 654 | static | ||
| 655 | long double safe_frexpl (long double x, int *exp) | ||
| 656 | { | ||
| 657 | union | ||
| 658 | { | ||
| 659 | long double value; | ||
| 660 | struct { unsigned int mant_word[2]; unsigned short sign_exp_word; } r; | ||
| 661 | } | ||
| 662 | u; | ||
| 663 | u.value = x; | ||
| 664 | if (u.r.sign_exp_word == 0 && (u.r.mant_word[1] & 0x80000000u) != 0) | ||
| 665 | { | ||
| 666 | /* Pseudo-Denormal. */ | ||
| 667 | *exp = LDBL_MIN_EXP; | ||
| 668 | u.r.sign_exp_word = 1 - LDBL_MIN_EXP; | ||
| 669 | return u.value; | ||
| 670 | } | ||
| 671 | else | ||
| 672 | return frexpl (x, exp); | ||
| 673 | } | ||
| 674 | |||
| 675 | # else | ||
| 676 | # define safe_frexpl frexpl | ||
| 677 | # endif | ||
| 678 | |||
| 679 | #endif | ||
| 680 | |||
| 409 | #if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE | 681 | #if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE |
| 410 | 682 | ||
| 683 | /* An indicator for a failed memory allocation. */ | ||
| 684 | # define NOMEM_PTR ((void *) (-1)) | ||
| 685 | |||
| 411 | /* Converting 'long double' to decimal without rare rounding bugs requires | 686 | /* Converting 'long double' to decimal without rare rounding bugs requires |
| 412 | real bignums. We use the naming conventions of GNU gmp, but vastly simpler | 687 | real bignums. We use the naming conventions of GNU gmp, but vastly simpler |
| 413 | (and slower) algorithms. */ | 688 | (and slower) algorithms. */ |
| @@ -428,8 +703,8 @@ typedef struct | |||
| 428 | } mpn_t; | 703 | } mpn_t; |
| 429 | 704 | ||
| 430 | /* Compute the product of two bignums >= 0. | 705 | /* Compute the product of two bignums >= 0. |
| 431 | Return the allocated memory in case of success, NULL in case of memory | 706 | Return the allocated memory (possibly NULL) in case of success, NOMEM_PTR |
| 432 | allocation failure. */ | 707 | in case of memory allocation failure. */ |
| 433 | static void * | 708 | static void * |
| 434 | multiply (mpn_t src1, mpn_t src2, mpn_t *dest) | 709 | multiply (mpn_t src1, mpn_t src2, mpn_t *dest) |
| 435 | { | 710 | { |
| @@ -457,7 +732,7 @@ multiply (mpn_t src1, mpn_t src2, mpn_t *dest) | |||
| 457 | { | 732 | { |
| 458 | /* src1 or src2 is zero. */ | 733 | /* src1 or src2 is zero. */ |
| 459 | dest->nlimbs = 0; | 734 | dest->nlimbs = 0; |
| 460 | dest->limbs = (mp_limb_t *) malloc (1); | 735 | dest->limbs = NULL; |
| 461 | } | 736 | } |
| 462 | else | 737 | else |
| 463 | { | 738 | { |
| @@ -469,7 +744,7 @@ multiply (mpn_t src1, mpn_t src2, mpn_t *dest) | |||
| 469 | dlen = len1 + len2; | 744 | dlen = len1 + len2; |
| 470 | dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t)); | 745 | dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t)); |
| 471 | if (dp == NULL) | 746 | if (dp == NULL) |
| 472 | return NULL; | 747 | return NOMEM_PTR; |
| 473 | for (k = len2; k > 0; ) | 748 | for (k = len2; k > 0; ) |
| 474 | dp[--k] = 0; | 749 | dp[--k] = 0; |
| 475 | for (i = 0; i < len1; i++) | 750 | for (i = 0; i < len1; i++) |
| @@ -500,8 +775,8 @@ multiply (mpn_t src1, mpn_t src2, mpn_t *dest) | |||
| 500 | the remainder. | 775 | the remainder. |
| 501 | Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd, | 776 | Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd, |
| 502 | q is incremented. | 777 | q is incremented. |
| 503 | Return the allocated memory in case of success, NULL in case of memory | 778 | Return the allocated memory (possibly NULL) in case of success, NOMEM_PTR |
| 504 | allocation failure. */ | 779 | in case of memory allocation failure. */ |
| 505 | static void * | 780 | static void * |
| 506 | divide (mpn_t a, mpn_t b, mpn_t *q) | 781 | divide (mpn_t a, mpn_t b, mpn_t *q) |
| 507 | { | 782 | { |
| @@ -572,7 +847,7 @@ divide (mpn_t a, mpn_t b, mpn_t *q) | |||
| 572 | final rounding of q.) */ | 847 | final rounding of q.) */ |
| 573 | roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t)); | 848 | roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t)); |
| 574 | if (roomptr == NULL) | 849 | if (roomptr == NULL) |
| 575 | return NULL; | 850 | return NOMEM_PTR; |
| 576 | 851 | ||
| 577 | /* Normalise a. */ | 852 | /* Normalise a. */ |
| 578 | while (a_len > 0 && a_ptr[a_len - 1] == 0) | 853 | while (a_len > 0 && a_ptr[a_len - 1] == 0) |
| @@ -708,7 +983,7 @@ divide (mpn_t a, mpn_t b, mpn_t *q) | |||
| 708 | if (tmp_roomptr == NULL) | 983 | if (tmp_roomptr == NULL) |
| 709 | { | 984 | { |
| 710 | free (roomptr); | 985 | free (roomptr); |
| 711 | return NULL; | 986 | return NOMEM_PTR; |
| 712 | } | 987 | } |
| 713 | { | 988 | { |
| 714 | const mp_limb_t *sourceptr = b_ptr; | 989 | const mp_limb_t *sourceptr = b_ptr; |
| @@ -930,7 +1205,7 @@ divide (mpn_t a, mpn_t b, mpn_t *q) | |||
| 930 | /* Avoid pointless GCC warning "argument 1 value '18446744073709551615' exceeds | 1205 | /* Avoid pointless GCC warning "argument 1 value '18446744073709551615' exceeds |
| 931 | maximum object size 9223372036854775807", triggered by the use of xsum as | 1206 | maximum object size 9223372036854775807", triggered by the use of xsum as |
| 932 | argument of malloc. */ | 1207 | argument of malloc. */ |
| 933 | # if __GNUC__ >= 7 | 1208 | # if _GL_GNUC_PREREQ (7, 0) |
| 934 | # pragma GCC diagnostic push | 1209 | # pragma GCC diagnostic push |
| 935 | # pragma GCC diagnostic ignored "-Walloc-size-larger-than=" | 1210 | # pragma GCC diagnostic ignored "-Walloc-size-larger-than=" |
| 936 | # endif | 1211 | # endif |
| @@ -991,7 +1266,7 @@ convert_to_decimal (mpn_t a, size_t extra_zeroes) | |||
| 991 | return c_ptr; | 1266 | return c_ptr; |
| 992 | } | 1267 | } |
| 993 | 1268 | ||
| 994 | # if __GNUC__ >= 7 | 1269 | # if _GL_GNUC_PREREQ (7, 0) |
| 995 | # pragma GCC diagnostic pop | 1270 | # pragma GCC diagnostic pop |
| 996 | # endif | 1271 | # endif |
| 997 | 1272 | ||
| @@ -1015,7 +1290,7 @@ decode_long_double (long double x, int *ep, mpn_t *mp) | |||
| 1015 | if (m.limbs == NULL) | 1290 | if (m.limbs == NULL) |
| 1016 | return NULL; | 1291 | return NULL; |
| 1017 | /* Split into exponential part and mantissa. */ | 1292 | /* Split into exponential part and mantissa. */ |
| 1018 | y = frexpl (x, &exp); | 1293 | y = safe_frexpl (x, &exp); |
| 1019 | if (!(y >= 0.0L && y < 1.0L)) | 1294 | if (!(y >= 0.0L && y < 1.0L)) |
| 1020 | abort (); | 1295 | abort (); |
| 1021 | /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the | 1296 | /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the |
| @@ -1306,7 +1581,7 @@ scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n) | |||
| 1306 | mpn_t denominator; | 1581 | mpn_t denominator; |
| 1307 | void *tmp_memory; | 1582 | void *tmp_memory; |
| 1308 | tmp_memory = multiply (m, pow5, &numerator); | 1583 | tmp_memory = multiply (m, pow5, &numerator); |
| 1309 | if (tmp_memory == NULL) | 1584 | if (tmp_memory == NOMEM_PTR) |
| 1310 | { | 1585 | { |
| 1311 | free (pow5_ptr); | 1586 | free (pow5_ptr); |
| 1312 | free (memory); | 1587 | free (memory); |
| @@ -1379,7 +1654,7 @@ scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n) | |||
| 1379 | 1654 | ||
| 1380 | /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */ | 1655 | /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */ |
| 1381 | 1656 | ||
| 1382 | if (z_memory == NULL) | 1657 | if (z_memory == NOMEM_PTR) |
| 1383 | return NULL; | 1658 | return NULL; |
| 1384 | digits = convert_to_decimal (z, extra_zeroes); | 1659 | digits = convert_to_decimal (z, extra_zeroes); |
| 1385 | free (z_memory); | 1660 | free (z_memory); |
| @@ -1442,7 +1717,7 @@ floorlog10l (long double x) | |||
| 1442 | double l; | 1717 | double l; |
| 1443 | 1718 | ||
| 1444 | /* Split into exponential part and mantissa. */ | 1719 | /* Split into exponential part and mantissa. */ |
| 1445 | y = frexpl (x, &exp); | 1720 | y = safe_frexpl (x, &exp); |
| 1446 | if (!(y >= 0.0L && y < 1.0L)) | 1721 | if (!(y >= 0.0L && y < 1.0L)) |
| 1447 | abort (); | 1722 | abort (); |
| 1448 | if (y == 0.0L) | 1723 | if (y == 0.0L) |
| @@ -1801,8 +2076,17 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, | |||
| 1801 | } | 2076 | } |
| 1802 | if (tmp_length < precision) | 2077 | if (tmp_length < precision) |
| 1803 | tmp_length = precision; | 2078 | tmp_length = precision; |
| 1804 | /* Multiply by 2, as an estimate for FLAG_GROUP. */ | 2079 | /* Account for thousands separators. */ |
| 1805 | tmp_length = xsum (tmp_length, tmp_length); | 2080 | if (flags & FLAG_GROUP) |
| 2081 | { | ||
| 2082 | /* A thousands separator needs to be inserted at most every 2 digits. | ||
| 2083 | This is the case in the ta_IN locale. */ | ||
| 2084 | # if WIDE_CHAR_VERSION | ||
| 2085 | tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_WCHAR_MAXLEN); | ||
| 2086 | # else | ||
| 2087 | tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_CHAR_MAXLEN); | ||
| 2088 | # endif | ||
| 2089 | } | ||
| 1806 | /* Add 1, to account for a leading sign. */ | 2090 | /* Add 1, to account for a leading sign. */ |
| 1807 | tmp_length = xsum (tmp_length, 1); | 2091 | tmp_length = xsum (tmp_length, 1); |
| 1808 | break; | 2092 | break; |
| @@ -2050,12 +2334,18 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, | |||
| 2050 | tmp_length = xsum (tmp_length, 2); | 2334 | tmp_length = xsum (tmp_length, 2); |
| 2051 | break; | 2335 | break; |
| 2052 | 2336 | ||
| 2337 | case 'e': case 'E': | ||
| 2338 | tmp_length = | ||
| 2339 | 12; /* sign, decimal point, exponent etc. */ | ||
| 2340 | tmp_length = xsum (tmp_length, precision); | ||
| 2341 | break; | ||
| 2342 | |||
| 2053 | case 'f': case 'F': | 2343 | case 'f': case 'F': |
| 2054 | if (type == TYPE_LONGDOUBLE) | 2344 | if (type == TYPE_LONGDOUBLE) |
| 2055 | tmp_length = | 2345 | tmp_length = |
| 2056 | (unsigned int) (LDBL_MAX_EXP | 2346 | (unsigned int) (LDBL_MAX_EXP |
| 2057 | * 0.30103 /* binary -> decimal */ | 2347 | * 0.30103 /* binary -> decimal */ |
| 2058 | * 2 /* estimate for FLAG_GROUP */ | 2348 | * 0.5 * 3 /* estimate for FLAG_GROUP */ |
| 2059 | ) | 2349 | ) |
| 2060 | + 1 /* turn floor into ceil */ | 2350 | + 1 /* turn floor into ceil */ |
| 2061 | + 10; /* sign, decimal point etc. */ | 2351 | + 10; /* sign, decimal point etc. */ |
| @@ -2063,17 +2353,20 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, | |||
| 2063 | tmp_length = | 2353 | tmp_length = |
| 2064 | (unsigned int) (DBL_MAX_EXP | 2354 | (unsigned int) (DBL_MAX_EXP |
| 2065 | * 0.30103 /* binary -> decimal */ | 2355 | * 0.30103 /* binary -> decimal */ |
| 2066 | * 2 /* estimate for FLAG_GROUP */ | 2356 | * 0.5 * 3 /* estimate for FLAG_GROUP */ |
| 2067 | ) | 2357 | ) |
| 2068 | + 1 /* turn floor into ceil */ | 2358 | + 1 /* turn floor into ceil */ |
| 2069 | + 10; /* sign, decimal point etc. */ | 2359 | + 10; /* sign, decimal point etc. */ |
| 2070 | tmp_length = xsum (tmp_length, precision); | 2360 | tmp_length = xsum (tmp_length, precision); |
| 2071 | break; | 2361 | break; |
| 2072 | 2362 | ||
| 2073 | case 'e': case 'E': case 'g': case 'G': | 2363 | case 'g': case 'G': |
| 2074 | tmp_length = | 2364 | tmp_length = |
| 2075 | 12; /* sign, decimal point, exponent etc. */ | 2365 | 12; /* sign, decimal point, exponent etc. */ |
| 2076 | tmp_length = xsum (tmp_length, precision); | 2366 | tmp_length = xsum (tmp_length, |
| 2367 | precision | ||
| 2368 | * 0.5 * 3 /* estimate for FLAG_GROUP */ | ||
| 2369 | ); | ||
| 2077 | break; | 2370 | break; |
| 2078 | 2371 | ||
| 2079 | case 'a': case 'A': | 2372 | case 'a': case 'A': |
| @@ -2111,10 +2404,9 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, | |||
| 2111 | break; | 2404 | break; |
| 2112 | 2405 | ||
| 2113 | case 's': | 2406 | case 's': |
| 2114 | # if HAVE_WCHAR_T | ||
| 2115 | if (type == TYPE_WIDE_STRING) | 2407 | if (type == TYPE_WIDE_STRING) |
| 2116 | { | 2408 | { |
| 2117 | # if WIDE_CHAR_VERSION | 2409 | # if WIDE_CHAR_VERSION |
| 2118 | /* ISO C says about %ls in fwprintf: | 2410 | /* ISO C says about %ls in fwprintf: |
| 2119 | "If the precision is not specified or is greater than the size | 2411 | "If the precision is not specified or is greater than the size |
| 2120 | of the array, the array shall contain a null wide character." | 2412 | of the array, the array shall contain a null wide character." |
| @@ -2125,7 +2417,7 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, | |||
| 2125 | tmp_length = local_wcsnlen (arg, precision); | 2417 | tmp_length = local_wcsnlen (arg, precision); |
| 2126 | else | 2418 | else |
| 2127 | tmp_length = local_wcslen (arg); | 2419 | tmp_length = local_wcslen (arg); |
| 2128 | # else | 2420 | # else |
| 2129 | /* ISO C says about %ls in fprintf: | 2421 | /* ISO C says about %ls in fprintf: |
| 2130 | "If a precision is specified, no more than that many bytes are | 2422 | "If a precision is specified, no more than that many bytes are |
| 2131 | written (including shift sequences, if any), and the array | 2423 | written (including shift sequences, if any), and the array |
| @@ -2136,10 +2428,9 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, | |||
| 2136 | So if there is a precision, we must not use wcslen. */ | 2428 | So if there is a precision, we must not use wcslen. */ |
| 2137 | /* This case has already been handled separately in VASNPRINTF. */ | 2429 | /* This case has already been handled separately in VASNPRINTF. */ |
| 2138 | abort (); | 2430 | abort (); |
| 2139 | # endif | 2431 | # endif |
| 2140 | } | 2432 | } |
| 2141 | else | 2433 | else |
| 2142 | # endif | ||
| 2143 | { | 2434 | { |
| 2144 | # if WIDE_CHAR_VERSION | 2435 | # if WIDE_CHAR_VERSION |
| 2145 | /* ISO C says about %s in fwprintf: | 2436 | /* ISO C says about %s in fwprintf: |
| @@ -2226,7 +2517,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2226 | TCHAR_T *buf; | 2517 | TCHAR_T *buf; |
| 2227 | TCHAR_T *buf_malloced; | 2518 | TCHAR_T *buf_malloced; |
| 2228 | const FCHAR_T *cp; | 2519 | const FCHAR_T *cp; |
| 2229 | size_t i; | 2520 | size_t di; |
| 2230 | DIRECTIVE *dp; | 2521 | DIRECTIVE *dp; |
| 2231 | /* Output string accumulator. */ | 2522 | /* Output string accumulator. */ |
| 2232 | DCHAR_T *result; | 2523 | DCHAR_T *result; |
| @@ -2290,7 +2581,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2290 | #define ENSURE_ALLOCATION(needed) \ | 2581 | #define ENSURE_ALLOCATION(needed) \ |
| 2291 | ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; ) | 2582 | ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; ) |
| 2292 | 2583 | ||
| 2293 | for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++) | 2584 | for (cp = format, di = 0, dp = &d.dir[0]; ; cp = dp->dir_end, di++, dp++) |
| 2294 | { | 2585 | { |
| 2295 | if (cp != dp->dir_start) | 2586 | if (cp != dp->dir_start) |
| 2296 | { | 2587 | { |
| @@ -2313,7 +2604,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2313 | while (--n > 0); | 2604 | while (--n > 0); |
| 2314 | } | 2605 | } |
| 2315 | } | 2606 | } |
| 2316 | if (i == d.count) | 2607 | if (di == d.count) |
| 2317 | break; | 2608 | break; |
| 2318 | 2609 | ||
| 2319 | /* Execute a single directive. */ | 2610 | /* Execute a single directive. */ |
| @@ -2423,6 +2714,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2423 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 2714 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 2424 | while (digitp != dp->width_end); | 2715 | while (digitp != dp->width_end); |
| 2425 | } | 2716 | } |
| 2717 | if (width > (size_t) INT_MAX) | ||
| 2718 | goto overflow; | ||
| 2426 | has_width = 1; | 2719 | has_width = 1; |
| 2427 | } | 2720 | } |
| 2428 | 2721 | ||
| @@ -2501,7 +2794,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2501 | { | 2794 | { |
| 2502 | /* Use the entire string. */ | 2795 | /* Use the entire string. */ |
| 2503 | arg_end = arg + u8_strlen (arg); | 2796 | arg_end = arg + u8_strlen (arg); |
| 2504 | /* The number of characters doesn't matter. */ | 2797 | /* The number of characters doesn't matter, |
| 2798 | because !has_width and therefore width==0. */ | ||
| 2505 | characters = 0; | 2799 | characters = 0; |
| 2506 | } | 2800 | } |
| 2507 | 2801 | ||
| @@ -2542,7 +2836,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2542 | if (converted != result + length) | 2836 | if (converted != result + length) |
| 2543 | { | 2837 | { |
| 2544 | ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), | 2838 | ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), |
| 2545 | { free (converted); goto out_of_memory; }); | 2839 | { free (converted); goto out_of_memory; }); |
| 2546 | DCHAR_CPY (result + length, converted, converted_len); | 2840 | DCHAR_CPY (result + length, converted, converted_len); |
| 2547 | free (converted); | 2841 | free (converted); |
| 2548 | } | 2842 | } |
| @@ -2603,7 +2897,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2603 | { | 2897 | { |
| 2604 | /* Use the entire string. */ | 2898 | /* Use the entire string. */ |
| 2605 | arg_end = arg + u16_strlen (arg); | 2899 | arg_end = arg + u16_strlen (arg); |
| 2606 | /* The number of characters doesn't matter. */ | 2900 | /* The number of characters doesn't matter, |
| 2901 | because !has_width and therefore width==0. */ | ||
| 2607 | characters = 0; | 2902 | characters = 0; |
| 2608 | } | 2903 | } |
| 2609 | 2904 | ||
| @@ -2644,7 +2939,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2644 | if (converted != result + length) | 2939 | if (converted != result + length) |
| 2645 | { | 2940 | { |
| 2646 | ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), | 2941 | ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), |
| 2647 | { free (converted); goto out_of_memory; }); | 2942 | { free (converted); goto out_of_memory; }); |
| 2648 | DCHAR_CPY (result + length, converted, converted_len); | 2943 | DCHAR_CPY (result + length, converted, converted_len); |
| 2649 | free (converted); | 2944 | free (converted); |
| 2650 | } | 2945 | } |
| @@ -2705,7 +3000,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2705 | { | 3000 | { |
| 2706 | /* Use the entire string. */ | 3001 | /* Use the entire string. */ |
| 2707 | arg_end = arg + u32_strlen (arg); | 3002 | arg_end = arg + u32_strlen (arg); |
| 2708 | /* The number of characters doesn't matter. */ | 3003 | /* The number of characters doesn't matter, |
| 3004 | because !has_width and therefore width==0. */ | ||
| 2709 | characters = 0; | 3005 | characters = 0; |
| 2710 | } | 3006 | } |
| 2711 | 3007 | ||
| @@ -2746,7 +3042,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2746 | if (converted != result + length) | 3042 | if (converted != result + length) |
| 2747 | { | 3043 | { |
| 2748 | ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), | 3044 | ENSURE_ALLOCATION_ELSE (xsum (length, converted_len), |
| 2749 | { free (converted); goto out_of_memory; }); | 3045 | { free (converted); goto out_of_memory; }); |
| 2750 | DCHAR_CPY (result + length, converted, converted_len); | 3046 | DCHAR_CPY (result + length, converted, converted_len); |
| 2751 | free (converted); | 3047 | free (converted); |
| 2752 | } | 3048 | } |
| @@ -2769,7 +3065,190 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2769 | } | 3065 | } |
| 2770 | } | 3066 | } |
| 2771 | #endif | 3067 | #endif |
| 2772 | #if WIDE_CHAR_VERSION && (!DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC) | 3068 | #if !WIDE_CHAR_VERSION && (PTRDIFF_MAX > INT_MAX) |
| 3069 | else if (dp->conversion == 's' | ||
| 3070 | && a.arg[dp->arg_index].type != TYPE_WIDE_STRING) | ||
| 3071 | { | ||
| 3072 | /* %s in vasnprintf. See the specification of fprintf. | ||
| 3073 | We handle it ourselves here, because the string may be longer | ||
| 3074 | than INT_MAX characters, whence snprintf or sprintf would | ||
| 3075 | fail to process it. */ | ||
| 3076 | int flags = dp->flags; | ||
| 3077 | int has_width; | ||
| 3078 | size_t width; | ||
| 3079 | int has_precision; | ||
| 3080 | size_t precision; | ||
| 3081 | |||
| 3082 | has_width = 0; | ||
| 3083 | width = 0; | ||
| 3084 | if (dp->width_start != dp->width_end) | ||
| 3085 | { | ||
| 3086 | if (dp->width_arg_index != ARG_NONE) | ||
| 3087 | { | ||
| 3088 | int arg; | ||
| 3089 | |||
| 3090 | if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) | ||
| 3091 | abort (); | ||
| 3092 | arg = a.arg[dp->width_arg_index].a.a_int; | ||
| 3093 | width = arg; | ||
| 3094 | if (arg < 0) | ||
| 3095 | { | ||
| 3096 | /* "A negative field width is taken as a '-' flag | ||
| 3097 | followed by a positive field width." */ | ||
| 3098 | flags |= FLAG_LEFT; | ||
| 3099 | width = -width; | ||
| 3100 | } | ||
| 3101 | } | ||
| 3102 | else | ||
| 3103 | { | ||
| 3104 | const FCHAR_T *digitp = dp->width_start; | ||
| 3105 | |||
| 3106 | do | ||
| 3107 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | ||
| 3108 | while (digitp != dp->width_end); | ||
| 3109 | } | ||
| 3110 | if (width > (size_t) INT_MAX) | ||
| 3111 | goto overflow; | ||
| 3112 | has_width = 1; | ||
| 3113 | } | ||
| 3114 | |||
| 3115 | has_precision = 0; | ||
| 3116 | precision = 6; | ||
| 3117 | if (dp->precision_start != dp->precision_end) | ||
| 3118 | { | ||
| 3119 | if (dp->precision_arg_index != ARG_NONE) | ||
| 3120 | { | ||
| 3121 | int arg; | ||
| 3122 | |||
| 3123 | if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) | ||
| 3124 | abort (); | ||
| 3125 | arg = a.arg[dp->precision_arg_index].a.a_int; | ||
| 3126 | /* "A negative precision is taken as if the precision | ||
| 3127 | were omitted." */ | ||
| 3128 | if (arg >= 0) | ||
| 3129 | { | ||
| 3130 | precision = arg; | ||
| 3131 | has_precision = 1; | ||
| 3132 | } | ||
| 3133 | } | ||
| 3134 | else | ||
| 3135 | { | ||
| 3136 | const FCHAR_T *digitp = dp->precision_start + 1; | ||
| 3137 | |||
| 3138 | precision = 0; | ||
| 3139 | while (digitp != dp->precision_end) | ||
| 3140 | precision = xsum (xtimes (precision, 10), *digitp++ - '0'); | ||
| 3141 | has_precision = 1; | ||
| 3142 | } | ||
| 3143 | } | ||
| 3144 | |||
| 3145 | { | ||
| 3146 | const char *arg = a.arg[dp->arg_index].a.a_string; | ||
| 3147 | size_t bytes; | ||
| 3148 | # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR | ||
| 3149 | size_t characters; | ||
| 3150 | # endif | ||
| 3151 | # if !DCHAR_IS_TCHAR | ||
| 3152 | /* This code assumes that TCHAR_T is 'char'. */ | ||
| 3153 | static_assert (sizeof (TCHAR_T) == 1); | ||
| 3154 | DCHAR_T *tmpdst; | ||
| 3155 | size_t tmpdst_len; | ||
| 3156 | # endif | ||
| 3157 | size_t w; | ||
| 3158 | |||
| 3159 | if (has_precision) | ||
| 3160 | { | ||
| 3161 | /* Use only at most PRECISION bytes, from the left. */ | ||
| 3162 | bytes = local_strnlen (arg, precision); | ||
| 3163 | } | ||
| 3164 | else | ||
| 3165 | { | ||
| 3166 | /* Use the entire string, and count the number of | ||
| 3167 | bytes. */ | ||
| 3168 | bytes = strlen (arg); | ||
| 3169 | } | ||
| 3170 | |||
| 3171 | # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR | ||
| 3172 | if (has_width) | ||
| 3173 | characters = mbsnlen (arg, bytes); | ||
| 3174 | else | ||
| 3175 | { | ||
| 3176 | /* The number of characters doesn't matter, | ||
| 3177 | because !has_width and therefore width==0. */ | ||
| 3178 | characters = 0; | ||
| 3179 | } | ||
| 3180 | # endif | ||
| 3181 | |||
| 3182 | # if !DCHAR_IS_TCHAR | ||
| 3183 | /* Convert from TCHAR_T[] to DCHAR_T[]. */ | ||
| 3184 | tmpdst = | ||
| 3185 | DCHAR_CONV_FROM_ENCODING (locale_charset (), | ||
| 3186 | iconveh_question_mark, | ||
| 3187 | arg, bytes, | ||
| 3188 | NULL, | ||
| 3189 | NULL, &tmpdst_len); | ||
| 3190 | if (tmpdst == NULL) | ||
| 3191 | goto fail_with_errno; | ||
| 3192 | # endif | ||
| 3193 | |||
| 3194 | if (has_width) | ||
| 3195 | { | ||
| 3196 | # if ENABLE_UNISTDIO | ||
| 3197 | /* Outside POSIX, it's preferable to compare the width | ||
| 3198 | against the number of _characters_ of the converted | ||
| 3199 | value. */ | ||
| 3200 | # if DCHAR_IS_TCHAR | ||
| 3201 | w = characters; | ||
| 3202 | # else | ||
| 3203 | w = DCHAR_MBSNLEN (tmpdst, tmpdst_len); | ||
| 3204 | # endif | ||
| 3205 | # else | ||
| 3206 | /* The width is compared against the number of _bytes_ | ||
| 3207 | of the converted value, says POSIX. */ | ||
| 3208 | w = bytes; | ||
| 3209 | # endif | ||
| 3210 | } | ||
| 3211 | else | ||
| 3212 | /* w doesn't matter. */ | ||
| 3213 | w = 0; | ||
| 3214 | |||
| 3215 | { | ||
| 3216 | # if DCHAR_IS_TCHAR | ||
| 3217 | size_t total = bytes + (w < width ? width - w : 0); | ||
| 3218 | ENSURE_ALLOCATION (xsum (length, total)); | ||
| 3219 | # else | ||
| 3220 | size_t total = tmpdst_len + (w < width ? width - w : 0); | ||
| 3221 | ENSURE_ALLOCATION_ELSE (xsum (length, total), | ||
| 3222 | { free (tmpdst); goto out_of_memory; }); | ||
| 3223 | # endif | ||
| 3224 | |||
| 3225 | if (w < width && !(flags & FLAG_LEFT)) | ||
| 3226 | { | ||
| 3227 | size_t n = width - w; | ||
| 3228 | DCHAR_SET (result + length, ' ', n); | ||
| 3229 | length += n; | ||
| 3230 | } | ||
| 3231 | |||
| 3232 | # if DCHAR_IS_TCHAR | ||
| 3233 | memcpy (result + length, arg, bytes); | ||
| 3234 | length += bytes; | ||
| 3235 | # else | ||
| 3236 | DCHAR_CPY (result + length, tmpdst, tmpdst_len); | ||
| 3237 | free (tmpdst); | ||
| 3238 | length += tmpdst_len; | ||
| 3239 | # endif | ||
| 3240 | |||
| 3241 | if (w < width && (flags & FLAG_LEFT)) | ||
| 3242 | { | ||
| 3243 | size_t n = width - w; | ||
| 3244 | DCHAR_SET (result + length, ' ', n); | ||
| 3245 | length += n; | ||
| 3246 | } | ||
| 3247 | } | ||
| 3248 | } | ||
| 3249 | } | ||
| 3250 | #endif | ||
| 3251 | #if WIDE_CHAR_VERSION && ((PTRDIFF_MAX > INT_MAX) || !DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC) | ||
| 2773 | else if ((dp->conversion == 's' | 3252 | else if ((dp->conversion == 's' |
| 2774 | && a.arg[dp->arg_index].type == TYPE_WIDE_STRING) | 3253 | && a.arg[dp->arg_index].type == TYPE_WIDE_STRING) |
| 2775 | || (dp->conversion == 'c' | 3254 | || (dp->conversion == 'c' |
| @@ -2810,6 +3289,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2810 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 3289 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 2811 | while (digitp != dp->width_end); | 3290 | while (digitp != dp->width_end); |
| 2812 | } | 3291 | } |
| 3292 | if (width > (size_t) INT_MAX) | ||
| 3293 | goto overflow; | ||
| 2813 | } | 3294 | } |
| 2814 | 3295 | ||
| 2815 | { | 3296 | { |
| @@ -2912,7 +3393,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2912 | } | 3393 | } |
| 2913 | } | 3394 | } |
| 2914 | #endif | 3395 | #endif |
| 2915 | #if (!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T | 3396 | #if WIDE_CHAR_VERSION || !USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK |
| 2916 | else if (dp->conversion == 's' | 3397 | else if (dp->conversion == 's' |
| 2917 | # if WIDE_CHAR_VERSION | 3398 | # if WIDE_CHAR_VERSION |
| 2918 | && a.arg[dp->arg_index].type != TYPE_WIDE_STRING | 3399 | && a.arg[dp->arg_index].type != TYPE_WIDE_STRING |
| @@ -2965,6 +3446,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 2965 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 3446 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 2966 | while (digitp != dp->width_end); | 3447 | while (digitp != dp->width_end); |
| 2967 | } | 3448 | } |
| 3449 | if (width > (size_t) INT_MAX) | ||
| 3450 | goto overflow; | ||
| 2968 | has_width = 1; | 3451 | has_width = 1; |
| 2969 | } | 3452 | } |
| 2970 | 3453 | ||
| @@ -3145,11 +3628,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3145 | { | 3628 | { |
| 3146 | const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; | 3629 | const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; |
| 3147 | const wchar_t *arg_end; | 3630 | const wchar_t *arg_end; |
| 3631 | size_t bytes; | ||
| 3632 | # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR | ||
| 3148 | size_t characters; | 3633 | size_t characters; |
| 3634 | # endif | ||
| 3149 | # if !DCHAR_IS_TCHAR | 3635 | # if !DCHAR_IS_TCHAR |
| 3150 | /* This code assumes that TCHAR_T is 'char'. */ | 3636 | /* This code assumes that TCHAR_T is 'char'. */ |
| 3151 | static_assert (sizeof (TCHAR_T) == 1); | 3637 | static_assert (sizeof (TCHAR_T) == 1); |
| 3152 | TCHAR_T *tmpsrc; | ||
| 3153 | DCHAR_T *tmpdst; | 3638 | DCHAR_T *tmpdst; |
| 3154 | size_t tmpdst_len; | 3639 | size_t tmpdst_len; |
| 3155 | # endif | 3640 | # endif |
| @@ -3164,7 +3649,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3164 | mbszero (&state); | 3649 | mbszero (&state); |
| 3165 | # endif | 3650 | # endif |
| 3166 | arg_end = arg; | 3651 | arg_end = arg; |
| 3652 | bytes = 0; | ||
| 3653 | # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR | ||
| 3167 | characters = 0; | 3654 | characters = 0; |
| 3655 | # endif | ||
| 3168 | while (precision > 0) | 3656 | while (precision > 0) |
| 3169 | { | 3657 | { |
| 3170 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | 3658 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ |
| @@ -3180,7 +3668,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3180 | if (precision < (unsigned int) count) | 3668 | if (precision < (unsigned int) count) |
| 3181 | break; | 3669 | break; |
| 3182 | arg_end++; | 3670 | arg_end++; |
| 3183 | characters += count; | 3671 | bytes += count; |
| 3672 | # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR | ||
| 3673 | characters += mbsnlen (cbuf, count); | ||
| 3674 | # endif | ||
| 3184 | precision -= count; | 3675 | precision -= count; |
| 3185 | } | 3676 | } |
| 3186 | } | 3677 | } |
| @@ -3197,7 +3688,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3197 | mbszero (&state); | 3688 | mbszero (&state); |
| 3198 | # endif | 3689 | # endif |
| 3199 | arg_end = arg; | 3690 | arg_end = arg; |
| 3691 | bytes = 0; | ||
| 3692 | # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR | ||
| 3200 | characters = 0; | 3693 | characters = 0; |
| 3694 | # endif | ||
| 3201 | for (;;) | 3695 | for (;;) |
| 3202 | { | 3696 | { |
| 3203 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | 3697 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ |
| @@ -3211,7 +3705,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3211 | /* Cannot convert. */ | 3705 | /* Cannot convert. */ |
| 3212 | goto fail_with_EILSEQ; | 3706 | goto fail_with_EILSEQ; |
| 3213 | arg_end++; | 3707 | arg_end++; |
| 3214 | characters += count; | 3708 | bytes += count; |
| 3709 | # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR | ||
| 3710 | characters += mbsnlen (cbuf, count); | ||
| 3711 | # endif | ||
| 3215 | } | 3712 | } |
| 3216 | } | 3713 | } |
| 3217 | # if DCHAR_IS_TCHAR | 3714 | # if DCHAR_IS_TCHAR |
| @@ -3219,56 +3716,64 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3219 | { | 3716 | { |
| 3220 | /* Use the entire string. */ | 3717 | /* Use the entire string. */ |
| 3221 | arg_end = arg + local_wcslen (arg); | 3718 | arg_end = arg + local_wcslen (arg); |
| 3222 | /* The number of bytes doesn't matter. */ | 3719 | /* The number of bytes and characters doesn't matter, |
| 3720 | because !has_width and therefore width==0. */ | ||
| 3721 | bytes = 0; | ||
| 3722 | # if ENABLE_UNISTDIO | ||
| 3223 | characters = 0; | 3723 | characters = 0; |
| 3724 | # endif | ||
| 3224 | } | 3725 | } |
| 3225 | # endif | 3726 | # endif |
| 3226 | 3727 | ||
| 3227 | # if !DCHAR_IS_TCHAR | 3728 | # if !DCHAR_IS_TCHAR |
| 3228 | /* Convert the string into a piece of temporary memory. */ | ||
| 3229 | tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T)); | ||
| 3230 | if (tmpsrc == NULL) | ||
| 3231 | goto out_of_memory; | ||
| 3232 | { | 3729 | { |
| 3233 | TCHAR_T *tmpptr = tmpsrc; | 3730 | TCHAR_T *tmpsrc; |
| 3234 | size_t remaining; | 3731 | |
| 3732 | /* Convert the string into a piece of temporary memory. */ | ||
| 3733 | tmpsrc = (TCHAR_T *) malloc (bytes * sizeof (TCHAR_T)); | ||
| 3734 | if (tmpsrc == NULL) | ||
| 3735 | goto out_of_memory; | ||
| 3736 | { | ||
| 3737 | TCHAR_T *tmpptr = tmpsrc; | ||
| 3738 | size_t remaining; | ||
| 3235 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3739 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 3236 | mbstate_t state; | 3740 | mbstate_t state; |
| 3237 | mbszero (&state); | 3741 | mbszero (&state); |
| 3238 | # endif | 3742 | # endif |
| 3239 | for (remaining = characters; remaining > 0; ) | 3743 | for (remaining = bytes; remaining > 0; ) |
| 3240 | { | 3744 | { |
| 3241 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | 3745 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ |
| 3242 | int count; | 3746 | int count; |
| 3243 | 3747 | ||
| 3244 | if (*arg == 0) | 3748 | if (*arg == 0) |
| 3245 | abort (); | 3749 | abort (); |
| 3246 | count = local_wcrtomb (cbuf, *arg, &state); | 3750 | count = local_wcrtomb (cbuf, *arg, &state); |
| 3247 | if (count <= 0) | 3751 | if (count <= 0) |
| 3248 | /* Inconsistency. */ | 3752 | /* Inconsistency. */ |
| 3249 | abort (); | 3753 | abort (); |
| 3250 | memcpy (tmpptr, cbuf, count); | 3754 | memcpy (tmpptr, cbuf, count); |
| 3251 | tmpptr += count; | 3755 | tmpptr += count; |
| 3252 | arg++; | 3756 | arg++; |
| 3253 | remaining -= count; | 3757 | remaining -= count; |
| 3758 | } | ||
| 3759 | if (!(arg == arg_end)) | ||
| 3760 | abort (); | ||
| 3761 | } | ||
| 3762 | |||
| 3763 | /* Convert from TCHAR_T[] to DCHAR_T[]. */ | ||
| 3764 | tmpdst = | ||
| 3765 | DCHAR_CONV_FROM_ENCODING (locale_charset (), | ||
| 3766 | iconveh_question_mark, | ||
| 3767 | tmpsrc, bytes, | ||
| 3768 | NULL, | ||
| 3769 | NULL, &tmpdst_len); | ||
| 3770 | if (tmpdst == NULL) | ||
| 3771 | { | ||
| 3772 | free (tmpsrc); | ||
| 3773 | goto fail_with_errno; | ||
| 3254 | } | 3774 | } |
| 3255 | if (!(arg == arg_end)) | 3775 | free (tmpsrc); |
| 3256 | abort (); | ||
| 3257 | } | 3776 | } |
| 3258 | |||
| 3259 | /* Convert from TCHAR_T[] to DCHAR_T[]. */ | ||
| 3260 | tmpdst = | ||
| 3261 | DCHAR_CONV_FROM_ENCODING (locale_charset (), | ||
| 3262 | iconveh_question_mark, | ||
| 3263 | tmpsrc, characters, | ||
| 3264 | NULL, | ||
| 3265 | NULL, &tmpdst_len); | ||
| 3266 | if (tmpdst == NULL) | ||
| 3267 | { | ||
| 3268 | free (tmpsrc); | ||
| 3269 | goto fail_with_errno; | ||
| 3270 | } | ||
| 3271 | free (tmpsrc); | ||
| 3272 | # endif | 3777 | # endif |
| 3273 | 3778 | ||
| 3274 | if (has_width) | 3779 | if (has_width) |
| @@ -3277,11 +3782,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3277 | /* Outside POSIX, it's preferable to compare the width | 3782 | /* Outside POSIX, it's preferable to compare the width |
| 3278 | against the number of _characters_ of the converted | 3783 | against the number of _characters_ of the converted |
| 3279 | value. */ | 3784 | value. */ |
| 3280 | w = DCHAR_MBSNLEN (result + length, characters); | 3785 | # if DCHAR_IS_TCHAR |
| 3786 | w = characters; | ||
| 3787 | # else | ||
| 3788 | w = DCHAR_MBSNLEN (tmpdst, tmpdst_len); | ||
| 3789 | # endif | ||
| 3281 | # else | 3790 | # else |
| 3282 | /* The width is compared against the number of _bytes_ | 3791 | /* The width is compared against the number of _bytes_ |
| 3283 | of the converted value, says POSIX. */ | 3792 | of the converted value, says POSIX. */ |
| 3284 | w = characters; | 3793 | w = bytes; |
| 3285 | # endif | 3794 | # endif |
| 3286 | } | 3795 | } |
| 3287 | else | 3796 | else |
| @@ -3291,7 +3800,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3291 | if (w < width && !(flags & FLAG_LEFT)) | 3800 | if (w < width && !(flags & FLAG_LEFT)) |
| 3292 | { | 3801 | { |
| 3293 | size_t n = width - w; | 3802 | size_t n = width - w; |
| 3803 | # if DCHAR_IS_TCHAR | ||
| 3294 | ENSURE_ALLOCATION (xsum (length, n)); | 3804 | ENSURE_ALLOCATION (xsum (length, n)); |
| 3805 | # else | ||
| 3806 | ENSURE_ALLOCATION_ELSE (xsum (length, n), | ||
| 3807 | { free (tmpdst); goto out_of_memory; }); | ||
| 3808 | # endif | ||
| 3295 | DCHAR_SET (result + length, ' ', n); | 3809 | DCHAR_SET (result + length, ' ', n); |
| 3296 | length += n; | 3810 | length += n; |
| 3297 | } | 3811 | } |
| @@ -3305,8 +3819,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3305 | mbstate_t state; | 3819 | mbstate_t state; |
| 3306 | mbszero (&state); | 3820 | mbszero (&state); |
| 3307 | # endif | 3821 | # endif |
| 3308 | ENSURE_ALLOCATION (xsum (length, characters)); | 3822 | ENSURE_ALLOCATION (xsum (length, bytes)); |
| 3309 | for (remaining = characters; remaining > 0; ) | 3823 | for (remaining = bytes; remaining > 0; ) |
| 3310 | { | 3824 | { |
| 3311 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | 3825 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ |
| 3312 | int count; | 3826 | int count; |
| @@ -3350,7 +3864,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3350 | } | 3864 | } |
| 3351 | # else | 3865 | # else |
| 3352 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), | 3866 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), |
| 3353 | { free (tmpdst); goto out_of_memory; }); | 3867 | { free (tmpdst); goto out_of_memory; }); |
| 3354 | DCHAR_CPY (result + length, tmpdst, tmpdst_len); | 3868 | DCHAR_CPY (result + length, tmpdst, tmpdst_len); |
| 3355 | free (tmpdst); | 3869 | free (tmpdst); |
| 3356 | length += tmpdst_len; | 3870 | length += tmpdst_len; |
| @@ -3406,17 +3920,21 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3406 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 3920 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 3407 | while (digitp != dp->width_end); | 3921 | while (digitp != dp->width_end); |
| 3408 | } | 3922 | } |
| 3923 | if (width > (size_t) INT_MAX) | ||
| 3924 | goto overflow; | ||
| 3409 | has_width = 1; | 3925 | has_width = 1; |
| 3410 | } | 3926 | } |
| 3411 | 3927 | ||
| 3412 | /* %lc in vasnprintf. See the specification of fprintf. */ | 3928 | /* %lc in vasnprintf. See the specification of fprintf. */ |
| 3413 | { | 3929 | { |
| 3414 | wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char; | 3930 | wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char; |
| 3931 | size_t bytes; | ||
| 3932 | # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR | ||
| 3415 | size_t characters; | 3933 | size_t characters; |
| 3934 | # endif | ||
| 3416 | # if !DCHAR_IS_TCHAR | 3935 | # if !DCHAR_IS_TCHAR |
| 3417 | /* This code assumes that TCHAR_T is 'char'. */ | 3936 | /* This code assumes that TCHAR_T is 'char'. */ |
| 3418 | static_assert (sizeof (TCHAR_T) == 1); | 3937 | static_assert (sizeof (TCHAR_T) == 1); |
| 3419 | TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64. */ | ||
| 3420 | DCHAR_T *tmpdst; | 3938 | DCHAR_T *tmpdst; |
| 3421 | size_t tmpdst_len; | 3939 | size_t tmpdst_len; |
| 3422 | # endif | 3940 | # endif |
| @@ -3427,7 +3945,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3427 | # endif | 3945 | # endif |
| 3428 | { | 3946 | { |
| 3429 | /* Count the number of bytes. */ | 3947 | /* Count the number of bytes. */ |
| 3430 | characters = 0; | ||
| 3431 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | 3948 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ |
| 3432 | int count; | 3949 | int count; |
| 3433 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3950 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| @@ -3439,43 +3956,54 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3439 | if (count < 0) | 3956 | if (count < 0) |
| 3440 | /* Cannot convert. */ | 3957 | /* Cannot convert. */ |
| 3441 | goto fail_with_EILSEQ; | 3958 | goto fail_with_EILSEQ; |
| 3442 | characters = count; | 3959 | bytes = count; |
| 3960 | # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR | ||
| 3961 | characters = mbsnlen (cbuf, count); | ||
| 3962 | # endif | ||
| 3443 | } | 3963 | } |
| 3444 | # if DCHAR_IS_TCHAR | 3964 | # if DCHAR_IS_TCHAR |
| 3445 | else | 3965 | else |
| 3446 | { | 3966 | { |
| 3447 | /* The number of bytes doesn't matter. */ | 3967 | /* The number of bytes and characters doesn't matter, |
| 3968 | because !has_width and therefore width==0. */ | ||
| 3969 | bytes = 0; | ||
| 3970 | # if ENABLE_UNISTDIO | ||
| 3448 | characters = 0; | 3971 | characters = 0; |
| 3972 | # endif | ||
| 3449 | } | 3973 | } |
| 3450 | # endif | 3974 | # endif |
| 3451 | 3975 | ||
| 3452 | # if !DCHAR_IS_TCHAR | 3976 | # if !DCHAR_IS_TCHAR |
| 3453 | /* Convert the string into a piece of temporary memory. */ | 3977 | { |
| 3454 | if (characters > 0) | 3978 | TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64. */ |
| 3455 | { | 3979 | |
| 3456 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | 3980 | /* Convert the string into a piece of temporary memory. */ |
| 3457 | int count; | 3981 | if (bytes > 0) |
| 3982 | { | ||
| 3983 | char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ | ||
| 3984 | int count; | ||
| 3458 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 3985 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| 3459 | mbstate_t state; | 3986 | mbstate_t state; |
| 3460 | mbszero (&state); | 3987 | mbszero (&state); |
| 3461 | # endif | 3988 | # endif |
| 3462 | 3989 | ||
| 3463 | count = local_wcrtomb (cbuf, arg, &state); | 3990 | count = local_wcrtomb (cbuf, arg, &state); |
| 3464 | if (count <= 0) | 3991 | if (count <= 0) |
| 3465 | /* Inconsistency. */ | 3992 | /* Inconsistency. */ |
| 3466 | abort (); | 3993 | abort (); |
| 3467 | memcpy (tmpsrc, cbuf, count); | 3994 | memcpy (tmpsrc, cbuf, count); |
| 3468 | } | 3995 | } |
| 3469 | 3996 | ||
| 3470 | /* Convert from TCHAR_T[] to DCHAR_T[]. */ | 3997 | /* Convert from TCHAR_T[] to DCHAR_T[]. */ |
| 3471 | tmpdst = | 3998 | tmpdst = |
| 3472 | DCHAR_CONV_FROM_ENCODING (locale_charset (), | 3999 | DCHAR_CONV_FROM_ENCODING (locale_charset (), |
| 3473 | iconveh_question_mark, | 4000 | iconveh_question_mark, |
| 3474 | tmpsrc, characters, | 4001 | tmpsrc, bytes, |
| 3475 | NULL, | 4002 | NULL, |
| 3476 | NULL, &tmpdst_len); | 4003 | NULL, &tmpdst_len); |
| 3477 | if (tmpdst == NULL) | 4004 | if (tmpdst == NULL) |
| 3478 | goto fail_with_errno; | 4005 | goto fail_with_errno; |
| 4006 | } | ||
| 3479 | # endif | 4007 | # endif |
| 3480 | 4008 | ||
| 3481 | if (has_width) | 4009 | if (has_width) |
| @@ -3484,11 +4012,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3484 | /* Outside POSIX, it's preferable to compare the width | 4012 | /* Outside POSIX, it's preferable to compare the width |
| 3485 | against the number of _characters_ of the converted | 4013 | against the number of _characters_ of the converted |
| 3486 | value. */ | 4014 | value. */ |
| 3487 | w = DCHAR_MBSNLEN (result + length, characters); | 4015 | # if DCHAR_IS_TCHAR |
| 4016 | w = characters; | ||
| 4017 | # else | ||
| 4018 | w = DCHAR_MBSNLEN (tmpdst, tmpdst_len); | ||
| 4019 | # endif | ||
| 3488 | # else | 4020 | # else |
| 3489 | /* The width is compared against the number of _bytes_ | 4021 | /* The width is compared against the number of _bytes_ |
| 3490 | of the converted value, says POSIX. */ | 4022 | of the converted value, says POSIX. */ |
| 3491 | w = characters; | 4023 | w = bytes; |
| 3492 | # endif | 4024 | # endif |
| 3493 | } | 4025 | } |
| 3494 | else | 4026 | else |
| @@ -3498,7 +4030,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3498 | if (w < width && !(flags & FLAG_LEFT)) | 4030 | if (w < width && !(flags & FLAG_LEFT)) |
| 3499 | { | 4031 | { |
| 3500 | size_t n = width - w; | 4032 | size_t n = width - w; |
| 4033 | # if DCHAR_IS_TCHAR | ||
| 3501 | ENSURE_ALLOCATION (xsum (length, n)); | 4034 | ENSURE_ALLOCATION (xsum (length, n)); |
| 4035 | # else | ||
| 4036 | ENSURE_ALLOCATION_ELSE (xsum (length, n), | ||
| 4037 | { free (tmpdst); goto out_of_memory; }); | ||
| 4038 | # endif | ||
| 3502 | DCHAR_SET (result + length, ' ', n); | 4039 | DCHAR_SET (result + length, ' ', n); |
| 3503 | length += n; | 4040 | length += n; |
| 3504 | } | 4041 | } |
| @@ -3507,8 +4044,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3507 | if (has_width) | 4044 | if (has_width) |
| 3508 | { | 4045 | { |
| 3509 | /* We know the number of bytes in advance. */ | 4046 | /* We know the number of bytes in advance. */ |
| 3510 | ENSURE_ALLOCATION (xsum (length, characters)); | 4047 | ENSURE_ALLOCATION (xsum (length, bytes)); |
| 3511 | if (characters > 0) | 4048 | if (bytes > 0) |
| 3512 | { | 4049 | { |
| 3513 | int count; | 4050 | int count; |
| 3514 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t | 4051 | # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t |
| @@ -3542,7 +4079,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3542 | } | 4079 | } |
| 3543 | # else | 4080 | # else |
| 3544 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), | 4081 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), |
| 3545 | { free (tmpdst); goto out_of_memory; }); | 4082 | { free (tmpdst); goto out_of_memory; }); |
| 3546 | DCHAR_CPY (result + length, tmpdst, tmpdst_len); | 4083 | DCHAR_CPY (result + length, tmpdst, tmpdst_len); |
| 3547 | free (tmpdst); | 4084 | free (tmpdst); |
| 3548 | length += tmpdst_len; | 4085 | length += tmpdst_len; |
| @@ -3594,6 +4131,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3594 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 4131 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 3595 | while (digitp != dp->width_end); | 4132 | while (digitp != dp->width_end); |
| 3596 | } | 4133 | } |
| 4134 | if (width > (size_t) INT_MAX) | ||
| 4135 | goto overflow; | ||
| 3597 | } | 4136 | } |
| 3598 | 4137 | ||
| 3599 | /* %c in vasnwprintf. See the specification of fwprintf. */ | 4138 | /* %c in vasnwprintf. See the specification of fwprintf. */ |
| @@ -3608,24 +4147,26 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3608 | /* Invalid or incomplete multibyte character. */ | 4147 | /* Invalid or incomplete multibyte character. */ |
| 3609 | goto fail_with_EILSEQ; | 4148 | goto fail_with_EILSEQ; |
| 3610 | 4149 | ||
| 3611 | if (1 < width && !(flags & FLAG_LEFT)) | 4150 | { |
| 3612 | { | 4151 | size_t total = (1 < width ? width : 1); |
| 3613 | size_t n = width - 1; | 4152 | ENSURE_ALLOCATION (xsum (length, total)); |
| 3614 | ENSURE_ALLOCATION (xsum (length, n)); | 4153 | |
| 3615 | DCHAR_SET (result + length, ' ', n); | 4154 | if (1 < width && !(flags & FLAG_LEFT)) |
| 3616 | length += n; | 4155 | { |
| 3617 | } | 4156 | size_t n = width - 1; |
| 4157 | DCHAR_SET (result + length, ' ', n); | ||
| 4158 | length += n; | ||
| 4159 | } | ||
| 3618 | 4160 | ||
| 3619 | ENSURE_ALLOCATION (xsum (length, 1)); | 4161 | result[length++] = wc; |
| 3620 | result[length++] = wc; | ||
| 3621 | 4162 | ||
| 3622 | if (1 < width && (flags & FLAG_LEFT)) | 4163 | if (1 < width && (flags & FLAG_LEFT)) |
| 3623 | { | 4164 | { |
| 3624 | size_t n = width - 1; | 4165 | size_t n = width - 1; |
| 3625 | ENSURE_ALLOCATION (xsum (length, n)); | 4166 | DCHAR_SET (result + length, ' ', n); |
| 3626 | DCHAR_SET (result + length, ' ', n); | 4167 | length += n; |
| 3627 | length += n; | 4168 | } |
| 3628 | } | 4169 | } |
| 3629 | } | 4170 | } |
| 3630 | } | 4171 | } |
| 3631 | #endif | 4172 | #endif |
| @@ -3682,6 +4223,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3682 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 4223 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 3683 | while (digitp != dp->width_end); | 4224 | while (digitp != dp->width_end); |
| 3684 | } | 4225 | } |
| 4226 | if (width > (size_t) INT_MAX) | ||
| 4227 | goto overflow; | ||
| 3685 | has_width = 1; | 4228 | has_width = 1; |
| 3686 | } | 4229 | } |
| 3687 | 4230 | ||
| @@ -3933,7 +4476,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3933 | { | 4476 | { |
| 3934 | size_t n = xsum (length, count); | 4477 | size_t n = xsum (length, count); |
| 3935 | 4478 | ||
| 3936 | ENSURE_ALLOCATION (n); | 4479 | ENSURE_ALLOCATION_ELSE (n, |
| 4480 | { if (tmp != tmpbuf) free (tmp); goto out_of_memory; }); | ||
| 3937 | } | 4481 | } |
| 3938 | 4482 | ||
| 3939 | /* Append the result. */ | 4483 | /* Append the result. */ |
| @@ -3996,6 +4540,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 3996 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 4540 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 3997 | while (digitp != dp->width_end); | 4541 | while (digitp != dp->width_end); |
| 3998 | } | 4542 | } |
| 4543 | if (width > (size_t) INT_MAX) | ||
| 4544 | goto overflow; | ||
| 3999 | } | 4545 | } |
| 4000 | 4546 | ||
| 4001 | has_precision = 0; | 4547 | has_precision = 0; |
| @@ -4423,7 +4969,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4423 | { | 4969 | { |
| 4424 | size_t n = xsum (length, count); | 4970 | size_t n = xsum (length, count); |
| 4425 | 4971 | ||
| 4426 | ENSURE_ALLOCATION (n); | 4972 | ENSURE_ALLOCATION_ELSE (n, |
| 4973 | { if (tmp != tmpbuf) free (tmp); goto out_of_memory; }); | ||
| 4427 | } | 4974 | } |
| 4428 | 4975 | ||
| 4429 | /* Append the result. */ | 4976 | /* Append the result. */ |
| @@ -4501,6 +5048,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4501 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 5048 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 4502 | while (digitp != dp->width_end); | 5049 | while (digitp != dp->width_end); |
| 4503 | } | 5050 | } |
| 5051 | if (width > (size_t) INT_MAX) | ||
| 5052 | goto overflow; | ||
| 4504 | } | 5053 | } |
| 4505 | 5054 | ||
| 4506 | has_precision = 0; | 5055 | has_precision = 0; |
| @@ -4587,6 +5136,17 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4587 | } | 5136 | } |
| 4588 | } | 5137 | } |
| 4589 | # endif | 5138 | # endif |
| 5139 | /* Account for thousands separators. */ | ||
| 5140 | if (flags & FLAG_GROUP) | ||
| 5141 | { | ||
| 5142 | /* A thousands separator needs to be inserted at most every 2 digits. | ||
| 5143 | This is the case in the ta_IN locale. */ | ||
| 5144 | # if WIDE_CHAR_VERSION | ||
| 5145 | tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_WCHAR_MAXLEN); | ||
| 5146 | # else | ||
| 5147 | tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_CHAR_MAXLEN); | ||
| 5148 | # endif | ||
| 5149 | } | ||
| 4590 | /* Account for sign, decimal point etc. */ | 5150 | /* Account for sign, decimal point etc. */ |
| 4591 | tmp_length = xsum (tmp_length, 12); | 5151 | tmp_length = xsum (tmp_length, 12); |
| 4592 | 5152 | ||
| @@ -4682,12 +5242,84 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4682 | ndigits = strlen (digits); | 5242 | ndigits = strlen (digits); |
| 4683 | 5243 | ||
| 4684 | if (ndigits > precision) | 5244 | if (ndigits > precision) |
| 4685 | do | 5245 | { |
| 4686 | { | 5246 | /* Number of digits before the decimal point. */ |
| 4687 | --ndigits; | 5247 | size_t intpart_digits = ndigits - precision; |
| 4688 | *p++ = digits[ndigits]; | 5248 | |
| 4689 | } | 5249 | const DCHAR_T *thousep = NULL; |
| 4690 | while (ndigits > precision); | 5250 | DCHAR_T thousep_buf[10]; |
| 5251 | # if !WIDE_CHAR_VERSION | ||
| 5252 | size_t thousep_len = 0; | ||
| 5253 | # endif | ||
| 5254 | const signed char *grouping; | ||
| 5255 | size_t insert = 0; | ||
| 5256 | |||
| 5257 | if ((flags & FLAG_GROUP) && (intpart_digits > 1)) | ||
| 5258 | { | ||
| 5259 | /* Determine the thousands separator and | ||
| 5260 | the grouping rule of the current locale. */ | ||
| 5261 | # if WIDE_CHAR_VERSION | ||
| 5262 | /* DCHAR_T is wchar_t. */ | ||
| 5263 | thousep = thousands_separator_wchar (thousep_buf); | ||
| 5264 | # define thousep_len 1 | ||
| 5265 | # elif defined DCHAR_CONV_FROM_ENCODING | ||
| 5266 | /* DCHAR_T is uintN_t. */ | ||
| 5267 | thousep = thousands_separator_DCHAR (thousep_buf); | ||
| 5268 | thousep_len = DCHAR_STRLEN (thousep); | ||
| 5269 | # else | ||
| 5270 | /* DCHAR_T is char. */ | ||
| 5271 | thousep = thousands_separator_char (thousep_buf); | ||
| 5272 | thousep_len = strlen (thousep); | ||
| 5273 | # endif | ||
| 5274 | if (*thousep == 0) | ||
| 5275 | thousep = NULL; | ||
| 5276 | if (thousep != NULL) | ||
| 5277 | { | ||
| 5278 | grouping = grouping_rule (); | ||
| 5279 | insert = | ||
| 5280 | num_thousands_separators (grouping, intpart_digits); | ||
| 5281 | } | ||
| 5282 | } | ||
| 5283 | |||
| 5284 | const char *digitp = digits + precision; | ||
| 5285 | DCHAR_T *p_before_intpart = p; | ||
| 5286 | p += intpart_digits + insert * thousep_len; | ||
| 5287 | DCHAR_T *p_after_intpart = p; | ||
| 5288 | if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */ | ||
| 5289 | { | ||
| 5290 | const signed char *g = grouping; | ||
| 5291 | for (;;) | ||
| 5292 | { | ||
| 5293 | int h = *g; | ||
| 5294 | if (h <= 0) | ||
| 5295 | abort (); | ||
| 5296 | int i = h; | ||
| 5297 | do | ||
| 5298 | *--p = *digitp++; | ||
| 5299 | while (--i > 0); | ||
| 5300 | # if WIDE_CHAR_VERSION | ||
| 5301 | *--p = thousep[0]; | ||
| 5302 | # else | ||
| 5303 | p -= thousep_len; | ||
| 5304 | DCHAR_CPY (p, thousep, thousep_len); | ||
| 5305 | # endif | ||
| 5306 | insert--; | ||
| 5307 | if (insert == 0) | ||
| 5308 | break; | ||
| 5309 | if (g[1] != 0) | ||
| 5310 | g++; | ||
| 5311 | } | ||
| 5312 | } | ||
| 5313 | for (;;) | ||
| 5314 | { | ||
| 5315 | *--p = *digitp++; | ||
| 5316 | if (p == p_before_intpart) | ||
| 5317 | break; | ||
| 5318 | } | ||
| 5319 | p = p_after_intpart; | ||
| 5320 | ndigits = precision; | ||
| 5321 | # undef thousep_len | ||
| 5322 | } | ||
| 4691 | else | 5323 | else |
| 4692 | *p++ = '0'; | 5324 | *p++ = '0'; |
| 4693 | /* Here ndigits <= precision. */ | 5325 | /* Here ndigits <= precision. */ |
| @@ -4940,10 +5572,84 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 4940 | digits without trailing zeroes. */ | 5572 | digits without trailing zeroes. */ |
| 4941 | if (exponent >= 0) | 5573 | if (exponent >= 0) |
| 4942 | { | 5574 | { |
| 4943 | size_t ecount = exponent + 1; | 5575 | /* Number of digits before the decimal point. */ |
| 4944 | /* Note: count <= precision = ndigits. */ | 5576 | size_t intpart_digits = exponent + 1; |
| 4945 | for (; ecount > 0; ecount--) | 5577 | /* Note: intpart_digits <= precision = ndigits. */ |
| 4946 | *p++ = digits[--ndigits]; | 5578 | |
| 5579 | const DCHAR_T *thousep = NULL; | ||
| 5580 | DCHAR_T thousep_buf[10]; | ||
| 5581 | # if !WIDE_CHAR_VERSION | ||
| 5582 | size_t thousep_len = 0; | ||
| 5583 | # endif | ||
| 5584 | const signed char *grouping; | ||
| 5585 | size_t insert = 0; | ||
| 5586 | |||
| 5587 | if ((flags & FLAG_GROUP) && (intpart_digits > 1)) | ||
| 5588 | { | ||
| 5589 | /* Determine the thousands separator and | ||
| 5590 | the grouping rule of the current locale. */ | ||
| 5591 | # if WIDE_CHAR_VERSION | ||
| 5592 | /* DCHAR_T is wchar_t. */ | ||
| 5593 | thousep = thousands_separator_wchar (thousep_buf); | ||
| 5594 | # define thousep_len 1 | ||
| 5595 | # elif defined DCHAR_CONV_FROM_ENCODING | ||
| 5596 | /* DCHAR_T is uintN_t. */ | ||
| 5597 | thousep = thousands_separator_DCHAR (thousep_buf); | ||
| 5598 | thousep_len = DCHAR_STRLEN (thousep); | ||
| 5599 | # else | ||
| 5600 | /* DCHAR_T is char. */ | ||
| 5601 | thousep = thousands_separator_char (thousep_buf); | ||
| 5602 | thousep_len = strlen (thousep); | ||
| 5603 | # endif | ||
| 5604 | if (*thousep == 0) | ||
| 5605 | thousep = NULL; | ||
| 5606 | if (thousep != NULL) | ||
| 5607 | { | ||
| 5608 | grouping = grouping_rule (); | ||
| 5609 | insert = | ||
| 5610 | num_thousands_separators (grouping, intpart_digits); | ||
| 5611 | } | ||
| 5612 | } | ||
| 5613 | |||
| 5614 | const char *digitp = digits + ndigits - intpart_digits; | ||
| 5615 | DCHAR_T *p_before_intpart = p; | ||
| 5616 | p += intpart_digits + insert * thousep_len; | ||
| 5617 | DCHAR_T *p_after_intpart = p; | ||
| 5618 | if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */ | ||
| 5619 | { | ||
| 5620 | const signed char *g = grouping; | ||
| 5621 | for (;;) | ||
| 5622 | { | ||
| 5623 | int h = *g; | ||
| 5624 | if (h <= 0) | ||
| 5625 | abort (); | ||
| 5626 | int i = h; | ||
| 5627 | do | ||
| 5628 | *--p = *digitp++; | ||
| 5629 | while (--i > 0); | ||
| 5630 | # if WIDE_CHAR_VERSION | ||
| 5631 | *--p = thousep[0]; | ||
| 5632 | # else | ||
| 5633 | p -= thousep_len; | ||
| 5634 | DCHAR_CPY (p, thousep, thousep_len); | ||
| 5635 | # endif | ||
| 5636 | insert--; | ||
| 5637 | if (insert == 0) | ||
| 5638 | break; | ||
| 5639 | if (g[1] != 0) | ||
| 5640 | g++; | ||
| 5641 | } | ||
| 5642 | } | ||
| 5643 | for (;;) | ||
| 5644 | { | ||
| 5645 | *--p = *digitp++; | ||
| 5646 | if (p == p_before_intpart) | ||
| 5647 | break; | ||
| 5648 | } | ||
| 5649 | p = p_after_intpart; | ||
| 5650 | ndigits -= intpart_digits; | ||
| 5651 | # undef thousep_len | ||
| 5652 | |||
| 4947 | if ((flags & FLAG_ALT) || ndigits > nzeroes) | 5653 | if ((flags & FLAG_ALT) || ndigits > nzeroes) |
| 4948 | { | 5654 | { |
| 4949 | *p++ = decimal_point_char (); | 5655 | *p++ = decimal_point_char (); |
| @@ -5144,12 +5850,84 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5144 | ndigits = strlen (digits); | 5850 | ndigits = strlen (digits); |
| 5145 | 5851 | ||
| 5146 | if (ndigits > precision) | 5852 | if (ndigits > precision) |
| 5147 | do | 5853 | { |
| 5148 | { | 5854 | /* Number of digits before the decimal point. */ |
| 5149 | --ndigits; | 5855 | size_t intpart_digits = ndigits - precision; |
| 5150 | *p++ = digits[ndigits]; | 5856 | |
| 5151 | } | 5857 | const DCHAR_T *thousep = NULL; |
| 5152 | while (ndigits > precision); | 5858 | DCHAR_T thousep_buf[10]; |
| 5859 | # if !WIDE_CHAR_VERSION | ||
| 5860 | size_t thousep_len = 0; | ||
| 5861 | # endif | ||
| 5862 | const signed char *grouping; | ||
| 5863 | size_t insert = 0; | ||
| 5864 | |||
| 5865 | if ((flags & FLAG_GROUP) && (intpart_digits > 1)) | ||
| 5866 | { | ||
| 5867 | /* Determine the thousands separator and | ||
| 5868 | the grouping rule of the current locale. */ | ||
| 5869 | # if WIDE_CHAR_VERSION | ||
| 5870 | /* DCHAR_T is wchar_t. */ | ||
| 5871 | thousep = thousands_separator_wchar (thousep_buf); | ||
| 5872 | # define thousep_len 1 | ||
| 5873 | # elif defined DCHAR_CONV_FROM_ENCODING | ||
| 5874 | /* DCHAR_T is uintN_t. */ | ||
| 5875 | thousep = thousands_separator_DCHAR (thousep_buf); | ||
| 5876 | thousep_len = DCHAR_STRLEN (thousep); | ||
| 5877 | # else | ||
| 5878 | /* DCHAR_T is char. */ | ||
| 5879 | thousep = thousands_separator_char (thousep_buf); | ||
| 5880 | thousep_len = strlen (thousep); | ||
| 5881 | # endif | ||
| 5882 | if (*thousep == 0) | ||
| 5883 | thousep = NULL; | ||
| 5884 | if (thousep != NULL) | ||
| 5885 | { | ||
| 5886 | grouping = grouping_rule (); | ||
| 5887 | insert = | ||
| 5888 | num_thousands_separators (grouping, intpart_digits); | ||
| 5889 | } | ||
| 5890 | } | ||
| 5891 | |||
| 5892 | const char *digitp = digits + precision; | ||
| 5893 | DCHAR_T *p_before_intpart = p; | ||
| 5894 | p += intpart_digits + insert * thousep_len; | ||
| 5895 | DCHAR_T *p_after_intpart = p; | ||
| 5896 | if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */ | ||
| 5897 | { | ||
| 5898 | const signed char *g = grouping; | ||
| 5899 | for (;;) | ||
| 5900 | { | ||
| 5901 | int h = *g; | ||
| 5902 | if (h <= 0) | ||
| 5903 | abort (); | ||
| 5904 | int i = h; | ||
| 5905 | do | ||
| 5906 | *--p = *digitp++; | ||
| 5907 | while (--i > 0); | ||
| 5908 | # if WIDE_CHAR_VERSION | ||
| 5909 | *--p = thousep[0]; | ||
| 5910 | # else | ||
| 5911 | p -= thousep_len; | ||
| 5912 | DCHAR_CPY (p, thousep, thousep_len); | ||
| 5913 | # endif | ||
| 5914 | insert--; | ||
| 5915 | if (insert == 0) | ||
| 5916 | break; | ||
| 5917 | if (g[1] != 0) | ||
| 5918 | g++; | ||
| 5919 | } | ||
| 5920 | } | ||
| 5921 | for (;;) | ||
| 5922 | { | ||
| 5923 | *--p = *digitp++; | ||
| 5924 | if (p == p_before_intpart) | ||
| 5925 | break; | ||
| 5926 | } | ||
| 5927 | p = p_after_intpart; | ||
| 5928 | ndigits = precision; | ||
| 5929 | # undef thousep_len | ||
| 5930 | } | ||
| 5153 | else | 5931 | else |
| 5154 | *p++ = '0'; | 5932 | *p++ = '0'; |
| 5155 | /* Here ndigits <= precision. */ | 5933 | /* Here ndigits <= precision. */ |
| @@ -5410,10 +6188,84 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5410 | digits without trailing zeroes. */ | 6188 | digits without trailing zeroes. */ |
| 5411 | if (exponent >= 0) | 6189 | if (exponent >= 0) |
| 5412 | { | 6190 | { |
| 5413 | size_t ecount = exponent + 1; | 6191 | /* Number of digits before the decimal point. */ |
| 5414 | /* Note: ecount <= precision = ndigits. */ | 6192 | size_t intpart_digits = exponent + 1; |
| 5415 | for (; ecount > 0; ecount--) | 6193 | /* Note: intpart_digits <= precision = ndigits. */ |
| 5416 | *p++ = digits[--ndigits]; | 6194 | |
| 6195 | const DCHAR_T *thousep = NULL; | ||
| 6196 | DCHAR_T thousep_buf[10]; | ||
| 6197 | # if !WIDE_CHAR_VERSION | ||
| 6198 | size_t thousep_len = 0; | ||
| 6199 | # endif | ||
| 6200 | const signed char *grouping; | ||
| 6201 | size_t insert = 0; | ||
| 6202 | |||
| 6203 | if ((flags & FLAG_GROUP) && (intpart_digits > 1)) | ||
| 6204 | { | ||
| 6205 | /* Determine the thousands separator and | ||
| 6206 | the grouping rule of the current locale. */ | ||
| 6207 | # if WIDE_CHAR_VERSION | ||
| 6208 | /* DCHAR_T is wchar_t. */ | ||
| 6209 | thousep = thousands_separator_wchar (thousep_buf); | ||
| 6210 | # define thousep_len 1 | ||
| 6211 | # elif defined DCHAR_CONV_FROM_ENCODING | ||
| 6212 | /* DCHAR_T is uintN_t. */ | ||
| 6213 | thousep = thousands_separator_DCHAR (thousep_buf); | ||
| 6214 | thousep_len = DCHAR_STRLEN (thousep); | ||
| 6215 | # else | ||
| 6216 | /* DCHAR_T is char. */ | ||
| 6217 | thousep = thousands_separator_char (thousep_buf); | ||
| 6218 | thousep_len = strlen (thousep); | ||
| 6219 | # endif | ||
| 6220 | if (*thousep == 0) | ||
| 6221 | thousep = NULL; | ||
| 6222 | if (thousep != NULL) | ||
| 6223 | { | ||
| 6224 | grouping = grouping_rule (); | ||
| 6225 | insert = | ||
| 6226 | num_thousands_separators (grouping, intpart_digits); | ||
| 6227 | } | ||
| 6228 | } | ||
| 6229 | |||
| 6230 | const char *digitp = digits + ndigits - intpart_digits; | ||
| 6231 | DCHAR_T *p_before_intpart = p; | ||
| 6232 | p += intpart_digits + insert * thousep_len; | ||
| 6233 | DCHAR_T *p_after_intpart = p; | ||
| 6234 | if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */ | ||
| 6235 | { | ||
| 6236 | const signed char *g = grouping; | ||
| 6237 | for (;;) | ||
| 6238 | { | ||
| 6239 | int h = *g; | ||
| 6240 | if (h <= 0) | ||
| 6241 | abort (); | ||
| 6242 | int i = h; | ||
| 6243 | do | ||
| 6244 | *--p = *digitp++; | ||
| 6245 | while (--i > 0); | ||
| 6246 | # if WIDE_CHAR_VERSION | ||
| 6247 | *--p = thousep[0]; | ||
| 6248 | # else | ||
| 6249 | p -= thousep_len; | ||
| 6250 | DCHAR_CPY (p, thousep, thousep_len); | ||
| 6251 | # endif | ||
| 6252 | insert--; | ||
| 6253 | if (insert == 0) | ||
| 6254 | break; | ||
| 6255 | if (g[1] != 0) | ||
| 6256 | g++; | ||
| 6257 | } | ||
| 6258 | } | ||
| 6259 | for (;;) | ||
| 6260 | { | ||
| 6261 | *--p = *digitp++; | ||
| 6262 | if (p == p_before_intpart) | ||
| 6263 | break; | ||
| 6264 | } | ||
| 6265 | p = p_after_intpart; | ||
| 6266 | ndigits -= intpart_digits; | ||
| 6267 | # undef thousep_len | ||
| 6268 | |||
| 5417 | if ((flags & FLAG_ALT) || ndigits > nzeroes) | 6269 | if ((flags & FLAG_ALT) || ndigits > nzeroes) |
| 5418 | { | 6270 | { |
| 5419 | *p++ = decimal_point_char (); | 6271 | *p++ = decimal_point_char (); |
| @@ -5606,7 +6458,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5606 | { | 6458 | { |
| 5607 | size_t n = xsum (length, count); | 6459 | size_t n = xsum (length, count); |
| 5608 | 6460 | ||
| 5609 | ENSURE_ALLOCATION (n); | 6461 | ENSURE_ALLOCATION_ELSE (n, |
| 6462 | { if (tmp != tmpbuf) free (tmp); goto out_of_memory; }); | ||
| 5610 | } | 6463 | } |
| 5611 | 6464 | ||
| 5612 | /* Append the result. */ | 6465 | /* Append the result. */ |
| @@ -5620,13 +6473,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5620 | { | 6473 | { |
| 5621 | arg_type type = a.arg[dp->arg_index].type; | 6474 | arg_type type = a.arg[dp->arg_index].type; |
| 5622 | int flags = dp->flags; | 6475 | int flags = dp->flags; |
| 5623 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 6476 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT |
| 5624 | int has_width; | 6477 | int has_width; |
| 5625 | #endif | 6478 | #endif |
| 5626 | #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 6479 | #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT |
| 5627 | size_t width; | 6480 | size_t width; |
| 5628 | #endif | 6481 | #endif |
| 5629 | #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 6482 | #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT |
| 5630 | int has_precision; | 6483 | int has_precision; |
| 5631 | size_t precision; | 6484 | size_t precision; |
| 5632 | #endif | 6485 | #endif |
| @@ -5635,9 +6488,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5635 | #else | 6488 | #else |
| 5636 | # define prec_ourselves 0 | 6489 | # define prec_ourselves 0 |
| 5637 | #endif | 6490 | #endif |
| 6491 | #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT | ||
| 6492 | int group_ourselves; | ||
| 6493 | #else | ||
| 6494 | # define group_ourselves 0 | ||
| 6495 | #endif | ||
| 5638 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST | 6496 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST |
| 5639 | # define pad_ourselves 1 | 6497 | # define pad_ourselves 1 |
| 5640 | #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 6498 | #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT |
| 5641 | int pad_ourselves; | 6499 | int pad_ourselves; |
| 5642 | #else | 6500 | #else |
| 5643 | # define pad_ourselves 0 | 6501 | # define pad_ourselves 0 |
| @@ -5652,10 +6510,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5652 | TCHAR_T *tmp; | 6510 | TCHAR_T *tmp; |
| 5653 | #endif | 6511 | #endif |
| 5654 | 6512 | ||
| 5655 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 6513 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT |
| 5656 | has_width = 0; | 6514 | has_width = 0; |
| 5657 | #endif | 6515 | #endif |
| 5658 | #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 6516 | #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT |
| 5659 | width = 0; | 6517 | width = 0; |
| 5660 | if (dp->width_start != dp->width_end) | 6518 | if (dp->width_start != dp->width_end) |
| 5661 | { | 6519 | { |
| @@ -5683,13 +6541,16 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5683 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | 6541 | width = xsum (xtimes (width, 10), *digitp++ - '0'); |
| 5684 | while (digitp != dp->width_end); | 6542 | while (digitp != dp->width_end); |
| 5685 | } | 6543 | } |
| 5686 | # if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 6544 | if (width > (size_t) INT_MAX) |
| 6545 | goto overflow; | ||
| 6546 | # define WIDTH_IS_CHECKED 1 | ||
| 6547 | # if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT | ||
| 5687 | has_width = 1; | 6548 | has_width = 1; |
| 5688 | # endif | 6549 | # endif |
| 5689 | } | 6550 | } |
| 5690 | #endif | 6551 | #endif |
| 5691 | 6552 | ||
| 5692 | #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 6553 | #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT |
| 5693 | has_precision = 0; | 6554 | has_precision = 0; |
| 5694 | precision = 6; | 6555 | precision = 6; |
| 5695 | if (dp->precision_start != dp->precision_end) | 6556 | if (dp->precision_start != dp->precision_end) |
| @@ -5754,8 +6615,37 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5754 | } | 6615 | } |
| 5755 | #endif | 6616 | #endif |
| 5756 | 6617 | ||
| 6618 | /* Decide whether to add the thousands separators ourselves. */ | ||
| 6619 | #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT | ||
| 6620 | if (flags & FLAG_GROUP) | ||
| 6621 | { | ||
| 6622 | switch (dp->conversion) | ||
| 6623 | { | ||
| 6624 | case 'd': case 'i': case 'u': | ||
| 6625 | # if NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT | ||
| 6626 | group_ourselves = 1; | ||
| 6627 | # else | ||
| 6628 | group_ourselves = prec_ourselves; | ||
| 6629 | # endif | ||
| 6630 | break; | ||
| 6631 | case 'f': case 'F': case 'g': case 'G': | ||
| 6632 | # if NEED_PRINTF_FLAG_GROUPING | ||
| 6633 | group_ourselves = 1; | ||
| 6634 | # else | ||
| 6635 | group_ourselves = prec_ourselves; | ||
| 6636 | # endif | ||
| 6637 | break; | ||
| 6638 | default: | ||
| 6639 | group_ourselves = 0; | ||
| 6640 | break; | ||
| 6641 | } | ||
| 6642 | } | ||
| 6643 | else | ||
| 6644 | group_ourselves = 0; | ||
| 6645 | #endif | ||
| 6646 | |||
| 5757 | /* Decide whether to perform the padding ourselves. */ | 6647 | /* Decide whether to perform the padding ourselves. */ |
| 5758 | #if !((WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST) && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION) | 6648 | #if !((WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST) && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT) |
| 5759 | switch (dp->conversion) | 6649 | switch (dp->conversion) |
| 5760 | { | 6650 | { |
| 5761 | # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO | 6651 | # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO |
| @@ -5772,7 +6662,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5772 | pad_ourselves = 1; | 6662 | pad_ourselves = 1; |
| 5773 | break; | 6663 | break; |
| 5774 | default: | 6664 | default: |
| 5775 | pad_ourselves = prec_ourselves; | 6665 | pad_ourselves = prec_ourselves | group_ourselves; |
| 5776 | break; | 6666 | break; |
| 5777 | } | 6667 | } |
| 5778 | #endif | 6668 | #endif |
| @@ -5805,14 +6695,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5805 | sprintf. */ | 6695 | sprintf. */ |
| 5806 | fbp = buf; | 6696 | fbp = buf; |
| 5807 | *fbp++ = '%'; | 6697 | *fbp++ = '%'; |
| 5808 | #if NEED_PRINTF_FLAG_GROUPING | 6698 | if ((flags & FLAG_GROUP) && !group_ourselves) |
| 5809 | /* The underlying implementation doesn't support the ' flag. | ||
| 5810 | Produce no grouping characters in this case; this is | ||
| 5811 | acceptable because the grouping is locale dependent. */ | ||
| 5812 | #else | ||
| 5813 | if (flags & FLAG_GROUP) | ||
| 5814 | *fbp++ = '\''; | 6699 | *fbp++ = '\''; |
| 5815 | #endif | ||
| 5816 | if (flags & FLAG_LEFT) | 6700 | if (flags & FLAG_LEFT) |
| 5817 | *fbp++ = '-'; | 6701 | *fbp++ = '-'; |
| 5818 | if (flags & FLAG_SHOWSIGN) | 6702 | if (flags & FLAG_SHOWSIGN) |
| @@ -5832,6 +6716,43 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5832 | if (dp->width_start != dp->width_end) | 6716 | if (dp->width_start != dp->width_end) |
| 5833 | { | 6717 | { |
| 5834 | size_t n = dp->width_end - dp->width_start; | 6718 | size_t n = dp->width_end - dp->width_start; |
| 6719 | #if !WIDTH_IS_CHECKED | ||
| 6720 | size_t width; | ||
| 6721 | /* Reject an out-of-range width. | ||
| 6722 | The underlying SNPRINTF already does this on some | ||
| 6723 | platforms (glibc, musl, macOS, FreeBSD, NetBSD, | ||
| 6724 | OpenBSD, Cygwin, Solaris, MSVC). However, on others | ||
| 6725 | (AIX, mingw), it doesn't; thus this vasnprintf | ||
| 6726 | invocation would succeed and produce a wrong result. | ||
| 6727 | So, this is redundant on some platforms, but it's a | ||
| 6728 | quick check anyway. */ | ||
| 6729 | if (dp->width_arg_index != ARG_NONE) | ||
| 6730 | { | ||
| 6731 | int arg; | ||
| 6732 | |||
| 6733 | if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) | ||
| 6734 | abort (); | ||
| 6735 | arg = a.arg[dp->width_arg_index].a.a_int; | ||
| 6736 | width = arg; | ||
| 6737 | if (arg < 0) | ||
| 6738 | { | ||
| 6739 | /* "A negative field width is taken as a '-' flag | ||
| 6740 | followed by a positive field width." */ | ||
| 6741 | width = -width; | ||
| 6742 | } | ||
| 6743 | } | ||
| 6744 | else | ||
| 6745 | { | ||
| 6746 | const FCHAR_T *digitp = dp->width_start; | ||
| 6747 | |||
| 6748 | width = 0; | ||
| 6749 | do | ||
| 6750 | width = xsum (xtimes (width, 10), *digitp++ - '0'); | ||
| 6751 | while (digitp != dp->width_end); | ||
| 6752 | } | ||
| 6753 | if (width > (size_t) INT_MAX) | ||
| 6754 | goto overflow; | ||
| 6755 | #endif | ||
| 5835 | /* The width specification is known to consist only | 6756 | /* The width specification is known to consist only |
| 5836 | of standard ASCII characters. */ | 6757 | of standard ASCII characters. */ |
| 5837 | if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) | 6758 | if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) |
| @@ -5870,7 +6791,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5870 | } | 6791 | } |
| 5871 | } | 6792 | } |
| 5872 | 6793 | ||
| 5873 | switch (type) | 6794 | switch (+type) |
| 5874 | { | 6795 | { |
| 5875 | case TYPE_LONGLONGINT: | 6796 | case TYPE_LONGLONGINT: |
| 5876 | case TYPE_ULONGLONGINT: | 6797 | case TYPE_ULONGLONGINT: |
| @@ -5984,9 +6905,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 5984 | #if HAVE_WINT_T | 6905 | #if HAVE_WINT_T |
| 5985 | case TYPE_WIDE_CHAR: | 6906 | case TYPE_WIDE_CHAR: |
| 5986 | #endif | 6907 | #endif |
| 5987 | #if HAVE_WCHAR_T | ||
| 5988 | case TYPE_WIDE_STRING: | 6908 | case TYPE_WIDE_STRING: |
| 5989 | #endif | ||
| 5990 | *fbp++ = 'l'; | 6909 | *fbp++ = 'l'; |
| 5991 | break; | 6910 | break; |
| 5992 | case TYPE_LONGDOUBLE: | 6911 | case TYPE_LONGDOUBLE: |
| @@ -6168,7 +7087,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 6168 | #endif | 7087 | #endif |
| 6169 | 7088 | ||
| 6170 | errno = 0; | 7089 | errno = 0; |
| 6171 | switch (type) | 7090 | switch (+type) |
| 6172 | { | 7091 | { |
| 6173 | case TYPE_SCHAR: | 7092 | case TYPE_SCHAR: |
| 6174 | { | 7093 | { |
| @@ -6358,14 +7277,12 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 6358 | SNPRINTF_BUF (arg); | 7277 | SNPRINTF_BUF (arg); |
| 6359 | } | 7278 | } |
| 6360 | break; | 7279 | break; |
| 6361 | #if HAVE_WCHAR_T | ||
| 6362 | case TYPE_WIDE_STRING: | 7280 | case TYPE_WIDE_STRING: |
| 6363 | { | 7281 | { |
| 6364 | const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; | 7282 | const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; |
| 6365 | SNPRINTF_BUF (arg); | 7283 | SNPRINTF_BUF (arg); |
| 6366 | } | 7284 | } |
| 6367 | break; | 7285 | break; |
| 6368 | #endif | ||
| 6369 | case TYPE_POINTER: | 7286 | case TYPE_POINTER: |
| 6370 | { | 7287 | { |
| 6371 | void *arg = a.arg[dp->arg_index].a.a_pointer; | 7288 | void *arg = a.arg[dp->arg_index].a.a_pointer; |
| @@ -6539,10 +7456,13 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 6539 | || *prec_ptr == ' ')) | 7456 | || *prec_ptr == ' ')) |
| 6540 | prefix_count = 1; | 7457 | prefix_count = 1; |
| 6541 | /* Put the additional zeroes after the 0x prefix if | 7458 | /* Put the additional zeroes after the 0x prefix if |
| 6542 | (flags & FLAG_ALT) || (dp->conversion == 'p'). */ | 7459 | (flags & FLAG_ALT) || (dp->conversion == 'p'), or |
| 7460 | after the 0b prefix if (flags & FLAG_ALT). */ | ||
| 6543 | else if (count >= 2 | 7461 | else if (count >= 2 |
| 6544 | && prec_ptr[0] == '0' | 7462 | && prec_ptr[0] == '0' |
| 6545 | && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X')) | 7463 | && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X' |
| 7464 | || prec_ptr[1] == 'b' | ||
| 7465 | || prec_ptr[1] == 'B')) | ||
| 6546 | prefix_count = 2; | 7466 | prefix_count = 2; |
| 6547 | 7467 | ||
| 6548 | move = count - prefix_count; | 7468 | move = count - prefix_count; |
| @@ -6591,6 +7511,135 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 6591 | } | 7511 | } |
| 6592 | #endif | 7512 | #endif |
| 6593 | 7513 | ||
| 7514 | #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT | ||
| 7515 | if (group_ourselves) /* implies (flags & FLAG_GROUP) */ | ||
| 7516 | /* Handle the grouping. */ | ||
| 7517 | switch (dp->conversion) | ||
| 7518 | { | ||
| 7519 | /* These are the only conversion to which grouping | ||
| 7520 | applies. */ | ||
| 7521 | case 'd': case 'i': case 'u': | ||
| 7522 | case 'f': case 'F': case 'g': case 'G': | ||
| 7523 | { | ||
| 7524 | /* Determine the thousands separator of the current | ||
| 7525 | locale. */ | ||
| 7526 | const TCHAR_T *thousep; | ||
| 7527 | TCHAR_T thousep_buf[10]; | ||
| 7528 | |||
| 7529 | # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR | ||
| 7530 | /* TCHAR_T is wchar_t. */ | ||
| 7531 | thousep = thousands_separator_wchar (thousep_buf); | ||
| 7532 | # else | ||
| 7533 | /* TCHAR_T is char. */ | ||
| 7534 | thousep = thousands_separator_char (thousep_buf); | ||
| 7535 | # endif | ||
| 7536 | |||
| 7537 | /* Nothing to do in locales where thousep is the empty | ||
| 7538 | string. */ | ||
| 7539 | if (*thousep != 0) | ||
| 7540 | { | ||
| 7541 | /* Since FLAG_LOCALIZED is only supported on glibc | ||
| 7542 | systems, here we can assume that all digits are | ||
| 7543 | the ASCII digits '0'..'9'. */ | ||
| 7544 | TCHAR_T *number_ptr = | ||
| 7545 | # if USE_SNPRINTF | ||
| 7546 | (TCHAR_T *) (result + length); | ||
| 7547 | # else | ||
| 7548 | tmp; | ||
| 7549 | # endif | ||
| 7550 | TCHAR_T *end_ptr = number_ptr + count; | ||
| 7551 | |||
| 7552 | /* Find where the leading digits start. */ | ||
| 7553 | TCHAR_T *digits_ptr = number_ptr; | ||
| 7554 | if (count >= 1 | ||
| 7555 | && (*digits_ptr == '-' || *digits_ptr == '+' | ||
| 7556 | || *digits_ptr == ' ')) | ||
| 7557 | digits_ptr++; | ||
| 7558 | |||
| 7559 | /* Find where the leading digits end. */ | ||
| 7560 | TCHAR_T *digits_end_ptr; | ||
| 7561 | switch (dp->conversion) | ||
| 7562 | { | ||
| 7563 | case 'd': case 'i': case 'u': | ||
| 7564 | digits_end_ptr = end_ptr; | ||
| 7565 | break; | ||
| 7566 | case 'f': case 'F': case 'g': case 'G': | ||
| 7567 | { | ||
| 7568 | TCHAR_T decimal_point = decimal_point_char (); | ||
| 7569 | for (digits_end_ptr = digits_ptr; | ||
| 7570 | digits_end_ptr < end_ptr; | ||
| 7571 | digits_end_ptr++) | ||
| 7572 | if (*digits_end_ptr == decimal_point | ||
| 7573 | || *digits_end_ptr == 'e') | ||
| 7574 | break; | ||
| 7575 | } | ||
| 7576 | break; | ||
| 7577 | } | ||
| 7578 | |||
| 7579 | /* Determine the number of thousands separators | ||
| 7580 | to insert. */ | ||
| 7581 | const signed char *grouping = grouping_rule (); | ||
| 7582 | size_t insert = | ||
| 7583 | num_thousands_separators (grouping, digits_end_ptr - digits_ptr); | ||
| 7584 | if (insert > 0) | ||
| 7585 | { | ||
| 7586 | # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR | ||
| 7587 | # define thousep_len 1 | ||
| 7588 | # else | ||
| 7589 | size_t thousep_len = strlen (thousep); | ||
| 7590 | # endif | ||
| 7591 | # if USE_SNPRINTF | ||
| 7592 | size_t digits_offset = digits_ptr - number_ptr; | ||
| 7593 | size_t digits_end_offset = digits_end_ptr - number_ptr; | ||
| 7594 | size_t n = | ||
| 7595 | xsum (length, | ||
| 7596 | (count + insert * thousep_len + TCHARS_PER_DCHAR - 1) | ||
| 7597 | / TCHARS_PER_DCHAR); | ||
| 7598 | length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; | ||
| 7599 | ENSURE_ALLOCATION (n); | ||
| 7600 | length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; | ||
| 7601 | number_ptr = (TCHAR_T *) (result + length); | ||
| 7602 | end_ptr = number_ptr + count; | ||
| 7603 | digits_ptr = number_ptr + digits_offset; | ||
| 7604 | digits_end_ptr = number_ptr + digits_end_offset; | ||
| 7605 | # endif | ||
| 7606 | |||
| 7607 | count += insert * thousep_len; | ||
| 7608 | |||
| 7609 | const TCHAR_T *p = end_ptr; | ||
| 7610 | TCHAR_T *q = end_ptr + insert * thousep_len; | ||
| 7611 | while (p > digits_end_ptr) | ||
| 7612 | *--q = *--p; | ||
| 7613 | const signed char *g = grouping; | ||
| 7614 | for (;;) | ||
| 7615 | { | ||
| 7616 | int h = *g; | ||
| 7617 | if (h <= 0) | ||
| 7618 | abort (); | ||
| 7619 | int i = h; | ||
| 7620 | do | ||
| 7621 | *--q = *--p; | ||
| 7622 | while (--i > 0); | ||
| 7623 | # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR | ||
| 7624 | *--q = *thousep; | ||
| 7625 | # else | ||
| 7626 | q -= thousep_len; | ||
| 7627 | memcpy (q, thousep, thousep_len); | ||
| 7628 | # endif | ||
| 7629 | insert--; | ||
| 7630 | if (insert == 0) | ||
| 7631 | break; | ||
| 7632 | if (g[1] != 0) | ||
| 7633 | g++; | ||
| 7634 | } | ||
| 7635 | /* Here q == p. Done with the insertions. */ | ||
| 7636 | } | ||
| 7637 | } | ||
| 7638 | } | ||
| 7639 | break; | ||
| 7640 | } | ||
| 7641 | #endif | ||
| 7642 | |||
| 6594 | #if !USE_SNPRINTF | 7643 | #if !USE_SNPRINTF |
| 6595 | if (count >= tmp_length) | 7644 | if (count >= tmp_length) |
| 6596 | /* tmp_length was incorrectly calculated - fix the | 7645 | /* tmp_length was incorrectly calculated - fix the |
| @@ -6601,6 +7650,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 6601 | #if !DCHAR_IS_TCHAR | 7650 | #if !DCHAR_IS_TCHAR |
| 6602 | /* Convert from TCHAR_T[] to DCHAR_T[]. */ | 7651 | /* Convert from TCHAR_T[] to DCHAR_T[]. */ |
| 6603 | if (dp->conversion == 'c' || dp->conversion == 's' | 7652 | if (dp->conversion == 'c' || dp->conversion == 's' |
| 7653 | || (flags & FLAG_GROUP) | ||
| 6604 | # if __GLIBC__ >= 2 && !defined __UCLIBC__ | 7654 | # if __GLIBC__ >= 2 && !defined __UCLIBC__ |
| 6605 | || (flags & FLAG_LOCALIZED) | 7655 | || (flags & FLAG_LOCALIZED) |
| 6606 | # endif | 7656 | # endif |
| @@ -6677,7 +7727,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 6677 | goto fail_with_errno; | 7727 | goto fail_with_errno; |
| 6678 | # endif | 7728 | # endif |
| 6679 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), | 7729 | ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len), |
| 6680 | { free (tmpdst); goto out_of_memory; }); | 7730 | { free (tmpdst); goto out_of_memory; }); |
| 6681 | DCHAR_CPY (result + length, tmpdst, tmpdst_len); | 7731 | DCHAR_CPY (result + length, tmpdst, tmpdst_len); |
| 6682 | free (tmpdst); | 7732 | free (tmpdst); |
| 6683 | count = tmpdst_len; | 7733 | count = tmpdst_len; |
| @@ -6742,7 +7792,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 6742 | /* Here count <= allocated - length. */ | 7792 | /* Here count <= allocated - length. */ |
| 6743 | 7793 | ||
| 6744 | /* Perform padding. */ | 7794 | /* Perform padding. */ |
| 6745 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION | 7795 | #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT |
| 6746 | if (pad_ourselves && has_width) | 7796 | if (pad_ourselves && has_width) |
| 6747 | { | 7797 | { |
| 6748 | size_t w; | 7798 | size_t w; |
| @@ -6751,6 +7801,23 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 6751 | against the number of _characters_ of the converted | 7801 | against the number of _characters_ of the converted |
| 6752 | value. */ | 7802 | value. */ |
| 6753 | w = DCHAR_MBSNLEN (result + length, count); | 7803 | w = DCHAR_MBSNLEN (result + length, count); |
| 7804 | # elif __GLIBC__ >= 2 | ||
| 7805 | /* glibc prefers to compare the width against the number | ||
| 7806 | of characters as well, but only for numeric conversion | ||
| 7807 | specifiers. See | ||
| 7808 | <https://sourceware.org/bugzilla/show_bug.cgi?id=28943> | ||
| 7809 | <https://sourceware.org/bugzilla/show_bug.cgi?id=30883> | ||
| 7810 | <https://sourceware.org/bugzilla/show_bug.cgi?id=31542> */ | ||
| 7811 | switch (dp->conversion) | ||
| 7812 | { | ||
| 7813 | case 'd': case 'i': case 'u': | ||
| 7814 | case 'f': case 'F': case 'g': case 'G': | ||
| 7815 | w = DCHAR_MBSNLEN (result + length, count); | ||
| 7816 | break; | ||
| 7817 | default: | ||
| 7818 | w = count; | ||
| 7819 | break; | ||
| 7820 | } | ||
| 6754 | # else | 7821 | # else |
| 6755 | /* The width is compared against the number of _bytes_ | 7822 | /* The width is compared against the number of _bytes_ |
| 6756 | of the converted value, says POSIX. */ | 7823 | of the converted value, says POSIX. */ |
| @@ -6929,17 +7996,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, | |||
| 6929 | not have this limitation. */ | 7996 | not have this limitation. */ |
| 6930 | return result; | 7997 | return result; |
| 6931 | 7998 | ||
| 6932 | #if USE_SNPRINTF | ||
| 6933 | overflow: | 7999 | overflow: |
| 6934 | errno = EOVERFLOW; | 8000 | errno = EOVERFLOW; |
| 6935 | goto fail_with_errno; | 8001 | goto fail_with_errno; |
| 6936 | #endif | ||
| 6937 | 8002 | ||
| 6938 | out_of_memory: | 8003 | out_of_memory: |
| 6939 | errno = ENOMEM; | 8004 | errno = ENOMEM; |
| 6940 | goto fail_with_errno; | 8005 | goto fail_with_errno; |
| 6941 | 8006 | ||
| 6942 | #if ENABLE_UNISTDIO || ((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION) || (NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION) | 8007 | #if ENABLE_UNISTDIO || (WIDE_CHAR_VERSION || !USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION) || (NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION) |
| 6943 | fail_with_EILSEQ: | 8008 | fail_with_EILSEQ: |
| 6944 | errno = EILSEQ; | 8009 | errno = EILSEQ; |
| 6945 | goto fail_with_errno; | 8010 | goto fail_with_errno; |
diff --git a/gl/vasnprintf.h b/gl/vasnprintf.h index 7ed9145c..ccd60e5e 100644 --- a/gl/vasnprintf.h +++ b/gl/vasnprintf.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* vsprintf with automatic memory allocation. | 1 | /* vsprintf with automatic memory allocation. |
| 2 | Copyright (C) 2002-2004, 2007-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2004, 2007-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/vasprintf.c b/gl/vasprintf.c index e52aaca5..30aa4469 100644 --- a/gl/vasprintf.c +++ b/gl/vasprintf.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Formatted output to strings. | 1 | /* Formatted output to strings. |
| 2 | Copyright (C) 1999, 2002, 2006-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2002, 2006-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -25,6 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | #include <errno.h> | 26 | #include <errno.h> |
| 27 | #include <limits.h> | 27 | #include <limits.h> |
| 28 | #include <stdint.h> | ||
| 28 | #include <stdlib.h> | 29 | #include <stdlib.h> |
| 29 | 30 | ||
| 30 | #include "vasnprintf.h" | 31 | #include "vasnprintf.h" |
| @@ -37,12 +38,21 @@ vasprintf (char **resultp, const char *format, va_list args) | |||
| 37 | if (result == NULL) | 38 | if (result == NULL) |
| 38 | return -1; | 39 | return -1; |
| 39 | 40 | ||
| 41 | #if PTRDIFF_MAX > INT_MAX | ||
| 40 | if (length > INT_MAX) | 42 | if (length > INT_MAX) |
| 41 | { | 43 | { |
| 42 | free (result); | 44 | free (result); |
| 43 | errno = EOVERFLOW; | 45 | errno = (length > PTRDIFF_MAX ? ENOMEM : EOVERFLOW); |
| 44 | return -1; | 46 | return -1; |
| 45 | } | 47 | } |
| 48 | #else | ||
| 49 | if (length > PTRDIFF_MAX) | ||
| 50 | { | ||
| 51 | free (result); | ||
| 52 | errno = ENOMEM; | ||
| 53 | return -1; | ||
| 54 | } | ||
| 55 | #endif | ||
| 46 | 56 | ||
| 47 | *resultp = result; | 57 | *resultp = result; |
| 48 | /* Return the number of resulting bytes, excluding the trailing NUL. */ | 58 | /* Return the number of resulting bytes, excluding the trailing NUL. */ |
diff --git a/gl/verify.h b/gl/verify.h index 08268c24..3b01d7c2 100644 --- a/gl/verify.h +++ b/gl/verify.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Compile-time assert-like macros. | 1 | /* Compile-time assert-like macros. |
| 2 | 2 | ||
| 3 | Copyright (C) 2005-2006, 2009-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2005-2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -34,11 +34,12 @@ | |||
| 34 | #ifndef __cplusplus | 34 | #ifndef __cplusplus |
| 35 | # if (201112 <= __STDC_VERSION__ \ | 35 | # if (201112 <= __STDC_VERSION__ \ |
| 36 | || (!defined __STRICT_ANSI__ \ | 36 | || (!defined __STRICT_ANSI__ \ |
| 37 | && (4 < __GNUC__ + (6 <= __GNUC_MINOR__) || 5 <= __clang_major__))) | 37 | && ((4 < __GNUC__ + (6 <= __GNUC_MINOR__) && !defined __clang__) \ |
| 38 | || 5 <= __clang_major__))) | ||
| 38 | # define _GL_HAVE__STATIC_ASSERT 1 | 39 | # define _GL_HAVE__STATIC_ASSERT 1 |
| 39 | # endif | 40 | # endif |
| 40 | # if (202311 <= __STDC_VERSION__ \ | 41 | # if (202311 <= __STDC_VERSION__ \ |
| 41 | || (!defined __STRICT_ANSI__ && 9 <= __GNUC__)) | 42 | || (!defined __STRICT_ANSI__ && 9 <= __GNUC__ && !defined __clang__)) |
| 42 | # define _GL_HAVE__STATIC_ASSERT1 1 | 43 | # define _GL_HAVE__STATIC_ASSERT1 1 |
| 43 | # endif | 44 | # endif |
| 44 | #endif | 45 | #endif |
| @@ -156,9 +157,10 @@ | |||
| 156 | #define _GL_CONCAT0(x, y) x##y | 157 | #define _GL_CONCAT0(x, y) x##y |
| 157 | 158 | ||
| 158 | /* _GL_COUNTER is an integer, preferably one that changes each time we | 159 | /* _GL_COUNTER is an integer, preferably one that changes each time we |
| 159 | use it. Use __COUNTER__ if it works, falling back on __LINE__ | 160 | use it. Use __COUNTER__ if it works (it does so with most compilers, |
| 160 | otherwise. __LINE__ isn't perfect, but it's better than a | 161 | see <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3457.htm>), |
| 161 | constant. */ | 162 | falling back on __LINE__ otherwise. __LINE__ isn't perfect, but it's |
| 163 | better than a constant. */ | ||
| 162 | #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ | 164 | #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ |
| 163 | # define _GL_COUNTER __COUNTER__ | 165 | # define _GL_COUNTER __COUNTER__ |
| 164 | #else | 166 | #else |
| @@ -215,7 +217,7 @@ template <int w> | |||
| 215 | # define _GL_VERIFY(R, DIAGNOSTIC, ...) \ | 217 | # define _GL_VERIFY(R, DIAGNOSTIC, ...) \ |
| 216 | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ | 218 | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ |
| 217 | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] | 219 | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] |
| 218 | # if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) | 220 | # if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) && !defined __clang__ |
| 219 | # pragma GCC diagnostic ignored "-Wnested-externs" | 221 | # pragma GCC diagnostic ignored "-Wnested-externs" |
| 220 | # endif | 222 | # endif |
| 221 | #endif | 223 | #endif |
| @@ -254,16 +256,32 @@ template <int w> | |||
| 254 | # endif | 256 | # endif |
| 255 | # endif | 257 | # endif |
| 256 | /* Define static_assert if needed. */ | 258 | /* Define static_assert if needed. */ |
| 259 | # if defined __cplusplus && defined __clang__ && __clang_major__ < 9 | ||
| 260 | /* clang++ before commit 5c739665a8721228cf6143fd4ef95870a59f55ae had a | ||
| 261 | two-arguments static_assert but not the one-argument static_assert. */ | ||
| 262 | # undef static_assert | ||
| 263 | # endif | ||
| 257 | # if (!defined static_assert \ | 264 | # if (!defined static_assert \ |
| 258 | && __STDC_VERSION__ < 202311 \ | 265 | && __STDC_VERSION__ < 202311 \ |
| 259 | && (!defined __cplusplus \ | 266 | && (!defined __cplusplus \ |
| 260 | || (__cpp_static_assert < 201411 \ | 267 | || (__cpp_static_assert < 201411 \ |
| 261 | && __GNUG__ < 6 && __clang_major__ < 6 && _MSC_VER < 1910))) | 268 | && __GNUG__ < 6 && __clang_major__ < 6 && _MSC_VER < 1910))) |
| 262 | # if defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__ | 269 | # if (defined __cplusplus && defined __GNUG__ && __GNUG__ < 6 \ |
| 270 | && __cplusplus == 201103L && !defined __clang__) | ||
| 271 | /* g++ >= 4.7, < 6 with option -std=c++11 or -std=gnu++11 supports the | ||
| 272 | two-arguments static_assert but not the one-argument static_assert, and | ||
| 273 | it does not support _Static_assert. | ||
| 274 | We have to play preprocessor tricks to distinguish the two cases. */ | ||
| 275 | # define _GL_SA1(a1) static_assert ((a1), "static assertion failed") | ||
| 276 | # define _GL_SA2 static_assert | ||
| 277 | # define _GL_SA3 static_assert | ||
| 278 | # define _GL_SA_PICK(x1,x2,x3,x4,...) x4 | ||
| 279 | # define static_assert(...) _GL_SA_PICK(__VA_ARGS__,_GL_SA3,_GL_SA2,_GL_SA1) (__VA_ARGS__) | ||
| 280 | # elif defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__ | ||
| 263 | /* MSVC 14 in C++ mode supports the two-arguments static_assert but not | 281 | /* MSVC 14 in C++ mode supports the two-arguments static_assert but not |
| 264 | the one-argument static_assert, and it does not support _Static_assert. | 282 | the one-argument static_assert, and it does not support _Static_assert. |
| 265 | We have to play preprocessor tricks to distinguish the two cases. | 283 | We have to play preprocessor tricks to distinguish the two cases. |
| 266 | Since the MSVC preprocessor is not ISO C compliant (see above),. | 284 | Since the MSVC preprocessor is not ISO C compliant (see above), |
| 267 | the solution is specific to MSVC. */ | 285 | the solution is specific to MSVC. */ |
| 268 | # define _GL_EXPAND(x) x | 286 | # define _GL_EXPAND(x) x |
| 269 | # define _GL_SA1(a1) static_assert ((a1), "static assertion failed") | 287 | # define _GL_SA1(a1) static_assert ((a1), "static assertion failed") |
| @@ -294,7 +312,7 @@ template <int w> | |||
| 294 | #ifndef _GL_HAS_BUILTIN_UNREACHABLE | 312 | #ifndef _GL_HAS_BUILTIN_UNREACHABLE |
| 295 | # if defined __clang_major__ && __clang_major__ < 5 | 313 | # if defined __clang_major__ && __clang_major__ < 5 |
| 296 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | 314 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 |
| 297 | # elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) | 315 | # elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) && !defined __clang__ |
| 298 | # define _GL_HAS_BUILTIN_UNREACHABLE 1 | 316 | # define _GL_HAS_BUILTIN_UNREACHABLE 1 |
| 299 | # elif defined __has_builtin | 317 | # elif defined __has_builtin |
| 300 | # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) | 318 | # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) |
diff --git a/gl/vsnprintf.c b/gl/vsnprintf.c index e6676a1f..d3d7ef7a 100644 --- a/gl/vsnprintf.c +++ b/gl/vsnprintf.c | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* Formatted output to strings. | 1 | /* Formatted output to strings. |
| 2 | Copyright (C) 2004, 2006-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2004, 2006-2025 Free Software Foundation, Inc. |
| 3 | Written by Simon Josefsson and Yoann Vandoorselaere <yoann@prelude-ids.org>. | ||
| 4 | 3 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -25,46 +24,20 @@ | |||
| 25 | #include <errno.h> | 24 | #include <errno.h> |
| 26 | #include <limits.h> | 25 | #include <limits.h> |
| 27 | #include <stdarg.h> | 26 | #include <stdarg.h> |
| 28 | #include <stdlib.h> | 27 | #include <stdint.h> |
| 29 | #include <string.h> | ||
| 30 | 28 | ||
| 31 | #include "vasnprintf.h" | ||
| 32 | |||
| 33 | /* Print formatted output to string STR. Similar to vsprintf, but | ||
| 34 | additional length SIZE limit how much is written into STR. Returns | ||
| 35 | string length of formatted string (which may be larger than SIZE). | ||
| 36 | STR may be NULL, in which case nothing will be written. On error, | ||
| 37 | return a negative value. */ | ||
| 38 | int | 29 | int |
| 39 | vsnprintf (char *str, size_t size, const char *format, va_list args) | 30 | vsnprintf (char *str, size_t size, const char *format, va_list args) |
| 40 | { | 31 | { |
| 41 | char *output; | 32 | ptrdiff_t ret = vsnzprintf (str, size, format, args); |
| 42 | size_t len; | ||
| 43 | size_t lenbuf = size; | ||
| 44 | |||
| 45 | output = vasnprintf (str, &lenbuf, format, args); | ||
| 46 | len = lenbuf; | ||
| 47 | |||
| 48 | if (!output) | ||
| 49 | return -1; | ||
| 50 | |||
| 51 | if (output != str) | ||
| 52 | { | ||
| 53 | if (size) | ||
| 54 | { | ||
| 55 | size_t pruned_len = (len < size ? len : size - 1); | ||
| 56 | memcpy (str, output, pruned_len); | ||
| 57 | str[pruned_len] = '\0'; | ||
| 58 | } | ||
| 59 | |||
| 60 | free (output); | ||
| 61 | } | ||
| 62 | 33 | ||
| 63 | if (len > INT_MAX) | 34 | #if PTRDIFF_MAX > INT_MAX |
| 35 | if (ret > INT_MAX) | ||
| 64 | { | 36 | { |
| 65 | errno = EOVERFLOW; | 37 | errno = EOVERFLOW; |
| 66 | return -1; | 38 | return -1; |
| 67 | } | 39 | } |
| 40 | #endif | ||
| 68 | 41 | ||
| 69 | return len; | 42 | return ret; |
| 70 | } | 43 | } |
diff --git a/gl/vsnzprintf.c b/gl/vsnzprintf.c new file mode 100644 index 00000000..f6e6b1d4 --- /dev/null +++ b/gl/vsnzprintf.c | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | /* Formatted output to strings. | ||
| 2 | Copyright (C) 2004, 2006-2025 Free Software Foundation, Inc. | ||
| 3 | Written by Simon Josefsson and Yoann Vandoorselaere <yoann@prelude-ids.org>. | ||
| 4 | |||
| 5 | This file is free software: you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU Lesser General Public License as | ||
| 7 | published by the Free Software Foundation; either version 2.1 of the | ||
| 8 | License, or (at your option) any later version. | ||
| 9 | |||
| 10 | This file is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU Lesser General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU Lesser General Public License | ||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #ifdef HAVE_CONFIG_H | ||
| 19 | # include <config.h> | ||
| 20 | #endif | ||
| 21 | |||
| 22 | /* Specification. */ | ||
| 23 | #include <stdio.h> | ||
| 24 | |||
| 25 | #include <errno.h> | ||
| 26 | #include <stdarg.h> | ||
| 27 | #include <stdint.h> | ||
| 28 | #include <stdlib.h> | ||
| 29 | #include <string.h> | ||
| 30 | |||
| 31 | #include "vasnprintf.h" | ||
| 32 | |||
| 33 | ptrdiff_t | ||
| 34 | vsnzprintf (char *str, size_t size, const char *format, va_list args) | ||
| 35 | { | ||
| 36 | char *output; | ||
| 37 | size_t len; | ||
| 38 | size_t lenbuf = size; | ||
| 39 | |||
| 40 | output = vasnprintf (str, &lenbuf, format, args); | ||
| 41 | len = lenbuf; | ||
| 42 | |||
| 43 | if (!output) | ||
| 44 | return -1; | ||
| 45 | |||
| 46 | if (output != str) | ||
| 47 | { | ||
| 48 | if (size) | ||
| 49 | { | ||
| 50 | size_t pruned_len = (len < size ? len : size - 1); | ||
| 51 | memcpy (str, output, pruned_len); | ||
| 52 | str[pruned_len] = '\0'; | ||
| 53 | } | ||
| 54 | |||
| 55 | free (output); | ||
| 56 | } | ||
| 57 | |||
| 58 | if (len > PTRDIFF_MAX) | ||
| 59 | { | ||
| 60 | errno = ENOMEM; | ||
| 61 | return -1; | ||
| 62 | } | ||
| 63 | |||
| 64 | return len; | ||
| 65 | } | ||
diff --git a/gl/w32sock.h b/gl/w32sock.h index 166a5f77..d7087a28 100644 --- a/gl/w32sock.h +++ b/gl/w32sock.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* w32sock.h --- internal auxiliary functions for Windows socket functions | 1 | /* w32sock.h --- internal auxiliary functions for Windows socket functions |
| 2 | 2 | ||
| 3 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/warn-on-use.h b/gl/warn-on-use.h index 701013a0..c0072412 100644 --- a/gl/warn-on-use.h +++ b/gl/warn-on-use.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* A C macro for emitting warnings if a function is used. | 1 | /* A C macro for emitting warnings if a function is used. |
| 2 | Copyright (C) 2010-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2010-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify it | 4 | This program is free software: you can redistribute it and/or modify it |
| 5 | under the terms of the GNU Lesser General Public License as published | 5 | under the terms of the GNU Lesser General Public License as published |
| @@ -85,7 +85,7 @@ | |||
| 85 | */ | 85 | */ |
| 86 | #ifndef _GL_WARN_ON_USE | 86 | #ifndef _GL_WARN_ON_USE |
| 87 | 87 | ||
| 88 | # if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) | 88 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ |
| 89 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ | 89 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ |
| 90 | # define _GL_WARN_ON_USE(function, message) \ | 90 | # define _GL_WARN_ON_USE(function, message) \ |
| 91 | _GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message))) | 91 | _GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message))) |
| @@ -98,7 +98,7 @@ _GL_WARN_EXTERN_C __typeof__ (function) function \ | |||
| 98 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) | 98 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) |
| 99 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) \ | 99 | # define _GL_WARN_ON_USE_ATTRIBUTE(message) \ |
| 100 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) | 100 | __attribute__ ((__diagnose_if__ (1, message, "warning"))) |
| 101 | # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING | 101 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING |
| 102 | /* Verify the existence of the function. */ | 102 | /* Verify the existence of the function. */ |
| 103 | # define _GL_WARN_ON_USE(function, message) \ | 103 | # define _GL_WARN_ON_USE(function, message) \ |
| 104 | _GL_WARN_EXTERN_C __typeof__ (function) function | 104 | _GL_WARN_EXTERN_C __typeof__ (function) function |
| @@ -121,7 +121,7 @@ _GL_WARN_EXTERN_C int _gl_warn_on_use | |||
| 121 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | 121 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ |
| 122 | _GL_WARN_ON_USE (function, msg) | 122 | _GL_WARN_ON_USE (function, msg) |
| 123 | # else | 123 | # else |
| 124 | # if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) | 124 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)) && !defined __clang__ |
| 125 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ | 125 | /* A compiler attribute is available in gcc versions 4.3.0 and later. */ |
| 126 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | 126 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ |
| 127 | extern rettype_gcc function parameters_and_attributes \ | 127 | extern rettype_gcc function parameters_and_attributes \ |
| @@ -131,7 +131,7 @@ extern rettype_gcc function parameters_and_attributes \ | |||
| 131 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | 131 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ |
| 132 | extern rettype_clang function parameters_and_attributes \ | 132 | extern rettype_clang function parameters_and_attributes \ |
| 133 | __attribute__ ((__diagnose_if__ (1, msg, "warning"))) | 133 | __attribute__ ((__diagnose_if__ (1, msg, "warning"))) |
| 134 | # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING | 134 | # elif (__GNUC__ >= 3 || defined __clang__) && GNULIB_STRICT_CHECKING |
| 135 | /* Verify the existence of the function. */ | 135 | /* Verify the existence of the function. */ |
| 136 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ | 136 | # define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ |
| 137 | extern rettype_gcc function parameters_and_attributes | 137 | extern rettype_gcc function parameters_and_attributes |
diff --git a/gl/wchar.in.h b/gl/wchar.in.h index a33a10f7..a6c52eb9 100644 --- a/gl/wchar.in.h +++ b/gl/wchar.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A substitute for ISO C99 <wchar.h>, for platforms that have issues. | 1 | /* A substitute for ISO C99 <wchar.h>, for platforms that have issues. |
| 2 | 2 | ||
| 3 | Copyright (C) 2007-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2007-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -37,7 +37,7 @@ | |||
| 37 | && !defined _GL_FINISHED_INCLUDING_SYSTEM_INTTYPES_H) \ | 37 | && !defined _GL_FINISHED_INCLUDING_SYSTEM_INTTYPES_H) \ |
| 38 | || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) \ | 38 | || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) \ |
| 39 | || (defined __MINGW32__ && defined __STRING_H_SOURCED__) \ | 39 | || (defined __MINGW32__ && defined __STRING_H_SOURCED__) \ |
| 40 | || defined _GL_ALREADY_INCLUDING_WCHAR_H) | 40 | || defined _@GUARD_PREFIX@_ALREADY_INCLUDING_WCHAR_H) |
| 41 | /* Special invocation convention: | 41 | /* Special invocation convention: |
| 42 | - Inside glibc and uClibc header files, but not MinGW. | 42 | - Inside glibc and uClibc header files, but not MinGW. |
| 43 | - On HP-UX 11.00 we have a sequence of nested includes | 43 | - On HP-UX 11.00 we have a sequence of nested includes |
| @@ -53,13 +53,16 @@ | |||
| 53 | <wctype.h> is completely included or is still being included. */ | 53 | <wctype.h> is completely included or is still being included. */ |
| 54 | 54 | ||
| 55 | #@INCLUDE_NEXT@ @NEXT_WCHAR_H@ | 55 | #@INCLUDE_NEXT@ @NEXT_WCHAR_H@ |
| 56 | /* The glibc 2.5 /usr/include/wchar.h defines __need_wint_t but never undefines | ||
| 57 | it. We need to do that here. */ | ||
| 58 | #undef __need_wint_t | ||
| 56 | 59 | ||
| 57 | #else | 60 | #else |
| 58 | /* Normal invocation convention. */ | 61 | /* Normal invocation convention. */ |
| 59 | 62 | ||
| 60 | #ifndef _@GUARD_PREFIX@_WCHAR_H | 63 | #ifndef _@GUARD_PREFIX@_WCHAR_H |
| 61 | 64 | ||
| 62 | #define _GL_ALREADY_INCLUDING_WCHAR_H | 65 | #define _@GUARD_PREFIX@_ALREADY_INCLUDING_WCHAR_H |
| 63 | 66 | ||
| 64 | #if @HAVE_FEATURES_H@ | 67 | #if @HAVE_FEATURES_H@ |
| 65 | # include <features.h> /* for __GLIBC__ */ | 68 | # include <features.h> /* for __GLIBC__ */ |
| @@ -79,7 +82,7 @@ | |||
| 79 | # @INCLUDE_NEXT@ @NEXT_WCHAR_H@ | 82 | # @INCLUDE_NEXT@ @NEXT_WCHAR_H@ |
| 80 | #endif | 83 | #endif |
| 81 | 84 | ||
| 82 | #undef _GL_ALREADY_INCLUDING_WCHAR_H | 85 | #undef _@GUARD_PREFIX@_ALREADY_INCLUDING_WCHAR_H |
| 83 | 86 | ||
| 84 | #ifndef _@GUARD_PREFIX@_WCHAR_H | 87 | #ifndef _@GUARD_PREFIX@_WCHAR_H |
| 85 | #define _@GUARD_PREFIX@_WCHAR_H | 88 | #define _@GUARD_PREFIX@_WCHAR_H |
| @@ -95,7 +98,7 @@ | |||
| 95 | that can be freed by passing them as the Ith argument to the | 98 | that can be freed by passing them as the Ith argument to the |
| 96 | function F. */ | 99 | function F. */ |
| 97 | #ifndef _GL_ATTRIBUTE_DEALLOC | 100 | #ifndef _GL_ATTRIBUTE_DEALLOC |
| 98 | # if __GNUC__ >= 11 | 101 | # if __GNUC__ >= 11 && !defined __clang__ |
| 99 | # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) | 102 | # define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute__ ((__malloc__ (f, i))) |
| 100 | # else | 103 | # else |
| 101 | # define _GL_ATTRIBUTE_DEALLOC(f, i) | 104 | # define _GL_ATTRIBUTE_DEALLOC(f, i) |
| @@ -137,11 +140,23 @@ | |||
| 137 | # endif | 140 | # endif |
| 138 | #endif | 141 | #endif |
| 139 | 142 | ||
| 143 | /* _GL_ATTRIBUTE_NONNULL_IF_NONZERO (NP, NI) declares that the argument NP | ||
| 144 | (a pointer) must not be NULL if the argument NI (an integer) is != 0. */ | ||
| 145 | /* Applies to: functions. */ | ||
| 146 | #ifndef _GL_ATTRIBUTE_NONNULL_IF_NONZERO | ||
| 147 | # if __GNUC__ >= 15 && !defined __clang__ | ||
| 148 | # define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) \ | ||
| 149 | __attribute__ ((__nonnull_if_nonzero__ (np, ni))) | ||
| 150 | # else | ||
| 151 | # define _GL_ATTRIBUTE_NONNULL_IF_NONZERO(np, ni) | ||
| 152 | # endif | ||
| 153 | #endif | ||
| 154 | |||
| 140 | /* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. | 155 | /* _GL_ATTRIBUTE_NOTHROW declares that the function does not throw exceptions. |
| 141 | */ | 156 | */ |
| 142 | #ifndef _GL_ATTRIBUTE_NOTHROW | 157 | #ifndef _GL_ATTRIBUTE_NOTHROW |
| 143 | # if defined __cplusplus | 158 | # if defined __cplusplus |
| 144 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major >= 4 | 159 | # if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 2) || __clang_major__ >= 4 |
| 145 | # if __cplusplus >= 201103L | 160 | # if __cplusplus >= 201103L |
| 146 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) | 161 | # define _GL_ATTRIBUTE_NOTHROW noexcept (true) |
| 147 | # else | 162 | # else |
| @@ -198,11 +213,12 @@ typedef unsigned int rpl_wint_t; | |||
| 198 | /* Override mbstate_t if it is too small. | 213 | /* Override mbstate_t if it is too small. |
| 199 | On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for | 214 | On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for |
| 200 | implementing mbrtowc for encodings like UTF-8. | 215 | implementing mbrtowc for encodings like UTF-8. |
| 201 | On AIX and MSVC, mbrtowc needs to be overridden, but mbstate_t exists and is | 216 | On AIX, MSVC, and OpenBSD 6.0, mbrtowc needs to be overridden, but |
| 202 | large enough and overriding it would cause problems in C++ mode. */ | 217 | mbstate_t exists and is large enough and overriding it would cause problems |
| 218 | in C++ mode. */ | ||
| 203 | #if !(((defined _WIN32 && !defined __CYGWIN__) || @HAVE_MBSINIT@) && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@ | 219 | #if !(((defined _WIN32 && !defined __CYGWIN__) || @HAVE_MBSINIT@) && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@ |
| 204 | # if !GNULIB_defined_mbstate_t | 220 | # if !GNULIB_defined_mbstate_t |
| 205 | # if !(defined _AIX || defined _MSC_VER) | 221 | # if !(defined _AIX || defined _MSC_VER || defined __OpenBSD__) |
| 206 | typedef int rpl_mbstate_t; | 222 | typedef int rpl_mbstate_t; |
| 207 | # undef mbstate_t | 223 | # undef mbstate_t |
| 208 | # define mbstate_t rpl_mbstate_t | 224 | # define mbstate_t rpl_mbstate_t |
| @@ -262,6 +278,55 @@ _GL_EXTERN_C void free (void *); | |||
| 262 | #endif | 278 | #endif |
| 263 | 279 | ||
| 264 | 280 | ||
| 281 | /* Declarations for ISO C N3322. */ | ||
| 282 | #if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ | ||
| 283 | _GL_EXTERN_C wchar_t *wmemcpy (wchar_t *__dest, const wchar_t *__src, size_t __n) | ||
| 284 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 285 | _GL_ATTRIBUTE_NOTHROW | ||
| 286 | # endif | ||
| 287 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 288 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 289 | _GL_EXTERN_C wchar_t *wmemmove (wchar_t *__dest, const wchar_t *__src, size_t __n) | ||
| 290 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 291 | _GL_ATTRIBUTE_NOTHROW | ||
| 292 | # endif | ||
| 293 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 294 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 295 | _GL_EXTERN_C wchar_t *wcsncpy (wchar_t *__dest, const wchar_t *__src, size_t __n) | ||
| 296 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 297 | _GL_ATTRIBUTE_NOTHROW | ||
| 298 | # endif | ||
| 299 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 300 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 301 | _GL_EXTERN_C wchar_t *wcsncat (wchar_t *__dest, const wchar_t *__src, size_t __n) | ||
| 302 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 303 | _GL_ATTRIBUTE_NOTHROW | ||
| 304 | # endif | ||
| 305 | _GL_ARG_NONNULL ((1)) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 306 | _GL_EXTERN_C int wmemcmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) | ||
| 307 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 308 | _GL_ATTRIBUTE_NOTHROW | ||
| 309 | # endif | ||
| 310 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 311 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 312 | _GL_EXTERN_C int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) | ||
| 313 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 314 | _GL_ATTRIBUTE_NOTHROW | ||
| 315 | # endif | ||
| 316 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 317 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); | ||
| 318 | # ifndef __cplusplus | ||
| 319 | _GL_EXTERN_C wchar_t *wmemchr (const wchar_t *__s, wchar_t __wc, size_t __n) | ||
| 320 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); | ||
| 321 | # endif | ||
| 322 | _GL_EXTERN_C wchar_t *wmemset (wchar_t *__s, wchar_t __wc, size_t __n) | ||
| 323 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | ||
| 324 | _GL_ATTRIBUTE_NOTHROW | ||
| 325 | # endif | ||
| 326 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); | ||
| 327 | #endif | ||
| 328 | |||
| 329 | |||
| 265 | /* Convert a single-byte character to a wide character. */ | 330 | /* Convert a single-byte character to a wide character. */ |
| 266 | #if @GNULIB_BTOWC@ | 331 | #if @GNULIB_BTOWC@ |
| 267 | # if @REPLACE_BTOWC@ | 332 | # if @REPLACE_BTOWC@ |
| @@ -269,11 +334,11 @@ _GL_EXTERN_C void free (void *); | |||
| 269 | # undef btowc | 334 | # undef btowc |
| 270 | # define btowc rpl_btowc | 335 | # define btowc rpl_btowc |
| 271 | # endif | 336 | # endif |
| 272 | _GL_FUNCDECL_RPL (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); | 337 | _GL_FUNCDECL_RPL (btowc, wint_t, (int c), _GL_ATTRIBUTE_PURE); |
| 273 | _GL_CXXALIAS_RPL (btowc, wint_t, (int c)); | 338 | _GL_CXXALIAS_RPL (btowc, wint_t, (int c)); |
| 274 | # else | 339 | # else |
| 275 | # if !@HAVE_BTOWC@ | 340 | # if !@HAVE_BTOWC@ |
| 276 | _GL_FUNCDECL_SYS (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); | 341 | _GL_FUNCDECL_SYS (btowc, wint_t, (int c), _GL_ATTRIBUTE_PURE); |
| 277 | # endif | 342 | # endif |
| 278 | /* Need to cast, because on mingw, the return type is 'unsigned short'. */ | 343 | /* Need to cast, because on mingw, the return type is 'unsigned short'. */ |
| 279 | _GL_CXXALIAS_SYS_CAST (btowc, wint_t, (int c)); | 344 | _GL_CXXALIAS_SYS_CAST (btowc, wint_t, (int c)); |
| @@ -297,12 +362,12 @@ _GL_WARN_ON_USE (btowc, "btowc is unportable - " | |||
| 297 | # undef wctob | 362 | # undef wctob |
| 298 | # define wctob rpl_wctob | 363 | # define wctob rpl_wctob |
| 299 | # endif | 364 | # endif |
| 300 | _GL_FUNCDECL_RPL (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); | 365 | _GL_FUNCDECL_RPL (wctob, int, (wint_t wc), _GL_ATTRIBUTE_PURE); |
| 301 | _GL_CXXALIAS_RPL (wctob, int, (wint_t wc)); | 366 | _GL_CXXALIAS_RPL (wctob, int, (wint_t wc)); |
| 302 | # else | 367 | # else |
| 303 | # if !defined wctob && !@HAVE_DECL_WCTOB@ | 368 | # if !defined wctob && !@HAVE_DECL_WCTOB@ |
| 304 | /* wctob is provided by gnulib, or wctob exists but is not declared. */ | 369 | /* wctob is provided by gnulib, or wctob exists but is not declared. */ |
| 305 | _GL_FUNCDECL_SYS (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); | 370 | _GL_FUNCDECL_SYS (wctob, int, (wint_t wc), _GL_ATTRIBUTE_PURE); |
| 306 | # endif | 371 | # endif |
| 307 | _GL_CXXALIAS_SYS (wctob, int, (wint_t wc)); | 372 | _GL_CXXALIAS_SYS (wctob, int, (wint_t wc)); |
| 308 | # endif | 373 | # endif |
| @@ -325,11 +390,11 @@ _GL_WARN_ON_USE (wctob, "wctob is unportable - " | |||
| 325 | # undef mbsinit | 390 | # undef mbsinit |
| 326 | # define mbsinit rpl_mbsinit | 391 | # define mbsinit rpl_mbsinit |
| 327 | # endif | 392 | # endif |
| 328 | _GL_FUNCDECL_RPL (mbsinit, int, (const mbstate_t *ps)); | 393 | _GL_FUNCDECL_RPL (mbsinit, int, (const mbstate_t *ps), ); |
| 329 | _GL_CXXALIAS_RPL (mbsinit, int, (const mbstate_t *ps)); | 394 | _GL_CXXALIAS_RPL (mbsinit, int, (const mbstate_t *ps)); |
| 330 | # else | 395 | # else |
| 331 | # if !@HAVE_MBSINIT@ | 396 | # if !@HAVE_MBSINIT@ |
| 332 | _GL_FUNCDECL_SYS (mbsinit, int, (const mbstate_t *ps)); | 397 | _GL_FUNCDECL_SYS (mbsinit, int, (const mbstate_t *ps), ); |
| 333 | # endif | 398 | # endif |
| 334 | _GL_CXXALIAS_SYS (mbsinit, int, (const mbstate_t *ps)); | 399 | _GL_CXXALIAS_SYS (mbsinit, int, (const mbstate_t *ps)); |
| 335 | # endif | 400 | # endif |
| @@ -531,16 +596,19 @@ _GL_WARN_ON_USE (mbsinit, "mbsinit is unportable - " | |||
| 531 | # define _GL_MBSTATE_ZERO_SIZE sizeof (mbstate_t) | 596 | # define _GL_MBSTATE_ZERO_SIZE sizeof (mbstate_t) |
| 532 | # endif | 597 | # endif |
| 533 | _GL_BEGIN_C_LINKAGE | 598 | _GL_BEGIN_C_LINKAGE |
| 534 | # if defined IN_MBSZERO | 599 | # if !GNULIB_defined_mbszero |
| 600 | # if defined IN_MBSZERO | ||
| 535 | _GL_EXTERN_INLINE | 601 | _GL_EXTERN_INLINE |
| 536 | # else | 602 | # else |
| 537 | _GL_INLINE | 603 | _GL_INLINE |
| 538 | # endif | 604 | # endif |
| 539 | _GL_ARG_NONNULL ((1)) void | 605 | _GL_ARG_NONNULL ((1)) void |
| 540 | mbszero (mbstate_t *ps) | 606 | mbszero (mbstate_t *ps) |
| 541 | { | 607 | { |
| 542 | memset (ps, 0, _GL_MBSTATE_ZERO_SIZE); | 608 | memset (ps, 0, _GL_MBSTATE_ZERO_SIZE); |
| 543 | } | 609 | } |
| 610 | # define GNULIB_defined_mbszero 1 | ||
| 611 | # endif | ||
| 544 | _GL_END_C_LINKAGE | 612 | _GL_END_C_LINKAGE |
| 545 | _GL_CXXALIAS_SYS (mbszero, void, (mbstate_t *ps)); | 613 | _GL_CXXALIAS_SYS (mbszero, void, (mbstate_t *ps)); |
| 546 | _GL_CXXALIASWARN (mbszero); | 614 | _GL_CXXALIASWARN (mbszero); |
| @@ -556,7 +624,7 @@ _GL_CXXALIASWARN (mbszero); | |||
| 556 | # endif | 624 | # endif |
| 557 | _GL_FUNCDECL_RPL (mbrtowc, size_t, | 625 | _GL_FUNCDECL_RPL (mbrtowc, size_t, |
| 558 | (wchar_t *restrict pwc, const char *restrict s, size_t n, | 626 | (wchar_t *restrict pwc, const char *restrict s, size_t n, |
| 559 | mbstate_t *restrict ps)); | 627 | mbstate_t *restrict ps), ); |
| 560 | _GL_CXXALIAS_RPL (mbrtowc, size_t, | 628 | _GL_CXXALIAS_RPL (mbrtowc, size_t, |
| 561 | (wchar_t *restrict pwc, const char *restrict s, size_t n, | 629 | (wchar_t *restrict pwc, const char *restrict s, size_t n, |
| 562 | mbstate_t *restrict ps)); | 630 | mbstate_t *restrict ps)); |
| @@ -564,7 +632,7 @@ _GL_CXXALIAS_RPL (mbrtowc, size_t, | |||
| 564 | # if !@HAVE_MBRTOWC@ | 632 | # if !@HAVE_MBRTOWC@ |
| 565 | _GL_FUNCDECL_SYS (mbrtowc, size_t, | 633 | _GL_FUNCDECL_SYS (mbrtowc, size_t, |
| 566 | (wchar_t *restrict pwc, const char *restrict s, size_t n, | 634 | (wchar_t *restrict pwc, const char *restrict s, size_t n, |
| 567 | mbstate_t *restrict ps)); | 635 | mbstate_t *restrict ps), ); |
| 568 | # endif | 636 | # endif |
| 569 | _GL_CXXALIAS_SYS (mbrtowc, size_t, | 637 | _GL_CXXALIAS_SYS (mbrtowc, size_t, |
| 570 | (wchar_t *restrict pwc, const char *restrict s, size_t n, | 638 | (wchar_t *restrict pwc, const char *restrict s, size_t n, |
| @@ -590,13 +658,13 @@ _GL_WARN_ON_USE (mbrtowc, "mbrtowc is unportable - " | |||
| 590 | # define mbrlen rpl_mbrlen | 658 | # define mbrlen rpl_mbrlen |
| 591 | # endif | 659 | # endif |
| 592 | _GL_FUNCDECL_RPL (mbrlen, size_t, | 660 | _GL_FUNCDECL_RPL (mbrlen, size_t, |
| 593 | (const char *restrict s, size_t n, mbstate_t *restrict ps)); | 661 | (const char *restrict s, size_t n, mbstate_t *restrict ps), ); |
| 594 | _GL_CXXALIAS_RPL (mbrlen, size_t, | 662 | _GL_CXXALIAS_RPL (mbrlen, size_t, |
| 595 | (const char *restrict s, size_t n, mbstate_t *restrict ps)); | 663 | (const char *restrict s, size_t n, mbstate_t *restrict ps)); |
| 596 | # else | 664 | # else |
| 597 | # if !@HAVE_MBRLEN@ | 665 | # if !@HAVE_MBRLEN@ |
| 598 | _GL_FUNCDECL_SYS (mbrlen, size_t, | 666 | _GL_FUNCDECL_SYS (mbrlen, size_t, |
| 599 | (const char *restrict s, size_t n, mbstate_t *restrict ps)); | 667 | (const char *restrict s, size_t n, mbstate_t *restrict ps), ); |
| 600 | # endif | 668 | # endif |
| 601 | _GL_CXXALIAS_SYS (mbrlen, size_t, | 669 | _GL_CXXALIAS_SYS (mbrlen, size_t, |
| 602 | (const char *restrict s, size_t n, mbstate_t *restrict ps)); | 670 | (const char *restrict s, size_t n, mbstate_t *restrict ps)); |
| @@ -623,7 +691,7 @@ _GL_WARN_ON_USE (mbrlen, "mbrlen is unportable - " | |||
| 623 | _GL_FUNCDECL_RPL (mbsrtowcs, size_t, | 691 | _GL_FUNCDECL_RPL (mbsrtowcs, size_t, |
| 624 | (wchar_t *restrict dest, | 692 | (wchar_t *restrict dest, |
| 625 | const char **restrict srcp, size_t len, | 693 | const char **restrict srcp, size_t len, |
| 626 | mbstate_t *restrict ps) | 694 | mbstate_t *restrict ps), |
| 627 | _GL_ARG_NONNULL ((2))); | 695 | _GL_ARG_NONNULL ((2))); |
| 628 | _GL_CXXALIAS_RPL (mbsrtowcs, size_t, | 696 | _GL_CXXALIAS_RPL (mbsrtowcs, size_t, |
| 629 | (wchar_t *restrict dest, | 697 | (wchar_t *restrict dest, |
| @@ -634,7 +702,7 @@ _GL_CXXALIAS_RPL (mbsrtowcs, size_t, | |||
| 634 | _GL_FUNCDECL_SYS (mbsrtowcs, size_t, | 702 | _GL_FUNCDECL_SYS (mbsrtowcs, size_t, |
| 635 | (wchar_t *restrict dest, | 703 | (wchar_t *restrict dest, |
| 636 | const char **restrict srcp, size_t len, | 704 | const char **restrict srcp, size_t len, |
| 637 | mbstate_t *restrict ps) | 705 | mbstate_t *restrict ps), |
| 638 | _GL_ARG_NONNULL ((2))); | 706 | _GL_ARG_NONNULL ((2))); |
| 639 | # endif | 707 | # endif |
| 640 | _GL_CXXALIAS_SYS (mbsrtowcs, size_t, | 708 | _GL_CXXALIAS_SYS (mbsrtowcs, size_t, |
| @@ -664,7 +732,7 @@ _GL_WARN_ON_USE (mbsrtowcs, "mbsrtowcs is unportable - " | |||
| 664 | _GL_FUNCDECL_RPL (mbsnrtowcs, size_t, | 732 | _GL_FUNCDECL_RPL (mbsnrtowcs, size_t, |
| 665 | (wchar_t *restrict dest, | 733 | (wchar_t *restrict dest, |
| 666 | const char **restrict srcp, size_t srclen, size_t len, | 734 | const char **restrict srcp, size_t srclen, size_t len, |
| 667 | mbstate_t *restrict ps) | 735 | mbstate_t *restrict ps), |
| 668 | _GL_ARG_NONNULL ((2))); | 736 | _GL_ARG_NONNULL ((2))); |
| 669 | _GL_CXXALIAS_RPL (mbsnrtowcs, size_t, | 737 | _GL_CXXALIAS_RPL (mbsnrtowcs, size_t, |
| 670 | (wchar_t *restrict dest, | 738 | (wchar_t *restrict dest, |
| @@ -675,7 +743,7 @@ _GL_CXXALIAS_RPL (mbsnrtowcs, size_t, | |||
| 675 | _GL_FUNCDECL_SYS (mbsnrtowcs, size_t, | 743 | _GL_FUNCDECL_SYS (mbsnrtowcs, size_t, |
| 676 | (wchar_t *restrict dest, | 744 | (wchar_t *restrict dest, |
| 677 | const char **restrict srcp, size_t srclen, size_t len, | 745 | const char **restrict srcp, size_t srclen, size_t len, |
| 678 | mbstate_t *restrict ps) | 746 | mbstate_t *restrict ps), |
| 679 | _GL_ARG_NONNULL ((2))); | 747 | _GL_ARG_NONNULL ((2))); |
| 680 | # endif | 748 | # endif |
| 681 | _GL_CXXALIAS_SYS (mbsnrtowcs, size_t, | 749 | _GL_CXXALIAS_SYS (mbsnrtowcs, size_t, |
| @@ -703,13 +771,13 @@ _GL_WARN_ON_USE (mbsnrtowcs, "mbsnrtowcs is unportable - " | |||
| 703 | # define wcrtomb rpl_wcrtomb | 771 | # define wcrtomb rpl_wcrtomb |
| 704 | # endif | 772 | # endif |
| 705 | _GL_FUNCDECL_RPL (wcrtomb, size_t, | 773 | _GL_FUNCDECL_RPL (wcrtomb, size_t, |
| 706 | (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); | 774 | (char *restrict s, wchar_t wc, mbstate_t *restrict ps), ); |
| 707 | _GL_CXXALIAS_RPL (wcrtomb, size_t, | 775 | _GL_CXXALIAS_RPL (wcrtomb, size_t, |
| 708 | (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); | 776 | (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); |
| 709 | # else | 777 | # else |
| 710 | # if !@HAVE_WCRTOMB@ | 778 | # if !@HAVE_WCRTOMB@ |
| 711 | _GL_FUNCDECL_SYS (wcrtomb, size_t, | 779 | _GL_FUNCDECL_SYS (wcrtomb, size_t, |
| 712 | (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); | 780 | (char *restrict s, wchar_t wc, mbstate_t *restrict ps), ); |
| 713 | # endif | 781 | # endif |
| 714 | _GL_CXXALIAS_SYS (wcrtomb, size_t, | 782 | _GL_CXXALIAS_SYS (wcrtomb, size_t, |
| 715 | (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); | 783 | (char *restrict s, wchar_t wc, mbstate_t *restrict ps)); |
| @@ -736,7 +804,7 @@ _GL_WARN_ON_USE (wcrtomb, "wcrtomb is unportable - " | |||
| 736 | _GL_FUNCDECL_RPL (wcsrtombs, size_t, | 804 | _GL_FUNCDECL_RPL (wcsrtombs, size_t, |
| 737 | (char *restrict dest, const wchar_t **restrict srcp, | 805 | (char *restrict dest, const wchar_t **restrict srcp, |
| 738 | size_t len, | 806 | size_t len, |
| 739 | mbstate_t *restrict ps) | 807 | mbstate_t *restrict ps), |
| 740 | _GL_ARG_NONNULL ((2))); | 808 | _GL_ARG_NONNULL ((2))); |
| 741 | _GL_CXXALIAS_RPL (wcsrtombs, size_t, | 809 | _GL_CXXALIAS_RPL (wcsrtombs, size_t, |
| 742 | (char *restrict dest, const wchar_t **restrict srcp, | 810 | (char *restrict dest, const wchar_t **restrict srcp, |
| @@ -747,7 +815,7 @@ _GL_CXXALIAS_RPL (wcsrtombs, size_t, | |||
| 747 | _GL_FUNCDECL_SYS (wcsrtombs, size_t, | 815 | _GL_FUNCDECL_SYS (wcsrtombs, size_t, |
| 748 | (char *restrict dest, const wchar_t **restrict srcp, | 816 | (char *restrict dest, const wchar_t **restrict srcp, |
| 749 | size_t len, | 817 | size_t len, |
| 750 | mbstate_t *restrict ps) | 818 | mbstate_t *restrict ps), |
| 751 | _GL_ARG_NONNULL ((2))); | 819 | _GL_ARG_NONNULL ((2))); |
| 752 | # endif | 820 | # endif |
| 753 | _GL_CXXALIAS_SYS (wcsrtombs, size_t, | 821 | _GL_CXXALIAS_SYS (wcsrtombs, size_t, |
| @@ -778,7 +846,7 @@ _GL_FUNCDECL_RPL (wcsnrtombs, size_t, | |||
| 778 | (char *restrict dest, | 846 | (char *restrict dest, |
| 779 | const wchar_t **restrict srcp, size_t srclen, | 847 | const wchar_t **restrict srcp, size_t srclen, |
| 780 | size_t len, | 848 | size_t len, |
| 781 | mbstate_t *restrict ps) | 849 | mbstate_t *restrict ps), |
| 782 | _GL_ARG_NONNULL ((2))); | 850 | _GL_ARG_NONNULL ((2))); |
| 783 | _GL_CXXALIAS_RPL (wcsnrtombs, size_t, | 851 | _GL_CXXALIAS_RPL (wcsnrtombs, size_t, |
| 784 | (char *restrict dest, | 852 | (char *restrict dest, |
| @@ -791,7 +859,7 @@ _GL_FUNCDECL_SYS (wcsnrtombs, size_t, | |||
| 791 | (char *restrict dest, | 859 | (char *restrict dest, |
| 792 | const wchar_t **restrict srcp, size_t srclen, | 860 | const wchar_t **restrict srcp, size_t srclen, |
| 793 | size_t len, | 861 | size_t len, |
| 794 | mbstate_t *restrict ps) | 862 | mbstate_t *restrict ps), |
| 795 | _GL_ARG_NONNULL ((2))); | 863 | _GL_ARG_NONNULL ((2))); |
| 796 | # endif | 864 | # endif |
| 797 | _GL_CXXALIAS_SYS (wcsnrtombs, size_t, | 865 | _GL_CXXALIAS_SYS (wcsnrtombs, size_t, |
| @@ -819,12 +887,12 @@ _GL_WARN_ON_USE (wcsnrtombs, "wcsnrtombs is unportable - " | |||
| 819 | # undef wcwidth | 887 | # undef wcwidth |
| 820 | # define wcwidth rpl_wcwidth | 888 | # define wcwidth rpl_wcwidth |
| 821 | # endif | 889 | # endif |
| 822 | _GL_FUNCDECL_RPL (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); | 890 | _GL_FUNCDECL_RPL (wcwidth, int, (wchar_t), _GL_ATTRIBUTE_PURE); |
| 823 | _GL_CXXALIAS_RPL (wcwidth, int, (wchar_t)); | 891 | _GL_CXXALIAS_RPL (wcwidth, int, (wchar_t)); |
| 824 | # else | 892 | # else |
| 825 | # if !@HAVE_DECL_WCWIDTH@ | 893 | # if !@HAVE_DECL_WCWIDTH@ |
| 826 | /* wcwidth exists but is not declared. */ | 894 | /* wcwidth exists but is not declared. */ |
| 827 | _GL_FUNCDECL_SYS (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); | 895 | _GL_FUNCDECL_SYS (wcwidth, int, (wchar_t), _GL_ATTRIBUTE_PURE); |
| 828 | # endif | 896 | # endif |
| 829 | _GL_CXXALIAS_SYS (wcwidth, int, (wchar_t)); | 897 | _GL_CXXALIAS_SYS (wcwidth, int, (wchar_t)); |
| 830 | # endif | 898 | # endif |
| @@ -843,8 +911,9 @@ _GL_WARN_ON_USE (wcwidth, "wcwidth is unportable - " | |||
| 843 | /* Search N wide characters of S for C. */ | 911 | /* Search N wide characters of S for C. */ |
| 844 | #if @GNULIB_WMEMCHR@ | 912 | #if @GNULIB_WMEMCHR@ |
| 845 | # if !@HAVE_WMEMCHR@ | 913 | # if !@HAVE_WMEMCHR@ |
| 846 | _GL_FUNCDECL_SYS (wmemchr, wchar_t *, (const wchar_t *s, wchar_t c, size_t n) | 914 | _GL_FUNCDECL_SYS (wmemchr, wchar_t *, |
| 847 | _GL_ATTRIBUTE_PURE); | 915 | (const wchar_t *s, wchar_t c, size_t n), |
| 916 | _GL_ATTRIBUTE_PURE _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); | ||
| 848 | # endif | 917 | # endif |
| 849 | /* On some systems, this function is defined as an overloaded function: | 918 | /* On some systems, this function is defined as an overloaded function: |
| 850 | extern "C++" { | 919 | extern "C++" { |
| @@ -855,11 +924,12 @@ _GL_CXXALIAS_SYS_CAST2 (wmemchr, | |||
| 855 | wchar_t *, (const wchar_t *, wchar_t, size_t), | 924 | wchar_t *, (const wchar_t *, wchar_t, size_t), |
| 856 | const wchar_t *, (const wchar_t *, wchar_t, size_t)); | 925 | const wchar_t *, (const wchar_t *, wchar_t, size_t)); |
| 857 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ | 926 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ |
| 858 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) | 927 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ |
| 928 | && !defined __clang__ | ||
| 859 | _GL_CXXALIASWARN1 (wmemchr, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); | 929 | _GL_CXXALIASWARN1 (wmemchr, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); |
| 860 | _GL_CXXALIASWARN1 (wmemchr, const wchar_t *, | 930 | _GL_CXXALIASWARN1 (wmemchr, const wchar_t *, |
| 861 | (const wchar_t *s, wchar_t c, size_t n)); | 931 | (const wchar_t *s, wchar_t c, size_t n)); |
| 862 | # elif __GLIBC__ >= 2 | 932 | # elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO |
| 863 | _GL_CXXALIASWARN (wmemchr); | 933 | _GL_CXXALIASWARN (wmemchr); |
| 864 | # endif | 934 | # endif |
| 865 | #elif defined GNULIB_POSIXCHECK | 935 | #elif defined GNULIB_POSIXCHECK |
| @@ -879,15 +949,19 @@ _GL_WARN_ON_USE (wmemchr, "wmemchr is unportable - " | |||
| 879 | # define wmemcmp rpl_wmemcmp | 949 | # define wmemcmp rpl_wmemcmp |
| 880 | # endif | 950 | # endif |
| 881 | _GL_FUNCDECL_RPL (wmemcmp, int, | 951 | _GL_FUNCDECL_RPL (wmemcmp, int, |
| 882 | (const wchar_t *s1, const wchar_t *s2, size_t n) | 952 | (const wchar_t *s1, const wchar_t *s2, size_t n), |
| 883 | _GL_ATTRIBUTE_PURE); | 953 | _GL_ATTRIBUTE_PURE |
| 954 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 955 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 884 | _GL_CXXALIAS_RPL (wmemcmp, int, | 956 | _GL_CXXALIAS_RPL (wmemcmp, int, |
| 885 | (const wchar_t *s1, const wchar_t *s2, size_t n)); | 957 | (const wchar_t *s1, const wchar_t *s2, size_t n)); |
| 886 | # else | 958 | # else |
| 887 | # if !@HAVE_WMEMCMP@ | 959 | # if !@HAVE_WMEMCMP@ |
| 888 | _GL_FUNCDECL_SYS (wmemcmp, int, | 960 | _GL_FUNCDECL_SYS (wmemcmp, int, |
| 889 | (const wchar_t *s1, const wchar_t *s2, size_t n) | 961 | (const wchar_t *s1, const wchar_t *s2, size_t n), |
| 890 | _GL_ATTRIBUTE_PURE); | 962 | _GL_ATTRIBUTE_PURE |
| 963 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 964 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 891 | # endif | 965 | # endif |
| 892 | _GL_CXXALIAS_SYS (wmemcmp, int, | 966 | _GL_CXXALIAS_SYS (wmemcmp, int, |
| 893 | (const wchar_t *s1, const wchar_t *s2, size_t n)); | 967 | (const wchar_t *s1, const wchar_t *s2, size_t n)); |
| @@ -909,7 +983,9 @@ _GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - " | |||
| 909 | # if !@HAVE_WMEMCPY@ | 983 | # if !@HAVE_WMEMCPY@ |
| 910 | _GL_FUNCDECL_SYS (wmemcpy, wchar_t *, | 984 | _GL_FUNCDECL_SYS (wmemcpy, wchar_t *, |
| 911 | (wchar_t *restrict dest, | 985 | (wchar_t *restrict dest, |
| 912 | const wchar_t *restrict src, size_t n)); | 986 | const wchar_t *restrict src, size_t n), |
| 987 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 988 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 913 | # endif | 989 | # endif |
| 914 | _GL_CXXALIAS_SYS (wmemcpy, wchar_t *, | 990 | _GL_CXXALIAS_SYS (wmemcpy, wchar_t *, |
| 915 | (wchar_t *restrict dest, | 991 | (wchar_t *restrict dest, |
| @@ -931,7 +1007,9 @@ _GL_WARN_ON_USE (wmemcpy, "wmemcpy is unportable - " | |||
| 931 | #if @GNULIB_WMEMMOVE@ | 1007 | #if @GNULIB_WMEMMOVE@ |
| 932 | # if !@HAVE_WMEMMOVE@ | 1008 | # if !@HAVE_WMEMMOVE@ |
| 933 | _GL_FUNCDECL_SYS (wmemmove, wchar_t *, | 1009 | _GL_FUNCDECL_SYS (wmemmove, wchar_t *, |
| 934 | (wchar_t *dest, const wchar_t *src, size_t n)); | 1010 | (wchar_t *dest, const wchar_t *src, size_t n), |
| 1011 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 1012 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 935 | # endif | 1013 | # endif |
| 936 | _GL_CXXALIAS_SYS (wmemmove, wchar_t *, | 1014 | _GL_CXXALIAS_SYS (wmemmove, wchar_t *, |
| 937 | (wchar_t *dest, const wchar_t *src, size_t n)); | 1015 | (wchar_t *dest, const wchar_t *src, size_t n)); |
| @@ -957,7 +1035,7 @@ _GL_WARN_ON_USE (wmemmove, "wmemmove is unportable - " | |||
| 957 | # endif | 1035 | # endif |
| 958 | _GL_FUNCDECL_RPL (wmempcpy, wchar_t *, | 1036 | _GL_FUNCDECL_RPL (wmempcpy, wchar_t *, |
| 959 | (wchar_t *restrict dest, | 1037 | (wchar_t *restrict dest, |
| 960 | const wchar_t *restrict src, size_t n)); | 1038 | const wchar_t *restrict src, size_t n), ); |
| 961 | _GL_CXXALIAS_RPL (wmempcpy, wchar_t *, | 1039 | _GL_CXXALIAS_RPL (wmempcpy, wchar_t *, |
| 962 | (wchar_t *restrict dest, | 1040 | (wchar_t *restrict dest, |
| 963 | const wchar_t *restrict src, size_t n)); | 1041 | const wchar_t *restrict src, size_t n)); |
| @@ -965,7 +1043,7 @@ _GL_CXXALIAS_RPL (wmempcpy, wchar_t *, | |||
| 965 | # if !@HAVE_WMEMPCPY@ | 1043 | # if !@HAVE_WMEMPCPY@ |
| 966 | _GL_FUNCDECL_SYS (wmempcpy, wchar_t *, | 1044 | _GL_FUNCDECL_SYS (wmempcpy, wchar_t *, |
| 967 | (wchar_t *restrict dest, | 1045 | (wchar_t *restrict dest, |
| 968 | const wchar_t *restrict src, size_t n)); | 1046 | const wchar_t *restrict src, size_t n), ); |
| 969 | # endif | 1047 | # endif |
| 970 | _GL_CXXALIAS_SYS (wmempcpy, wchar_t *, | 1048 | _GL_CXXALIAS_SYS (wmempcpy, wchar_t *, |
| 971 | (wchar_t *restrict dest, | 1049 | (wchar_t *restrict dest, |
| @@ -986,7 +1064,8 @@ _GL_WARN_ON_USE (wmempcpy, "wmempcpy is unportable - " | |||
| 986 | /* Set N wide characters of S to C. */ | 1064 | /* Set N wide characters of S to C. */ |
| 987 | #if @GNULIB_WMEMSET@ | 1065 | #if @GNULIB_WMEMSET@ |
| 988 | # if !@HAVE_WMEMSET@ | 1066 | # if !@HAVE_WMEMSET@ |
| 989 | _GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); | 1067 | _GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n), |
| 1068 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3)); | ||
| 990 | # endif | 1069 | # endif |
| 991 | _GL_CXXALIAS_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); | 1070 | _GL_CXXALIAS_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); |
| 992 | # if __GLIBC__ >= 2 | 1071 | # if __GLIBC__ >= 2 |
| @@ -1004,7 +1083,7 @@ _GL_WARN_ON_USE (wmemset, "wmemset is unportable - " | |||
| 1004 | /* Return the number of wide characters in S. */ | 1083 | /* Return the number of wide characters in S. */ |
| 1005 | #if @GNULIB_WCSLEN@ | 1084 | #if @GNULIB_WCSLEN@ |
| 1006 | # if !@HAVE_WCSLEN@ | 1085 | # if !@HAVE_WCSLEN@ |
| 1007 | _GL_FUNCDECL_SYS (wcslen, size_t, (const wchar_t *s) _GL_ATTRIBUTE_PURE); | 1086 | _GL_FUNCDECL_SYS (wcslen, size_t, (const wchar_t *s), _GL_ATTRIBUTE_PURE); |
| 1008 | # endif | 1087 | # endif |
| 1009 | _GL_CXXALIAS_SYS (wcslen, size_t, (const wchar_t *s)); | 1088 | _GL_CXXALIAS_SYS (wcslen, size_t, (const wchar_t *s)); |
| 1010 | # if __GLIBC__ >= 2 | 1089 | # if __GLIBC__ >= 2 |
| @@ -1025,7 +1104,7 @@ _GL_WARN_ON_USE (wcslen, "wcslen is unportable - " | |||
| 1025 | namespace, not in the global namespace. So, force a declaration in | 1104 | namespace, not in the global namespace. So, force a declaration in |
| 1026 | the global namespace. */ | 1105 | the global namespace. */ |
| 1027 | # if !@HAVE_WCSNLEN@ || (defined __sun && defined __cplusplus) | 1106 | # if !@HAVE_WCSNLEN@ || (defined __sun && defined __cplusplus) |
| 1028 | _GL_FUNCDECL_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen) | 1107 | _GL_FUNCDECL_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen), |
| 1029 | _GL_ATTRIBUTE_PURE); | 1108 | _GL_ATTRIBUTE_PURE); |
| 1030 | # endif | 1109 | # endif |
| 1031 | _GL_CXXALIAS_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen)); | 1110 | _GL_CXXALIAS_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen)); |
| @@ -1043,7 +1122,7 @@ _GL_WARN_ON_USE (wcsnlen, "wcsnlen is unportable - " | |||
| 1043 | #if @GNULIB_WCSCPY@ | 1122 | #if @GNULIB_WCSCPY@ |
| 1044 | # if !@HAVE_WCSCPY@ | 1123 | # if !@HAVE_WCSCPY@ |
| 1045 | _GL_FUNCDECL_SYS (wcscpy, wchar_t *, | 1124 | _GL_FUNCDECL_SYS (wcscpy, wchar_t *, |
| 1046 | (wchar_t *restrict dest, const wchar_t *restrict src)); | 1125 | (wchar_t *restrict dest, const wchar_t *restrict src), ); |
| 1047 | # endif | 1126 | # endif |
| 1048 | _GL_CXXALIAS_SYS (wcscpy, wchar_t *, | 1127 | _GL_CXXALIAS_SYS (wcscpy, wchar_t *, |
| 1049 | (wchar_t *restrict dest, const wchar_t *restrict src)); | 1128 | (wchar_t *restrict dest, const wchar_t *restrict src)); |
| @@ -1066,7 +1145,7 @@ _GL_WARN_ON_USE (wcscpy, "wcscpy is unportable - " | |||
| 1066 | the global namespace. */ | 1145 | the global namespace. */ |
| 1067 | # if !@HAVE_WCPCPY@ || (defined __sun && defined __cplusplus) | 1146 | # if !@HAVE_WCPCPY@ || (defined __sun && defined __cplusplus) |
| 1068 | _GL_FUNCDECL_SYS (wcpcpy, wchar_t *, | 1147 | _GL_FUNCDECL_SYS (wcpcpy, wchar_t *, |
| 1069 | (wchar_t *restrict dest, const wchar_t *restrict src)); | 1148 | (wchar_t *restrict dest, const wchar_t *restrict src), ); |
| 1070 | # endif | 1149 | # endif |
| 1071 | _GL_CXXALIAS_SYS (wcpcpy, wchar_t *, | 1150 | _GL_CXXALIAS_SYS (wcpcpy, wchar_t *, |
| 1072 | (wchar_t *restrict dest, const wchar_t *restrict src)); | 1151 | (wchar_t *restrict dest, const wchar_t *restrict src)); |
| @@ -1085,7 +1164,9 @@ _GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - " | |||
| 1085 | # if !@HAVE_WCSNCPY@ | 1164 | # if !@HAVE_WCSNCPY@ |
| 1086 | _GL_FUNCDECL_SYS (wcsncpy, wchar_t *, | 1165 | _GL_FUNCDECL_SYS (wcsncpy, wchar_t *, |
| 1087 | (wchar_t *restrict dest, | 1166 | (wchar_t *restrict dest, |
| 1088 | const wchar_t *restrict src, size_t n)); | 1167 | const wchar_t *restrict src, size_t n), |
| 1168 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 1169 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 1089 | # endif | 1170 | # endif |
| 1090 | _GL_CXXALIAS_SYS (wcsncpy, wchar_t *, | 1171 | _GL_CXXALIAS_SYS (wcsncpy, wchar_t *, |
| 1091 | (wchar_t *restrict dest, | 1172 | (wchar_t *restrict dest, |
| @@ -1111,7 +1192,7 @@ _GL_WARN_ON_USE (wcsncpy, "wcsncpy is unportable - " | |||
| 1111 | # if !@HAVE_WCPNCPY@ || (defined __sun && defined __cplusplus) | 1192 | # if !@HAVE_WCPNCPY@ || (defined __sun && defined __cplusplus) |
| 1112 | _GL_FUNCDECL_SYS (wcpncpy, wchar_t *, | 1193 | _GL_FUNCDECL_SYS (wcpncpy, wchar_t *, |
| 1113 | (wchar_t *restrict dest, | 1194 | (wchar_t *restrict dest, |
| 1114 | const wchar_t *restrict src, size_t n)); | 1195 | const wchar_t *restrict src, size_t n), ); |
| 1115 | # endif | 1196 | # endif |
| 1116 | _GL_CXXALIAS_SYS (wcpncpy, wchar_t *, | 1197 | _GL_CXXALIAS_SYS (wcpncpy, wchar_t *, |
| 1117 | (wchar_t *restrict dest, | 1198 | (wchar_t *restrict dest, |
| @@ -1130,7 +1211,7 @@ _GL_WARN_ON_USE (wcpncpy, "wcpncpy is unportable - " | |||
| 1130 | #if @GNULIB_WCSCAT@ | 1211 | #if @GNULIB_WCSCAT@ |
| 1131 | # if !@HAVE_WCSCAT@ | 1212 | # if !@HAVE_WCSCAT@ |
| 1132 | _GL_FUNCDECL_SYS (wcscat, wchar_t *, | 1213 | _GL_FUNCDECL_SYS (wcscat, wchar_t *, |
| 1133 | (wchar_t *restrict dest, const wchar_t *restrict src)); | 1214 | (wchar_t *restrict dest, const wchar_t *restrict src), ); |
| 1134 | # endif | 1215 | # endif |
| 1135 | _GL_CXXALIAS_SYS (wcscat, wchar_t *, | 1216 | _GL_CXXALIAS_SYS (wcscat, wchar_t *, |
| 1136 | (wchar_t *restrict dest, const wchar_t *restrict src)); | 1217 | (wchar_t *restrict dest, const wchar_t *restrict src)); |
| @@ -1148,14 +1229,31 @@ _GL_WARN_ON_USE (wcscat, "wcscat is unportable - " | |||
| 1148 | 1229 | ||
| 1149 | /* Append no more than N wide characters of SRC onto DEST. */ | 1230 | /* Append no more than N wide characters of SRC onto DEST. */ |
| 1150 | #if @GNULIB_WCSNCAT@ | 1231 | #if @GNULIB_WCSNCAT@ |
| 1151 | # if !@HAVE_WCSNCAT@ | 1232 | # if @REPLACE_WCSNCAT@ |
| 1152 | _GL_FUNCDECL_SYS (wcsncat, wchar_t *, | 1233 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 1234 | # undef wcsncat | ||
| 1235 | # define wcsncat rpl_wcsncat | ||
| 1236 | # endif | ||
| 1237 | _GL_FUNCDECL_RPL (wcsncat, wchar_t *, | ||
| 1238 | (wchar_t *restrict dest, const wchar_t *restrict src, | ||
| 1239 | size_t n), | ||
| 1240 | _GL_ARG_NONNULL ((1)) | ||
| 1241 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 1242 | _GL_CXXALIAS_RPL (wcsncat, wchar_t *, | ||
| 1153 | (wchar_t *restrict dest, const wchar_t *restrict src, | 1243 | (wchar_t *restrict dest, const wchar_t *restrict src, |
| 1154 | size_t n)); | 1244 | size_t n)); |
| 1155 | # endif | 1245 | # else |
| 1246 | # if !@HAVE_WCSNCAT@ | ||
| 1247 | _GL_FUNCDECL_SYS (wcsncat, wchar_t *, | ||
| 1248 | (wchar_t *restrict dest, const wchar_t *restrict src, | ||
| 1249 | size_t n), | ||
| 1250 | _GL_ARG_NONNULL ((1)) | ||
| 1251 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 1252 | # endif | ||
| 1156 | _GL_CXXALIAS_SYS (wcsncat, wchar_t *, | 1253 | _GL_CXXALIAS_SYS (wcsncat, wchar_t *, |
| 1157 | (wchar_t *restrict dest, const wchar_t *restrict src, | 1254 | (wchar_t *restrict dest, const wchar_t *restrict src, |
| 1158 | size_t n)); | 1255 | size_t n)); |
| 1256 | # endif | ||
| 1159 | # if __GLIBC__ >= 2 | 1257 | # if __GLIBC__ >= 2 |
| 1160 | _GL_CXXALIASWARN (wcsncat); | 1258 | _GL_CXXALIASWARN (wcsncat); |
| 1161 | # endif | 1259 | # endif |
| @@ -1175,12 +1273,12 @@ _GL_WARN_ON_USE (wcsncat, "wcsncat is unportable - " | |||
| 1175 | # undef wcscmp | 1273 | # undef wcscmp |
| 1176 | # define wcscmp rpl_wcscmp | 1274 | # define wcscmp rpl_wcscmp |
| 1177 | # endif | 1275 | # endif |
| 1178 | _GL_FUNCDECL_RPL (wcscmp, int, (const wchar_t *s1, const wchar_t *s2) | 1276 | _GL_FUNCDECL_RPL (wcscmp, int, (const wchar_t *s1, const wchar_t *s2), |
| 1179 | _GL_ATTRIBUTE_PURE); | 1277 | _GL_ATTRIBUTE_PURE); |
| 1180 | _GL_CXXALIAS_RPL (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)); | 1278 | _GL_CXXALIAS_RPL (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)); |
| 1181 | # else | 1279 | # else |
| 1182 | # if !@HAVE_WCSCMP@ | 1280 | # if !@HAVE_WCSCMP@ |
| 1183 | _GL_FUNCDECL_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2) | 1281 | _GL_FUNCDECL_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2), |
| 1184 | _GL_ATTRIBUTE_PURE); | 1282 | _GL_ATTRIBUTE_PURE); |
| 1185 | # endif | 1283 | # endif |
| 1186 | _GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)); | 1284 | _GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)); |
| @@ -1205,15 +1303,19 @@ _GL_WARN_ON_USE (wcscmp, "wcscmp is unportable - " | |||
| 1205 | # define wcsncmp rpl_wcsncmp | 1303 | # define wcsncmp rpl_wcsncmp |
| 1206 | # endif | 1304 | # endif |
| 1207 | _GL_FUNCDECL_RPL (wcsncmp, int, | 1305 | _GL_FUNCDECL_RPL (wcsncmp, int, |
| 1208 | (const wchar_t *s1, const wchar_t *s2, size_t n) | 1306 | (const wchar_t *s1, const wchar_t *s2, size_t n), |
| 1209 | _GL_ATTRIBUTE_PURE); | 1307 | _GL_ATTRIBUTE_PURE |
| 1308 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 1309 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 1210 | _GL_CXXALIAS_RPL (wcsncmp, int, | 1310 | _GL_CXXALIAS_RPL (wcsncmp, int, |
| 1211 | (const wchar_t *s1, const wchar_t *s2, size_t n)); | 1311 | (const wchar_t *s1, const wchar_t *s2, size_t n)); |
| 1212 | # else | 1312 | # else |
| 1213 | # if !@HAVE_WCSNCMP@ | 1313 | # if !@HAVE_WCSNCMP@ |
| 1214 | _GL_FUNCDECL_SYS (wcsncmp, int, | 1314 | _GL_FUNCDECL_SYS (wcsncmp, int, |
| 1215 | (const wchar_t *s1, const wchar_t *s2, size_t n) | 1315 | (const wchar_t *s1, const wchar_t *s2, size_t n), |
| 1216 | _GL_ATTRIBUTE_PURE); | 1316 | _GL_ATTRIBUTE_PURE |
| 1317 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) | ||
| 1318 | _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3)); | ||
| 1217 | # endif | 1319 | # endif |
| 1218 | _GL_CXXALIAS_SYS (wcsncmp, int, | 1320 | _GL_CXXALIAS_SYS (wcsncmp, int, |
| 1219 | (const wchar_t *s1, const wchar_t *s2, size_t n)); | 1321 | (const wchar_t *s1, const wchar_t *s2, size_t n)); |
| @@ -1236,7 +1338,7 @@ _GL_WARN_ON_USE (wcsncmp, "wcsncmp is unportable - " | |||
| 1236 | namespace, not in the global namespace. So, force a declaration in | 1338 | namespace, not in the global namespace. So, force a declaration in |
| 1237 | the global namespace. */ | 1339 | the global namespace. */ |
| 1238 | # if !@HAVE_WCSCASECMP@ || (defined __sun && defined __cplusplus) | 1340 | # if !@HAVE_WCSCASECMP@ || (defined __sun && defined __cplusplus) |
| 1239 | _GL_FUNCDECL_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2) | 1341 | _GL_FUNCDECL_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2), |
| 1240 | _GL_ATTRIBUTE_PURE); | 1342 | _GL_ATTRIBUTE_PURE); |
| 1241 | # endif | 1343 | # endif |
| 1242 | _GL_CXXALIAS_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2)); | 1344 | _GL_CXXALIAS_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2)); |
| @@ -1257,7 +1359,7 @@ _GL_WARN_ON_USE (wcscasecmp, "wcscasecmp is unportable - " | |||
| 1257 | the global namespace. */ | 1359 | the global namespace. */ |
| 1258 | # if !@HAVE_WCSNCASECMP@ || (defined __sun && defined __cplusplus) | 1360 | # if !@HAVE_WCSNCASECMP@ || (defined __sun && defined __cplusplus) |
| 1259 | _GL_FUNCDECL_SYS (wcsncasecmp, int, | 1361 | _GL_FUNCDECL_SYS (wcsncasecmp, int, |
| 1260 | (const wchar_t *s1, const wchar_t *s2, size_t n) | 1362 | (const wchar_t *s1, const wchar_t *s2, size_t n), |
| 1261 | _GL_ATTRIBUTE_PURE); | 1363 | _GL_ATTRIBUTE_PURE); |
| 1262 | # endif | 1364 | # endif |
| 1263 | _GL_CXXALIAS_SYS (wcsncasecmp, int, | 1365 | _GL_CXXALIAS_SYS (wcsncasecmp, int, |
| @@ -1276,7 +1378,7 @@ _GL_WARN_ON_USE (wcsncasecmp, "wcsncasecmp is unportable - " | |||
| 1276 | category of the current locale. */ | 1378 | category of the current locale. */ |
| 1277 | #if @GNULIB_WCSCOLL@ | 1379 | #if @GNULIB_WCSCOLL@ |
| 1278 | # if !@HAVE_WCSCOLL@ | 1380 | # if !@HAVE_WCSCOLL@ |
| 1279 | _GL_FUNCDECL_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); | 1381 | _GL_FUNCDECL_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2), ); |
| 1280 | # endif | 1382 | # endif |
| 1281 | _GL_CXXALIAS_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); | 1383 | _GL_CXXALIAS_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); |
| 1282 | # if __GLIBC__ >= 2 | 1384 | # if __GLIBC__ >= 2 |
| @@ -1297,7 +1399,7 @@ _GL_WARN_ON_USE (wcscoll, "wcscoll is unportable - " | |||
| 1297 | #if @GNULIB_WCSXFRM@ | 1399 | #if @GNULIB_WCSXFRM@ |
| 1298 | # if !@HAVE_WCSXFRM@ | 1400 | # if !@HAVE_WCSXFRM@ |
| 1299 | _GL_FUNCDECL_SYS (wcsxfrm, size_t, | 1401 | _GL_FUNCDECL_SYS (wcsxfrm, size_t, |
| 1300 | (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n)); | 1402 | (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n), ); |
| 1301 | # endif | 1403 | # endif |
| 1302 | _GL_CXXALIAS_SYS (wcsxfrm, size_t, | 1404 | _GL_CXXALIAS_SYS (wcsxfrm, size_t, |
| 1303 | (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n)); | 1405 | (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n)); |
| @@ -1325,15 +1427,16 @@ _GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s)); | |||
| 1325 | /* On Solaris 11.3, the header files declare the function in the std:: | 1427 | /* On Solaris 11.3, the header files declare the function in the std:: |
| 1326 | namespace, not in the global namespace. So, force a declaration in | 1428 | namespace, not in the global namespace. So, force a declaration in |
| 1327 | the global namespace. */ | 1429 | the global namespace. */ |
| 1328 | # if !@HAVE_WCSDUP@ || (defined __sun && defined __cplusplus) || __GNUC__ >= 11 | 1430 | # if !@HAVE_WCSDUP@ || (defined __sun && defined __cplusplus) \ |
| 1431 | || (__GNUC__ >= 11 && !defined __clang__) | ||
| 1329 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 1432 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 1330 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, | 1433 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, |
| 1331 | (const wchar_t *s) | 1434 | (const wchar_t *s), |
| 1332 | _GL_ATTRIBUTE_NOTHROW | 1435 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 1333 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 1436 | _GL_ATTRIBUTE_NOTHROW; |
| 1334 | # else | 1437 | # else |
| 1335 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, | 1438 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, |
| 1336 | (const wchar_t *s) | 1439 | (const wchar_t *s), |
| 1337 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 1440 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 1338 | # endif | 1441 | # endif |
| 1339 | # endif | 1442 | # endif |
| @@ -1341,16 +1444,16 @@ _GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s)); | |||
| 1341 | # endif | 1444 | # endif |
| 1342 | _GL_CXXALIASWARN (wcsdup); | 1445 | _GL_CXXALIASWARN (wcsdup); |
| 1343 | #else | 1446 | #else |
| 1344 | # if __GNUC__ >= 11 && !defined wcsdup | 1447 | # if (__GNUC__ >= 11 && !defined __clang__) && !defined wcsdup |
| 1345 | /* For -Wmismatched-dealloc: Associate wcsdup with free or rpl_free. */ | 1448 | /* For -Wmismatched-dealloc: Associate wcsdup with free or rpl_free. */ |
| 1346 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 1449 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 1347 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, | 1450 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, |
| 1348 | (const wchar_t *s) | 1451 | (const wchar_t *s), |
| 1349 | _GL_ATTRIBUTE_NOTHROW | 1452 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 1350 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 1453 | _GL_ATTRIBUTE_NOTHROW; |
| 1351 | # else | 1454 | # else |
| 1352 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, | 1455 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, |
| 1353 | (const wchar_t *s) | 1456 | (const wchar_t *s), |
| 1354 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 1457 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 1355 | # endif | 1458 | # endif |
| 1356 | # endif | 1459 | # endif |
| @@ -1373,12 +1476,12 @@ _GL_CXXALIAS_MDA (wcsdup, wchar_t *, (const wchar_t *s)); | |||
| 1373 | # else | 1476 | # else |
| 1374 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 | 1477 | # if __GLIBC__ + (__GLIBC_MINOR__ >= 2) > 2 |
| 1375 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, | 1478 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, |
| 1376 | (const wchar_t *s) | 1479 | (const wchar_t *s), |
| 1377 | _GL_ATTRIBUTE_NOTHROW | 1480 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE) |
| 1378 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 1481 | _GL_ATTRIBUTE_NOTHROW; |
| 1379 | # else | 1482 | # else |
| 1380 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, | 1483 | _GL_FUNCDECL_SYS (wcsdup, wchar_t *, |
| 1381 | (const wchar_t *s) | 1484 | (const wchar_t *s), |
| 1382 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); | 1485 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE); |
| 1383 | # endif | 1486 | # endif |
| 1384 | # if @HAVE_DECL_WCSDUP@ | 1487 | # if @HAVE_DECL_WCSDUP@ |
| @@ -1395,7 +1498,7 @@ _GL_CXXALIASWARN (wcsdup); | |||
| 1395 | /* Find the first occurrence of WC in WCS. */ | 1498 | /* Find the first occurrence of WC in WCS. */ |
| 1396 | #if @GNULIB_WCSCHR@ | 1499 | #if @GNULIB_WCSCHR@ |
| 1397 | # if !@HAVE_WCSCHR@ | 1500 | # if !@HAVE_WCSCHR@ |
| 1398 | _GL_FUNCDECL_SYS (wcschr, wchar_t *, (const wchar_t *wcs, wchar_t wc) | 1501 | _GL_FUNCDECL_SYS (wcschr, wchar_t *, (const wchar_t *wcs, wchar_t wc), |
| 1399 | _GL_ATTRIBUTE_PURE); | 1502 | _GL_ATTRIBUTE_PURE); |
| 1400 | # endif | 1503 | # endif |
| 1401 | /* On some systems, this function is defined as an overloaded function: | 1504 | /* On some systems, this function is defined as an overloaded function: |
| @@ -1407,10 +1510,11 @@ _GL_CXXALIAS_SYS_CAST2 (wcschr, | |||
| 1407 | wchar_t *, (const wchar_t *, wchar_t), | 1510 | wchar_t *, (const wchar_t *, wchar_t), |
| 1408 | const wchar_t *, (const wchar_t *, wchar_t)); | 1511 | const wchar_t *, (const wchar_t *, wchar_t)); |
| 1409 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ | 1512 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ |
| 1410 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) | 1513 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ |
| 1514 | && !defined __clang__ | ||
| 1411 | _GL_CXXALIASWARN1 (wcschr, wchar_t *, (wchar_t *wcs, wchar_t wc)); | 1515 | _GL_CXXALIASWARN1 (wcschr, wchar_t *, (wchar_t *wcs, wchar_t wc)); |
| 1412 | _GL_CXXALIASWARN1 (wcschr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); | 1516 | _GL_CXXALIASWARN1 (wcschr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); |
| 1413 | # elif __GLIBC__ >= 2 | 1517 | # elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO |
| 1414 | _GL_CXXALIASWARN (wcschr); | 1518 | _GL_CXXALIASWARN (wcschr); |
| 1415 | # endif | 1519 | # endif |
| 1416 | #elif defined GNULIB_POSIXCHECK | 1520 | #elif defined GNULIB_POSIXCHECK |
| @@ -1425,7 +1529,7 @@ _GL_WARN_ON_USE (wcschr, "wcschr is unportable - " | |||
| 1425 | /* Find the last occurrence of WC in WCS. */ | 1529 | /* Find the last occurrence of WC in WCS. */ |
| 1426 | #if @GNULIB_WCSRCHR@ | 1530 | #if @GNULIB_WCSRCHR@ |
| 1427 | # if !@HAVE_WCSRCHR@ | 1531 | # if !@HAVE_WCSRCHR@ |
| 1428 | _GL_FUNCDECL_SYS (wcsrchr, wchar_t *, (const wchar_t *wcs, wchar_t wc) | 1532 | _GL_FUNCDECL_SYS (wcsrchr, wchar_t *, (const wchar_t *wcs, wchar_t wc), |
| 1429 | _GL_ATTRIBUTE_PURE); | 1533 | _GL_ATTRIBUTE_PURE); |
| 1430 | # endif | 1534 | # endif |
| 1431 | /* On some systems, this function is defined as an overloaded function: | 1535 | /* On some systems, this function is defined as an overloaded function: |
| @@ -1437,10 +1541,11 @@ _GL_CXXALIAS_SYS_CAST2 (wcsrchr, | |||
| 1437 | wchar_t *, (const wchar_t *, wchar_t), | 1541 | wchar_t *, (const wchar_t *, wchar_t), |
| 1438 | const wchar_t *, (const wchar_t *, wchar_t)); | 1542 | const wchar_t *, (const wchar_t *, wchar_t)); |
| 1439 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ | 1543 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ |
| 1440 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) | 1544 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ |
| 1545 | && !defined __clang__ | ||
| 1441 | _GL_CXXALIASWARN1 (wcsrchr, wchar_t *, (wchar_t *wcs, wchar_t wc)); | 1546 | _GL_CXXALIASWARN1 (wcsrchr, wchar_t *, (wchar_t *wcs, wchar_t wc)); |
| 1442 | _GL_CXXALIASWARN1 (wcsrchr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); | 1547 | _GL_CXXALIASWARN1 (wcsrchr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); |
| 1443 | # elif __GLIBC__ >= 2 | 1548 | # elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO |
| 1444 | _GL_CXXALIASWARN (wcsrchr); | 1549 | _GL_CXXALIASWARN (wcsrchr); |
| 1445 | # endif | 1550 | # endif |
| 1446 | #elif defined GNULIB_POSIXCHECK | 1551 | #elif defined GNULIB_POSIXCHECK |
| @@ -1456,7 +1561,7 @@ _GL_WARN_ON_USE (wcsrchr, "wcsrchr is unportable - " | |||
| 1456 | of wide characters not in REJECT. */ | 1561 | of wide characters not in REJECT. */ |
| 1457 | #if @GNULIB_WCSCSPN@ | 1562 | #if @GNULIB_WCSCSPN@ |
| 1458 | # if !@HAVE_WCSCSPN@ | 1563 | # if !@HAVE_WCSCSPN@ |
| 1459 | _GL_FUNCDECL_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject) | 1564 | _GL_FUNCDECL_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject), |
| 1460 | _GL_ATTRIBUTE_PURE); | 1565 | _GL_ATTRIBUTE_PURE); |
| 1461 | # endif | 1566 | # endif |
| 1462 | _GL_CXXALIAS_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject)); | 1567 | _GL_CXXALIAS_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject)); |
| @@ -1476,7 +1581,7 @@ _GL_WARN_ON_USE (wcscspn, "wcscspn is unportable - " | |||
| 1476 | of wide characters in ACCEPT. */ | 1581 | of wide characters in ACCEPT. */ |
| 1477 | #if @GNULIB_WCSSPN@ | 1582 | #if @GNULIB_WCSSPN@ |
| 1478 | # if !@HAVE_WCSSPN@ | 1583 | # if !@HAVE_WCSSPN@ |
| 1479 | _GL_FUNCDECL_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept) | 1584 | _GL_FUNCDECL_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept), |
| 1480 | _GL_ATTRIBUTE_PURE); | 1585 | _GL_ATTRIBUTE_PURE); |
| 1481 | # endif | 1586 | # endif |
| 1482 | _GL_CXXALIAS_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept)); | 1587 | _GL_CXXALIAS_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept)); |
| @@ -1496,7 +1601,7 @@ _GL_WARN_ON_USE (wcsspn, "wcsspn is unportable - " | |||
| 1496 | #if @GNULIB_WCSPBRK@ | 1601 | #if @GNULIB_WCSPBRK@ |
| 1497 | # if !@HAVE_WCSPBRK@ | 1602 | # if !@HAVE_WCSPBRK@ |
| 1498 | _GL_FUNCDECL_SYS (wcspbrk, wchar_t *, | 1603 | _GL_FUNCDECL_SYS (wcspbrk, wchar_t *, |
| 1499 | (const wchar_t *wcs, const wchar_t *accept) | 1604 | (const wchar_t *wcs, const wchar_t *accept), |
| 1500 | _GL_ATTRIBUTE_PURE); | 1605 | _GL_ATTRIBUTE_PURE); |
| 1501 | # endif | 1606 | # endif |
| 1502 | /* On some systems, this function is defined as an overloaded function: | 1607 | /* On some systems, this function is defined as an overloaded function: |
| @@ -1508,12 +1613,13 @@ _GL_CXXALIAS_SYS_CAST2 (wcspbrk, | |||
| 1508 | wchar_t *, (const wchar_t *, const wchar_t *), | 1613 | wchar_t *, (const wchar_t *, const wchar_t *), |
| 1509 | const wchar_t *, (const wchar_t *, const wchar_t *)); | 1614 | const wchar_t *, (const wchar_t *, const wchar_t *)); |
| 1510 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ | 1615 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ |
| 1511 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) | 1616 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ |
| 1617 | && !defined __clang__ | ||
| 1512 | _GL_CXXALIASWARN1 (wcspbrk, wchar_t *, | 1618 | _GL_CXXALIASWARN1 (wcspbrk, wchar_t *, |
| 1513 | (wchar_t *wcs, const wchar_t *accept)); | 1619 | (wchar_t *wcs, const wchar_t *accept)); |
| 1514 | _GL_CXXALIASWARN1 (wcspbrk, const wchar_t *, | 1620 | _GL_CXXALIASWARN1 (wcspbrk, const wchar_t *, |
| 1515 | (const wchar_t *wcs, const wchar_t *accept)); | 1621 | (const wchar_t *wcs, const wchar_t *accept)); |
| 1516 | # elif __GLIBC__ >= 2 | 1622 | # elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO |
| 1517 | _GL_CXXALIASWARN (wcspbrk); | 1623 | _GL_CXXALIASWARN (wcspbrk); |
| 1518 | # endif | 1624 | # endif |
| 1519 | #elif defined GNULIB_POSIXCHECK | 1625 | #elif defined GNULIB_POSIXCHECK |
| @@ -1534,7 +1640,7 @@ _GL_WARN_ON_USE (wcspbrk, "wcspbrk is unportable - " | |||
| 1534 | # endif | 1640 | # endif |
| 1535 | _GL_FUNCDECL_RPL (wcsstr, wchar_t *, | 1641 | _GL_FUNCDECL_RPL (wcsstr, wchar_t *, |
| 1536 | (const wchar_t *restrict haystack, | 1642 | (const wchar_t *restrict haystack, |
| 1537 | const wchar_t *restrict needle) | 1643 | const wchar_t *restrict needle), |
| 1538 | _GL_ATTRIBUTE_PURE); | 1644 | _GL_ATTRIBUTE_PURE); |
| 1539 | _GL_CXXALIAS_RPL (wcsstr, wchar_t *, | 1645 | _GL_CXXALIAS_RPL (wcsstr, wchar_t *, |
| 1540 | (const wchar_t *restrict haystack, | 1646 | (const wchar_t *restrict haystack, |
| @@ -1543,7 +1649,7 @@ _GL_CXXALIAS_RPL (wcsstr, wchar_t *, | |||
| 1543 | # if !@HAVE_WCSSTR@ | 1649 | # if !@HAVE_WCSSTR@ |
| 1544 | _GL_FUNCDECL_SYS (wcsstr, wchar_t *, | 1650 | _GL_FUNCDECL_SYS (wcsstr, wchar_t *, |
| 1545 | (const wchar_t *restrict haystack, | 1651 | (const wchar_t *restrict haystack, |
| 1546 | const wchar_t *restrict needle) | 1652 | const wchar_t *restrict needle), |
| 1547 | _GL_ATTRIBUTE_PURE); | 1653 | _GL_ATTRIBUTE_PURE); |
| 1548 | # endif | 1654 | # endif |
| 1549 | /* On some systems, this function is defined as an overloaded function: | 1655 | /* On some systems, this function is defined as an overloaded function: |
| @@ -1558,14 +1664,15 @@ _GL_CXXALIAS_SYS_CAST2 (wcsstr, | |||
| 1558 | (const wchar_t *restrict, const wchar_t *restrict)); | 1664 | (const wchar_t *restrict, const wchar_t *restrict)); |
| 1559 | # endif | 1665 | # endif |
| 1560 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ | 1666 | # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ |
| 1561 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) | 1667 | && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) \ |
| 1668 | && !defined __clang__ | ||
| 1562 | _GL_CXXALIASWARN1 (wcsstr, wchar_t *, | 1669 | _GL_CXXALIASWARN1 (wcsstr, wchar_t *, |
| 1563 | (wchar_t *restrict haystack, | 1670 | (wchar_t *restrict haystack, |
| 1564 | const wchar_t *restrict needle)); | 1671 | const wchar_t *restrict needle)); |
| 1565 | _GL_CXXALIASWARN1 (wcsstr, const wchar_t *, | 1672 | _GL_CXXALIASWARN1 (wcsstr, const wchar_t *, |
| 1566 | (const wchar_t *restrict haystack, | 1673 | (const wchar_t *restrict haystack, |
| 1567 | const wchar_t *restrict needle)); | 1674 | const wchar_t *restrict needle)); |
| 1568 | # elif __GLIBC__ >= 2 | 1675 | # elif __GLIBC__ >= 2 && !defined __CORRECT_ISO_CPP_WCHAR_H_PROTO |
| 1569 | _GL_CXXALIASWARN (wcsstr); | 1676 | _GL_CXXALIASWARN (wcsstr); |
| 1570 | # endif | 1677 | # endif |
| 1571 | #elif defined GNULIB_POSIXCHECK | 1678 | #elif defined GNULIB_POSIXCHECK |
| @@ -1586,7 +1693,7 @@ _GL_WARN_ON_USE (wcsstr, "wcsstr is unportable - " | |||
| 1586 | # endif | 1693 | # endif |
| 1587 | _GL_FUNCDECL_RPL (wcstok, wchar_t *, | 1694 | _GL_FUNCDECL_RPL (wcstok, wchar_t *, |
| 1588 | (wchar_t *restrict wcs, const wchar_t *restrict delim, | 1695 | (wchar_t *restrict wcs, const wchar_t *restrict delim, |
| 1589 | wchar_t **restrict ptr)); | 1696 | wchar_t **restrict ptr), ); |
| 1590 | _GL_CXXALIAS_RPL (wcstok, wchar_t *, | 1697 | _GL_CXXALIAS_RPL (wcstok, wchar_t *, |
| 1591 | (wchar_t *restrict wcs, const wchar_t *restrict delim, | 1698 | (wchar_t *restrict wcs, const wchar_t *restrict delim, |
| 1592 | wchar_t **restrict ptr)); | 1699 | wchar_t **restrict ptr)); |
| @@ -1594,7 +1701,7 @@ _GL_CXXALIAS_RPL (wcstok, wchar_t *, | |||
| 1594 | # if !@HAVE_WCSTOK@ | 1701 | # if !@HAVE_WCSTOK@ |
| 1595 | _GL_FUNCDECL_SYS (wcstok, wchar_t *, | 1702 | _GL_FUNCDECL_SYS (wcstok, wchar_t *, |
| 1596 | (wchar_t *restrict wcs, const wchar_t *restrict delim, | 1703 | (wchar_t *restrict wcs, const wchar_t *restrict delim, |
| 1597 | wchar_t **restrict ptr)); | 1704 | wchar_t **restrict ptr), ); |
| 1598 | # endif | 1705 | # endif |
| 1599 | _GL_CXXALIAS_SYS (wcstok, wchar_t *, | 1706 | _GL_CXXALIAS_SYS (wcstok, wchar_t *, |
| 1600 | (wchar_t *restrict wcs, const wchar_t *restrict delim, | 1707 | (wchar_t *restrict wcs, const wchar_t *restrict delim, |
| @@ -1620,12 +1727,12 @@ _GL_WARN_ON_USE (wcstok, "wcstok is unportable - " | |||
| 1620 | # undef wcswidth | 1727 | # undef wcswidth |
| 1621 | # define wcswidth rpl_wcswidth | 1728 | # define wcswidth rpl_wcswidth |
| 1622 | # endif | 1729 | # endif |
| 1623 | _GL_FUNCDECL_RPL (wcswidth, int, (const wchar_t *s, size_t n) | 1730 | _GL_FUNCDECL_RPL (wcswidth, int, (const wchar_t *s, size_t n), |
| 1624 | _GL_ATTRIBUTE_PURE); | 1731 | _GL_ATTRIBUTE_PURE); |
| 1625 | _GL_CXXALIAS_RPL (wcswidth, int, (const wchar_t *s, size_t n)); | 1732 | _GL_CXXALIAS_RPL (wcswidth, int, (const wchar_t *s, size_t n)); |
| 1626 | # else | 1733 | # else |
| 1627 | # if !@HAVE_WCSWIDTH@ | 1734 | # if !@HAVE_WCSWIDTH@ |
| 1628 | _GL_FUNCDECL_SYS (wcswidth, int, (const wchar_t *s, size_t n) | 1735 | _GL_FUNCDECL_SYS (wcswidth, int, (const wchar_t *s, size_t n), |
| 1629 | _GL_ATTRIBUTE_PURE); | 1736 | _GL_ATTRIBUTE_PURE); |
| 1630 | # endif | 1737 | # endif |
| 1631 | _GL_CXXALIAS_SYS (wcswidth, int, (const wchar_t *s, size_t n)); | 1738 | _GL_CXXALIAS_SYS (wcswidth, int, (const wchar_t *s, size_t n)); |
| @@ -1653,7 +1760,7 @@ _GL_WARN_ON_USE (wcswidth, "wcswidth is unportable - " | |||
| 1653 | _GL_FUNCDECL_RPL (wcsftime, size_t, | 1760 | _GL_FUNCDECL_RPL (wcsftime, size_t, |
| 1654 | (wchar_t *restrict __buf, size_t __bufsize, | 1761 | (wchar_t *restrict __buf, size_t __bufsize, |
| 1655 | const wchar_t *restrict __fmt, | 1762 | const wchar_t *restrict __fmt, |
| 1656 | const struct tm *restrict __tp) | 1763 | const struct tm *restrict __tp), |
| 1657 | _GL_ARG_NONNULL ((1, 3, 4))); | 1764 | _GL_ARG_NONNULL ((1, 3, 4))); |
| 1658 | _GL_CXXALIAS_RPL (wcsftime, size_t, | 1765 | _GL_CXXALIAS_RPL (wcsftime, size_t, |
| 1659 | (wchar_t *restrict __buf, size_t __bufsize, | 1766 | (wchar_t *restrict __buf, size_t __bufsize, |
| @@ -1664,7 +1771,7 @@ _GL_CXXALIAS_RPL (wcsftime, size_t, | |||
| 1664 | _GL_FUNCDECL_SYS (wcsftime, size_t, | 1771 | _GL_FUNCDECL_SYS (wcsftime, size_t, |
| 1665 | (wchar_t *restrict __buf, size_t __bufsize, | 1772 | (wchar_t *restrict __buf, size_t __bufsize, |
| 1666 | const wchar_t *restrict __fmt, | 1773 | const wchar_t *restrict __fmt, |
| 1667 | const struct tm *restrict __tp) | 1774 | const struct tm *restrict __tp), |
| 1668 | _GL_ARG_NONNULL ((1, 3, 4))); | 1775 | _GL_ARG_NONNULL ((1, 3, 4))); |
| 1669 | # endif | 1776 | # endif |
| 1670 | _GL_CXXALIAS_SYS (wcsftime, size_t, | 1777 | _GL_CXXALIAS_SYS (wcsftime, size_t, |
| @@ -1698,7 +1805,7 @@ _GL_WARN_ON_USE (wcsftime, "wcsftime is unportable - " | |||
| 1698 | Possible errno values include: | 1805 | Possible errno values include: |
| 1699 | - ERANGE if SIZE is too small. | 1806 | - ERANGE if SIZE is too small. |
| 1700 | - ENOMEM if the memory could no be allocated. */ | 1807 | - ENOMEM if the memory could no be allocated. */ |
| 1701 | _GL_FUNCDECL_SYS (wgetcwd, wchar_t *, (wchar_t *buf, size_t size)); | 1808 | _GL_FUNCDECL_SYS (wgetcwd, wchar_t *, (wchar_t *buf, size_t size), ); |
| 1702 | #endif | 1809 | #endif |
| 1703 | 1810 | ||
| 1704 | 1811 | ||
diff --git a/gl/wcrtomb.c b/gl/wcrtomb.c index 197b020e..c9ebcf0c 100644 --- a/gl/wcrtomb.c +++ b/gl/wcrtomb.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Convert wide character to multibyte character. | 1 | /* Convert wide character to multibyte character. |
| 2 | Copyright (C) 2008-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2008. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/wctype-h.c b/gl/wctype-h.c index 7e4ff13a..098014a9 100644 --- a/gl/wctype-h.c +++ b/gl/wctype-h.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Inline functions for <wctype.h>. | 1 | /* Inline functions for <wctype.h>. |
| 2 | 2 | ||
| 3 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2012-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -17,7 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | /* Normally this would be wctype.c, but that name's already taken. */ | 18 | /* Normally this would be wctype.c, but that name's already taken. */ |
| 19 | 19 | ||
| 20 | #define _GL_WCTYPE_INLINE _GL_EXTERN_INLINE | ||
| 20 | #include <config.h> | 21 | #include <config.h> |
| 21 | 22 | ||
| 22 | #define _GL_WCTYPE_INLINE _GL_EXTERN_INLINE | ||
| 23 | #include <wctype.h> | 23 | #include <wctype.h> |
diff --git a/gl/wctype-impl.h b/gl/wctype-impl.h index 26d68b41..8bb83be7 100644 --- a/gl/wctype-impl.h +++ b/gl/wctype-impl.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Get descriptor for a wide character property. | 1 | /* Get descriptor for a wide character property. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/wctype.c b/gl/wctype.c index 914f6847..b421ad38 100644 --- a/gl/wctype.c +++ b/gl/wctype.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Get descriptor for a wide character property. | 1 | /* Get descriptor for a wide character property. |
| 2 | Copyright (C) 2011-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2011-2025 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2011. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
diff --git a/gl/wctype.in.h b/gl/wctype.in.h index 851c4f4e..aa4a8e7d 100644 --- a/gl/wctype.in.h +++ b/gl/wctype.in.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* A substitute for ISO C99 <wctype.h>, for platforms that lack it. | 1 | /* A substitute for ISO C99 <wctype.h>, for platforms that lack it. |
| 2 | 2 | ||
| 3 | Copyright (C) 2006-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2006-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -478,9 +478,9 @@ towupper | |||
| 478 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) | 478 | # if !(defined __cplusplus && defined GNULIB_NAMESPACE) |
| 479 | # define iswblank rpl_iswblank | 479 | # define iswblank rpl_iswblank |
| 480 | # endif | 480 | # endif |
| 481 | _GL_FUNCDECL_RPL (iswblank, int, (wint_t wc)); | 481 | _GL_FUNCDECL_RPL (iswblank, int, (wint_t wc), ); |
| 482 | # else | 482 | # else |
| 483 | _GL_FUNCDECL_SYS (iswblank, int, (wint_t wc)); | 483 | _GL_FUNCDECL_SYS (iswblank, int, (wint_t wc), ); |
| 484 | # endif | 484 | # endif |
| 485 | # endif | 485 | # endif |
| 486 | 486 | ||
| @@ -490,7 +490,7 @@ _GL_FUNCDECL_SYS (iswblank, int, (wint_t wc)); | |||
| 490 | # undef iswdigit | 490 | # undef iswdigit |
| 491 | # define iswdigit rpl_iswdigit | 491 | # define iswdigit rpl_iswdigit |
| 492 | # endif | 492 | # endif |
| 493 | _GL_FUNCDECL_RPL (iswdigit, int, (wint_t wc)); | 493 | _GL_FUNCDECL_RPL (iswdigit, int, (wint_t wc), ); |
| 494 | # endif | 494 | # endif |
| 495 | # endif | 495 | # endif |
| 496 | 496 | ||
| @@ -500,7 +500,7 @@ _GL_FUNCDECL_RPL (iswdigit, int, (wint_t wc)); | |||
| 500 | # undef iswpunct | 500 | # undef iswpunct |
| 501 | # define iswpunct rpl_iswpunct | 501 | # define iswpunct rpl_iswpunct |
| 502 | # endif | 502 | # endif |
| 503 | _GL_FUNCDECL_RPL (iswpunct, int, (wint_t wc)); | 503 | _GL_FUNCDECL_RPL (iswpunct, int, (wint_t wc), ); |
| 504 | # endif | 504 | # endif |
| 505 | # endif | 505 | # endif |
| 506 | 506 | ||
| @@ -510,7 +510,7 @@ _GL_FUNCDECL_RPL (iswpunct, int, (wint_t wc)); | |||
| 510 | # undef iswxdigit | 510 | # undef iswxdigit |
| 511 | # define iswxdigit rpl_iswxdigit | 511 | # define iswxdigit rpl_iswxdigit |
| 512 | # endif | 512 | # endif |
| 513 | _GL_FUNCDECL_RPL (iswxdigit, int, (wint_t wc)); | 513 | _GL_FUNCDECL_RPL (iswxdigit, int, (wint_t wc), ); |
| 514 | # endif | 514 | # endif |
| 515 | # endif | 515 | # endif |
| 516 | 516 | ||
| @@ -659,12 +659,12 @@ typedef void *rpl_wctype_t; | |||
| 659 | # undef wctype | 659 | # undef wctype |
| 660 | # define wctype rpl_wctype | 660 | # define wctype rpl_wctype |
| 661 | # endif | 661 | # endif |
| 662 | _GL_FUNCDECL_RPL (wctype, wctype_t, (const char *name) | 662 | _GL_FUNCDECL_RPL (wctype, wctype_t, (const char *name), |
| 663 | _GL_ARG_NONNULL ((1))); | 663 | _GL_ARG_NONNULL ((1))); |
| 664 | _GL_CXXALIAS_RPL (wctype, wctype_t, (const char *name)); | 664 | _GL_CXXALIAS_RPL (wctype, wctype_t, (const char *name)); |
| 665 | # else | 665 | # else |
| 666 | # if !@HAVE_WCTYPE_T@ | 666 | # if !@HAVE_WCTYPE_T@ |
| 667 | _GL_FUNCDECL_SYS (wctype, wctype_t, (const char *name) | 667 | _GL_FUNCDECL_SYS (wctype, wctype_t, (const char *name), |
| 668 | _GL_ARG_NONNULL ((1))); | 668 | _GL_ARG_NONNULL ((1))); |
| 669 | # endif | 669 | # endif |
| 670 | _GL_CXXALIAS_SYS (wctype, wctype_t, (const char *name)); | 670 | _GL_CXXALIAS_SYS (wctype, wctype_t, (const char *name)); |
| @@ -689,11 +689,11 @@ _GL_WARN_ON_USE (wctype, "wctype is unportable - " | |||
| 689 | # undef iswctype | 689 | # undef iswctype |
| 690 | # define iswctype rpl_iswctype | 690 | # define iswctype rpl_iswctype |
| 691 | # endif | 691 | # endif |
| 692 | _GL_FUNCDECL_RPL (iswctype, int, (wint_t wc, wctype_t desc)); | 692 | _GL_FUNCDECL_RPL (iswctype, int, (wint_t wc, wctype_t desc), ); |
| 693 | _GL_CXXALIAS_RPL (iswctype, int, (wint_t wc, wctype_t desc)); | 693 | _GL_CXXALIAS_RPL (iswctype, int, (wint_t wc, wctype_t desc)); |
| 694 | # else | 694 | # else |
| 695 | # if !@HAVE_WCTYPE_T@ | 695 | # if !@HAVE_WCTYPE_T@ |
| 696 | _GL_FUNCDECL_SYS (iswctype, int, (wint_t wc, wctype_t desc)); | 696 | _GL_FUNCDECL_SYS (iswctype, int, (wint_t wc, wctype_t desc), ); |
| 697 | # endif | 697 | # endif |
| 698 | _GL_CXXALIAS_SYS (iswctype, int, (wint_t wc, wctype_t desc)); | 698 | _GL_CXXALIAS_SYS (iswctype, int, (wint_t wc, wctype_t desc)); |
| 699 | # endif | 699 | # endif |
| @@ -741,12 +741,12 @@ typedef void *rpl_wctrans_t; | |||
| 741 | # undef wctrans | 741 | # undef wctrans |
| 742 | # define wctrans rpl_wctrans | 742 | # define wctrans rpl_wctrans |
| 743 | # endif | 743 | # endif |
| 744 | _GL_FUNCDECL_RPL (wctrans, wctrans_t, (const char *name) | 744 | _GL_FUNCDECL_RPL (wctrans, wctrans_t, (const char *name), |
| 745 | _GL_ARG_NONNULL ((1))); | 745 | _GL_ARG_NONNULL ((1))); |
| 746 | _GL_CXXALIAS_RPL (wctrans, wctrans_t, (const char *name)); | 746 | _GL_CXXALIAS_RPL (wctrans, wctrans_t, (const char *name)); |
| 747 | # else | 747 | # else |
| 748 | # if !@HAVE_WCTRANS_T@ | 748 | # if !@HAVE_WCTRANS_T@ |
| 749 | _GL_FUNCDECL_SYS (wctrans, wctrans_t, (const char *name) | 749 | _GL_FUNCDECL_SYS (wctrans, wctrans_t, (const char *name), |
| 750 | _GL_ARG_NONNULL ((1))); | 750 | _GL_ARG_NONNULL ((1))); |
| 751 | # endif | 751 | # endif |
| 752 | _GL_CXXALIAS_SYS (wctrans, wctrans_t, (const char *name)); | 752 | _GL_CXXALIAS_SYS (wctrans, wctrans_t, (const char *name)); |
| @@ -771,11 +771,11 @@ _GL_WARN_ON_USE (wctrans, "wctrans is unportable - " | |||
| 771 | # undef towctrans | 771 | # undef towctrans |
| 772 | # define towctrans rpl_towctrans | 772 | # define towctrans rpl_towctrans |
| 773 | # endif | 773 | # endif |
| 774 | _GL_FUNCDECL_RPL (towctrans, wint_t, (wint_t wc, wctrans_t desc)); | 774 | _GL_FUNCDECL_RPL (towctrans, wint_t, (wint_t wc, wctrans_t desc), ); |
| 775 | _GL_CXXALIAS_RPL (towctrans, wint_t, (wint_t wc, wctrans_t desc)); | 775 | _GL_CXXALIAS_RPL (towctrans, wint_t, (wint_t wc, wctrans_t desc)); |
| 776 | # else | 776 | # else |
| 777 | # if !@HAVE_WCTRANS_T@ | 777 | # if !@HAVE_WCTRANS_T@ |
| 778 | _GL_FUNCDECL_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); | 778 | _GL_FUNCDECL_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc), ); |
| 779 | # endif | 779 | # endif |
| 780 | _GL_CXXALIAS_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); | 780 | _GL_CXXALIAS_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); |
| 781 | # endif | 781 | # endif |
diff --git a/gl/wcwidth.c b/gl/wcwidth.c new file mode 100644 index 00000000..6e7141d0 --- /dev/null +++ b/gl/wcwidth.c | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | /* Determine the number of screen columns needed for a character. | ||
| 2 | Copyright (C) 2006-2007, 2010-2025 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU Lesser General Public License as | ||
| 6 | published by the Free Software Foundation; either version 2.1 of the | ||
| 7 | License, or (at your option) any later version. | ||
| 8 | |||
| 9 | This file is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU Lesser General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU Lesser General Public License | ||
| 15 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 16 | |||
| 17 | #include <config.h> | ||
| 18 | |||
| 19 | /* Specification. */ | ||
| 20 | #include <wchar.h> | ||
| 21 | |||
| 22 | /* Get iswprint. */ | ||
| 23 | #include <wctype.h> | ||
| 24 | |||
| 25 | #include "localcharset.h" | ||
| 26 | #include "streq.h" | ||
| 27 | #include "uniwidth.h" | ||
| 28 | |||
| 29 | /* Returns 1 if the current locale is an UTF-8 locale, 0 otherwise. */ | ||
| 30 | static inline int | ||
| 31 | is_locale_utf8 (void) | ||
| 32 | { | ||
| 33 | const char *encoding = locale_charset (); | ||
| 34 | return STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0); | ||
| 35 | } | ||
| 36 | |||
| 37 | #if GNULIB_WCHAR_SINGLE_LOCALE | ||
| 38 | /* When we know that the locale does not change, provide a speedup by | ||
| 39 | caching the value of is_locale_utf8. */ | ||
| 40 | static int cached_is_locale_utf8 = -1; | ||
| 41 | static inline int | ||
| 42 | is_locale_utf8_cached (void) | ||
| 43 | { | ||
| 44 | if (cached_is_locale_utf8 < 0) | ||
| 45 | cached_is_locale_utf8 = is_locale_utf8 (); | ||
| 46 | return cached_is_locale_utf8; | ||
| 47 | } | ||
| 48 | #else | ||
| 49 | /* By default, don't make assumptions, hence no caching. */ | ||
| 50 | # define is_locale_utf8_cached is_locale_utf8 | ||
| 51 | #endif | ||
| 52 | |||
| 53 | int | ||
| 54 | wcwidth (wchar_t wc) | ||
| 55 | #undef wcwidth | ||
| 56 | { | ||
| 57 | /* In UTF-8 locales, use a Unicode aware width function. */ | ||
| 58 | if (is_locale_utf8_cached ()) | ||
| 59 | { | ||
| 60 | /* We assume that in a UTF-8 locale, a wide character is the same as a | ||
| 61 | Unicode character. */ | ||
| 62 | return uc_width (wc, "UTF-8"); | ||
| 63 | } | ||
| 64 | else | ||
| 65 | { | ||
| 66 | /* Otherwise, fall back to the system's wcwidth function. */ | ||
| 67 | #if HAVE_WCWIDTH | ||
| 68 | return wcwidth (wc); | ||
| 69 | #else | ||
| 70 | return wc == 0 ? 0 : iswprint (wc) ? 1 : -1; | ||
| 71 | #endif | ||
| 72 | } | ||
| 73 | } | ||
diff --git a/gl/windows-initguard.h b/gl/windows-initguard.h index 6bace3f0..4f45e5bb 100644 --- a/gl/windows-initguard.h +++ b/gl/windows-initguard.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Init guards, somewhat like spinlocks (native Windows implementation). | 1 | /* Init guards, somewhat like spinlocks (native Windows implementation). |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/windows-mutex.c b/gl/windows-mutex.c index b112e13b..87b75735 100644 --- a/gl/windows-mutex.c +++ b/gl/windows-mutex.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Plain mutexes (native Windows implementation). | 1 | /* Plain mutexes (native Windows implementation). |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -23,10 +23,12 @@ | |||
| 23 | #include "windows-mutex.h" | 23 | #include "windows-mutex.h" |
| 24 | 24 | ||
| 25 | #include <errno.h> | 25 | #include <errno.h> |
| 26 | #include <stdlib.h> | ||
| 26 | 27 | ||
| 27 | void | 28 | void |
| 28 | glwthread_mutex_init (glwthread_mutex_t *mutex) | 29 | glwthread_mutex_init (glwthread_mutex_t *mutex) |
| 29 | { | 30 | { |
| 31 | mutex->owner = 0; | ||
| 30 | InitializeCriticalSection (&mutex->lock); | 32 | InitializeCriticalSection (&mutex->lock); |
| 31 | mutex->guard.done = 1; | 33 | mutex->guard.done = 1; |
| 32 | } | 34 | } |
| @@ -49,7 +51,13 @@ glwthread_mutex_lock (glwthread_mutex_t *mutex) | |||
| 49 | Sleep (0); | 51 | Sleep (0); |
| 50 | } | 52 | } |
| 51 | } | 53 | } |
| 54 | /* If this thread already owns the mutex, POSIX pthread_mutex_lock() is | ||
| 55 | required to deadlock here. But let's not do that on purpose. */ | ||
| 52 | EnterCriticalSection (&mutex->lock); | 56 | EnterCriticalSection (&mutex->lock); |
| 57 | { | ||
| 58 | DWORD self = GetCurrentThreadId (); | ||
| 59 | mutex->owner = self; | ||
| 60 | } | ||
| 53 | return 0; | 61 | return 0; |
| 54 | } | 62 | } |
| 55 | 63 | ||
| @@ -72,6 +80,21 @@ glwthread_mutex_trylock (glwthread_mutex_t *mutex) | |||
| 72 | } | 80 | } |
| 73 | if (!TryEnterCriticalSection (&mutex->lock)) | 81 | if (!TryEnterCriticalSection (&mutex->lock)) |
| 74 | return EBUSY; | 82 | return EBUSY; |
| 83 | { | ||
| 84 | DWORD self = GetCurrentThreadId (); | ||
| 85 | /* TryEnterCriticalSection succeeded. This means that the mutex was either | ||
| 86 | previously unlocked (and thus mutex->owner == 0) or previously locked by | ||
| 87 | this thread (and thus mutex->owner == self). Since the mutex is meant to | ||
| 88 | be plain, we need to fail in the latter case. */ | ||
| 89 | if (mutex->owner == self) | ||
| 90 | { | ||
| 91 | LeaveCriticalSection (&mutex->lock); | ||
| 92 | return EBUSY; | ||
| 93 | } | ||
| 94 | if (mutex->owner != 0) | ||
| 95 | abort (); | ||
| 96 | mutex->owner = self; | ||
| 97 | } | ||
| 75 | return 0; | 98 | return 0; |
| 76 | } | 99 | } |
| 77 | 100 | ||
| @@ -80,6 +103,7 @@ glwthread_mutex_unlock (glwthread_mutex_t *mutex) | |||
| 80 | { | 103 | { |
| 81 | if (!mutex->guard.done) | 104 | if (!mutex->guard.done) |
| 82 | return EINVAL; | 105 | return EINVAL; |
| 106 | mutex->owner = 0; | ||
| 83 | LeaveCriticalSection (&mutex->lock); | 107 | LeaveCriticalSection (&mutex->lock); |
| 84 | return 0; | 108 | return 0; |
| 85 | } | 109 | } |
diff --git a/gl/windows-mutex.h b/gl/windows-mutex.h index 88de4bdc..dc6b41e0 100644 --- a/gl/windows-mutex.h +++ b/gl/windows-mutex.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Plain mutexes (native Windows implementation). | 1 | /* Plain mutexes (native Windows implementation). |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -28,6 +28,7 @@ | |||
| 28 | typedef struct | 28 | typedef struct |
| 29 | { | 29 | { |
| 30 | glwthread_initguard_t guard; /* protects the initialization */ | 30 | glwthread_initguard_t guard; /* protects the initialization */ |
| 31 | DWORD owner; | ||
| 31 | CRITICAL_SECTION lock; | 32 | CRITICAL_SECTION lock; |
| 32 | } | 33 | } |
| 33 | glwthread_mutex_t; | 34 | glwthread_mutex_t; |
diff --git a/gl/windows-once.c b/gl/windows-once.c index 17854f5c..bd9e672a 100644 --- a/gl/windows-once.c +++ b/gl/windows-once.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Once-only control (native Windows implementation). | 1 | /* Once-only control (native Windows implementation). |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -29,7 +29,9 @@ glwthread_once (glwthread_once_t *once_control, void (*initfunction) (void)) | |||
| 29 | { | 29 | { |
| 30 | if (once_control->inited <= 0) | 30 | if (once_control->inited <= 0) |
| 31 | { | 31 | { |
| 32 | if (InterlockedIncrement (&once_control->started) == 0) | 32 | InterlockedIncrement (&once_control->num_threads); |
| 33 | /* If once_control->started is == -1, set it to 0. */ | ||
| 34 | if (InterlockedCompareExchange (&once_control->started, 0, -1) < 0) | ||
| 33 | { | 35 | { |
| 34 | /* This thread is the first one to come to this once_control. */ | 36 | /* This thread is the first one to come to this once_control. */ |
| 35 | InitializeCriticalSection (&once_control->lock); | 37 | InitializeCriticalSection (&once_control->lock); |
| @@ -41,8 +43,6 @@ glwthread_once (glwthread_once_t *once_control, void (*initfunction) (void)) | |||
| 41 | } | 43 | } |
| 42 | else | 44 | else |
| 43 | { | 45 | { |
| 44 | /* Don't let once_control->started grow and wrap around. */ | ||
| 45 | InterlockedDecrement (&once_control->started); | ||
| 46 | /* Some other thread has already started the initialization. | 46 | /* Some other thread has already started the initialization. |
| 47 | Yield the CPU while waiting for the other thread to finish | 47 | Yield the CPU while waiting for the other thread to finish |
| 48 | initializing and taking the lock. */ | 48 | initializing and taking the lock. */ |
| @@ -58,5 +58,48 @@ glwthread_once (glwthread_once_t *once_control, void (*initfunction) (void)) | |||
| 58 | abort (); | 58 | abort (); |
| 59 | } | 59 | } |
| 60 | } | 60 | } |
| 61 | /* Here once_control->started == 0 and once_control->inited > 0. */ | ||
| 62 | if (InterlockedDecrement (&once_control->num_threads) == 0) | ||
| 63 | /* once_control->num_threads is now zero, and | ||
| 64 | once_control->started == 0 and once_control->inited > 0. | ||
| 65 | No other thread will need to use the lock. | ||
| 66 | We can therefore destroy the lock, to free resources. */ | ||
| 67 | /* If once_control->inited is == 1, set it to 2. */ | ||
| 68 | if (InterlockedCompareExchange (&once_control->inited, 2, 1) == 1) | ||
| 69 | DeleteCriticalSection (&once_control->lock); | ||
| 61 | } | 70 | } |
| 71 | /* Proof of correctness: | ||
| 72 | * num_threads is incremented and then decremented by some threads. | ||
| 73 | Therefore, num_threads always stays >= 0, and is == 0 at the end. | ||
| 74 | * The first thread to go through the once_control->started fence | ||
| 75 | initializes the lock and moves inited from <= 0 to > 0. The other | ||
| 76 | threads don't move inited from <= 0 to > 0. | ||
| 77 | * started, once == 0, stays == 0. | ||
| 78 | * inited, once > 0, stays > 0 (since at the place where it is assigned 0, | ||
| 79 | it cannot be > 0). | ||
| 80 | * inited does not change any more once it is 2. | ||
| 81 | Therefore, it can be changed from 1 to 2 only once. | ||
| 82 | * DeleteCriticalSection gets invoked right after inited has been changed | ||
| 83 | from 1 to 2. Therefore, DeleteCriticalSection gets invoked only once. | ||
| 84 | * After a moment where num_threads was 0 and started was 0 and | ||
| 85 | inited was > 0, no thread can reach an InitializeCriticalSection or | ||
| 86 | EnterCriticalSection invocation. Proof: | ||
| 87 | - At such a moment, no thread is in the code range between | ||
| 88 | InterlockedIncrement (&once_control->num_threads) | ||
| 89 | and | ||
| 90 | InterlockedDecrement (&once_control->num_threads) | ||
| 91 | - After such a moment, some thread can increment num_threads, but from | ||
| 92 | there they cannot reach the InitializeCriticalSection invocation, | ||
| 93 | because the once_control->started test prevents that, and they cannot | ||
| 94 | reach the EnterCriticalSection invocation in the other branch because | ||
| 95 | the | ||
| 96 | if (once_control->inited <= 0) | ||
| 97 | test prevents that. | ||
| 98 | * From this it follows that: | ||
| 99 | - DeleteCriticalSection cannot be executed while the lock is taken | ||
| 100 | (because DeleteCriticalSection is only executed after a moment where | ||
| 101 | num_threads was 0 and started was 0 and inited was > 0). | ||
| 102 | - Once DeleteCriticalSection has been executed, the lock is not used any | ||
| 103 | more. | ||
| 104 | */ | ||
| 62 | } | 105 | } |
diff --git a/gl/windows-once.h b/gl/windows-once.h index c5bbcd57..b27ae538 100644 --- a/gl/windows-once.h +++ b/gl/windows-once.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Once-only control (native Windows implementation). | 1 | /* Once-only control (native Windows implementation). |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
| @@ -25,13 +25,14 @@ | |||
| 25 | 25 | ||
| 26 | typedef struct | 26 | typedef struct |
| 27 | { | 27 | { |
| 28 | volatile int inited; | 28 | volatile LONG inited; |
| 29 | volatile LONG num_threads; | ||
| 29 | volatile LONG started; | 30 | volatile LONG started; |
| 30 | CRITICAL_SECTION lock; | 31 | CRITICAL_SECTION lock; |
| 31 | } | 32 | } |
| 32 | glwthread_once_t; | 33 | glwthread_once_t; |
| 33 | 34 | ||
| 34 | #define GLWTHREAD_ONCE_INIT { -1, -1 } | 35 | #define GLWTHREAD_ONCE_INIT { -1, 0, -1 } |
| 35 | 36 | ||
| 36 | #ifdef __cplusplus | 37 | #ifdef __cplusplus |
| 37 | extern "C" { | 38 | extern "C" { |
diff --git a/gl/windows-recmutex.c b/gl/windows-recmutex.c index e5672baf..09341d56 100644 --- a/gl/windows-recmutex.c +++ b/gl/windows-recmutex.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Plain recursive mutexes (native Windows implementation). | 1 | /* Plain recursive mutexes (native Windows implementation). |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/windows-recmutex.h b/gl/windows-recmutex.h index 9fa445b3..25a883d4 100644 --- a/gl/windows-recmutex.h +++ b/gl/windows-recmutex.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Plain recursive mutexes (native Windows implementation). | 1 | /* Plain recursive mutexes (native Windows implementation). |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/windows-rwlock.c b/gl/windows-rwlock.c index e60c4efc..313f14ca 100644 --- a/gl/windows-rwlock.c +++ b/gl/windows-rwlock.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Read-write locks (native Windows implementation). | 1 | /* Read-write locks (native Windows implementation). |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/windows-rwlock.h b/gl/windows-rwlock.h index 08d67750..b1b4063a 100644 --- a/gl/windows-rwlock.h +++ b/gl/windows-rwlock.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Read-write locks (native Windows implementation). | 1 | /* Read-write locks (native Windows implementation). |
| 2 | Copyright (C) 2005-2024 Free Software Foundation, Inc. | 2 | Copyright (C) 2005-2025 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is free software: you can redistribute it and/or modify | 4 | This file is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU Lesser General Public License as | 5 | it under the terms of the GNU Lesser General Public License as |
diff --git a/gl/xalloc-die.c b/gl/xalloc-die.c index c053c7a8..db1ee8ff 100644 --- a/gl/xalloc-die.c +++ b/gl/xalloc-die.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Report a memory allocation failure and exit. | 1 | /* Report a memory allocation failure and exit. |
| 2 | 2 | ||
| 3 | Copyright (C) 1997-2000, 2002-2004, 2006, 2009-2024 Free Software | 3 | Copyright (C) 1997-2000, 2002-2004, 2006, 2009-2025 Free Software |
| 4 | Foundation, Inc. | 4 | Foundation, Inc. |
| 5 | 5 | ||
| 6 | This program is free software: you can redistribute it and/or modify | 6 | This program is free software: you can redistribute it and/or modify |
| @@ -26,7 +26,7 @@ | |||
| 26 | #include "exitfail.h" | 26 | #include "exitfail.h" |
| 27 | 27 | ||
| 28 | #include "gettext.h" | 28 | #include "gettext.h" |
| 29 | #define _(msgid) gettext (msgid) | 29 | #define _(msgid) dgettext ("gnulib", msgid) |
| 30 | 30 | ||
| 31 | void | 31 | void |
| 32 | xalloc_die (void) | 32 | xalloc_die (void) |
diff --git a/gl/xalloc-oversized.h b/gl/xalloc-oversized.h index 7f30f83e..0f66bd06 100644 --- a/gl/xalloc-oversized.h +++ b/gl/xalloc-oversized.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* xalloc-oversized.h -- memory allocation size checking | 1 | /* xalloc-oversized.h -- memory allocation size checking |
| 2 | 2 | ||
| 3 | Copyright (C) 1990-2000, 2003-2004, 2006-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1990-2000, 2003-2004, 2006-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -47,7 +47,8 @@ | |||
| 47 | #if 7 <= __GNUC__ && !defined __clang__ && PTRDIFF_MAX < SIZE_MAX | 47 | #if 7 <= __GNUC__ && !defined __clang__ && PTRDIFF_MAX < SIZE_MAX |
| 48 | # define xalloc_oversized(n, s) \ | 48 | # define xalloc_oversized(n, s) \ |
| 49 | __builtin_mul_overflow_p (n, s, (ptrdiff_t) 1) | 49 | __builtin_mul_overflow_p (n, s, (ptrdiff_t) 1) |
| 50 | #elif 5 <= __GNUC__ && !defined __ICC && PTRDIFF_MAX < SIZE_MAX | 50 | #elif 5 <= __GNUC__ && !defined __clang__ && !defined __ICC \ |
| 51 | && PTRDIFF_MAX < SIZE_MAX | ||
| 51 | # define xalloc_oversized(n, s) \ | 52 | # define xalloc_oversized(n, s) \ |
| 52 | (__builtin_constant_p (n) && __builtin_constant_p (s) \ | 53 | (__builtin_constant_p (n) && __builtin_constant_p (s) \ |
| 53 | ? __xalloc_oversized (n, s) \ | 54 | ? __xalloc_oversized (n, s) \ |
diff --git a/gl/xalloc.h b/gl/xalloc.h index 75a5db30..438e5caa 100644 --- a/gl/xalloc.h +++ b/gl/xalloc.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* xalloc.h -- malloc with out-of-memory checking | 1 | /* xalloc.h -- malloc with out-of-memory checking |
| 2 | 2 | ||
| 3 | Copyright (C) 1990-2000, 2003-2004, 2006-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1990-2000, 2003-2004, 2006-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software: you can redistribute it and/or modify | 5 | This program is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
diff --git a/gl/xmalloc.c b/gl/xmalloc.c index 5befdab7..8a715807 100644 --- a/gl/xmalloc.c +++ b/gl/xmalloc.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* xmalloc.c -- malloc with out of memory checking | 1 | /* xmalloc.c -- malloc with out of memory checking |
| 2 | 2 | ||
| 3 | Copyright (C) 1990-2000, 2002-2006, 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 1990-2000, 2002-2006, 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This program is free software: you can redistribute it and/or modify | 5 | This program is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
| @@ -64,7 +64,7 @@ void * | |||
| 64 | xrealloc (void *p, size_t s) | 64 | xrealloc (void *p, size_t s) |
| 65 | { | 65 | { |
| 66 | void *r = realloc (p, s); | 66 | void *r = realloc (p, s); |
| 67 | if (!r && (!p || s)) | 67 | if (!r) |
| 68 | xalloc_die (); | 68 | xalloc_die (); |
| 69 | return r; | 69 | return r; |
| 70 | } | 70 | } |
| @@ -82,7 +82,7 @@ void * | |||
| 82 | xreallocarray (void *p, size_t n, size_t s) | 82 | xreallocarray (void *p, size_t n, size_t s) |
| 83 | { | 83 | { |
| 84 | void *r = reallocarray (p, n, s); | 84 | void *r = reallocarray (p, n, s); |
| 85 | if (!r && (!p || (n && s))) | 85 | if (!r) |
| 86 | xalloc_die (); | 86 | xalloc_die (); |
| 87 | return r; | 87 | return r; |
| 88 | } | 88 | } |
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Checked size_t computations. | 1 | /* Checked size_t computations. |
| 2 | 2 | ||
| 3 | Copyright (C) 2012-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2012-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -1,6 +1,6 @@ | |||
| 1 | /* xsize.h -- Checked size_t computations. | 1 | /* xsize.h -- Checked size_t computations. |
| 2 | 2 | ||
| 3 | Copyright (C) 2003, 2008-2024 Free Software Foundation, Inc. | 3 | Copyright (C) 2003, 2008-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -26,7 +26,7 @@ | |||
| 26 | /* Get size_t. */ | 26 | /* Get size_t. */ |
| 27 | #include <stddef.h> | 27 | #include <stddef.h> |
| 28 | 28 | ||
| 29 | /* Get SIZE_MAX. */ | 29 | /* Get INT_MAX, SIZE_MAX. */ |
| 30 | #include <limits.h> | 30 | #include <limits.h> |
| 31 | #if HAVE_STDINT_H | 31 | #if HAVE_STDINT_H |
| 32 | # include <stdint.h> | 32 | # include <stdint.h> |
| @@ -61,7 +61,8 @@ extern "C" { | |||
| 61 | void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); | 61 | void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); |
| 62 | */ | 62 | */ |
| 63 | 63 | ||
| 64 | /* Convert an arbitrary value >= 0 to type size_t. */ | 64 | /* Convert an arbitrary N >= 0 to type size_t. |
| 65 | N should not have side effects. */ | ||
| 65 | #define xcast_size_t(N) \ | 66 | #define xcast_size_t(N) \ |
| 66 | ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) | 67 | ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) |
| 67 | 68 | ||
| @@ -69,8 +70,15 @@ extern "C" { | |||
| 69 | XSIZE_INLINE size_t ATTRIBUTE_PURE | 70 | XSIZE_INLINE size_t ATTRIBUTE_PURE |
| 70 | xsum (size_t size1, size_t size2) | 71 | xsum (size_t size1, size_t size2) |
| 71 | { | 72 | { |
| 72 | size_t sum = size1 + size2; | 73 | if (INT_MAX < SIZE_MAX) |
| 73 | return (sum >= size1 ? sum : SIZE_MAX); | 74 | { |
| 75 | /* Optimize for the common case where size_t arithmetic wraps | ||
| 76 | around without undefined behavior. */ | ||
| 77 | size_t sum = size1 + size2; | ||
| 78 | return size1 <= sum ? sum : SIZE_MAX; | ||
| 79 | } | ||
| 80 | |||
| 81 | return size1 <= SIZE_MAX - size2 ? size1 + size2 : SIZE_MAX; | ||
| 74 | } | 82 | } |
| 75 | 83 | ||
| 76 | /* Sum of three sizes, with overflow check. */ | 84 | /* Sum of three sizes, with overflow check. */ |
| @@ -98,6 +106,8 @@ xmax (size_t size1, size_t size2) | |||
| 98 | 106 | ||
| 99 | /* Multiplication of a count with an element size, with overflow check. | 107 | /* Multiplication of a count with an element size, with overflow check. |
| 100 | The count must be >= 0 and the element size must be > 0. | 108 | The count must be >= 0 and the element size must be > 0. |
| 109 | Arguments should not have side effects. | ||
| 110 | The element size's type should be no wider than size_t. | ||
| 101 | This is a macro, not a function, so that it works correctly even | 111 | This is a macro, not a function, so that it works correctly even |
| 102 | when N is of a wider type and N > SIZE_MAX. */ | 112 | when N is of a wider type and N > SIZE_MAX. */ |
| 103 | #define xtimes(N, ELSIZE) \ | 113 | #define xtimes(N, ELSIZE) \ |
diff --git a/lib/Makefile.am b/lib/Makefile.am index e41201c4..27a08278 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am | |||
| @@ -4,13 +4,12 @@ SUBDIRS = . tests | |||
| 4 | 4 | ||
| 5 | noinst_LIBRARIES = libmonitoringplug.a | 5 | noinst_LIBRARIES = libmonitoringplug.a |
| 6 | 6 | ||
| 7 | AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ | 7 | AM_CPPFLAGS = \ |
| 8 | -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins | 8 | -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins |
| 9 | 9 | ||
| 10 | libmonitoringplug_a_SOURCES = utils_base.c utils_disk.c utils_tcp.c utils_cmd.c maxfd.c output.c perfdata.c output.c thresholds.c vendor/cJSON/cJSON.c | 10 | libmonitoringplug_a_SOURCES = utils_base.c utils_tcp.c utils_cmd.c maxfd.c output.c perfdata.c output.c thresholds.c vendor/cJSON/cJSON.c |
| 11 | 11 | ||
| 12 | EXTRA_DIST = utils_base.h \ | 12 | EXTRA_DIST = utils_base.h \ |
| 13 | utils_disk.h \ | ||
| 14 | utils_tcp.h \ | 13 | utils_tcp.h \ |
| 15 | utils_cmd.h \ | 14 | utils_cmd.h \ |
| 16 | parse_ini.h \ | 15 | parse_ini.h \ |
diff --git a/lib/extra_opts.c b/lib/extra_opts.c index 88787336..3fe69014 100644 --- a/lib/extra_opts.c +++ b/lib/extra_opts.c | |||
| @@ -27,27 +27,32 @@ | |||
| 27 | 27 | ||
| 28 | /* FIXME: copied from utils.h; we should move a bunch of libs! */ | 28 | /* FIXME: copied from utils.h; we should move a bunch of libs! */ |
| 29 | bool is_option2(char *str) { | 29 | bool is_option2(char *str) { |
| 30 | if (!str) | 30 | if (!str) { |
| 31 | return false; | 31 | return false; |
| 32 | else if (strspn(str, "-") == 1 || strspn(str, "-") == 2) | 32 | } |
| 33 | |||
| 34 | if (strspn(str, "-") == 1 || strspn(str, "-") == 2) { | ||
| 33 | return true; | 35 | return true; |
| 34 | else | 36 | } |
| 35 | return false; | 37 | |
| 38 | return false; | ||
| 36 | } | 39 | } |
| 37 | 40 | ||
| 38 | /* this is the externally visible function used by plugins */ | 41 | /* this is the externally visible function used by plugins */ |
| 39 | char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | 42 | char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { |
| 40 | np_arg_list *extra_args = NULL, *ea1 = NULL, *ea_tmp = NULL; | ||
| 41 | char **argv_new = NULL; | ||
| 42 | char *argptr = NULL; | ||
| 43 | int i, j, optfound, argc_new, ea_num = *argc; | ||
| 44 | |||
| 45 | if (*argc < 2) { | 43 | if (*argc < 2) { |
| 46 | /* No arguments provided */ | 44 | /* No arguments provided */ |
| 47 | return argv; | 45 | return argv; |
| 48 | } | 46 | } |
| 49 | 47 | ||
| 50 | for (i = 1; i < *argc; i++) { | 48 | np_arg_list *extra_args = NULL; |
| 49 | np_arg_list *ea1 = NULL; | ||
| 50 | np_arg_list *ea_tmp = NULL; | ||
| 51 | char *argptr = NULL; | ||
| 52 | int optfound; | ||
| 53 | size_t ea_num = (size_t)*argc; | ||
| 54 | |||
| 55 | for (int i = 1; i < *argc; i++) { | ||
| 51 | argptr = NULL; | 56 | argptr = NULL; |
| 52 | optfound = 0; | 57 | optfound = 0; |
| 53 | 58 | ||
| @@ -56,8 +61,10 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 56 | /* It is a single argument with value */ | 61 | /* It is a single argument with value */ |
| 57 | argptr = argv[i] + 13; | 62 | argptr = argv[i] + 13; |
| 58 | /* Delete the extra opts argument */ | 63 | /* Delete the extra opts argument */ |
| 59 | for (j = i; j < *argc; j++) | 64 | for (int j = i; j < *argc; j++) { |
| 60 | argv[j] = argv[j + 1]; | 65 | argv[j] = argv[j + 1]; |
| 66 | } | ||
| 67 | |||
| 61 | i--; | 68 | i--; |
| 62 | *argc -= 1; | 69 | *argc -= 1; |
| 63 | } else if (strcmp(argv[i], "--extra-opts") == 0) { | 70 | } else if (strcmp(argv[i], "--extra-opts") == 0) { |
| @@ -65,8 +72,10 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 65 | /* It is a argument with separate value */ | 72 | /* It is a argument with separate value */ |
| 66 | argptr = argv[i + 1]; | 73 | argptr = argv[i + 1]; |
| 67 | /* Delete the extra-opts argument/value */ | 74 | /* Delete the extra-opts argument/value */ |
| 68 | for (j = i; j < *argc - 1; j++) | 75 | for (int j = i; j < *argc - 1; j++) { |
| 69 | argv[j] = argv[j + 2]; | 76 | argv[j] = argv[j + 2]; |
| 77 | } | ||
| 78 | |||
| 70 | i -= 2; | 79 | i -= 2; |
| 71 | *argc -= 2; | 80 | *argc -= 2; |
| 72 | ea_num--; | 81 | ea_num--; |
| @@ -74,8 +83,10 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 74 | /* It has no value */ | 83 | /* It has no value */ |
| 75 | optfound = 1; | 84 | optfound = 1; |
| 76 | /* Delete the extra opts argument */ | 85 | /* Delete the extra opts argument */ |
| 77 | for (j = i; j < *argc; j++) | 86 | for (int j = i; j < *argc; j++) { |
| 78 | argv[j] = argv[j + 1]; | 87 | argv[j] = argv[j + 1]; |
| 88 | } | ||
| 89 | |||
| 79 | i--; | 90 | i--; |
| 80 | *argc -= 1; | 91 | *argc -= 1; |
| 81 | } | 92 | } |
| @@ -94,34 +105,37 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 94 | /* append the list to extra_args */ | 105 | /* append the list to extra_args */ |
| 95 | if (extra_args == NULL) { | 106 | if (extra_args == NULL) { |
| 96 | extra_args = ea1; | 107 | extra_args = ea1; |
| 97 | while ((ea1 = ea1->next)) | 108 | while ((ea1 = ea1->next)) { |
| 98 | ea_num++; | 109 | ea_num++; |
| 110 | } | ||
| 99 | } else { | 111 | } else { |
| 100 | ea_tmp = extra_args; | 112 | ea_tmp = extra_args; |
| 101 | while (ea_tmp->next) { | 113 | while (ea_tmp->next) { |
| 102 | ea_tmp = ea_tmp->next; | 114 | ea_tmp = ea_tmp->next; |
| 103 | } | 115 | } |
| 104 | ea_tmp->next = ea1; | 116 | ea_tmp->next = ea1; |
| 105 | while ((ea1 = ea1->next)) | 117 | while ((ea1 = ea1->next)) { |
| 106 | ea_num++; | 118 | ea_num++; |
| 119 | } | ||
| 107 | } | 120 | } |
| 108 | ea1 = ea_tmp = NULL; | 121 | ea1 = ea_tmp = NULL; |
| 109 | } | 122 | } |
| 110 | } /* lather, rince, repeat */ | 123 | } /* lather, rince, repeat */ |
| 111 | 124 | ||
| 112 | if (ea_num == *argc && extra_args == NULL) { | 125 | if (ea_num == (size_t)*argc && extra_args == NULL) { |
| 113 | /* No extra-opts */ | 126 | /* No extra-opts */ |
| 114 | return argv; | 127 | return argv; |
| 115 | } | 128 | } |
| 116 | 129 | ||
| 117 | /* done processing arguments. now create a new argv array... */ | 130 | /* done processing arguments. now create a new argv array... */ |
| 118 | argv_new = (char **)malloc((ea_num + 1) * sizeof(char **)); | 131 | char **argv_new = (char **)malloc((ea_num + 1) * sizeof(char **)); |
| 119 | if (argv_new == NULL) | 132 | if (argv_new == NULL) { |
| 120 | die(STATE_UNKNOWN, _("malloc() failed!\n")); | 133 | die(STATE_UNKNOWN, _("malloc() failed!\n")); |
| 134 | } | ||
| 121 | 135 | ||
| 122 | /* starting with program name */ | 136 | /* starting with program name */ |
| 123 | argv_new[0] = argv[0]; | 137 | argv_new[0] = argv[0]; |
| 124 | argc_new = 1; | 138 | int argc_new = 1; |
| 125 | /* then parsed ini opts (frying them up in the same run) */ | 139 | /* then parsed ini opts (frying them up in the same run) */ |
| 126 | while (extra_args) { | 140 | while (extra_args) { |
| 127 | argv_new[argc_new++] = extra_args->arg; | 141 | argv_new[argc_new++] = extra_args->arg; |
| @@ -130,8 +144,9 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 130 | free(ea1); | 144 | free(ea1); |
| 131 | } | 145 | } |
| 132 | /* finally the rest of the argv array */ | 146 | /* finally the rest of the argv array */ |
| 133 | for (i = 1; i < *argc; i++) | 147 | for (int i = 1; i < *argc; i++) { |
| 134 | argv_new[argc_new++] = argv[i]; | 148 | argv_new[argc_new++] = argv[i]; |
| 149 | } | ||
| 135 | *argc = argc_new; | 150 | *argc = argc_new; |
| 136 | /* and terminate. */ | 151 | /* and terminate. */ |
| 137 | argv_new[argc_new] = NULL; | 152 | argv_new[argc_new] = NULL; |
diff --git a/lib/maxfd.c b/lib/maxfd.c index ca5b6e54..a0f79949 100644 --- a/lib/maxfd.c +++ b/lib/maxfd.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | *****************************************************************************/ | 19 | *****************************************************************************/ |
| 20 | 20 | ||
| 21 | #include "./maxfd.h" | 21 | #include "./maxfd.h" |
| 22 | #include <errno.h> | ||
| 23 | 22 | ||
| 24 | long mp_open_max(void) { | 23 | long mp_open_max(void) { |
| 25 | long maxfd = 0L; | 24 | long maxfd = 0L; |
| @@ -31,10 +30,11 @@ long mp_open_max(void) { | |||
| 31 | #ifdef _SC_OPEN_MAX | 30 | #ifdef _SC_OPEN_MAX |
| 32 | errno = 0; | 31 | errno = 0; |
| 33 | if ((maxfd = sysconf(_SC_OPEN_MAX)) < 0) { | 32 | if ((maxfd = sysconf(_SC_OPEN_MAX)) < 0) { |
| 34 | if (errno == 0) | 33 | if (errno == 0) { |
| 35 | maxfd = DEFAULT_MAXFD; /* it's indeterminate */ | 34 | maxfd = DEFAULT_MAXFD; /* it's indeterminate */ |
| 36 | else | 35 | } else { |
| 37 | die(STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n")); | 36 | die(STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n")); |
| 37 | } | ||
| 38 | } | 38 | } |
| 39 | #elif defined(OPEN_MAX) | 39 | #elif defined(OPEN_MAX) |
| 40 | return OPEN_MAX | 40 | return OPEN_MAX |
diff --git a/lib/output.c b/lib/output.c index 61fbf832..62e1366d 100644 --- a/lib/output.c +++ b/lib/output.c | |||
| @@ -13,9 +13,11 @@ | |||
| 13 | 13 | ||
| 14 | // == Global variables | 14 | // == Global variables |
| 15 | static mp_output_format output_format = MP_FORMAT_DEFAULT; | 15 | static mp_output_format output_format = MP_FORMAT_DEFAULT; |
| 16 | static mp_output_detail_level level_of_detail = MP_DETAIL_ALL; | ||
| 16 | 17 | ||
| 17 | // == Prototypes == | 18 | // == Prototypes == |
| 18 | static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); | 19 | static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, |
| 20 | unsigned int indentation); | ||
| 19 | static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); | 21 | static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); |
| 20 | 22 | ||
| 21 | // == Implementation == | 23 | // == Implementation == |
| @@ -40,7 +42,7 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) { | |||
| 40 | 42 | ||
| 41 | while (subchecks != NULL) { | 43 | while (subchecks != NULL) { |
| 42 | if (added > 0) { | 44 | if (added > 0) { |
| 43 | added = asprintf(&result, "%s%s", result, fmt_subcheck_perfdata(subchecks->subcheck)); | 45 | added = asprintf(&result, "%s %s", result, fmt_subcheck_perfdata(subchecks->subcheck)); |
| 44 | } else { | 46 | } else { |
| 45 | // TODO free previous result here? | 47 | // TODO free previous result here? |
| 46 | added = asprintf(&result, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); | 48 | added = asprintf(&result, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); |
| @@ -57,7 +59,9 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) { | |||
| 57 | * It sets useful defaults | 59 | * It sets useful defaults |
| 58 | */ | 60 | */ |
| 59 | mp_check mp_check_init(void) { | 61 | mp_check mp_check_init(void) { |
| 60 | mp_check check = {0}; | 62 | mp_check check = { |
| 63 | .evaluation_function = &mp_eval_check_default, | ||
| 64 | }; | ||
| 61 | return check; | 65 | return check; |
| 62 | } | 66 | } |
| 63 | 67 | ||
| @@ -120,7 +124,8 @@ void mp_add_perfdata_to_subcheck(mp_subcheck check[static 1], const mp_perfdata | |||
| 120 | */ | 124 | */ |
| 121 | int mp_add_subcheck_to_subcheck(mp_subcheck check[static 1], mp_subcheck subcheck) { | 125 | int mp_add_subcheck_to_subcheck(mp_subcheck check[static 1], mp_subcheck subcheck) { |
| 122 | if (subcheck.output == NULL) { | 126 | if (subcheck.output == NULL) { |
| 123 | die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__, "Sub check output is NULL"); | 127 | die(STATE_UNKNOWN, "%s - %s #%d: %s", __FILE__, __func__, __LINE__, |
| 128 | "Sub check output is NULL"); | ||
| 124 | } | 129 | } |
| 125 | 130 | ||
| 126 | mp_subcheck_list *tmp = NULL; | 131 | mp_subcheck_list *tmp = NULL; |
| @@ -193,16 +198,33 @@ char *get_subcheck_summary(mp_check check) { | |||
| 193 | return result; | 198 | return result; |
| 194 | } | 199 | } |
| 195 | 200 | ||
| 201 | mp_state_enum mp_compute_subcheck_state(const mp_subcheck subcheck) { | ||
| 202 | if (subcheck.evaluation_function == NULL) { | ||
| 203 | return mp_eval_subcheck_default(subcheck); | ||
| 204 | } | ||
| 205 | return subcheck.evaluation_function(subcheck); | ||
| 206 | } | ||
| 207 | |||
| 196 | /* | 208 | /* |
| 197 | * Generate the result state of a mp_subcheck object based on it's own state and it's subchecks states | 209 | * Generate the result state of a mp_subcheck object based on its own state and its subchecks |
| 210 | * states | ||
| 198 | */ | 211 | */ |
| 199 | mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { | 212 | mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck) { |
| 200 | if (check.state_set_explicitly) { | 213 | if (subcheck.evaluation_function != NULL) { |
| 201 | return check.state; | 214 | return subcheck.evaluation_function(subcheck); |
| 202 | } | 215 | } |
| 203 | 216 | ||
| 204 | mp_subcheck_list *scl = check.subchecks; | 217 | if (subcheck.state_set_explicitly) { |
| 205 | mp_state_enum result = check.default_state; | 218 | return subcheck.state; |
| 219 | } | ||
| 220 | |||
| 221 | mp_subcheck_list *scl = subcheck.subchecks; | ||
| 222 | |||
| 223 | if (scl == NULL) { | ||
| 224 | return subcheck.default_state; | ||
| 225 | } | ||
| 226 | |||
| 227 | mp_state_enum result = STATE_OK; | ||
| 206 | 228 | ||
| 207 | while (scl != NULL) { | 229 | while (scl != NULL) { |
| 208 | result = max_state_alt(result, mp_compute_subcheck_state(scl->subcheck)); | 230 | result = max_state_alt(result, mp_compute_subcheck_state(scl->subcheck)); |
| @@ -212,10 +234,18 @@ mp_state_enum mp_compute_subcheck_state(const mp_subcheck check) { | |||
| 212 | return result; | 234 | return result; |
| 213 | } | 235 | } |
| 214 | 236 | ||
| 237 | mp_state_enum mp_compute_check_state(const mp_check check) { | ||
| 238 | // just a safety check | ||
| 239 | if (check.evaluation_function == NULL) { | ||
| 240 | return mp_eval_check_default(check); | ||
| 241 | } | ||
| 242 | return check.evaluation_function(check); | ||
| 243 | } | ||
| 244 | |||
| 215 | /* | 245 | /* |
| 216 | * Generate the result state of a mp_check object based on it's own state and it's subchecks states | 246 | * Generate the result state of a mp_check object based on it's own state and it's subchecks states |
| 217 | */ | 247 | */ |
| 218 | mp_state_enum mp_compute_check_state(const mp_check check) { | 248 | mp_state_enum mp_eval_check_default(const mp_check check) { |
| 219 | assert(check.subchecks != NULL); // a mp_check without subchecks is invalid, die here | 249 | assert(check.subchecks != NULL); // a mp_check without subchecks is invalid, die here |
| 220 | 250 | ||
| 221 | mp_subcheck_list *scl = check.subchecks; | 251 | mp_subcheck_list *scl = check.subchecks; |
| @@ -247,7 +277,11 @@ char *mp_fmt_output(mp_check check) { | |||
| 247 | mp_subcheck_list *subchecks = check.subchecks; | 277 | mp_subcheck_list *subchecks = check.subchecks; |
| 248 | 278 | ||
| 249 | while (subchecks != NULL) { | 279 | while (subchecks != NULL) { |
| 250 | asprintf(&result, "%s\n%s", result, fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); | 280 | if (level_of_detail == MP_DETAIL_ALL || |
| 281 | mp_compute_subcheck_state(subchecks->subcheck) != STATE_OK) { | ||
| 282 | asprintf(&result, "%s\n%s", result, | ||
| 283 | fmt_subcheck_output(MP_FORMAT_MULTI_LINE, subchecks->subcheck, 1)); | ||
| 284 | } | ||
| 251 | subchecks = subchecks->next; | 285 | subchecks = subchecks->next; |
| 252 | } | 286 | } |
| 253 | 287 | ||
| @@ -258,7 +292,8 @@ char *mp_fmt_output(mp_check check) { | |||
| 258 | if (pd_string == NULL) { | 292 | if (pd_string == NULL) { |
| 259 | asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); | 293 | asprintf(&pd_string, "%s", fmt_subcheck_perfdata(subchecks->subcheck)); |
| 260 | } else { | 294 | } else { |
| 261 | asprintf(&pd_string, "%s %s", pd_string, fmt_subcheck_perfdata(subchecks->subcheck)); | 295 | asprintf(&pd_string, "%s %s", pd_string, |
| 296 | fmt_subcheck_perfdata(subchecks->subcheck)); | ||
| 262 | } | 297 | } |
| 263 | 298 | ||
| 264 | subchecks = subchecks->next; | 299 | subchecks = subchecks->next; |
| @@ -327,22 +362,58 @@ static char *generate_indentation_string(unsigned int indentation) { | |||
| 327 | /* | 362 | /* |
| 328 | * Helper function to generate the output string of mp_subcheck | 363 | * Helper function to generate the output string of mp_subcheck |
| 329 | */ | 364 | */ |
| 330 | static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation) { | 365 | static inline char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, |
| 366 | unsigned int indentation) { | ||
| 331 | char *result = NULL; | 367 | char *result = NULL; |
| 332 | mp_subcheck_list *subchecks = NULL; | 368 | mp_subcheck_list *subchecks = NULL; |
| 333 | 369 | ||
| 334 | switch (output_format) { | 370 | switch (output_format) { |
| 335 | case MP_FORMAT_MULTI_LINE: | 371 | case MP_FORMAT_MULTI_LINE: { |
| 336 | asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), state_text(mp_compute_subcheck_state(check)), | 372 | char *tmp_string = NULL; |
| 337 | check.output); | 373 | if ((tmp_string = strchr(check.output, '\n')) != NULL) { |
| 374 | // This is a multiline string, put the correct indentation in before proceeding | ||
| 375 | char *intermediate_string = ""; | ||
| 376 | bool have_residual_chars = false; | ||
| 377 | |||
| 378 | while (tmp_string != NULL) { | ||
| 379 | *tmp_string = '\0'; | ||
| 380 | asprintf(&intermediate_string, "%s%s\n%s", intermediate_string, check.output, | ||
| 381 | generate_indentation_string( | ||
| 382 | indentation + 1)); // one more indentation to make it look better | ||
| 383 | |||
| 384 | if (*(tmp_string + 1) != '\0') { | ||
| 385 | check.output = tmp_string + 1; | ||
| 386 | have_residual_chars = true; | ||
| 387 | } else { | ||
| 388 | // Null after the \n, so this is the end | ||
| 389 | have_residual_chars = false; | ||
| 390 | break; | ||
| 391 | } | ||
| 392 | |||
| 393 | tmp_string = strchr(check.output, '\n'); | ||
| 394 | } | ||
| 395 | |||
| 396 | // add the rest (if any) | ||
| 397 | if (have_residual_chars) { | ||
| 398 | char *tmp = check.output; | ||
| 399 | xasprintf(&check.output, "%s\n%s%s", intermediate_string, | ||
| 400 | generate_indentation_string(indentation + 1), tmp); | ||
| 401 | } else { | ||
| 402 | check.output = intermediate_string; | ||
| 403 | } | ||
| 404 | } | ||
| 405 | asprintf(&result, "%s\\_[%s] - %s", generate_indentation_string(indentation), | ||
| 406 | state_text(mp_compute_subcheck_state(check)), check.output); | ||
| 338 | 407 | ||
| 339 | subchecks = check.subchecks; | 408 | subchecks = check.subchecks; |
| 340 | 409 | ||
| 341 | while (subchecks != NULL) { | 410 | while (subchecks != NULL) { |
| 342 | asprintf(&result, "%s\n%s", result, fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1)); | 411 | asprintf(&result, "%s\n%s", result, |
| 412 | fmt_subcheck_output(output_format, subchecks->subcheck, indentation + 1)); | ||
| 343 | subchecks = subchecks->next; | 413 | subchecks = subchecks->next; |
| 344 | } | 414 | } |
| 345 | return result; | 415 | return result; |
| 416 | } | ||
| 346 | default: | 417 | default: |
| 347 | die(STATE_UNKNOWN, "Invalid format"); | 418 | die(STATE_UNKNOWN, "Invalid format"); |
| 348 | } | 419 | } |
| @@ -539,3 +610,27 @@ parsed_output_format mp_parse_output_format(char *format_string) { | |||
| 539 | void mp_set_format(mp_output_format format) { output_format = format; } | 610 | void mp_set_format(mp_output_format format) { output_format = format; } |
| 540 | 611 | ||
| 541 | mp_output_format mp_get_format(void) { return output_format; } | 612 | mp_output_format mp_get_format(void) { return output_format; } |
| 613 | |||
| 614 | void mp_set_level_of_detail(mp_output_detail_level level) { level_of_detail = level; } | ||
| 615 | |||
| 616 | mp_output_detail_level mp_get_level_of_detail(void) { return level_of_detail; } | ||
| 617 | |||
| 618 | mp_state_enum mp_eval_ok(mp_check overall) { | ||
| 619 | (void)overall; | ||
| 620 | return STATE_OK; | ||
| 621 | } | ||
| 622 | |||
| 623 | mp_state_enum mp_eval_warning(mp_check overall) { | ||
| 624 | (void)overall; | ||
| 625 | return STATE_WARNING; | ||
| 626 | } | ||
| 627 | |||
| 628 | mp_state_enum mp_eval_critical(mp_check overall) { | ||
| 629 | (void)overall; | ||
| 630 | return STATE_CRITICAL; | ||
| 631 | } | ||
| 632 | |||
| 633 | mp_state_enum mp_eval_unknown(mp_check overall) { | ||
| 634 | (void)overall; | ||
| 635 | return STATE_UNKNOWN; | ||
| 636 | } | ||
diff --git a/lib/output.h b/lib/output.h index 2bdfa074..c63c8e3f 100644 --- a/lib/output.h +++ b/lib/output.h | |||
| @@ -7,15 +7,21 @@ | |||
| 7 | /* | 7 | /* |
| 8 | * A partial check result | 8 | * A partial check result |
| 9 | */ | 9 | */ |
| 10 | typedef struct { | 10 | typedef struct mp_subcheck mp_subcheck; |
| 11 | struct mp_subcheck { | ||
| 11 | mp_state_enum state; // OK, Warning, Critical ... set explicitly | 12 | mp_state_enum state; // OK, Warning, Critical ... set explicitly |
| 12 | mp_state_enum default_state; // OK, Warning, Critical .. if not set explicitly | 13 | mp_state_enum default_state; // OK, Warning, Critical .. if not set explicitly |
| 13 | bool state_set_explicitly; // was the state set explicitly (or should it be derived from subchecks) | 14 | bool state_set_explicitly; // was the state set explicitly (or should it be derived from |
| 15 | // subchecks) | ||
| 14 | 16 | ||
| 15 | char *output; // Text output for humans ("Filesystem xyz is fine", "Could not create TCP connection to..") | 17 | char *output; // Text output for humans ("Filesystem xyz is fine", "Could not create TCP |
| 16 | pd_list *perfdata; // Performance data for this check | 18 | // connection to..") |
| 19 | pd_list *perfdata; // Performance data for this check | ||
| 17 | struct subcheck_list *subchecks; // subchecks deeper in the hierarchy | 20 | struct subcheck_list *subchecks; // subchecks deeper in the hierarchy |
| 18 | } mp_subcheck; | 21 | |
| 22 | // the evaluation_functions computes the state of subcheck | ||
| 23 | mp_state_enum (*evaluation_function)(mp_subcheck); | ||
| 24 | }; | ||
| 19 | 25 | ||
| 20 | /* | 26 | /* |
| 21 | * A list of subchecks, used in subchecks and the main check | 27 | * A list of subchecks, used in subchecks and the main check |
| @@ -38,8 +44,18 @@ typedef enum output_format { | |||
| 38 | /* | 44 | /* |
| 39 | * Format related functions | 45 | * Format related functions |
| 40 | */ | 46 | */ |
| 41 | void mp_set_format(mp_output_format format); | 47 | void mp_set_format(mp_output_format format); |
| 42 | mp_output_format mp_get_format(void); | 48 | mp_output_format mp_get_format(void); |
| 49 | |||
| 50 | // Output detail level | ||
| 51 | |||
| 52 | typedef enum output_detail_level { | ||
| 53 | MP_DETAIL_ALL, | ||
| 54 | MP_DETAIL_NON_OK_ONLY, | ||
| 55 | } mp_output_detail_level; | ||
| 56 | |||
| 57 | void mp_set_level_of_detail(mp_output_detail_level level); | ||
| 58 | mp_output_detail_level mp_get_level_of_detail(void); | ||
| 43 | 59 | ||
| 44 | /* | 60 | /* |
| 45 | * The main state object of a plugin. Exists only ONCE per plugin. | 61 | * The main state object of a plugin. Exists only ONCE per plugin. |
| @@ -47,10 +63,14 @@ typedef enum output_format { | |||
| 47 | * The final result is always derived from the children and the "worst" state | 63 | * The final result is always derived from the children and the "worst" state |
| 48 | * in the first layer of subchecks | 64 | * in the first layer of subchecks |
| 49 | */ | 65 | */ |
| 50 | typedef struct { | 66 | typedef struct mp_check mp_check; |
| 51 | char *summary; // Overall summary, if not set a summary will be automatically generated | 67 | struct mp_check { |
| 68 | char *summary; // Overall summary, if not set a summary will be automatically generated | ||
| 52 | mp_subcheck_list *subchecks; | 69 | mp_subcheck_list *subchecks; |
| 53 | } mp_check; | 70 | |
| 71 | // the evaluation_functions computes the state of check | ||
| 72 | mp_state_enum (*evaluation_function)(mp_check); | ||
| 73 | }; | ||
| 54 | 74 | ||
| 55 | mp_check mp_check_init(void); | 75 | mp_check mp_check_init(void); |
| 56 | mp_subcheck mp_subcheck_init(void); | 76 | mp_subcheck mp_subcheck_init(void); |
| @@ -68,6 +88,13 @@ void mp_add_summary(mp_check check[static 1], char *summary); | |||
| 68 | mp_state_enum mp_compute_check_state(mp_check); | 88 | mp_state_enum mp_compute_check_state(mp_check); |
| 69 | mp_state_enum mp_compute_subcheck_state(mp_subcheck); | 89 | mp_state_enum mp_compute_subcheck_state(mp_subcheck); |
| 70 | 90 | ||
| 91 | mp_state_enum mp_eval_ok(mp_check overall); | ||
| 92 | mp_state_enum mp_eval_warning(mp_check overall); | ||
| 93 | mp_state_enum mp_eval_critical(mp_check overall); | ||
| 94 | mp_state_enum mp_eval_unknown(mp_check overall); | ||
| 95 | mp_state_enum mp_eval_check_default(mp_check check); | ||
| 96 | mp_state_enum mp_eval_subcheck_default(mp_subcheck subcheck); | ||
| 97 | |||
| 71 | typedef struct { | 98 | typedef struct { |
| 72 | bool parsing_success; | 99 | bool parsing_success; |
| 73 | mp_output_format output_format; | 100 | mp_output_format output_format; |
diff --git a/lib/parse_ini.c b/lib/parse_ini.c index 1289aae2..db337622 100644 --- a/lib/parse_ini.c +++ b/lib/parse_ini.c | |||
| @@ -40,26 +40,29 @@ typedef struct { | |||
| 40 | char *stanza; | 40 | char *stanza; |
| 41 | } np_ini_info; | 41 | } np_ini_info; |
| 42 | 42 | ||
| 43 | static char *default_ini_file_names[] = {"monitoring-plugins.ini", "plugins.ini", "nagios-plugins.ini", NULL}; | 43 | static char *default_ini_file_names[] = {"monitoring-plugins.ini", "plugins.ini", |
| 44 | "nagios-plugins.ini", NULL}; | ||
| 44 | 45 | ||
| 45 | static char *default_ini_path_names[] = { | 46 | static char *default_ini_path_names[] = { |
| 46 | "/usr/local/etc/monitoring-plugins/monitoring-plugins.ini", "/usr/local/etc/monitoring-plugins.ini", | 47 | "/usr/local/etc/monitoring-plugins/monitoring-plugins.ini", |
| 47 | "/etc/monitoring-plugins/monitoring-plugins.ini", "/etc/monitoring-plugins.ini", | 48 | "/usr/local/etc/monitoring-plugins.ini", "/etc/monitoring-plugins/monitoring-plugins.ini", |
| 49 | "/etc/monitoring-plugins.ini", | ||
| 48 | /* deprecated path names (for backward compatibility): */ | 50 | /* deprecated path names (for backward compatibility): */ |
| 49 | "/etc/nagios/plugins.ini", "/usr/local/nagios/etc/plugins.ini", "/usr/local/etc/nagios/plugins.ini", "/etc/opt/nagios/plugins.ini", | 51 | "/etc/nagios/plugins.ini", "/usr/local/nagios/etc/plugins.ini", |
| 50 | "/etc/nagios-plugins.ini", "/usr/local/etc/nagios-plugins.ini", "/etc/opt/nagios-plugins.ini", NULL}; | 52 | "/usr/local/etc/nagios/plugins.ini", "/etc/opt/nagios/plugins.ini", "/etc/nagios-plugins.ini", |
| 53 | "/usr/local/etc/nagios-plugins.ini", "/etc/opt/nagios-plugins.ini", NULL}; | ||
| 51 | 54 | ||
| 52 | /* eat all characters from a FILE pointer until n is encountered */ | 55 | /* eat all characters from a FILE pointer until n is encountered */ |
| 53 | #define GOBBLE_TO(f, c, n) \ | 56 | #define GOBBLE_TO(f, c, n) \ |
| 54 | do { \ | 57 | do { \ |
| 55 | (c) = fgetc((f)); \ | 58 | (c) = fgetc((f)); \ |
| 56 | } while ((c) != EOF && (c) != (n)) | 59 | } while ((c) != EOF && (c) != (n)) |
| 57 | 60 | ||
| 58 | /* internal function that returns the constructed defaults options */ | 61 | /* internal function that returns the constructed defaults options */ |
| 59 | static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts); | 62 | static bool read_defaults(FILE *defaults_file, const char *stanza, np_arg_list **opts); |
| 60 | 63 | ||
| 61 | /* internal function that converts a single line into options format */ | 64 | /* internal function that converts a single line into options format */ |
| 62 | static int add_option(FILE *f, np_arg_list **optlst); | 65 | static int add_option(FILE *filePointer, np_arg_list **optlst); |
| 63 | 66 | ||
| 64 | /* internal functions to find default file */ | 67 | /* internal functions to find default file */ |
| 65 | static char *default_file(void); | 68 | static char *default_file(void); |
| @@ -71,7 +74,8 @@ static char *default_file_in_path(void); | |||
| 71 | * into its separate parts. | 74 | * into its separate parts. |
| 72 | */ | 75 | */ |
| 73 | static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i) { | 76 | static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i) { |
| 74 | size_t locator_len = 0, stanza_len = 0; | 77 | size_t locator_len = 0; |
| 78 | size_t stanza_len = 0; | ||
| 75 | 79 | ||
| 76 | /* if locator is NULL we'll use default values */ | 80 | /* if locator is NULL we'll use default values */ |
| 77 | if (locator != NULL) { | 81 | if (locator != NULL) { |
| @@ -87,8 +91,9 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in | |||
| 87 | i->stanza = strdup(def_stanza); | 91 | i->stanza = strdup(def_stanza); |
| 88 | } | 92 | } |
| 89 | 93 | ||
| 90 | if (i->stanza == NULL) | 94 | if (i->stanza == NULL) { |
| 91 | die(STATE_UNKNOWN, _("malloc() failed!\n")); | 95 | die(STATE_UNKNOWN, _("malloc() failed!\n")); |
| 96 | } | ||
| 92 | 97 | ||
| 93 | /* check whether there's an @file part */ | 98 | /* check whether there's an @file part */ |
| 94 | if (stanza_len == locator_len) { | 99 | if (stanza_len == locator_len) { |
| @@ -99,39 +104,46 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in | |||
| 99 | i->file_string_on_heap = true; | 104 | i->file_string_on_heap = true; |
| 100 | } | 105 | } |
| 101 | 106 | ||
| 102 | if (i->file == NULL || i->file[0] == '\0') | 107 | if (i->file == NULL || i->file[0] == '\0') { |
| 103 | die(STATE_UNKNOWN, _("Cannot find config file in any standard location.\n")); | 108 | die(STATE_UNKNOWN, _("Cannot find config file in any standard location.\n")); |
| 109 | } | ||
| 104 | } | 110 | } |
| 105 | 111 | ||
| 106 | /* | 112 | /* |
| 107 | * This is the externally visible function used by extra_opts. | 113 | * This is the externally visible function used by extra_opts. |
| 108 | */ | 114 | */ |
| 109 | np_arg_list *np_get_defaults(const char *locator, const char *default_section) { | 115 | np_arg_list *np_get_defaults(const char *locator, const char *default_section) { |
| 110 | FILE *inifile = NULL; | ||
| 111 | np_arg_list *defaults = NULL; | ||
| 112 | np_ini_info i; | ||
| 113 | int is_suid_plugin = mp_suid(); | 116 | int is_suid_plugin = mp_suid(); |
| 114 | 117 | ||
| 115 | if (is_suid_plugin && idpriv_temp_drop() == -1) | 118 | if (is_suid_plugin && idpriv_temp_drop() == -1) { |
| 116 | die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"), strerror(errno)); | 119 | die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"), strerror(errno)); |
| 120 | } | ||
| 117 | 121 | ||
| 118 | parse_locator(locator, default_section, &i); | 122 | FILE *inifile = NULL; |
| 119 | inifile = strcmp(i.file, "-") == 0 ? stdin : fopen(i.file, "r"); | 123 | np_ini_info ini_info; |
| 124 | parse_locator(locator, default_section, &ini_info); | ||
| 125 | inifile = strcmp(ini_info.file, "-") == 0 ? stdin : fopen(ini_info.file, "r"); | ||
| 120 | 126 | ||
| 121 | if (inifile == NULL) | 127 | if (inifile == NULL) { |
| 122 | die(STATE_UNKNOWN, _("Can't read config file: %s\n"), strerror(errno)); | 128 | die(STATE_UNKNOWN, _("Can't read config file: %s\n"), strerror(errno)); |
| 123 | if (!read_defaults(inifile, i.stanza, &defaults)) | 129 | } |
| 124 | die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), i.stanza, i.file); | ||
| 125 | 130 | ||
| 126 | if (i.file_string_on_heap) { | 131 | np_arg_list *defaults = NULL; |
| 127 | free(i.file); | 132 | if (!read_defaults(inifile, ini_info.stanza, &defaults)) { |
| 133 | die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), ini_info.stanza, ini_info.file); | ||
| 134 | } | ||
| 135 | |||
| 136 | if (ini_info.file_string_on_heap) { | ||
| 137 | free(ini_info.file); | ||
| 128 | } | 138 | } |
| 129 | 139 | ||
| 130 | if (inifile != stdin) | 140 | if (inifile != stdin) { |
| 131 | fclose(inifile); | 141 | fclose(inifile); |
| 132 | free(i.stanza); | 142 | } |
| 133 | if (is_suid_plugin && idpriv_temp_restore() == -1) | 143 | free(ini_info.stanza); |
| 144 | if (is_suid_plugin && idpriv_temp_restore() == -1) { | ||
| 134 | die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"), strerror(errno)); | 145 | die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"), strerror(errno)); |
| 146 | } | ||
| 135 | 147 | ||
| 136 | return defaults; | 148 | return defaults; |
| 137 | } | 149 | } |
| @@ -143,54 +155,58 @@ np_arg_list *np_get_defaults(const char *locator, const char *default_section) { | |||
| 143 | * be extra careful about user-supplied input (i.e. avoiding possible | 155 | * be extra careful about user-supplied input (i.e. avoiding possible |
| 144 | * format string vulnerabilities, etc). | 156 | * format string vulnerabilities, etc). |
| 145 | */ | 157 | */ |
| 146 | static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { | 158 | static bool read_defaults(FILE *defaults_file, const char *stanza, np_arg_list **opts) { |
| 147 | int c = 0; | ||
| 148 | bool status = false; | 159 | bool status = false; |
| 149 | size_t i, stanza_len; | ||
| 150 | enum { | 160 | enum { |
| 151 | NOSTANZA, | 161 | NOSTANZA, |
| 152 | WRONGSTANZA, | 162 | WRONGSTANZA, |
| 153 | RIGHTSTANZA | 163 | RIGHTSTANZA |
| 154 | } stanzastate = NOSTANZA; | 164 | } stanzastate = NOSTANZA; |
| 155 | 165 | ||
| 156 | stanza_len = strlen(stanza); | 166 | size_t stanza_len = strlen(stanza); |
| 157 | 167 | ||
| 158 | /* our little stanza-parsing state machine */ | 168 | /* our little stanza-parsing state machine */ |
| 159 | while ((c = fgetc(f)) != EOF) { | 169 | int current_char = 0; |
| 170 | while ((current_char = fgetc(defaults_file)) != EOF) { | ||
| 160 | /* gobble up leading whitespace */ | 171 | /* gobble up leading whitespace */ |
| 161 | if (isspace(c)) | 172 | if (isspace(current_char)) { |
| 162 | continue; | 173 | continue; |
| 163 | switch (c) { | 174 | } |
| 175 | switch (current_char) { | ||
| 164 | /* globble up comment lines */ | 176 | /* globble up comment lines */ |
| 165 | case ';': | 177 | case ';': |
| 166 | case '#': | 178 | case '#': |
| 167 | GOBBLE_TO(f, c, '\n'); | 179 | GOBBLE_TO(defaults_file, current_char, '\n'); |
| 168 | break; | 180 | break; |
| 169 | /* start of a stanza, check to see if it matches */ | 181 | /* start of a stanza, check to see if it matches */ |
| 170 | case '[': | 182 | case '[': { |
| 171 | stanzastate = WRONGSTANZA; | 183 | stanzastate = WRONGSTANZA; |
| 184 | size_t i; | ||
| 172 | for (i = 0; i < stanza_len; i++) { | 185 | for (i = 0; i < stanza_len; i++) { |
| 173 | c = fgetc(f); | 186 | current_char = fgetc(defaults_file); |
| 174 | /* strip leading whitespace */ | 187 | /* strip leading whitespace */ |
| 175 | if (i == 0) | 188 | if (i == 0) { |
| 176 | for (; isspace(c); c = fgetc(f)) | 189 | for (; isspace(current_char); current_char = fgetc(defaults_file)) { |
| 177 | continue; | 190 | } |
| 191 | } | ||
| 178 | /* nope, read to the end of the line */ | 192 | /* nope, read to the end of the line */ |
| 179 | if (c != stanza[i]) { | 193 | if (current_char != stanza[i]) { |
| 180 | GOBBLE_TO(f, c, '\n'); | 194 | GOBBLE_TO(defaults_file, current_char, '\n'); |
| 181 | break; | 195 | break; |
| 182 | } | 196 | } |
| 183 | } | 197 | } |
| 198 | |||
| 184 | /* if it matched up to here and the next char is ']'... */ | 199 | /* if it matched up to here and the next char is ']'... */ |
| 185 | if (i == stanza_len) { | 200 | if (i == stanza_len) { |
| 186 | c = fgetc(f); | 201 | current_char = fgetc(defaults_file); |
| 187 | /* strip trailing whitespace */ | 202 | /* strip trailing whitespace */ |
| 188 | for (; isspace(c); c = fgetc(f)) | 203 | for (; isspace(current_char); current_char = fgetc(defaults_file)) { |
| 189 | continue; | 204 | } |
| 190 | if (c == ']') | 205 | if (current_char == ']') { |
| 191 | stanzastate = RIGHTSTANZA; | 206 | stanzastate = RIGHTSTANZA; |
| 207 | } | ||
| 192 | } | 208 | } |
| 193 | break; | 209 | } break; |
| 194 | /* otherwise, we're in the body of a stanza or a parse error */ | 210 | /* otherwise, we're in the body of a stanza or a parse error */ |
| 195 | default: | 211 | default: |
| 196 | switch (stanzastate) { | 212 | switch (stanzastate) { |
| @@ -201,12 +217,12 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { | |||
| 201 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); | 217 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); |
| 202 | /* we're in a stanza, but for a different plugin */ | 218 | /* we're in a stanza, but for a different plugin */ |
| 203 | case WRONGSTANZA: | 219 | case WRONGSTANZA: |
| 204 | GOBBLE_TO(f, c, '\n'); | 220 | GOBBLE_TO(defaults_file, current_char, '\n'); |
| 205 | break; | 221 | break; |
| 206 | /* okay, this is where we start taking the config */ | 222 | /* okay, this is where we start taking the config */ |
| 207 | case RIGHTSTANZA: | 223 | case RIGHTSTANZA: |
| 208 | ungetc(c, f); | 224 | ungetc(current_char, defaults_file); |
| 209 | if (add_option(f, opts)) { | 225 | if (add_option(defaults_file, opts)) { |
| 210 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); | 226 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); |
| 211 | } | 227 | } |
| 212 | status = true; | 228 | status = true; |
| @@ -225,13 +241,12 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { | |||
| 225 | * --option[=value] | 241 | * --option[=value] |
| 226 | * appending it to the linked list optbuf. | 242 | * appending it to the linked list optbuf. |
| 227 | */ | 243 | */ |
| 228 | static int add_option(FILE *f, np_arg_list **optlst) { | 244 | static int add_option(FILE *filePointer, np_arg_list **optlst) { |
| 229 | np_arg_list *opttmp = *optlst, *optnew; | 245 | char *linebuf = NULL; |
| 230 | char *linebuf = NULL, *lineend = NULL, *optptr = NULL, *optend = NULL; | 246 | bool done_reading = false; |
| 231 | char *eqptr = NULL, *valptr = NULL, *valend = NULL; | 247 | const size_t read_sz = 8; |
| 232 | short done_reading = 0, equals = 0, value = 0; | 248 | size_t linebuf_sz = 0; |
| 233 | size_t cfg_len = 0, read_sz = 8, linebuf_sz = 0, read_pos = 0; | 249 | size_t read_pos = 0; |
| 234 | size_t opt_len = 0, val_len = 0; | ||
| 235 | 250 | ||
| 236 | /* read one line from the file */ | 251 | /* read one line from the file */ |
| 237 | while (!done_reading) { | 252 | while (!done_reading) { |
| @@ -239,74 +254,101 @@ static int add_option(FILE *f, np_arg_list **optlst) { | |||
| 239 | if (linebuf == NULL || read_pos + read_sz >= linebuf_sz) { | 254 | if (linebuf == NULL || read_pos + read_sz >= linebuf_sz) { |
| 240 | linebuf_sz = linebuf_sz > 0 ? linebuf_sz << 1 : read_sz; | 255 | linebuf_sz = linebuf_sz > 0 ? linebuf_sz << 1 : read_sz; |
| 241 | linebuf = realloc(linebuf, linebuf_sz); | 256 | linebuf = realloc(linebuf, linebuf_sz); |
| 242 | if (linebuf == NULL) | 257 | if (linebuf == NULL) { |
| 243 | die(STATE_UNKNOWN, _("malloc() failed!\n")); | 258 | die(STATE_UNKNOWN, _("malloc() failed!\n")); |
| 259 | } | ||
| 244 | } | 260 | } |
| 245 | if (fgets(&linebuf[read_pos], (int)read_sz, f) == NULL) | 261 | |
| 246 | done_reading = 1; | 262 | if (fgets(&linebuf[read_pos], (int)read_sz, filePointer) == NULL) { |
| 247 | else { | 263 | done_reading = true; |
| 264 | } else { | ||
| 248 | read_pos = strlen(linebuf); | 265 | read_pos = strlen(linebuf); |
| 249 | if (linebuf[read_pos - 1] == '\n') { | 266 | if (linebuf[read_pos - 1] == '\n') { |
| 250 | linebuf[--read_pos] = '\0'; | 267 | linebuf[--read_pos] = '\0'; |
| 251 | done_reading = 1; | 268 | done_reading = true; |
| 252 | } | 269 | } |
| 253 | } | 270 | } |
| 254 | } | 271 | } |
| 255 | lineend = &linebuf[read_pos]; | 272 | |
| 273 | char *lineend = &linebuf[read_pos]; | ||
| 256 | /* all that to read one line, isn't C fun? :) now comes the parsing :/ */ | 274 | /* all that to read one line, isn't C fun? :) now comes the parsing :/ */ |
| 257 | 275 | ||
| 258 | /* skip leading whitespace */ | 276 | /* skip leading whitespace */ |
| 259 | for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++) | 277 | char *optptr = NULL; |
| 260 | continue; | 278 | for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++) { |
| 279 | } | ||
| 280 | |||
| 261 | /* continue to '=' or EOL, watching for spaces that might precede it */ | 281 | /* continue to '=' or EOL, watching for spaces that might precede it */ |
| 282 | char *eqptr = NULL; | ||
| 283 | char *optend = NULL; | ||
| 262 | for (eqptr = optptr; eqptr < lineend && *eqptr != '='; eqptr++) { | 284 | for (eqptr = optptr; eqptr < lineend && *eqptr != '='; eqptr++) { |
| 263 | if (isspace(*eqptr) && optend == NULL) | 285 | if (isspace(*eqptr) && optend == NULL) { |
| 264 | optend = eqptr; | 286 | optend = eqptr; |
| 265 | else | 287 | } else { |
| 266 | optend = NULL; | 288 | optend = NULL; |
| 289 | } | ||
| 267 | } | 290 | } |
| 268 | if (optend == NULL) | 291 | |
| 292 | if (optend == NULL) { | ||
| 269 | optend = eqptr; | 293 | optend = eqptr; |
| 294 | } | ||
| 295 | |||
| 270 | --optend; | 296 | --optend; |
| 297 | |||
| 271 | /* ^[[:space:]]*=foo is a syntax error */ | 298 | /* ^[[:space:]]*=foo is a syntax error */ |
| 272 | if (optptr == eqptr) | 299 | if (optptr == eqptr) { |
| 273 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); | 300 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); |
| 301 | } | ||
| 302 | |||
| 274 | /* continue from '=' to start of value or EOL */ | 303 | /* continue from '=' to start of value or EOL */ |
| 275 | for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++) | 304 | char *valptr = NULL; |
| 276 | continue; | 305 | for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++) { |
| 306 | } | ||
| 307 | |||
| 277 | /* continue to the end of value */ | 308 | /* continue to the end of value */ |
| 278 | for (valend = valptr; valend < lineend; valend++) | 309 | char *valend = NULL; |
| 279 | continue; | 310 | for (valend = valptr; valend < lineend; valend++) { |
| 311 | } | ||
| 312 | |||
| 280 | --valend; | 313 | --valend; |
| 314 | |||
| 281 | /* finally trim off trailing spaces */ | 315 | /* finally trim off trailing spaces */ |
| 282 | for (; isspace(*valend); valend--) | 316 | for (; isspace(*valend); valend--) { |
| 283 | continue; | 317 | } |
| 318 | |||
| 284 | /* calculate the length of "--foo" */ | 319 | /* calculate the length of "--foo" */ |
| 285 | opt_len = (size_t)(1 + optend - optptr); | 320 | size_t opt_len = (size_t)(1 + optend - optptr); |
| 286 | /* 1-character params needs only one dash */ | 321 | /* 1-character params needs only one dash */ |
| 287 | if (opt_len == 1) | 322 | size_t cfg_len = 0; |
| 323 | if (opt_len == 1) { | ||
| 288 | cfg_len = 1 + (opt_len); | 324 | cfg_len = 1 + (opt_len); |
| 289 | else | 325 | } else { |
| 290 | cfg_len = 2 + (opt_len); | 326 | cfg_len = 2 + (opt_len); |
| 327 | } | ||
| 328 | |||
| 329 | size_t val_len = 0; | ||
| 330 | bool equals = false; | ||
| 331 | bool value = false; | ||
| 291 | /* if valptr<lineend then we have to also allocate space for "=bar" */ | 332 | /* if valptr<lineend then we have to also allocate space for "=bar" */ |
| 292 | if (valptr < lineend) { | 333 | if (valptr < lineend) { |
| 293 | equals = value = 1; | 334 | equals = value = true; |
| 294 | val_len = (size_t)(1 + valend - valptr); | 335 | val_len = (size_t)(1 + valend - valptr); |
| 295 | cfg_len += 1 + val_len; | 336 | cfg_len += 1 + val_len; |
| 296 | } | 337 | } else if (valptr == lineend) { |
| 297 | /* if valptr==valend then we have "=" but no "bar" */ | 338 | /* if valptr==valend then we have "=" but no "bar" */ |
| 298 | else if (valptr == lineend) { | 339 | equals = true; |
| 299 | equals = 1; | ||
| 300 | cfg_len += 1; | 340 | cfg_len += 1; |
| 301 | } | 341 | } |
| 342 | |||
| 302 | /* a line with no equal sign isn't valid */ | 343 | /* a line with no equal sign isn't valid */ |
| 303 | if (equals == 0) | 344 | if (!equals) { |
| 304 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); | 345 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); |
| 346 | } | ||
| 305 | 347 | ||
| 306 | /* okay, now we have all the info we need, so we create a new np_arg_list | 348 | /* okay, now we have all the info we need, so we create a new np_arg_list |
| 307 | * element and set the argument... | 349 | * element and set the argument... |
| 308 | */ | 350 | */ |
| 309 | optnew = malloc(sizeof(np_arg_list)); | 351 | np_arg_list *optnew = malloc(sizeof(np_arg_list)); |
| 310 | optnew->next = NULL; | 352 | optnew->next = NULL; |
| 311 | 353 | ||
| 312 | read_pos = 0; | 354 | read_pos = 0; |
| @@ -329,11 +371,13 @@ static int add_option(FILE *f, np_arg_list **optlst) { | |||
| 329 | optnew->arg[read_pos] = '\0'; | 371 | optnew->arg[read_pos] = '\0'; |
| 330 | 372 | ||
| 331 | /* ...and put that to the end of the list */ | 373 | /* ...and put that to the end of the list */ |
| 332 | if (*optlst == NULL) | 374 | if (*optlst == NULL) { |
| 333 | *optlst = optnew; | 375 | *optlst = optnew; |
| 334 | else { | 376 | } else { |
| 335 | while (opttmp->next != NULL) | 377 | np_arg_list *opttmp = *optlst; |
| 378 | while (opttmp->next != NULL) { | ||
| 336 | opttmp = opttmp->next; | 379 | opttmp = opttmp->next; |
| 380 | } | ||
| 337 | opttmp->next = optnew; | 381 | opttmp->next = optnew; |
| 338 | } | 382 | } |
| 339 | 383 | ||
| @@ -344,7 +388,8 @@ static int add_option(FILE *f, np_arg_list **optlst) { | |||
| 344 | static char *default_file(void) { | 388 | static char *default_file(void) { |
| 345 | char *ini_file; | 389 | char *ini_file; |
| 346 | 390 | ||
| 347 | if ((ini_file = getenv("MP_CONFIG_FILE")) != NULL || (ini_file = default_file_in_path()) != NULL) { | 391 | if ((ini_file = getenv("MP_CONFIG_FILE")) != NULL || |
| 392 | (ini_file = default_file_in_path()) != NULL) { | ||
| 348 | return ini_file; | 393 | return ini_file; |
| 349 | } | 394 | } |
| 350 | 395 | ||
| @@ -357,19 +402,25 @@ static char *default_file(void) { | |||
| 357 | } | 402 | } |
| 358 | 403 | ||
| 359 | static char *default_file_in_path(void) { | 404 | static char *default_file_in_path(void) { |
| 360 | char *config_path, **file; | 405 | char *config_path; |
| 361 | char *dir, *ini_file, *tokens; | 406 | char **file; |
| 407 | char *dir; | ||
| 408 | char *ini_file; | ||
| 409 | char *tokens; | ||
| 362 | 410 | ||
| 363 | if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL) | 411 | if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL) { |
| 364 | return NULL; | 412 | return NULL; |
| 413 | } | ||
| 365 | /* shall we spit out a warning that NAGIOS_CONFIG_PATH is deprecated? */ | 414 | /* shall we spit out a warning that NAGIOS_CONFIG_PATH is deprecated? */ |
| 366 | 415 | ||
| 367 | if ((tokens = strdup(config_path)) == NULL) | 416 | if ((tokens = strdup(config_path)) == NULL) { |
| 368 | die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory")); | 417 | die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory")); |
| 418 | } | ||
| 369 | for (dir = strtok(tokens, ":"); dir != NULL; dir = strtok(NULL, ":")) { | 419 | for (dir = strtok(tokens, ":"); dir != NULL; dir = strtok(NULL, ":")) { |
| 370 | for (file = default_ini_file_names; *file != NULL; file++) { | 420 | for (file = default_ini_file_names; *file != NULL; file++) { |
| 371 | if ((asprintf(&ini_file, "%s/%s", dir, *file)) < 0) | 421 | if ((asprintf(&ini_file, "%s/%s", dir, *file)) < 0) { |
| 372 | die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory")); | 422 | die(STATE_UNKNOWN, "%s\n", _("Insufficient Memory")); |
| 423 | } | ||
| 373 | if (access(ini_file, F_OK) == 0) { | 424 | if (access(ini_file, F_OK) == 0) { |
| 374 | free(tokens); | 425 | free(tokens); |
| 375 | return ini_file; | 426 | return ini_file; |
diff --git a/lib/perfdata.c b/lib/perfdata.c index 661756c5..2930a8bc 100644 --- a/lib/perfdata.c +++ b/lib/perfdata.c | |||
| @@ -33,7 +33,18 @@ char *pd_value_to_string(const mp_perfdata_value pd) { | |||
| 33 | char *pd_to_string(mp_perfdata pd) { | 33 | char *pd_to_string(mp_perfdata pd) { |
| 34 | assert(pd.label != NULL); | 34 | assert(pd.label != NULL); |
| 35 | char *result = NULL; | 35 | char *result = NULL; |
| 36 | asprintf(&result, "%s=", pd.label); | 36 | |
| 37 | if (strchr(pd.label, '\'') == NULL) { | ||
| 38 | asprintf(&result, "'%s'=", pd.label); | ||
| 39 | } else { | ||
| 40 | // we have a illegal single quote in the string | ||
| 41 | // replace it silently instead of complaining | ||
| 42 | for (char *ptr = pd.label; *ptr == '\0'; ptr++) { | ||
| 43 | if (*ptr == '\'') { | ||
| 44 | *ptr = '_'; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
| 37 | 48 | ||
| 38 | asprintf(&result, "%s%s", result, pd_value_to_string(pd.value)); | 49 | asprintf(&result, "%s%s", result, pd_value_to_string(pd.value)); |
| 39 | 50 | ||
| @@ -249,7 +260,9 @@ char *mp_range_to_string(const mp_range input) { | |||
| 249 | return result; | 260 | return result; |
| 250 | } | 261 | } |
| 251 | 262 | ||
| 252 | mp_perfdata mp_set_pd_value_float(mp_perfdata pd, float value) { return mp_set_pd_value_double(pd, value); } | 263 | mp_perfdata mp_set_pd_value_float(mp_perfdata pd, float value) { |
| 264 | return mp_set_pd_value_double(pd, value); | ||
| 265 | } | ||
| 253 | 266 | ||
| 254 | mp_perfdata mp_set_pd_value_double(mp_perfdata pd, double value) { | 267 | mp_perfdata mp_set_pd_value_double(mp_perfdata pd, double value) { |
| 255 | pd.value.pd_double = value; | 268 | pd.value.pd_double = value; |
| @@ -257,11 +270,25 @@ mp_perfdata mp_set_pd_value_double(mp_perfdata pd, double value) { | |||
| 257 | return pd; | 270 | return pd; |
| 258 | } | 271 | } |
| 259 | 272 | ||
| 260 | mp_perfdata mp_set_pd_value_int(mp_perfdata pd, int value) { return mp_set_pd_value_long_long(pd, (long long)value); } | 273 | mp_perfdata mp_set_pd_value_char(mp_perfdata pd, char value) { |
| 274 | return mp_set_pd_value_long_long(pd, (long long)value); | ||
| 275 | } | ||
| 261 | 276 | ||
| 262 | mp_perfdata mp_set_pd_value_u_int(mp_perfdata pd, unsigned int value) { return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); } | 277 | mp_perfdata mp_set_pd_value_u_char(mp_perfdata pd, unsigned char value) { |
| 278 | return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); | ||
| 279 | } | ||
| 263 | 280 | ||
| 264 | mp_perfdata mp_set_pd_value_long(mp_perfdata pd, long value) { return mp_set_pd_value_long_long(pd, (long long)value); } | 281 | mp_perfdata mp_set_pd_value_int(mp_perfdata pd, int value) { |
| 282 | return mp_set_pd_value_long_long(pd, (long long)value); | ||
| 283 | } | ||
| 284 | |||
| 285 | mp_perfdata mp_set_pd_value_u_int(mp_perfdata pd, unsigned int value) { | ||
| 286 | return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); | ||
| 287 | } | ||
| 288 | |||
| 289 | mp_perfdata mp_set_pd_value_long(mp_perfdata pd, long value) { | ||
| 290 | return mp_set_pd_value_long_long(pd, (long long)value); | ||
| 291 | } | ||
| 265 | 292 | ||
| 266 | mp_perfdata mp_set_pd_value_u_long(mp_perfdata pd, unsigned long value) { | 293 | mp_perfdata mp_set_pd_value_u_long(mp_perfdata pd, unsigned long value) { |
| 267 | return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); | 294 | return mp_set_pd_value_u_long_long(pd, (unsigned long long)value); |
| @@ -286,15 +313,33 @@ mp_perfdata_value mp_create_pd_value_double(double value) { | |||
| 286 | return res; | 313 | return res; |
| 287 | } | 314 | } |
| 288 | 315 | ||
| 289 | mp_perfdata_value mp_create_pd_value_float(float value) { return mp_create_pd_value_double((double)value); } | 316 | mp_perfdata_value mp_create_pd_value_float(float value) { |
| 317 | return mp_create_pd_value_double((double)value); | ||
| 318 | } | ||
| 290 | 319 | ||
| 291 | mp_perfdata_value mp_create_pd_value_int(int value) { return mp_create_pd_value_long_long((long long)value); } | 320 | mp_perfdata_value mp_create_pd_value_char(char value) { |
| 321 | return mp_create_pd_value_long_long((long long)value); | ||
| 322 | } | ||
| 292 | 323 | ||
| 293 | mp_perfdata_value mp_create_pd_value_u_int(unsigned int value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } | 324 | mp_perfdata_value mp_create_pd_value_u_char(unsigned char value) { |
| 325 | return mp_create_pd_value_u_long_long((unsigned long long)value); | ||
| 326 | } | ||
| 327 | |||
| 328 | mp_perfdata_value mp_create_pd_value_int(int value) { | ||
| 329 | return mp_create_pd_value_long_long((long long)value); | ||
| 330 | } | ||
| 331 | |||
| 332 | mp_perfdata_value mp_create_pd_value_u_int(unsigned int value) { | ||
| 333 | return mp_create_pd_value_u_long_long((unsigned long long)value); | ||
| 334 | } | ||
| 294 | 335 | ||
| 295 | mp_perfdata_value mp_create_pd_value_long(long value) { return mp_create_pd_value_long_long((long long)value); } | 336 | mp_perfdata_value mp_create_pd_value_long(long value) { |
| 337 | return mp_create_pd_value_long_long((long long)value); | ||
| 338 | } | ||
| 296 | 339 | ||
| 297 | mp_perfdata_value mp_create_pd_value_u_long(unsigned long value) { return mp_create_pd_value_u_long_long((unsigned long long)value); } | 340 | mp_perfdata_value mp_create_pd_value_u_long(unsigned long value) { |
| 341 | return mp_create_pd_value_u_long_long((unsigned long long)value); | ||
| 342 | } | ||
| 298 | 343 | ||
| 299 | mp_perfdata_value mp_create_pd_value_long_long(long long value) { | 344 | mp_perfdata_value mp_create_pd_value_long_long(long long value) { |
| 300 | mp_perfdata_value res = {0}; | 345 | mp_perfdata_value res = {0}; |
| @@ -360,6 +405,13 @@ mp_range_parsed mp_parse_range_string(const char *input) { | |||
| 360 | } | 405 | } |
| 361 | 406 | ||
| 362 | char *working_copy = strdup(input); | 407 | char *working_copy = strdup(input); |
| 408 | if (working_copy == NULL) { | ||
| 409 | // strdup error, probably | ||
| 410 | mp_range_parsed result = { | ||
| 411 | .error = MP_RANGE_PARSING_FAILURE, | ||
| 412 | }; | ||
| 413 | return result; | ||
| 414 | } | ||
| 363 | input = working_copy; | 415 | input = working_copy; |
| 364 | 416 | ||
| 365 | char *separator = index(working_copy, ':'); | 417 | char *separator = index(working_copy, ':'); |
| @@ -514,3 +566,84 @@ perfdata_value_parser_wrapper parse_pd_value(const char *input) { | |||
| 514 | } | 566 | } |
| 515 | return result; | 567 | return result; |
| 516 | } | 568 | } |
| 569 | |||
| 570 | mp_perfdata mp_set_pd_max_value(mp_perfdata perfdata, mp_perfdata_value value) { | ||
| 571 | perfdata.max = value; | ||
| 572 | perfdata.max_present = true; | ||
| 573 | return perfdata; | ||
| 574 | } | ||
| 575 | |||
| 576 | mp_perfdata mp_set_pd_min_value(mp_perfdata perfdata, mp_perfdata_value value) { | ||
| 577 | perfdata.min = value; | ||
| 578 | perfdata.min_present = true; | ||
| 579 | return perfdata; | ||
| 580 | } | ||
| 581 | |||
| 582 | double mp_get_pd_value(mp_perfdata_value value) { | ||
| 583 | assert(value.type != PD_TYPE_NONE); | ||
| 584 | switch (value.type) { | ||
| 585 | case PD_TYPE_DOUBLE: | ||
| 586 | return value.pd_double; | ||
| 587 | case PD_TYPE_INT: | ||
| 588 | return (double)value.pd_int; | ||
| 589 | case PD_TYPE_UINT: | ||
| 590 | return (double)value.pd_uint; | ||
| 591 | default: | ||
| 592 | return 0; // just to make the compiler happy | ||
| 593 | } | ||
| 594 | } | ||
| 595 | |||
| 596 | mp_perfdata_value mp_pd_value_multiply(mp_perfdata_value left, mp_perfdata_value right) { | ||
| 597 | if (left.type == right.type) { | ||
| 598 | switch (left.type) { | ||
| 599 | case PD_TYPE_DOUBLE: | ||
| 600 | left.pd_double *= right.pd_double; | ||
| 601 | return left; | ||
| 602 | case PD_TYPE_INT: | ||
| 603 | left.pd_int *= right.pd_int; | ||
| 604 | return left; | ||
| 605 | case PD_TYPE_UINT: | ||
| 606 | left.pd_uint *= right.pd_uint; | ||
| 607 | return left; | ||
| 608 | default: | ||
| 609 | // what to here? | ||
| 610 | return left; | ||
| 611 | } | ||
| 612 | } | ||
| 613 | |||
| 614 | // Different types, oh boy, just do the lazy thing for now and switch to double | ||
| 615 | switch (left.type) { | ||
| 616 | case PD_TYPE_INT: | ||
| 617 | left.pd_double = (double)left.pd_int; | ||
| 618 | left.type = PD_TYPE_DOUBLE; | ||
| 619 | break; | ||
| 620 | case PD_TYPE_UINT: | ||
| 621 | left.pd_double = (double)left.pd_uint; | ||
| 622 | left.type = PD_TYPE_DOUBLE; | ||
| 623 | break; | ||
| 624 | } | ||
| 625 | |||
| 626 | switch (right.type) { | ||
| 627 | case PD_TYPE_INT: | ||
| 628 | right.pd_double = (double)right.pd_int; | ||
| 629 | right.type = PD_TYPE_DOUBLE; | ||
| 630 | break; | ||
| 631 | case PD_TYPE_UINT: | ||
| 632 | right.pd_double = (double)right.pd_uint; | ||
| 633 | right.type = PD_TYPE_DOUBLE; | ||
| 634 | break; | ||
| 635 | } | ||
| 636 | |||
| 637 | left.pd_double *= right.pd_double; | ||
| 638 | return left; | ||
| 639 | } | ||
| 640 | |||
| 641 | mp_range mp_range_multiply(mp_range range, mp_perfdata_value factor) { | ||
| 642 | if (!range.end_infinity) { | ||
| 643 | range.end = mp_pd_value_multiply(range.end, factor); | ||
| 644 | } | ||
| 645 | if (!range.start_infinity) { | ||
| 646 | range.start = mp_pd_value_multiply(range.start, factor); | ||
| 647 | } | ||
| 648 | return range; | ||
| 649 | } | ||
diff --git a/lib/perfdata.h b/lib/perfdata.h index 74583ee5..e51ef5fd 100644 --- a/lib/perfdata.h +++ b/lib/perfdata.h | |||
| @@ -28,7 +28,7 @@ typedef struct { | |||
| 28 | /* | 28 | /* |
| 29 | * New range type with generic numerical values | 29 | * New range type with generic numerical values |
| 30 | */ | 30 | */ |
| 31 | typedef struct mp_range_struct { | 31 | typedef struct { |
| 32 | mp_perfdata_value start; | 32 | mp_perfdata_value start; |
| 33 | bool start_infinity; /* false (default) or true */ | 33 | bool start_infinity; /* false (default) or true */ |
| 34 | 34 | ||
| @@ -41,11 +41,11 @@ typedef struct mp_range_struct { | |||
| 41 | /* | 41 | /* |
| 42 | * Old range type with floating point values | 42 | * Old range type with floating point values |
| 43 | */ | 43 | */ |
| 44 | typedef struct range_struct { | 44 | typedef struct { |
| 45 | double start; | 45 | double start; |
| 46 | bool start_infinity; | 46 | bool start_infinity; |
| 47 | double end; | 47 | double end; |
| 48 | int end_infinity; | 48 | bool end_infinity; |
| 49 | int alert_on; /* OUTSIDE (default) or INSIDE */ | 49 | int alert_on; /* OUTSIDE (default) or INSIDE */ |
| 50 | char *text; /* original unparsed text input */ | 50 | char *text; /* original unparsed text input */ |
| 51 | } range; | 51 | } range; |
| @@ -53,7 +53,7 @@ typedef struct range_struct { | |||
| 53 | /* | 53 | /* |
| 54 | * Perfdata type for storing perfdata output | 54 | * Perfdata type for storing perfdata output |
| 55 | */ | 55 | */ |
| 56 | typedef struct perfdata_struct { | 56 | typedef struct { |
| 57 | char *label; | 57 | char *label; |
| 58 | char *uom; | 58 | char *uom; |
| 59 | mp_perfdata_value value; | 59 | mp_perfdata_value value; |
| @@ -131,15 +131,15 @@ mp_range_parsed mp_parse_range_string(const char * /*input*/); | |||
| 131 | */ | 131 | */ |
| 132 | void pd_list_append(pd_list[1], mp_perfdata); | 132 | void pd_list_append(pd_list[1], mp_perfdata); |
| 133 | 133 | ||
| 134 | #define mp_set_pd_value(P, V) \ | 134 | #define mp_set_pd_value(P, V) \ |
| 135 | _Generic((V), \ | 135 | _Generic((V), \ |
| 136 | float: mp_set_pd_value_float, \ | 136 | float: mp_set_pd_value_float, \ |
| 137 | double: mp_set_pd_value_double, \ | 137 | double: mp_set_pd_value_double, \ |
| 138 | int: mp_set_pd_value_int, \ | 138 | int: mp_set_pd_value_int, \ |
| 139 | unsigned int: mp_set_pd_value_u_int, \ | 139 | unsigned int: mp_set_pd_value_u_int, \ |
| 140 | long: mp_set_pd_value_long, \ | 140 | long: mp_set_pd_value_long, \ |
| 141 | unsigned long: mp_set_pd_value_u_long, \ | 141 | unsigned long: mp_set_pd_value_u_long, \ |
| 142 | long long: mp_set_pd_value_long_long, \ | 142 | long long: mp_set_pd_value_long_long, \ |
| 143 | unsigned long long: mp_set_pd_value_u_long_long)(P, V) | 143 | unsigned long long: mp_set_pd_value_u_long_long)(P, V) |
| 144 | 144 | ||
| 145 | mp_perfdata mp_set_pd_value_float(mp_perfdata, float); | 145 | mp_perfdata mp_set_pd_value_float(mp_perfdata, float); |
| @@ -151,19 +151,23 @@ mp_perfdata mp_set_pd_value_u_long(mp_perfdata, unsigned long); | |||
| 151 | mp_perfdata mp_set_pd_value_long_long(mp_perfdata, long long); | 151 | mp_perfdata mp_set_pd_value_long_long(mp_perfdata, long long); |
| 152 | mp_perfdata mp_set_pd_value_u_long_long(mp_perfdata, unsigned long long); | 152 | mp_perfdata mp_set_pd_value_u_long_long(mp_perfdata, unsigned long long); |
| 153 | 153 | ||
| 154 | #define mp_create_pd_value(V) \ | 154 | #define mp_create_pd_value(V) \ |
| 155 | _Generic((V), \ | 155 | _Generic((V), \ |
| 156 | float: mp_create_pd_value_float, \ | 156 | float: mp_create_pd_value_float, \ |
| 157 | double: mp_create_pd_value_double, \ | 157 | double: mp_create_pd_value_double, \ |
| 158 | int: mp_create_pd_value_int, \ | 158 | char: mp_create_pd_value_char, \ |
| 159 | unsigned int: mp_create_pd_value_u_int, \ | 159 | unsigned char: mp_create_pd_value_u_char, \ |
| 160 | long: mp_create_pd_value_long, \ | 160 | int: mp_create_pd_value_int, \ |
| 161 | unsigned long: mp_create_pd_value_u_long, \ | 161 | unsigned int: mp_create_pd_value_u_int, \ |
| 162 | long long: mp_create_pd_value_long_long, \ | 162 | long: mp_create_pd_value_long, \ |
| 163 | unsigned long: mp_create_pd_value_u_long, \ | ||
| 164 | long long: mp_create_pd_value_long_long, \ | ||
| 163 | unsigned long long: mp_create_pd_value_u_long_long)(V) | 165 | unsigned long long: mp_create_pd_value_u_long_long)(V) |
| 164 | 166 | ||
| 165 | mp_perfdata_value mp_create_pd_value_float(float); | 167 | mp_perfdata_value mp_create_pd_value_float(float); |
| 166 | mp_perfdata_value mp_create_pd_value_double(double); | 168 | mp_perfdata_value mp_create_pd_value_double(double); |
| 169 | mp_perfdata_value mp_create_pd_value_char(char); | ||
| 170 | mp_perfdata_value mp_create_pd_value_u_char(unsigned char); | ||
| 167 | mp_perfdata_value mp_create_pd_value_int(int); | 171 | mp_perfdata_value mp_create_pd_value_int(int); |
| 168 | mp_perfdata_value mp_create_pd_value_u_int(unsigned int); | 172 | mp_perfdata_value mp_create_pd_value_u_int(unsigned int); |
| 169 | mp_perfdata_value mp_create_pd_value_long(long); | 173 | mp_perfdata_value mp_create_pd_value_long(long); |
| @@ -171,6 +175,11 @@ mp_perfdata_value mp_create_pd_value_u_long(unsigned long); | |||
| 171 | mp_perfdata_value mp_create_pd_value_long_long(long long); | 175 | mp_perfdata_value mp_create_pd_value_long_long(long long); |
| 172 | mp_perfdata_value mp_create_pd_value_u_long_long(unsigned long long); | 176 | mp_perfdata_value mp_create_pd_value_u_long_long(unsigned long long); |
| 173 | 177 | ||
| 178 | mp_perfdata mp_set_pd_max_value(mp_perfdata perfdata, mp_perfdata_value value); | ||
| 179 | mp_perfdata mp_set_pd_min_value(mp_perfdata perfdata, mp_perfdata_value value); | ||
| 180 | |||
| 181 | double mp_get_pd_value(mp_perfdata_value value); | ||
| 182 | |||
| 174 | /* | 183 | /* |
| 175 | * Free the memory used by a pd_list | 184 | * Free the memory used by a pd_list |
| 176 | */ | 185 | */ |
| @@ -178,6 +187,13 @@ void pd_list_free(pd_list[1]); | |||
| 178 | 187 | ||
| 179 | int cmp_perfdata_value(mp_perfdata_value, mp_perfdata_value); | 188 | int cmp_perfdata_value(mp_perfdata_value, mp_perfdata_value); |
| 180 | 189 | ||
| 190 | // ================ | ||
| 191 | // Helper functions | ||
| 192 | // ================ | ||
| 193 | |||
| 194 | mp_perfdata_value mp_pd_value_multiply(mp_perfdata_value left, mp_perfdata_value right); | ||
| 195 | mp_range mp_range_multiply(mp_range range, mp_perfdata_value factor); | ||
| 196 | |||
| 181 | // ================= | 197 | // ================= |
| 182 | // String formatters | 198 | // String formatters |
| 183 | // ================= | 199 | // ================= |
diff --git a/lib/tests/Makefile.am b/lib/tests/Makefile.am index 9be94f6d..7798a72e 100644 --- a/lib/tests/Makefile.am +++ b/lib/tests/Makefile.am | |||
| @@ -8,9 +8,9 @@ check_PROGRAMS = @EXTRA_TEST@ | |||
| 8 | AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ | 8 | AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ |
| 9 | -I$(top_srcdir)/lib -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins | 9 | -I$(top_srcdir)/lib -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins |
| 10 | 10 | ||
| 11 | EXTRA_PROGRAMS = test_utils test_disk test_tcp test_cmd test_base64 test_ini1 test_ini3 test_opts1 test_opts2 test_opts3 test_generic_output | 11 | EXTRA_PROGRAMS = test_utils test_tcp test_cmd test_base64 test_ini1 test_ini3 test_opts1 test_opts2 test_opts3 test_generic_output |
| 12 | 12 | ||
| 13 | np_test_scripts = test_base64.t test_cmd.t test_disk.t test_ini1.t test_ini3.t test_opts1.t test_opts2.t test_opts3.t test_tcp.t test_utils.t test_generic_output.t | 13 | np_test_scripts = test_base64.t test_cmd.t test_ini1.t test_ini3.t test_opts1.t test_opts2.t test_opts3.t test_tcp.t test_utils.t test_generic_output.t |
| 14 | np_test_files = config-dos.ini config-opts.ini config-tiny.ini plugin.ini plugins.ini | 14 | np_test_files = config-dos.ini config-opts.ini config-tiny.ini plugin.ini plugins.ini |
| 15 | EXTRA_DIST = $(np_test_scripts) $(np_test_files) var | 15 | EXTRA_DIST = $(np_test_scripts) $(np_test_files) var |
| 16 | 16 | ||
| @@ -29,7 +29,7 @@ AM_CFLAGS = -g -I$(top_srcdir)/lib -I$(top_srcdir)/gl $(tap_cflags) | |||
| 29 | AM_LDFLAGS = $(tap_ldflags) -ltap | 29 | AM_LDFLAGS = $(tap_ldflags) -ltap |
| 30 | LDADD = $(top_srcdir)/lib/libmonitoringplug.a $(top_srcdir)/gl/libgnu.a $(LIB_CRYPTO) | 30 | LDADD = $(top_srcdir)/lib/libmonitoringplug.a $(top_srcdir)/gl/libgnu.a $(LIB_CRYPTO) |
| 31 | 31 | ||
| 32 | SOURCES = test_utils.c test_disk.c test_tcp.c test_cmd.c test_base64.c test_ini1.c test_ini3.c test_opts1.c test_opts2.c test_opts3.c test_generic_output.c | 32 | SOURCES = test_utils.c test_tcp.c test_cmd.c test_base64.c test_ini1.c test_ini3.c test_opts1.c test_opts2.c test_opts3.c test_generic_output.c |
| 33 | 33 | ||
| 34 | test: ${noinst_PROGRAMS} | 34 | test: ${noinst_PROGRAMS} |
| 35 | perl -MTest::Harness -e '$$Test::Harness::switches=""; runtests(map {$$_ .= ".t"} @ARGV)' $(EXTRA_PROGRAMS) | 35 | perl -MTest::Harness -e '$$Test::Harness::switches=""; runtests(map {$$_ .= ".t"} @ARGV)' $(EXTRA_PROGRAMS) |
diff --git a/lib/tests/test_base64.c b/lib/tests/test_base64.c index 94cb5aa9..798244da 100644 --- a/lib/tests/test_base64.c +++ b/lib/tests/test_base64.c | |||
| @@ -180,117 +180,168 @@ int main(int argc, char **argv) { | |||
| 180 | #endif | 180 | #endif |
| 181 | 181 | ||
| 182 | char random[1024] = { | 182 | char random[1024] = { |
| 183 | 0x0b, 0x30, 0x44, 0x62, 0x7c, 0x22, 0x1f, 0x0d, 0x05, 0x67, 0x2c, 0x2a, 0x39, 0x21, 0x46, 0x08, 0x50, 0x66, 0x34, 0x37, 0x0b, 0x45, | 183 | 0x0b, 0x30, 0x44, 0x62, 0x7c, 0x22, 0x1f, 0x0d, 0x05, 0x67, 0x2c, 0x2a, 0x39, 0x21, 0x46, |
| 184 | 0x4b, 0x38, 0x32, 0x06, 0x7a, 0x3e, 0x7f, 0x0c, 0x40, 0x18, 0x6b, 0x2d, 0x60, 0x4c, 0x60, 0x0c, 0x23, 0x43, 0x3b, 0x3e, 0x1b, 0x16, | 184 | 0x08, 0x50, 0x66, 0x34, 0x37, 0x0b, 0x45, 0x4b, 0x38, 0x32, 0x06, 0x7a, 0x3e, 0x7f, 0x0c, |
| 185 | 0x04, 0x46, 0x58, 0x3f, 0x40, 0x6a, 0x11, 0x05, 0x63, 0x71, 0x14, 0x35, 0x47, 0x79, 0x13, 0x6f, 0x6b, 0x27, 0x18, 0x5b, 0x48, 0x27, | 185 | 0x40, 0x18, 0x6b, 0x2d, 0x60, 0x4c, 0x60, 0x0c, 0x23, 0x43, 0x3b, 0x3e, 0x1b, 0x16, 0x04, |
| 186 | 0x3e, 0x6f, 0x15, 0x33, 0x4f, 0x3e, 0x5e, 0x51, 0x73, 0x68, 0x25, 0x0f, 0x06, 0x5b, 0x7c, 0x72, 0x75, 0x3e, 0x3f, 0x1b, 0x5c, 0x6d, | 186 | 0x46, 0x58, 0x3f, 0x40, 0x6a, 0x11, 0x05, 0x63, 0x71, 0x14, 0x35, 0x47, 0x79, 0x13, 0x6f, |
| 187 | 0x6a, 0x39, 0x7c, 0x63, 0x63, 0x60, 0x6c, 0x7a, 0x33, 0x76, 0x52, 0x13, 0x25, 0x33, 0x7d, 0x65, 0x23, 0x27, 0x11, 0x06, 0x06, 0x47, | 187 | 0x6b, 0x27, 0x18, 0x5b, 0x48, 0x27, 0x3e, 0x6f, 0x15, 0x33, 0x4f, 0x3e, 0x5e, 0x51, 0x73, |
| 188 | 0x71, 0x1e, 0x14, 0x74, 0x63, 0x70, 0x2d, 0x15, 0x27, 0x18, 0x51, 0x06, 0x05, 0x33, 0x11, 0x2c, 0x6b, 0x00, 0x2d, 0x77, 0x20, 0x48, | 188 | 0x68, 0x25, 0x0f, 0x06, 0x5b, 0x7c, 0x72, 0x75, 0x3e, 0x3f, 0x1b, 0x5c, 0x6d, 0x6a, 0x39, |
| 189 | 0x0d, 0x73, 0x51, 0x45, 0x25, 0x7f, 0x7f, 0x35, 0x26, 0x2e, 0x26, 0x53, 0x24, 0x68, 0x1e, 0x0e, 0x58, 0x3a, 0x59, 0x50, 0x56, 0x37, | 189 | 0x7c, 0x63, 0x63, 0x60, 0x6c, 0x7a, 0x33, 0x76, 0x52, 0x13, 0x25, 0x33, 0x7d, 0x65, 0x23, |
| 190 | 0x5f, 0x66, 0x01, 0x4c, 0x5a, 0x64, 0x32, 0x50, 0x7b, 0x6a, 0x20, 0x72, 0x2b, 0x1d, 0x7e, 0x43, 0x7b, 0x61, 0x42, 0x0b, 0x61, 0x73, | 190 | 0x27, 0x11, 0x06, 0x06, 0x47, 0x71, 0x1e, 0x14, 0x74, 0x63, 0x70, 0x2d, 0x15, 0x27, 0x18, |
| 191 | 0x24, 0x79, 0x3a, 0x6b, 0x4a, 0x79, 0x6e, 0x09, 0x0f, 0x27, 0x2d, 0x0c, 0x5e, 0x32, 0x4b, 0x0d, 0x79, 0x46, 0x39, 0x21, 0x0a, 0x26, | 191 | 0x51, 0x06, 0x05, 0x33, 0x11, 0x2c, 0x6b, 0x00, 0x2d, 0x77, 0x20, 0x48, 0x0d, 0x73, 0x51, |
| 192 | 0x5f, 0x3a, 0x00, 0x26, 0x3f, 0x13, 0x2e, 0x7e, 0x50, 0x2b, 0x67, 0x46, 0x72, 0x3f, 0x3b, 0x01, 0x46, 0x1b, 0x0b, 0x35, 0x49, 0x39, | 192 | 0x45, 0x25, 0x7f, 0x7f, 0x35, 0x26, 0x2e, 0x26, 0x53, 0x24, 0x68, 0x1e, 0x0e, 0x58, 0x3a, |
| 193 | 0x19, 0x70, 0x3d, 0x02, 0x41, 0x0e, 0x38, 0x05, 0x76, 0x65, 0x4f, 0x31, 0x6c, 0x5e, 0x17, 0x04, 0x15, 0x36, 0x26, 0x64, 0x34, 0x14, | 193 | 0x59, 0x50, 0x56, 0x37, 0x5f, 0x66, 0x01, 0x4c, 0x5a, 0x64, 0x32, 0x50, 0x7b, 0x6a, 0x20, |
| 194 | 0x17, 0x7c, 0x0e, 0x0b, 0x5b, 0x55, 0x53, 0x6b, 0x00, 0x42, 0x41, 0x4f, 0x02, 0x5c, 0x13, 0x0a, 0x2c, 0x2c, 0x3e, 0x10, 0x14, 0x33, | 194 | 0x72, 0x2b, 0x1d, 0x7e, 0x43, 0x7b, 0x61, 0x42, 0x0b, 0x61, 0x73, 0x24, 0x79, 0x3a, 0x6b, |
| 195 | 0x45, 0x7c, 0x7a, 0x5a, 0x31, 0x61, 0x39, 0x08, 0x22, 0x6a, 0x1e, 0x0f, 0x6f, 0x1b, 0x6c, 0x13, 0x5e, 0x79, 0x20, 0x79, 0x50, 0x62, | 195 | 0x4a, 0x79, 0x6e, 0x09, 0x0f, 0x27, 0x2d, 0x0c, 0x5e, 0x32, 0x4b, 0x0d, 0x79, 0x46, 0x39, |
| 196 | 0x06, 0x2c, 0x76, 0x17, 0x04, 0x2b, 0x2a, 0x75, 0x1f, 0x0c, 0x37, 0x4e, 0x0f, 0x7b, 0x2d, 0x34, 0x75, 0x60, 0x31, 0x74, 0x2e, 0x0a, | 196 | 0x21, 0x0a, 0x26, 0x5f, 0x3a, 0x00, 0x26, 0x3f, 0x13, 0x2e, 0x7e, 0x50, 0x2b, 0x67, 0x46, |
| 197 | 0x4a, 0x11, 0x6c, 0x49, 0x25, 0x01, 0x3a, 0x3d, 0x22, 0x1e, 0x6d, 0x18, 0x51, 0x78, 0x2d, 0x62, 0x31, 0x4c, 0x50, 0x40, 0x17, 0x4b, | 197 | 0x72, 0x3f, 0x3b, 0x01, 0x46, 0x1b, 0x0b, 0x35, 0x49, 0x39, 0x19, 0x70, 0x3d, 0x02, 0x41, |
| 198 | 0x6f, 0x22, 0x00, 0x7f, 0x61, 0x2a, 0x34, 0x3e, 0x00, 0x5f, 0x2f, 0x5f, 0x2f, 0x14, 0x2a, 0x55, 0x27, 0x1f, 0x46, 0x1f, 0x12, 0x46, | 198 | 0x0e, 0x38, 0x05, 0x76, 0x65, 0x4f, 0x31, 0x6c, 0x5e, 0x17, 0x04, 0x15, 0x36, 0x26, 0x64, |
| 199 | 0x5e, 0x1e, 0x0c, 0x7c, 0x38, 0x01, 0x61, 0x64, 0x76, 0x22, 0x6e, 0x08, 0x20, 0x38, 0x4f, 0x73, 0x72, 0x55, 0x12, 0x42, 0x19, 0x50, | 199 | 0x34, 0x14, 0x17, 0x7c, 0x0e, 0x0b, 0x5b, 0x55, 0x53, 0x6b, 0x00, 0x42, 0x41, 0x4f, 0x02, |
| 200 | 0x61, 0x43, 0x77, 0x7d, 0x41, 0x2e, 0x35, 0x4f, 0x3d, 0x31, 0x28, 0x58, 0x67, 0x1b, 0x03, 0x51, 0x20, 0x32, 0x1c, 0x08, 0x6e, 0x37, | 200 | 0x5c, 0x13, 0x0a, 0x2c, 0x2c, 0x3e, 0x10, 0x14, 0x33, 0x45, 0x7c, 0x7a, 0x5a, 0x31, 0x61, |
| 201 | 0x75, 0x37, 0x44, 0x4f, 0x68, 0x19, 0x07, 0x64, 0x14, 0x28, 0x25, 0x2b, 0x69, 0x35, 0x18, 0x27, 0x26, 0x14, 0x13, 0x70, 0x42, 0x19, | 201 | 0x39, 0x08, 0x22, 0x6a, 0x1e, 0x0f, 0x6f, 0x1b, 0x6c, 0x13, 0x5e, 0x79, 0x20, 0x79, 0x50, |
| 202 | 0x12, 0x75, 0x3e, 0x02, 0x5d, 0x7c, 0x13, 0x1f, 0x16, 0x53, 0x3b, 0x74, 0x48, 0x3c, 0x5e, 0x39, 0x6c, 0x1c, 0x1c, 0x74, 0x39, 0x1f, | 202 | 0x62, 0x06, 0x2c, 0x76, 0x17, 0x04, 0x2b, 0x2a, 0x75, 0x1f, 0x0c, 0x37, 0x4e, 0x0f, 0x7b, |
| 203 | 0x00, 0x1b, 0x06, 0x0a, 0x68, 0x3b, 0x52, 0x4f, 0x1e, 0x6e, 0x3c, 0x35, 0x0c, 0x38, 0x0e, 0x0b, 0x3b, 0x1a, 0x76, 0x23, 0x29, 0x53, | 203 | 0x2d, 0x34, 0x75, 0x60, 0x31, 0x74, 0x2e, 0x0a, 0x4a, 0x11, 0x6c, 0x49, 0x25, 0x01, 0x3a, |
| 204 | 0x1e, 0x5f, 0x41, 0x0c, 0x4b, 0x0a, 0x65, 0x28, 0x78, 0x67, 0x48, 0x59, 0x26, 0x6d, 0x31, 0x76, 0x23, 0x70, 0x61, 0x64, 0x3b, 0x38, | 204 | 0x3d, 0x22, 0x1e, 0x6d, 0x18, 0x51, 0x78, 0x2d, 0x62, 0x31, 0x4c, 0x50, 0x40, 0x17, 0x4b, |
| 205 | 0x79, 0x66, 0x74, 0x53, 0x2c, 0x64, 0x64, 0x54, 0x03, 0x54, 0x65, 0x44, 0x4c, 0x18, 0x4f, 0x48, 0x20, 0x4f, 0x72, 0x10, 0x3f, 0x0c, | 205 | 0x6f, 0x22, 0x00, 0x7f, 0x61, 0x2a, 0x34, 0x3e, 0x00, 0x5f, 0x2f, 0x5f, 0x2f, 0x14, 0x2a, |
| 206 | 0x52, 0x2d, 0x03, 0x14, 0x03, 0x51, 0x42, 0x10, 0x77, 0x6a, 0x34, 0x06, 0x32, 0x03, 0x72, 0x14, 0x7c, 0x08, 0x5d, 0x52, 0x1a, 0x62, | 206 | 0x55, 0x27, 0x1f, 0x46, 0x1f, 0x12, 0x46, 0x5e, 0x1e, 0x0c, 0x7c, 0x38, 0x01, 0x61, 0x64, |
| 207 | 0x7c, 0x3e, 0x30, 0x7e, 0x5f, 0x7f, 0x54, 0x0f, 0x44, 0x49, 0x5d, 0x5e, 0x10, 0x6a, 0x06, 0x2b, 0x06, 0x53, 0x10, 0x39, 0x37, 0x32, | 207 | 0x76, 0x22, 0x6e, 0x08, 0x20, 0x38, 0x4f, 0x73, 0x72, 0x55, 0x12, 0x42, 0x19, 0x50, 0x61, |
| 208 | 0x4a, 0x4e, 0x3d, 0x2b, 0x65, 0x38, 0x39, 0x07, 0x72, 0x54, 0x64, 0x4d, 0x56, 0x6a, 0x03, 0x22, 0x70, 0x7b, 0x5f, 0x60, 0x0b, 0x2a, | 208 | 0x43, 0x77, 0x7d, 0x41, 0x2e, 0x35, 0x4f, 0x3d, 0x31, 0x28, 0x58, 0x67, 0x1b, 0x03, 0x51, |
| 209 | 0x0b, 0x6b, 0x10, 0x64, 0x14, 0x05, 0x22, 0x00, 0x73, 0x40, 0x23, 0x5b, 0x51, 0x1f, 0x2b, 0x1a, 0x5d, 0x69, 0x7a, 0x46, 0x0c, 0x5f, | 209 | 0x20, 0x32, 0x1c, 0x08, 0x6e, 0x37, 0x75, 0x37, 0x44, 0x4f, 0x68, 0x19, 0x07, 0x64, 0x14, |
| 210 | 0x32, 0x4b, 0x4a, 0x28, 0x52, 0x79, 0x5b, 0x12, 0x42, 0x18, 0x00, 0x5d, 0x27, 0x31, 0x53, 0x3c, 0x4c, 0x36, 0x4e, 0x38, 0x3f, 0x72, | 210 | 0x28, 0x25, 0x2b, 0x69, 0x35, 0x18, 0x27, 0x26, 0x14, 0x13, 0x70, 0x42, 0x19, 0x12, 0x75, |
| 211 | 0x03, 0x71, 0x02, 0x5b, 0x36, 0x59, 0x7f, 0x75, 0x6e, 0x08, 0x54, 0x0d, 0x34, 0x1c, 0x34, 0x57, 0x5d, 0x69, 0x48, 0x00, 0x3b, 0x05, | 211 | 0x3e, 0x02, 0x5d, 0x7c, 0x13, 0x1f, 0x16, 0x53, 0x3b, 0x74, 0x48, 0x3c, 0x5e, 0x39, 0x6c, |
| 212 | 0x07, 0x6e, 0x27, 0x65, 0x6e, 0x40, 0x3d, 0x3a, 0x4f, 0x72, 0x5d, 0x39, 0x16, 0x0f, 0x63, 0x12, 0x12, 0x15, 0x3a, 0x70, 0x0d, 0x57, | 212 | 0x1c, 0x1c, 0x74, 0x39, 0x1f, 0x00, 0x1b, 0x06, 0x0a, 0x68, 0x3b, 0x52, 0x4f, 0x1e, 0x6e, |
| 213 | 0x18, 0x0d, 0x5e, 0x3d, 0x22, 0x68, 0x68, 0x7c, 0x6d, 0x4f, 0x0c, 0x7b, 0x09, 0x2d, 0x4a, 0x73, 0x20, 0x47, 0x07, 0x57, 0x75, 0x5d, | 213 | 0x3c, 0x35, 0x0c, 0x38, 0x0e, 0x0b, 0x3b, 0x1a, 0x76, 0x23, 0x29, 0x53, 0x1e, 0x5f, 0x41, |
| 214 | 0x53, 0x70, 0x34, 0x21, 0x40, 0x57, 0x51, 0x5e, 0x49, 0x44, 0x00, 0x54, 0x27, 0x04, 0x68, 0x7e, 0x59, 0x56, 0x58, 0x74, 0x14, 0x3c, | 214 | 0x0c, 0x4b, 0x0a, 0x65, 0x28, 0x78, 0x67, 0x48, 0x59, 0x26, 0x6d, 0x31, 0x76, 0x23, 0x70, |
| 215 | 0x16, 0x33, 0x41, 0x16, 0x4b, 0x2f, 0x49, 0x37, 0x0a, 0x54, 0x08, 0x08, 0x1f, 0x39, 0x67, 0x76, 0x28, 0x28, 0x07, 0x1d, 0x61, 0x47, | 215 | 0x61, 0x64, 0x3b, 0x38, 0x79, 0x66, 0x74, 0x53, 0x2c, 0x64, 0x64, 0x54, 0x03, 0x54, 0x65, |
| 216 | 0x51, 0x4d, 0x75, 0x26, 0x52, 0x47, 0x47, 0x0c, 0x57, 0x58, 0x74, 0x3e, 0x62, 0x6c, 0x58, 0x3a, 0x44, 0x1e, 0x16, 0x2e, 0x21, 0x1c, | 216 | 0x44, 0x4c, 0x18, 0x4f, 0x48, 0x20, 0x4f, 0x72, 0x10, 0x3f, 0x0c, 0x52, 0x2d, 0x03, 0x14, |
| 217 | 0x73, 0x45, 0x67, 0x74, 0x4f, 0x33, 0x66, 0x0e, 0x74, 0x66, 0x26, 0x1f, 0x2e, 0x38, 0x44, 0x40, 0x7e, 0x2a, 0x50, 0x52, 0x5e, 0x43, | 217 | 0x03, 0x51, 0x42, 0x10, 0x77, 0x6a, 0x34, 0x06, 0x32, 0x03, 0x72, 0x14, 0x7c, 0x08, 0x5d, |
| 218 | 0x01, 0x7a, 0x38, 0x49, 0x3c, 0x55, 0x4d, 0x5a, 0x44, 0x08, 0x26, 0x59, 0x4d, 0x45, 0x0b, 0x48, 0x0a, 0x33, 0x5e, 0x4a, 0x4d, 0x75, | 218 | 0x52, 0x1a, 0x62, 0x7c, 0x3e, 0x30, 0x7e, 0x5f, 0x7f, 0x54, 0x0f, 0x44, 0x49, 0x5d, 0x5e, |
| 219 | 0x16, 0x17, 0x63, 0x46, 0x01, 0x2a, 0x55, 0x7b, 0x0f, 0x02, 0x73, 0x6a, 0x4b, 0x7f, 0x75, 0x65, 0x3c, 0x4c, 0x33, 0x39, 0x6c, 0x74, | 219 | 0x10, 0x6a, 0x06, 0x2b, 0x06, 0x53, 0x10, 0x39, 0x37, 0x32, 0x4a, 0x4e, 0x3d, 0x2b, 0x65, |
| 220 | 0x05, 0x60, 0x0f, 0x7f, 0x2d, 0x41, 0x4d, 0x4d, 0x46, 0x71, 0x09, 0x6f, 0x4f, 0x60, 0x15, 0x0f, 0x46, 0x73, 0x63, 0x4c, 0x5e, 0x74, | 220 | 0x38, 0x39, 0x07, 0x72, 0x54, 0x64, 0x4d, 0x56, 0x6a, 0x03, 0x22, 0x70, 0x7b, 0x5f, 0x60, |
| 221 | 0x30, 0x0d, 0x28, 0x43, 0x08, 0x72, 0x32, 0x04, 0x2e, 0x31, 0x29, 0x27, 0x44, 0x6d, 0x13, 0x17, 0x48, 0x0f, 0x49, 0x52, 0x10, 0x13, | 221 | 0x0b, 0x2a, 0x0b, 0x6b, 0x10, 0x64, 0x14, 0x05, 0x22, 0x00, 0x73, 0x40, 0x23, 0x5b, 0x51, |
| 222 | 0x7f, 0x17, 0x16, 0x62, 0x79, 0x35, 0x78, 0x3e, 0x01, 0x7c, 0x2e, 0x0f, 0x76, 0x3e, 0x5e, 0x53, 0x6c, 0x5b, 0x5f, 0x7c, 0x19, 0x41, | 222 | 0x1f, 0x2b, 0x1a, 0x5d, 0x69, 0x7a, 0x46, 0x0c, 0x5f, 0x32, 0x4b, 0x4a, 0x28, 0x52, 0x79, |
| 223 | 0x02, 0x2f, 0x17, 0x64, 0x41, 0x75, 0x10, 0x04, 0x47, 0x7c, 0x3d, 0x4b, 0x52, 0x00, 0x10, 0x5d, 0x51, 0x4e, 0x7a, 0x27, 0x25, 0x55, | 223 | 0x5b, 0x12, 0x42, 0x18, 0x00, 0x5d, 0x27, 0x31, 0x53, 0x3c, 0x4c, 0x36, 0x4e, 0x38, 0x3f, |
| 224 | 0x40, 0x12, 0x35, 0x60, 0x05, 0x1b, 0x34, 0x2d, 0x04, 0x7a, 0x6a, 0x69, 0x02, 0x79, 0x03, 0x3a, 0x2f, 0x06, 0x0a, 0x79, 0x7b, 0x12, | 224 | 0x72, 0x03, 0x71, 0x02, 0x5b, 0x36, 0x59, 0x7f, 0x75, 0x6e, 0x08, 0x54, 0x0d, 0x34, 0x1c, |
| 225 | 0x5d, 0x7c, 0x52, 0x29, 0x47, 0x58, 0x12, 0x73, 0x3f, 0x27, 0x56, 0x05, 0x0c, 0x48, 0x32, 0x58, 0x6b, 0x57, 0x5c, 0x03, 0x64, 0x56, | 225 | 0x34, 0x57, 0x5d, 0x69, 0x48, 0x00, 0x3b, 0x05, 0x07, 0x6e, 0x27, 0x65, 0x6e, 0x40, 0x3d, |
| 226 | 0x11, 0x52, 0x7a, 0x30, 0x36, 0x29, 0x17, 0x3b, 0x68, 0x7a, 0x7c, 0x05, 0x6b, 0x6b, 0x13, 0x6a, 0x24, 0x5c, 0x68, 0x42, 0x18, 0x32, | 226 | 0x3a, 0x4f, 0x72, 0x5d, 0x39, 0x16, 0x0f, 0x63, 0x12, 0x12, 0x15, 0x3a, 0x70, 0x0d, 0x57, |
| 227 | 0x03, 0x73, 0x6e, 0x04, 0x21, 0x2e, 0x01, 0x04, 0x63, 0x7d, 0x44, 0x41, 0x12, 0x31, 0x0b, 0x15, 0x1f, 0x70, 0x00, 0x2e, 0x66, 0x14, | 227 | 0x18, 0x0d, 0x5e, 0x3d, 0x22, 0x68, 0x68, 0x7c, 0x6d, 0x4f, 0x0c, 0x7b, 0x09, 0x2d, 0x4a, |
| 228 | 0x3c, 0x7f, 0x2b, 0x00, 0x1f, 0x0c, 0x28, 0x59, 0x0a, 0x16, 0x49, 0x5a, 0x5c, 0x64, 0x65, 0x4b, 0x11, 0x29, 0x15, 0x36, 0x5a, 0x65, | 228 | 0x73, 0x20, 0x47, 0x07, 0x57, 0x75, 0x5d, 0x53, 0x70, 0x34, 0x21, 0x40, 0x57, 0x51, 0x5e, |
| 229 | 0x19, 0x4f, 0x60, 0x23, 0x3a, 0x3a, 0x13, 0x25, 0x02, 0x78, 0x4c, 0x54}; | 229 | 0x49, 0x44, 0x00, 0x54, 0x27, 0x04, 0x68, 0x7e, 0x59, 0x56, 0x58, 0x74, 0x14, 0x3c, 0x16, |
| 230 | 0x33, 0x41, 0x16, 0x4b, 0x2f, 0x49, 0x37, 0x0a, 0x54, 0x08, 0x08, 0x1f, 0x39, 0x67, 0x76, | ||
| 231 | 0x28, 0x28, 0x07, 0x1d, 0x61, 0x47, 0x51, 0x4d, 0x75, 0x26, 0x52, 0x47, 0x47, 0x0c, 0x57, | ||
| 232 | 0x58, 0x74, 0x3e, 0x62, 0x6c, 0x58, 0x3a, 0x44, 0x1e, 0x16, 0x2e, 0x21, 0x1c, 0x73, 0x45, | ||
| 233 | 0x67, 0x74, 0x4f, 0x33, 0x66, 0x0e, 0x74, 0x66, 0x26, 0x1f, 0x2e, 0x38, 0x44, 0x40, 0x7e, | ||
| 234 | 0x2a, 0x50, 0x52, 0x5e, 0x43, 0x01, 0x7a, 0x38, 0x49, 0x3c, 0x55, 0x4d, 0x5a, 0x44, 0x08, | ||
| 235 | 0x26, 0x59, 0x4d, 0x45, 0x0b, 0x48, 0x0a, 0x33, 0x5e, 0x4a, 0x4d, 0x75, 0x16, 0x17, 0x63, | ||
| 236 | 0x46, 0x01, 0x2a, 0x55, 0x7b, 0x0f, 0x02, 0x73, 0x6a, 0x4b, 0x7f, 0x75, 0x65, 0x3c, 0x4c, | ||
| 237 | 0x33, 0x39, 0x6c, 0x74, 0x05, 0x60, 0x0f, 0x7f, 0x2d, 0x41, 0x4d, 0x4d, 0x46, 0x71, 0x09, | ||
| 238 | 0x6f, 0x4f, 0x60, 0x15, 0x0f, 0x46, 0x73, 0x63, 0x4c, 0x5e, 0x74, 0x30, 0x0d, 0x28, 0x43, | ||
| 239 | 0x08, 0x72, 0x32, 0x04, 0x2e, 0x31, 0x29, 0x27, 0x44, 0x6d, 0x13, 0x17, 0x48, 0x0f, 0x49, | ||
| 240 | 0x52, 0x10, 0x13, 0x7f, 0x17, 0x16, 0x62, 0x79, 0x35, 0x78, 0x3e, 0x01, 0x7c, 0x2e, 0x0f, | ||
| 241 | 0x76, 0x3e, 0x5e, 0x53, 0x6c, 0x5b, 0x5f, 0x7c, 0x19, 0x41, 0x02, 0x2f, 0x17, 0x64, 0x41, | ||
| 242 | 0x75, 0x10, 0x04, 0x47, 0x7c, 0x3d, 0x4b, 0x52, 0x00, 0x10, 0x5d, 0x51, 0x4e, 0x7a, 0x27, | ||
| 243 | 0x25, 0x55, 0x40, 0x12, 0x35, 0x60, 0x05, 0x1b, 0x34, 0x2d, 0x04, 0x7a, 0x6a, 0x69, 0x02, | ||
| 244 | 0x79, 0x03, 0x3a, 0x2f, 0x06, 0x0a, 0x79, 0x7b, 0x12, 0x5d, 0x7c, 0x52, 0x29, 0x47, 0x58, | ||
| 245 | 0x12, 0x73, 0x3f, 0x27, 0x56, 0x05, 0x0c, 0x48, 0x32, 0x58, 0x6b, 0x57, 0x5c, 0x03, 0x64, | ||
| 246 | 0x56, 0x11, 0x52, 0x7a, 0x30, 0x36, 0x29, 0x17, 0x3b, 0x68, 0x7a, 0x7c, 0x05, 0x6b, 0x6b, | ||
| 247 | 0x13, 0x6a, 0x24, 0x5c, 0x68, 0x42, 0x18, 0x32, 0x03, 0x73, 0x6e, 0x04, 0x21, 0x2e, 0x01, | ||
| 248 | 0x04, 0x63, 0x7d, 0x44, 0x41, 0x12, 0x31, 0x0b, 0x15, 0x1f, 0x70, 0x00, 0x2e, 0x66, 0x14, | ||
| 249 | 0x3c, 0x7f, 0x2b, 0x00, 0x1f, 0x0c, 0x28, 0x59, 0x0a, 0x16, 0x49, 0x5a, 0x5c, 0x64, 0x65, | ||
| 250 | 0x4b, 0x11, 0x29, 0x15, 0x36, 0x5a, 0x65, 0x19, 0x4f, 0x60, 0x23, 0x3a, 0x3a, 0x13, 0x25, | ||
| 251 | 0x02, 0x78, 0x4c, 0x54}; | ||
| 230 | char b64_known[1369] = { | 252 | char b64_known[1369] = { |
| 231 | 0x43, 0x7a, 0x42, 0x45, 0x59, 0x6e, 0x77, 0x69, 0x48, 0x77, 0x30, 0x46, 0x5a, 0x79, 0x77, 0x71, 0x4f, 0x53, 0x46, 0x47, 0x43, 0x46, | 253 | 0x43, 0x7a, 0x42, 0x45, 0x59, 0x6e, 0x77, 0x69, 0x48, 0x77, 0x30, 0x46, 0x5a, 0x79, 0x77, |
| 232 | 0x42, 0x6d, 0x4e, 0x44, 0x63, 0x4c, 0x52, 0x55, 0x73, 0x34, 0x4d, 0x67, 0x5a, 0x36, 0x50, 0x6e, 0x38, 0x4d, 0x51, 0x42, 0x68, 0x72, | 254 | 0x71, 0x4f, 0x53, 0x46, 0x47, 0x43, 0x46, 0x42, 0x6d, 0x4e, 0x44, 0x63, 0x4c, 0x52, 0x55, |
| 233 | 0x4c, 0x57, 0x42, 0x4d, 0x59, 0x41, 0x77, 0x6a, 0x51, 0x7a, 0x73, 0x2b, 0x47, 0x78, 0x59, 0x45, 0x52, 0x6c, 0x67, 0x2f, 0x51, 0x47, | 255 | 0x73, 0x34, 0x4d, 0x67, 0x5a, 0x36, 0x50, 0x6e, 0x38, 0x4d, 0x51, 0x42, 0x68, 0x72, 0x4c, |
| 234 | 0x6f, 0x52, 0x42, 0x57, 0x4e, 0x78, 0x46, 0x44, 0x56, 0x48, 0x65, 0x52, 0x4e, 0x76, 0x61, 0x79, 0x63, 0x59, 0x57, 0x30, 0x67, 0x6e, | 256 | 0x57, 0x42, 0x4d, 0x59, 0x41, 0x77, 0x6a, 0x51, 0x7a, 0x73, 0x2b, 0x47, 0x78, 0x59, 0x45, |
| 235 | 0x50, 0x6d, 0x38, 0x56, 0x4d, 0x30, 0x38, 0x2b, 0x58, 0x6c, 0x46, 0x7a, 0x61, 0x43, 0x55, 0x50, 0x42, 0x6c, 0x74, 0x38, 0x63, 0x6e, | 257 | 0x52, 0x6c, 0x67, 0x2f, 0x51, 0x47, 0x6f, 0x52, 0x42, 0x57, 0x4e, 0x78, 0x46, 0x44, 0x56, |
| 236 | 0x55, 0x2b, 0x50, 0x78, 0x74, 0x63, 0x62, 0x57, 0x6f, 0x35, 0x66, 0x47, 0x4e, 0x6a, 0x59, 0x47, 0x78, 0x36, 0x4d, 0x33, 0x5a, 0x53, | 258 | 0x48, 0x65, 0x52, 0x4e, 0x76, 0x61, 0x79, 0x63, 0x59, 0x57, 0x30, 0x67, 0x6e, 0x50, 0x6d, |
| 237 | 0x45, 0x79, 0x55, 0x7a, 0x66, 0x57, 0x55, 0x6a, 0x4a, 0x78, 0x45, 0x47, 0x42, 0x6b, 0x64, 0x78, 0x48, 0x68, 0x52, 0x30, 0x59, 0x33, | 259 | 0x38, 0x56, 0x4d, 0x30, 0x38, 0x2b, 0x58, 0x6c, 0x46, 0x7a, 0x61, 0x43, 0x55, 0x50, 0x42, |
| 238 | 0x41, 0x74, 0x46, 0x53, 0x63, 0x59, 0x55, 0x51, 0x59, 0x46, 0x4d, 0x78, 0x45, 0x73, 0x61, 0x77, 0x41, 0x74, 0x64, 0x79, 0x42, 0x49, | 260 | 0x6c, 0x74, 0x38, 0x63, 0x6e, 0x55, 0x2b, 0x50, 0x78, 0x74, 0x63, 0x62, 0x57, 0x6f, 0x35, |
| 239 | 0x44, 0x58, 0x4e, 0x52, 0x52, 0x53, 0x56, 0x2f, 0x66, 0x7a, 0x55, 0x6d, 0x4c, 0x69, 0x5a, 0x54, 0x4a, 0x47, 0x67, 0x65, 0x44, 0x6c, | 261 | 0x66, 0x47, 0x4e, 0x6a, 0x59, 0x47, 0x78, 0x36, 0x4d, 0x33, 0x5a, 0x53, 0x45, 0x79, 0x55, |
| 240 | 0x67, 0x36, 0x57, 0x56, 0x42, 0x57, 0x4e, 0x31, 0x39, 0x6d, 0x41, 0x55, 0x78, 0x61, 0x5a, 0x44, 0x4a, 0x51, 0x65, 0x32, 0x6f, 0x67, | 262 | 0x7a, 0x66, 0x57, 0x55, 0x6a, 0x4a, 0x78, 0x45, 0x47, 0x42, 0x6b, 0x64, 0x78, 0x48, 0x68, |
| 241 | 0x63, 0x69, 0x73, 0x64, 0x66, 0x6b, 0x4e, 0x37, 0x59, 0x55, 0x49, 0x4c, 0x59, 0x58, 0x4d, 0x6b, 0x65, 0x54, 0x70, 0x72, 0x53, 0x6e, | 263 | 0x52, 0x30, 0x59, 0x33, 0x41, 0x74, 0x46, 0x53, 0x63, 0x59, 0x55, 0x51, 0x59, 0x46, 0x4d, |
| 242 | 0x6c, 0x75, 0x43, 0x51, 0x38, 0x6e, 0x4c, 0x51, 0x78, 0x65, 0x4d, 0x6b, 0x73, 0x4e, 0x65, 0x55, 0x59, 0x35, 0x49, 0x51, 0x6f, 0x6d, | 264 | 0x78, 0x45, 0x73, 0x61, 0x77, 0x41, 0x74, 0x64, 0x79, 0x42, 0x49, 0x44, 0x58, 0x4e, 0x52, |
| 243 | 0x58, 0x7a, 0x6f, 0x41, 0x4a, 0x6a, 0x38, 0x54, 0x4c, 0x6e, 0x35, 0x51, 0x4b, 0x32, 0x64, 0x47, 0x63, 0x6a, 0x38, 0x37, 0x41, 0x55, | 265 | 0x52, 0x53, 0x56, 0x2f, 0x66, 0x7a, 0x55, 0x6d, 0x4c, 0x69, 0x5a, 0x54, 0x4a, 0x47, 0x67, |
| 244 | 0x59, 0x62, 0x43, 0x7a, 0x56, 0x4a, 0x4f, 0x52, 0x6c, 0x77, 0x50, 0x51, 0x4a, 0x42, 0x44, 0x6a, 0x67, 0x46, 0x64, 0x6d, 0x56, 0x50, | 266 | 0x65, 0x44, 0x6c, 0x67, 0x36, 0x57, 0x56, 0x42, 0x57, 0x4e, 0x31, 0x39, 0x6d, 0x41, 0x55, |
| 245 | 0x4d, 0x57, 0x78, 0x65, 0x46, 0x77, 0x51, 0x56, 0x4e, 0x69, 0x5a, 0x6b, 0x4e, 0x42, 0x51, 0x58, 0x66, 0x41, 0x34, 0x4c, 0x57, 0x31, | 267 | 0x78, 0x61, 0x5a, 0x44, 0x4a, 0x51, 0x65, 0x32, 0x6f, 0x67, 0x63, 0x69, 0x73, 0x64, 0x66, |
| 246 | 0x56, 0x54, 0x61, 0x77, 0x42, 0x43, 0x51, 0x55, 0x38, 0x43, 0x58, 0x42, 0x4d, 0x4b, 0x4c, 0x43, 0x77, 0x2b, 0x45, 0x42, 0x51, 0x7a, | 268 | 0x6b, 0x4e, 0x37, 0x59, 0x55, 0x49, 0x4c, 0x59, 0x58, 0x4d, 0x6b, 0x65, 0x54, 0x70, 0x72, |
| 247 | 0x52, 0x58, 0x78, 0x36, 0x57, 0x6a, 0x46, 0x68, 0x4f, 0x51, 0x67, 0x69, 0x61, 0x68, 0x34, 0x50, 0x62, 0x78, 0x74, 0x73, 0x45, 0x31, | 269 | 0x53, 0x6e, 0x6c, 0x75, 0x43, 0x51, 0x38, 0x6e, 0x4c, 0x51, 0x78, 0x65, 0x4d, 0x6b, 0x73, |
| 248 | 0x35, 0x35, 0x49, 0x48, 0x6c, 0x51, 0x59, 0x67, 0x59, 0x73, 0x64, 0x68, 0x63, 0x45, 0x4b, 0x79, 0x70, 0x31, 0x48, 0x77, 0x77, 0x33, | 270 | 0x4e, 0x65, 0x55, 0x59, 0x35, 0x49, 0x51, 0x6f, 0x6d, 0x58, 0x7a, 0x6f, 0x41, 0x4a, 0x6a, |
| 249 | 0x54, 0x67, 0x39, 0x37, 0x4c, 0x54, 0x52, 0x31, 0x59, 0x44, 0x46, 0x30, 0x4c, 0x67, 0x70, 0x4b, 0x45, 0x57, 0x78, 0x4a, 0x4a, 0x51, | 271 | 0x38, 0x54, 0x4c, 0x6e, 0x35, 0x51, 0x4b, 0x32, 0x64, 0x47, 0x63, 0x6a, 0x38, 0x37, 0x41, |
| 250 | 0x45, 0x36, 0x50, 0x53, 0x49, 0x65, 0x62, 0x52, 0x68, 0x52, 0x65, 0x43, 0x31, 0x69, 0x4d, 0x55, 0x78, 0x51, 0x51, 0x42, 0x64, 0x4c, | 272 | 0x55, 0x59, 0x62, 0x43, 0x7a, 0x56, 0x4a, 0x4f, 0x52, 0x6c, 0x77, 0x50, 0x51, 0x4a, 0x42, |
| 251 | 0x62, 0x79, 0x49, 0x41, 0x66, 0x32, 0x45, 0x71, 0x4e, 0x44, 0x34, 0x41, 0x58, 0x79, 0x39, 0x66, 0x4c, 0x78, 0x51, 0x71, 0x56, 0x53, | 273 | 0x44, 0x6a, 0x67, 0x46, 0x64, 0x6d, 0x56, 0x50, 0x4d, 0x57, 0x78, 0x65, 0x46, 0x77, 0x51, |
| 252 | 0x63, 0x66, 0x52, 0x68, 0x38, 0x53, 0x52, 0x6c, 0x34, 0x65, 0x44, 0x48, 0x77, 0x34, 0x41, 0x57, 0x46, 0x6b, 0x64, 0x69, 0x4a, 0x75, | 274 | 0x56, 0x4e, 0x69, 0x5a, 0x6b, 0x4e, 0x42, 0x51, 0x58, 0x66, 0x41, 0x34, 0x4c, 0x57, 0x31, |
| 253 | 0x43, 0x43, 0x41, 0x34, 0x54, 0x33, 0x4e, 0x79, 0x56, 0x52, 0x4a, 0x43, 0x47, 0x56, 0x42, 0x68, 0x51, 0x33, 0x64, 0x39, 0x51, 0x53, | 275 | 0x56, 0x54, 0x61, 0x77, 0x42, 0x43, 0x51, 0x55, 0x38, 0x43, 0x58, 0x42, 0x4d, 0x4b, 0x4c, |
| 254 | 0x34, 0x31, 0x54, 0x7a, 0x30, 0x78, 0x4b, 0x46, 0x68, 0x6e, 0x47, 0x77, 0x4e, 0x52, 0x49, 0x44, 0x49, 0x63, 0x43, 0x47, 0x34, 0x33, | 276 | 0x43, 0x77, 0x2b, 0x45, 0x42, 0x51, 0x7a, 0x52, 0x58, 0x78, 0x36, 0x57, 0x6a, 0x46, 0x68, |
| 255 | 0x64, 0x54, 0x64, 0x45, 0x54, 0x32, 0x67, 0x5a, 0x42, 0x32, 0x51, 0x55, 0x4b, 0x43, 0x55, 0x72, 0x61, 0x54, 0x55, 0x59, 0x4a, 0x79, | 277 | 0x4f, 0x51, 0x67, 0x69, 0x61, 0x68, 0x34, 0x50, 0x62, 0x78, 0x74, 0x73, 0x45, 0x31, 0x35, |
| 256 | 0x59, 0x55, 0x45, 0x33, 0x42, 0x43, 0x47, 0x52, 0x4a, 0x31, 0x50, 0x67, 0x4a, 0x64, 0x66, 0x42, 0x4d, 0x66, 0x46, 0x6c, 0x4d, 0x37, | 278 | 0x35, 0x49, 0x48, 0x6c, 0x51, 0x59, 0x67, 0x59, 0x73, 0x64, 0x68, 0x63, 0x45, 0x4b, 0x79, |
| 257 | 0x64, 0x45, 0x67, 0x38, 0x58, 0x6a, 0x6c, 0x73, 0x48, 0x42, 0x78, 0x30, 0x4f, 0x52, 0x38, 0x41, 0x47, 0x77, 0x59, 0x4b, 0x61, 0x44, | 279 | 0x70, 0x31, 0x48, 0x77, 0x77, 0x33, 0x54, 0x67, 0x39, 0x37, 0x4c, 0x54, 0x52, 0x31, 0x59, |
| 258 | 0x74, 0x53, 0x54, 0x78, 0x35, 0x75, 0x50, 0x44, 0x55, 0x4d, 0x4f, 0x41, 0x34, 0x4c, 0x4f, 0x78, 0x70, 0x32, 0x49, 0x79, 0x6c, 0x54, | 280 | 0x44, 0x46, 0x30, 0x4c, 0x67, 0x70, 0x4b, 0x45, 0x57, 0x78, 0x4a, 0x4a, 0x51, 0x45, 0x36, |
| 259 | 0x48, 0x6c, 0x39, 0x42, 0x44, 0x45, 0x73, 0x4b, 0x5a, 0x53, 0x68, 0x34, 0x5a, 0x30, 0x68, 0x5a, 0x4a, 0x6d, 0x30, 0x78, 0x64, 0x69, | 281 | 0x50, 0x53, 0x49, 0x65, 0x62, 0x52, 0x68, 0x52, 0x65, 0x43, 0x31, 0x69, 0x4d, 0x55, 0x78, |
| 260 | 0x4e, 0x77, 0x59, 0x57, 0x51, 0x37, 0x4f, 0x48, 0x6c, 0x6d, 0x64, 0x46, 0x4d, 0x73, 0x5a, 0x47, 0x52, 0x55, 0x41, 0x31, 0x52, 0x6c, | 282 | 0x51, 0x51, 0x42, 0x64, 0x4c, 0x62, 0x79, 0x49, 0x41, 0x66, 0x32, 0x45, 0x71, 0x4e, 0x44, |
| 261 | 0x52, 0x45, 0x77, 0x59, 0x54, 0x30, 0x67, 0x67, 0x54, 0x33, 0x49, 0x51, 0x50, 0x77, 0x78, 0x53, 0x4c, 0x51, 0x4d, 0x55, 0x41, 0x31, | 283 | 0x34, 0x41, 0x58, 0x79, 0x39, 0x66, 0x4c, 0x78, 0x51, 0x71, 0x56, 0x53, 0x63, 0x66, 0x52, |
| 262 | 0x46, 0x43, 0x45, 0x48, 0x64, 0x71, 0x4e, 0x41, 0x59, 0x79, 0x41, 0x33, 0x49, 0x55, 0x66, 0x41, 0x68, 0x64, 0x55, 0x68, 0x70, 0x69, | 284 | 0x68, 0x38, 0x53, 0x52, 0x6c, 0x34, 0x65, 0x44, 0x48, 0x77, 0x34, 0x41, 0x57, 0x46, 0x6b, |
| 263 | 0x66, 0x44, 0x34, 0x77, 0x66, 0x6c, 0x39, 0x2f, 0x56, 0x41, 0x39, 0x45, 0x53, 0x56, 0x31, 0x65, 0x45, 0x47, 0x6f, 0x47, 0x4b, 0x77, | 285 | 0x64, 0x69, 0x4a, 0x75, 0x43, 0x43, 0x41, 0x34, 0x54, 0x33, 0x4e, 0x79, 0x56, 0x52, 0x4a, |
| 264 | 0x5a, 0x54, 0x45, 0x44, 0x6b, 0x33, 0x4d, 0x6b, 0x70, 0x4f, 0x50, 0x53, 0x74, 0x6c, 0x4f, 0x44, 0x6b, 0x48, 0x63, 0x6c, 0x52, 0x6b, | 286 | 0x43, 0x47, 0x56, 0x42, 0x68, 0x51, 0x33, 0x64, 0x39, 0x51, 0x53, 0x34, 0x31, 0x54, 0x7a, |
| 265 | 0x54, 0x56, 0x5a, 0x71, 0x41, 0x79, 0x4a, 0x77, 0x65, 0x31, 0x39, 0x67, 0x43, 0x79, 0x6f, 0x4c, 0x61, 0x78, 0x42, 0x6b, 0x46, 0x41, | 287 | 0x30, 0x78, 0x4b, 0x46, 0x68, 0x6e, 0x47, 0x77, 0x4e, 0x52, 0x49, 0x44, 0x49, 0x63, 0x43, |
| 266 | 0x55, 0x69, 0x41, 0x48, 0x4e, 0x41, 0x49, 0x31, 0x74, 0x52, 0x48, 0x79, 0x73, 0x61, 0x58, 0x57, 0x6c, 0x36, 0x52, 0x67, 0x78, 0x66, | 288 | 0x47, 0x34, 0x33, 0x64, 0x54, 0x64, 0x45, 0x54, 0x32, 0x67, 0x5a, 0x42, 0x32, 0x51, 0x55, |
| 267 | 0x4d, 0x6b, 0x74, 0x4b, 0x4b, 0x46, 0x4a, 0x35, 0x57, 0x78, 0x4a, 0x43, 0x47, 0x41, 0x42, 0x64, 0x4a, 0x7a, 0x46, 0x54, 0x50, 0x45, | 289 | 0x4b, 0x43, 0x55, 0x72, 0x61, 0x54, 0x55, 0x59, 0x4a, 0x79, 0x59, 0x55, 0x45, 0x33, 0x42, |
| 268 | 0x77, 0x32, 0x54, 0x6a, 0x67, 0x2f, 0x63, 0x67, 0x4e, 0x78, 0x41, 0x6c, 0x73, 0x32, 0x57, 0x58, 0x39, 0x31, 0x62, 0x67, 0x68, 0x55, | 290 | 0x43, 0x47, 0x52, 0x4a, 0x31, 0x50, 0x67, 0x4a, 0x64, 0x66, 0x42, 0x4d, 0x66, 0x46, 0x6c, |
| 269 | 0x44, 0x54, 0x51, 0x63, 0x4e, 0x46, 0x64, 0x64, 0x61, 0x55, 0x67, 0x41, 0x4f, 0x77, 0x55, 0x48, 0x62, 0x69, 0x64, 0x6c, 0x62, 0x6b, | 291 | 0x4d, 0x37, 0x64, 0x45, 0x67, 0x38, 0x58, 0x6a, 0x6c, 0x73, 0x48, 0x42, 0x78, 0x30, 0x4f, |
| 270 | 0x41, 0x39, 0x4f, 0x6b, 0x39, 0x79, 0x58, 0x54, 0x6b, 0x57, 0x44, 0x32, 0x4d, 0x53, 0x45, 0x68, 0x55, 0x36, 0x63, 0x41, 0x31, 0x58, | 292 | 0x52, 0x38, 0x41, 0x47, 0x77, 0x59, 0x4b, 0x61, 0x44, 0x74, 0x53, 0x54, 0x78, 0x35, 0x75, |
| 271 | 0x47, 0x41, 0x31, 0x65, 0x50, 0x53, 0x4a, 0x6f, 0x61, 0x48, 0x78, 0x74, 0x54, 0x77, 0x78, 0x37, 0x43, 0x53, 0x31, 0x4b, 0x63, 0x79, | 293 | 0x50, 0x44, 0x55, 0x4d, 0x4f, 0x41, 0x34, 0x4c, 0x4f, 0x78, 0x70, 0x32, 0x49, 0x79, 0x6c, |
| 272 | 0x42, 0x48, 0x42, 0x31, 0x64, 0x31, 0x58, 0x56, 0x4e, 0x77, 0x4e, 0x43, 0x46, 0x41, 0x56, 0x31, 0x46, 0x65, 0x53, 0x55, 0x51, 0x41, | 294 | 0x54, 0x48, 0x6c, 0x39, 0x42, 0x44, 0x45, 0x73, 0x4b, 0x5a, 0x53, 0x68, 0x34, 0x5a, 0x30, |
| 273 | 0x56, 0x43, 0x63, 0x45, 0x61, 0x48, 0x35, 0x5a, 0x56, 0x6c, 0x68, 0x30, 0x46, 0x44, 0x77, 0x57, 0x4d, 0x30, 0x45, 0x57, 0x53, 0x79, | 295 | 0x68, 0x5a, 0x4a, 0x6d, 0x30, 0x78, 0x64, 0x69, 0x4e, 0x77, 0x59, 0x57, 0x51, 0x37, 0x4f, |
| 274 | 0x39, 0x4a, 0x4e, 0x77, 0x70, 0x55, 0x43, 0x41, 0x67, 0x66, 0x4f, 0x57, 0x64, 0x32, 0x4b, 0x43, 0x67, 0x48, 0x48, 0x57, 0x46, 0x48, | 296 | 0x48, 0x6c, 0x6d, 0x64, 0x46, 0x4d, 0x73, 0x5a, 0x47, 0x52, 0x55, 0x41, 0x31, 0x52, 0x6c, |
| 275 | 0x55, 0x55, 0x31, 0x31, 0x4a, 0x6c, 0x4a, 0x48, 0x52, 0x77, 0x78, 0x58, 0x57, 0x48, 0x51, 0x2b, 0x59, 0x6d, 0x78, 0x59, 0x4f, 0x6b, | 297 | 0x52, 0x45, 0x77, 0x59, 0x54, 0x30, 0x67, 0x67, 0x54, 0x33, 0x49, 0x51, 0x50, 0x77, 0x78, |
| 276 | 0x51, 0x65, 0x46, 0x69, 0x34, 0x68, 0x48, 0x48, 0x4e, 0x46, 0x5a, 0x33, 0x52, 0x50, 0x4d, 0x32, 0x59, 0x4f, 0x64, 0x47, 0x59, 0x6d, | 298 | 0x53, 0x4c, 0x51, 0x4d, 0x55, 0x41, 0x31, 0x46, 0x43, 0x45, 0x48, 0x64, 0x71, 0x4e, 0x41, |
| 277 | 0x48, 0x79, 0x34, 0x34, 0x52, 0x45, 0x42, 0x2b, 0x4b, 0x6c, 0x42, 0x53, 0x58, 0x6b, 0x4d, 0x42, 0x65, 0x6a, 0x68, 0x4a, 0x50, 0x46, | 299 | 0x59, 0x79, 0x41, 0x33, 0x49, 0x55, 0x66, 0x41, 0x68, 0x64, 0x55, 0x68, 0x70, 0x69, 0x66, |
| 278 | 0x56, 0x4e, 0x57, 0x6b, 0x51, 0x49, 0x4a, 0x6c, 0x6c, 0x4e, 0x52, 0x51, 0x74, 0x49, 0x43, 0x6a, 0x4e, 0x65, 0x53, 0x6b, 0x31, 0x31, | 300 | 0x44, 0x34, 0x77, 0x66, 0x6c, 0x39, 0x2f, 0x56, 0x41, 0x39, 0x45, 0x53, 0x56, 0x31, 0x65, |
| 279 | 0x46, 0x68, 0x64, 0x6a, 0x52, 0x67, 0x45, 0x71, 0x56, 0x58, 0x73, 0x50, 0x41, 0x6e, 0x4e, 0x71, 0x53, 0x33, 0x39, 0x31, 0x5a, 0x54, | 301 | 0x45, 0x47, 0x6f, 0x47, 0x4b, 0x77, 0x5a, 0x54, 0x45, 0x44, 0x6b, 0x33, 0x4d, 0x6b, 0x70, |
| 280 | 0x78, 0x4d, 0x4d, 0x7a, 0x6c, 0x73, 0x64, 0x41, 0x56, 0x67, 0x44, 0x33, 0x38, 0x74, 0x51, 0x55, 0x31, 0x4e, 0x52, 0x6e, 0x45, 0x4a, | 302 | 0x4f, 0x50, 0x53, 0x74, 0x6c, 0x4f, 0x44, 0x6b, 0x48, 0x63, 0x6c, 0x52, 0x6b, 0x54, 0x56, |
| 281 | 0x62, 0x30, 0x39, 0x67, 0x46, 0x51, 0x39, 0x47, 0x63, 0x32, 0x4e, 0x4d, 0x58, 0x6e, 0x51, 0x77, 0x44, 0x53, 0x68, 0x44, 0x43, 0x48, | 303 | 0x5a, 0x71, 0x41, 0x79, 0x4a, 0x77, 0x65, 0x31, 0x39, 0x67, 0x43, 0x79, 0x6f, 0x4c, 0x61, |
| 282 | 0x49, 0x79, 0x42, 0x43, 0x34, 0x78, 0x4b, 0x53, 0x64, 0x45, 0x62, 0x52, 0x4d, 0x58, 0x53, 0x41, 0x39, 0x4a, 0x55, 0x68, 0x41, 0x54, | 304 | 0x78, 0x42, 0x6b, 0x46, 0x41, 0x55, 0x69, 0x41, 0x48, 0x4e, 0x41, 0x49, 0x31, 0x74, 0x52, |
| 283 | 0x66, 0x78, 0x63, 0x57, 0x59, 0x6e, 0x6b, 0x31, 0x65, 0x44, 0x34, 0x42, 0x66, 0x43, 0x34, 0x50, 0x64, 0x6a, 0x35, 0x65, 0x55, 0x32, | 305 | 0x48, 0x79, 0x73, 0x61, 0x58, 0x57, 0x6c, 0x36, 0x52, 0x67, 0x78, 0x66, 0x4d, 0x6b, 0x74, |
| 284 | 0x78, 0x62, 0x58, 0x33, 0x77, 0x5a, 0x51, 0x51, 0x49, 0x76, 0x46, 0x32, 0x52, 0x42, 0x64, 0x52, 0x41, 0x45, 0x52, 0x33, 0x77, 0x39, | 306 | 0x4b, 0x4b, 0x46, 0x4a, 0x35, 0x57, 0x78, 0x4a, 0x43, 0x47, 0x41, 0x42, 0x64, 0x4a, 0x7a, |
| 285 | 0x53, 0x31, 0x49, 0x41, 0x45, 0x46, 0x31, 0x52, 0x54, 0x6e, 0x6f, 0x6e, 0x4a, 0x56, 0x56, 0x41, 0x45, 0x6a, 0x56, 0x67, 0x42, 0x52, | 307 | 0x46, 0x54, 0x50, 0x45, 0x77, 0x32, 0x54, 0x6a, 0x67, 0x2f, 0x63, 0x67, 0x4e, 0x78, 0x41, |
| 286 | 0x73, 0x30, 0x4c, 0x51, 0x52, 0x36, 0x61, 0x6d, 0x6b, 0x43, 0x65, 0x51, 0x4d, 0x36, 0x4c, 0x77, 0x59, 0x4b, 0x65, 0x58, 0x73, 0x53, | 308 | 0x6c, 0x73, 0x32, 0x57, 0x58, 0x39, 0x31, 0x62, 0x67, 0x68, 0x55, 0x44, 0x54, 0x51, 0x63, |
| 287 | 0x58, 0x58, 0x78, 0x53, 0x4b, 0x55, 0x64, 0x59, 0x45, 0x6e, 0x4d, 0x2f, 0x4a, 0x31, 0x59, 0x46, 0x44, 0x45, 0x67, 0x79, 0x57, 0x47, | 309 | 0x4e, 0x46, 0x64, 0x64, 0x61, 0x55, 0x67, 0x41, 0x4f, 0x77, 0x55, 0x48, 0x62, 0x69, 0x64, |
| 288 | 0x74, 0x58, 0x58, 0x41, 0x4e, 0x6b, 0x56, 0x68, 0x46, 0x53, 0x65, 0x6a, 0x41, 0x32, 0x4b, 0x52, 0x63, 0x37, 0x61, 0x48, 0x70, 0x38, | 310 | 0x6c, 0x62, 0x6b, 0x41, 0x39, 0x4f, 0x6b, 0x39, 0x79, 0x58, 0x54, 0x6b, 0x57, 0x44, 0x32, |
| 289 | 0x42, 0x57, 0x74, 0x72, 0x45, 0x32, 0x6f, 0x6b, 0x58, 0x47, 0x68, 0x43, 0x47, 0x44, 0x49, 0x44, 0x63, 0x32, 0x34, 0x45, 0x49, 0x53, | 311 | 0x4d, 0x53, 0x45, 0x68, 0x55, 0x36, 0x63, 0x41, 0x31, 0x58, 0x47, 0x41, 0x31, 0x65, 0x50, |
| 290 | 0x34, 0x42, 0x42, 0x47, 0x4e, 0x39, 0x52, 0x45, 0x45, 0x53, 0x4d, 0x51, 0x73, 0x56, 0x48, 0x33, 0x41, 0x41, 0x4c, 0x6d, 0x59, 0x55, | 312 | 0x53, 0x4a, 0x6f, 0x61, 0x48, 0x78, 0x74, 0x54, 0x77, 0x78, 0x37, 0x43, 0x53, 0x31, 0x4b, |
| 291 | 0x50, 0x48, 0x38, 0x72, 0x41, 0x42, 0x38, 0x4d, 0x4b, 0x46, 0x6b, 0x4b, 0x46, 0x6b, 0x6c, 0x61, 0x58, 0x47, 0x52, 0x6c, 0x53, 0x78, | 313 | 0x63, 0x79, 0x42, 0x48, 0x42, 0x31, 0x64, 0x31, 0x58, 0x56, 0x4e, 0x77, 0x4e, 0x43, 0x46, |
| 292 | 0x45, 0x70, 0x46, 0x54, 0x5a, 0x61, 0x5a, 0x52, 0x6c, 0x50, 0x59, 0x43, 0x4d, 0x36, 0x4f, 0x68, 0x4d, 0x6c, 0x41, 0x6e, 0x68, 0x4d, | 314 | 0x41, 0x56, 0x31, 0x46, 0x65, 0x53, 0x55, 0x51, 0x41, 0x56, 0x43, 0x63, 0x45, 0x61, 0x48, |
| 293 | 0x56, 0x41, 0x3d, 0x3d, 0x00}; | 315 | 0x35, 0x5a, 0x56, 0x6c, 0x68, 0x30, 0x46, 0x44, 0x77, 0x57, 0x4d, 0x30, 0x45, 0x57, 0x53, |
| 316 | 0x79, 0x39, 0x4a, 0x4e, 0x77, 0x70, 0x55, 0x43, 0x41, 0x67, 0x66, 0x4f, 0x57, 0x64, 0x32, | ||
| 317 | 0x4b, 0x43, 0x67, 0x48, 0x48, 0x57, 0x46, 0x48, 0x55, 0x55, 0x31, 0x31, 0x4a, 0x6c, 0x4a, | ||
| 318 | 0x48, 0x52, 0x77, 0x78, 0x58, 0x57, 0x48, 0x51, 0x2b, 0x59, 0x6d, 0x78, 0x59, 0x4f, 0x6b, | ||
| 319 | 0x51, 0x65, 0x46, 0x69, 0x34, 0x68, 0x48, 0x48, 0x4e, 0x46, 0x5a, 0x33, 0x52, 0x50, 0x4d, | ||
| 320 | 0x32, 0x59, 0x4f, 0x64, 0x47, 0x59, 0x6d, 0x48, 0x79, 0x34, 0x34, 0x52, 0x45, 0x42, 0x2b, | ||
| 321 | 0x4b, 0x6c, 0x42, 0x53, 0x58, 0x6b, 0x4d, 0x42, 0x65, 0x6a, 0x68, 0x4a, 0x50, 0x46, 0x56, | ||
| 322 | 0x4e, 0x57, 0x6b, 0x51, 0x49, 0x4a, 0x6c, 0x6c, 0x4e, 0x52, 0x51, 0x74, 0x49, 0x43, 0x6a, | ||
| 323 | 0x4e, 0x65, 0x53, 0x6b, 0x31, 0x31, 0x46, 0x68, 0x64, 0x6a, 0x52, 0x67, 0x45, 0x71, 0x56, | ||
| 324 | 0x58, 0x73, 0x50, 0x41, 0x6e, 0x4e, 0x71, 0x53, 0x33, 0x39, 0x31, 0x5a, 0x54, 0x78, 0x4d, | ||
| 325 | 0x4d, 0x7a, 0x6c, 0x73, 0x64, 0x41, 0x56, 0x67, 0x44, 0x33, 0x38, 0x74, 0x51, 0x55, 0x31, | ||
| 326 | 0x4e, 0x52, 0x6e, 0x45, 0x4a, 0x62, 0x30, 0x39, 0x67, 0x46, 0x51, 0x39, 0x47, 0x63, 0x32, | ||
| 327 | 0x4e, 0x4d, 0x58, 0x6e, 0x51, 0x77, 0x44, 0x53, 0x68, 0x44, 0x43, 0x48, 0x49, 0x79, 0x42, | ||
| 328 | 0x43, 0x34, 0x78, 0x4b, 0x53, 0x64, 0x45, 0x62, 0x52, 0x4d, 0x58, 0x53, 0x41, 0x39, 0x4a, | ||
| 329 | 0x55, 0x68, 0x41, 0x54, 0x66, 0x78, 0x63, 0x57, 0x59, 0x6e, 0x6b, 0x31, 0x65, 0x44, 0x34, | ||
| 330 | 0x42, 0x66, 0x43, 0x34, 0x50, 0x64, 0x6a, 0x35, 0x65, 0x55, 0x32, 0x78, 0x62, 0x58, 0x33, | ||
| 331 | 0x77, 0x5a, 0x51, 0x51, 0x49, 0x76, 0x46, 0x32, 0x52, 0x42, 0x64, 0x52, 0x41, 0x45, 0x52, | ||
| 332 | 0x33, 0x77, 0x39, 0x53, 0x31, 0x49, 0x41, 0x45, 0x46, 0x31, 0x52, 0x54, 0x6e, 0x6f, 0x6e, | ||
| 333 | 0x4a, 0x56, 0x56, 0x41, 0x45, 0x6a, 0x56, 0x67, 0x42, 0x52, 0x73, 0x30, 0x4c, 0x51, 0x52, | ||
| 334 | 0x36, 0x61, 0x6d, 0x6b, 0x43, 0x65, 0x51, 0x4d, 0x36, 0x4c, 0x77, 0x59, 0x4b, 0x65, 0x58, | ||
| 335 | 0x73, 0x53, 0x58, 0x58, 0x78, 0x53, 0x4b, 0x55, 0x64, 0x59, 0x45, 0x6e, 0x4d, 0x2f, 0x4a, | ||
| 336 | 0x31, 0x59, 0x46, 0x44, 0x45, 0x67, 0x79, 0x57, 0x47, 0x74, 0x58, 0x58, 0x41, 0x4e, 0x6b, | ||
| 337 | 0x56, 0x68, 0x46, 0x53, 0x65, 0x6a, 0x41, 0x32, 0x4b, 0x52, 0x63, 0x37, 0x61, 0x48, 0x70, | ||
| 338 | 0x38, 0x42, 0x57, 0x74, 0x72, 0x45, 0x32, 0x6f, 0x6b, 0x58, 0x47, 0x68, 0x43, 0x47, 0x44, | ||
| 339 | 0x49, 0x44, 0x63, 0x32, 0x34, 0x45, 0x49, 0x53, 0x34, 0x42, 0x42, 0x47, 0x4e, 0x39, 0x52, | ||
| 340 | 0x45, 0x45, 0x53, 0x4d, 0x51, 0x73, 0x56, 0x48, 0x33, 0x41, 0x41, 0x4c, 0x6d, 0x59, 0x55, | ||
| 341 | 0x50, 0x48, 0x38, 0x72, 0x41, 0x42, 0x38, 0x4d, 0x4b, 0x46, 0x6b, 0x4b, 0x46, 0x6b, 0x6c, | ||
| 342 | 0x61, 0x58, 0x47, 0x52, 0x6c, 0x53, 0x78, 0x45, 0x70, 0x46, 0x54, 0x5a, 0x61, 0x5a, 0x52, | ||
| 343 | 0x6c, 0x50, 0x59, 0x43, 0x4d, 0x36, 0x4f, 0x68, 0x4d, 0x6c, 0x41, 0x6e, 0x68, 0x4d, 0x56, | ||
| 344 | 0x41, 0x3d, 0x3d, 0x00}; | ||
| 294 | char *b64_test; | 345 | char *b64_test; |
| 295 | 346 | ||
| 296 | plan_tests(1); | 347 | plan_tests(1); |
diff --git a/lib/tests/test_cmd.c b/lib/tests/test_cmd.c index c8867dfb..d51016cc 100644 --- a/lib/tests/test_cmd.c +++ b/lib/tests/test_cmd.c | |||
| @@ -38,36 +38,35 @@ char *get_command(char *const *line) { | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | int main(int argc, char **argv) { | 40 | int main(int argc, char **argv) { |
| 41 | char **command_line = malloc(sizeof(char *) * COMMAND_LINE); | ||
| 42 | char *command = NULL; | ||
| 43 | char *perl; | ||
| 44 | output chld_out, chld_err; | ||
| 45 | int c; | ||
| 46 | int result = UNSET; | ||
| 47 | |||
| 48 | plan_tests(51); | 41 | plan_tests(51); |
| 49 | 42 | ||
| 50 | diag("Running plain echo command, set one"); | 43 | diag("Running plain echo command, set one"); |
| 51 | 44 | ||
| 52 | /* ensure everything is empty before we begin */ | 45 | /* ensure everything is empty before we begin */ |
| 46 | |||
| 47 | output chld_out; | ||
| 53 | memset(&chld_out, 0, sizeof(output)); | 48 | memset(&chld_out, 0, sizeof(output)); |
| 49 | output chld_err; | ||
| 54 | memset(&chld_err, 0, sizeof(output)); | 50 | memset(&chld_err, 0, sizeof(output)); |
| 55 | ok(chld_out.lines == 0, "(initialised) Checking stdout is reset"); | 51 | ok(chld_out.lines == 0, "(initialised) Checking stdout is reset"); |
| 56 | ok(chld_err.lines == 0, "(initialised) Checking stderr is reset"); | 52 | ok(chld_err.lines == 0, "(initialised) Checking stderr is reset"); |
| 53 | int result = UNSET; | ||
| 57 | ok(result == UNSET, "(initialised) Checking exit code is reset"); | 54 | ok(result == UNSET, "(initialised) Checking exit code is reset"); |
| 58 | 55 | ||
| 56 | char **command_line = malloc(sizeof(char *) * COMMAND_LINE); | ||
| 59 | command_line[0] = strdup("/bin/echo"); | 57 | command_line[0] = strdup("/bin/echo"); |
| 60 | command_line[1] = strdup("this"); | 58 | command_line[1] = strdup("this"); |
| 61 | command_line[2] = strdup("is"); | 59 | command_line[2] = strdup("is"); |
| 62 | command_line[3] = strdup("test"); | 60 | command_line[3] = strdup("test"); |
| 63 | command_line[4] = strdup("one"); | 61 | command_line[4] = strdup("one"); |
| 64 | 62 | ||
| 65 | command = get_command(command_line); | 63 | char *command = get_command(command_line); |
| 66 | 64 | ||
| 67 | result = cmd_run_array(command_line, &chld_out, &chld_err, 0); | 65 | result = cmd_run_array(command_line, &chld_out, &chld_err, 0); |
| 68 | ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines"); | 66 | ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines"); |
| 69 | ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines"); | 67 | ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines"); |
| 70 | ok(strcmp(chld_out.line[0], "this is test one") == 0, "(array) Check for expected stdout output"); | 68 | ok(strcmp(chld_out.line[0], "this is test one") == 0, |
| 69 | "(array) Check for expected stdout output"); | ||
| 71 | ok(result == 0, "(array) Checking exit code"); | 70 | ok(result == 0, "(array) Checking exit code"); |
| 72 | 71 | ||
| 73 | /* ensure everything is empty again */ | 72 | /* ensure everything is empty again */ |
| @@ -82,7 +81,8 @@ int main(int argc, char **argv) { | |||
| 82 | 81 | ||
| 83 | ok(chld_out.lines == 1, "(string) Check for expected number of stdout lines"); | 82 | ok(chld_out.lines == 1, "(string) Check for expected number of stdout lines"); |
| 84 | ok(chld_err.lines == 0, "(string) Check for expected number of stderr lines"); | 83 | ok(chld_err.lines == 0, "(string) Check for expected number of stderr lines"); |
| 85 | ok(strcmp(chld_out.line[0], "this is test one") == 0, "(string) Check for expected stdout output"); | 84 | ok(strcmp(chld_out.line[0], "this is test one") == 0, |
| 85 | "(string) Check for expected stdout output"); | ||
| 86 | ok(result == 0, "(string) Checking exit code"); | 86 | ok(result == 0, "(string) Checking exit code"); |
| 87 | 87 | ||
| 88 | diag("Running plain echo command, set two"); | 88 | diag("Running plain echo command, set two"); |
| @@ -104,7 +104,8 @@ int main(int argc, char **argv) { | |||
| 104 | result = cmd_run_array(command_line, &chld_out, &chld_err, 0); | 104 | result = cmd_run_array(command_line, &chld_out, &chld_err, 0); |
| 105 | ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines"); | 105 | ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines"); |
| 106 | ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines"); | 106 | ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines"); |
| 107 | ok(strcmp(chld_out.line[0], "this is test two") == 0, "(array) Check for expected stdout output"); | 107 | ok(strcmp(chld_out.line[0], "this is test two") == 0, |
| 108 | "(array) Check for expected stdout output"); | ||
| 108 | ok(result == 0, "(array) Checking exit code"); | 109 | ok(result == 0, "(array) Checking exit code"); |
| 109 | 110 | ||
| 110 | /* ensure everything is empty again */ | 111 | /* ensure everything is empty again */ |
| @@ -119,7 +120,8 @@ int main(int argc, char **argv) { | |||
| 119 | 120 | ||
| 120 | ok(chld_out.lines == 1, "(string) Check for expected number of stdout lines"); | 121 | ok(chld_out.lines == 1, "(string) Check for expected number of stdout lines"); |
| 121 | ok(chld_err.lines == 0, "(string) Check for expected number of stderr lines"); | 122 | ok(chld_err.lines == 0, "(string) Check for expected number of stderr lines"); |
| 122 | ok(strcmp(chld_out.line[0], "this is test one") == 0, "(string) Check for expected stdout output"); | 123 | ok(strcmp(chld_out.line[0], "this is test one") == 0, |
| 124 | "(string) Check for expected stdout output"); | ||
| 123 | ok(result == 0, "(string) Checking exit code"); | 125 | ok(result == 0, "(string) Checking exit code"); |
| 124 | 126 | ||
| 125 | /* ensure everything is empty again */ | 127 | /* ensure everything is empty again */ |
| @@ -130,7 +132,8 @@ int main(int argc, char **argv) { | |||
| 130 | ok(chld_err.lines == 0, "(initialised) Checking stderr is reset"); | 132 | ok(chld_err.lines == 0, "(initialised) Checking stderr is reset"); |
| 131 | ok(result == UNSET, "(initialised) Checking exit code is reset"); | 133 | ok(result == UNSET, "(initialised) Checking exit code is reset"); |
| 132 | 134 | ||
| 133 | /* Pass linefeeds via parameters through - those should be evaluated by echo to give multi line output */ | 135 | /* Pass linefeeds via parameters through - those should be evaluated by echo to give multi line |
| 136 | * output */ | ||
| 134 | command_line[0] = strdup("/bin/echo"); | 137 | command_line[0] = strdup("/bin/echo"); |
| 135 | command_line[1] = strdup("this is a test via echo\nline two\nit's line 3"); | 138 | command_line[1] = strdup("this is a test via echo\nline two\nit's line 3"); |
| 136 | command_line[2] = strdup("and (note space between '3' and 'and') $$ will not get evaluated"); | 139 | command_line[2] = strdup("and (note space between '3' and 'and') $$ will not get evaluated"); |
| @@ -138,9 +141,12 @@ int main(int argc, char **argv) { | |||
| 138 | result = cmd_run_array(command_line, &chld_out, &chld_err, 0); | 141 | result = cmd_run_array(command_line, &chld_out, &chld_err, 0); |
| 139 | ok(chld_out.lines == 3, "(array) Check for expected number of stdout lines"); | 142 | ok(chld_out.lines == 3, "(array) Check for expected number of stdout lines"); |
| 140 | ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines"); | 143 | ok(chld_err.lines == 0, "(array) Check for expected number of stderr lines"); |
| 141 | ok(strcmp(chld_out.line[0], "this is a test via echo") == 0, "(array) Check line 1 for expected stdout output"); | 144 | ok(strcmp(chld_out.line[0], "this is a test via echo") == 0, |
| 142 | ok(strcmp(chld_out.line[1], "line two") == 0, "(array) Check line 2 for expected stdout output"); | 145 | "(array) Check line 1 for expected stdout output"); |
| 143 | ok(strcmp(chld_out.line[2], "it's line 3 and (note space between '3' and 'and') $$ will not get evaluated") == 0, | 146 | ok(strcmp(chld_out.line[1], "line two") == 0, |
| 147 | "(array) Check line 2 for expected stdout output"); | ||
| 148 | ok(strcmp(chld_out.line[2], | ||
| 149 | "it's line 3 and (note space between '3' and 'and') $$ will not get evaluated") == 0, | ||
| 144 | "(array) Check line 3 for expected stdout output"); | 150 | "(array) Check line 3 for expected stdout output"); |
| 145 | ok(result == 0, "(array) Checking exit code"); | 151 | ok(result == 0, "(array) Checking exit code"); |
| 146 | 152 | ||
| @@ -171,7 +177,8 @@ int main(int argc, char **argv) { | |||
| 171 | 177 | ||
| 172 | ok(chld_out.lines == 0, "/bin/sh returns no stdout when file is missing..."); | 178 | ok(chld_out.lines == 0, "/bin/sh returns no stdout when file is missing..."); |
| 173 | ok(chld_err.lines == 1, "...but does give an error line"); | 179 | ok(chld_err.lines == 1, "...but does give an error line"); |
| 174 | ok(strstr(chld_err.line[0], "non-existent-file") != NULL, "And missing filename is in error message"); | 180 | ok(strstr(chld_err.line[0], "non-existent-file") != NULL, |
| 181 | "And missing filename is in error message"); | ||
| 175 | ok(result != 0, "Get non-zero return code from /bin/sh"); | 182 | ok(result != 0, "Get non-zero return code from /bin/sh"); |
| 176 | 183 | ||
| 177 | /* ensure everything is empty again */ | 184 | /* ensure everything is empty again */ |
diff --git a/lib/tests/test_disk.t b/lib/tests/test_disk.t deleted file mode 100755 index da84dfdf..00000000 --- a/lib/tests/test_disk.t +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | use Test::More; | ||
| 3 | if (! -e "./test_disk") { | ||
| 4 | plan skip_all => "./test_disk not compiled - please enable libtap library to test"; | ||
| 5 | } | ||
| 6 | exec "./test_disk"; | ||
diff --git a/lib/tests/test_generic_output.c b/lib/tests/test_generic_output.c index e67aefc9..e4a78bcd 100644 --- a/lib/tests/test_generic_output.c +++ b/lib/tests/test_generic_output.c | |||
| @@ -110,7 +110,8 @@ void test_two_subchecks(void) { | |||
| 110 | sc1.output = "foobar"; | 110 | sc1.output = "foobar"; |
| 111 | sc1 = mp_set_subcheck_state(sc1, STATE_WARNING); | 111 | sc1 = mp_set_subcheck_state(sc1, STATE_WARNING); |
| 112 | 112 | ||
| 113 | ok(mp_compute_subcheck_state(sc1) == STATE_WARNING, "Test subcheck state directly after setting it"); | 113 | ok(mp_compute_subcheck_state(sc1) == STATE_WARNING, |
| 114 | "Test subcheck state directly after setting it"); | ||
| 114 | 115 | ||
| 115 | mp_perfdata pd1 = perfdata_init(); | 116 | mp_perfdata pd1 = perfdata_init(); |
| 116 | 117 | ||
| @@ -129,7 +130,8 @@ void test_two_subchecks(void) { | |||
| 129 | 130 | ||
| 130 | mp_add_subcheck_to_subcheck(&sc1, sc2); | 131 | mp_add_subcheck_to_subcheck(&sc1, sc2); |
| 131 | 132 | ||
| 132 | ok(mp_compute_subcheck_state(sc1) == STATE_WARNING, "Test subcheck state after adding a subcheck"); | 133 | ok(mp_compute_subcheck_state(sc1) == STATE_WARNING, |
| 134 | "Test subcheck state after adding a subcheck"); | ||
| 133 | 135 | ||
| 134 | mp_check check = mp_check_init(); | 136 | mp_check check = mp_check_init(); |
| 135 | mp_add_subcheck_to_check(&check, sc1); | 137 | mp_add_subcheck_to_check(&check, sc1); |
diff --git a/lib/tests/test_ini1.c b/lib/tests/test_ini1.c index 246c1250..de983764 100644 --- a/lib/tests/test_ini1.c +++ b/lib/tests/test_ini1.c | |||
| @@ -42,27 +42,30 @@ char *list2str(np_arg_list *optlst) { | |||
| 42 | free(optltmp); | 42 | free(optltmp); |
| 43 | } | 43 | } |
| 44 | /* Strip last whitespace */ | 44 | /* Strip last whitespace */ |
| 45 | if (strlen(optstr) > 1) | 45 | if (strlen(optstr) > 1) { |
| 46 | optstr[strlen(optstr) - 1] = '\0'; | 46 | optstr[strlen(optstr) - 1] = '\0'; |
| 47 | } | ||
| 47 | 48 | ||
| 48 | return optstr; | 49 | return optstr; |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | int main(int argc, char **argv) { | 52 | int main(int argc, char **argv) { |
| 52 | char *optstr = NULL; | ||
| 53 | 53 | ||
| 54 | plan_tests(12); | 54 | plan_tests(12); |
| 55 | 55 | ||
| 56 | optstr = list2str(np_get_defaults("section@./config-tiny.ini", "check_disk")); | 56 | char *optstr = list2str(np_get_defaults("section@./config-tiny.ini", "check_disk")); |
| 57 | ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), "config-tiny.ini's section as expected"); | 57 | ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), |
| 58 | "config-tiny.ini's section as expected"); | ||
| 58 | my_free(optstr); | 59 | my_free(optstr); |
| 59 | 60 | ||
| 60 | optstr = list2str(np_get_defaults("@./config-tiny.ini", "section")); | 61 | optstr = list2str(np_get_defaults("@./config-tiny.ini", "section")); |
| 61 | ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), "Used default section name, without specific"); | 62 | ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), |
| 63 | "Used default section name, without specific"); | ||
| 62 | my_free(optstr); | 64 | my_free(optstr); |
| 63 | 65 | ||
| 64 | optstr = list2str(np_get_defaults("Section Two@./config-tiny.ini", "check_disk")); | 66 | optstr = list2str(np_get_defaults("Section Two@./config-tiny.ini", "check_disk")); |
| 65 | ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), "config-tiny.ini's Section Two as expected"); | 67 | ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), |
| 68 | "config-tiny.ini's Section Two as expected"); | ||
| 66 | my_free(optstr); | 69 | my_free(optstr); |
| 67 | 70 | ||
| 68 | optstr = list2str(np_get_defaults("/path/to/file.txt@./config-tiny.ini", "check_disk")); | 71 | optstr = list2str(np_get_defaults("/path/to/file.txt@./config-tiny.ini", "check_disk")); |
| @@ -70,15 +73,18 @@ int main(int argc, char **argv) { | |||
| 70 | my_free(optstr); | 73 | my_free(optstr); |
| 71 | 74 | ||
| 72 | optstr = list2str(np_get_defaults("section2@./config-tiny.ini", "check_disk")); | 75 | optstr = list2str(np_get_defaults("section2@./config-tiny.ini", "check_disk")); |
| 73 | ok(!strcmp(optstr, "--this=that"), "config-tiny.ini's section2 with whitespace before section name"); | 76 | ok(!strcmp(optstr, "--this=that"), |
| 77 | "config-tiny.ini's section2 with whitespace before section name"); | ||
| 74 | my_free(optstr); | 78 | my_free(optstr); |
| 75 | 79 | ||
| 76 | optstr = list2str(np_get_defaults("section3@./config-tiny.ini", "check_disk")); | 80 | optstr = list2str(np_get_defaults("section3@./config-tiny.ini", "check_disk")); |
| 77 | ok(!strcmp(optstr, "--this=that"), "config-tiny.ini's section3 with whitespace after section name"); | 81 | ok(!strcmp(optstr, "--this=that"), |
| 82 | "config-tiny.ini's section3 with whitespace after section name"); | ||
| 78 | my_free(optstr); | 83 | my_free(optstr); |
| 79 | 84 | ||
| 80 | optstr = list2str(np_get_defaults("check_mysql@./plugin.ini", "check_disk")); | 85 | optstr = list2str(np_get_defaults("check_mysql@./plugin.ini", "check_disk")); |
| 81 | ok(!strcmp(optstr, "--username=operator --password=secret"), "plugin.ini's check_mysql as expected"); | 86 | ok(!strcmp(optstr, "--username=operator --password=secret"), |
| 87 | "plugin.ini's check_mysql as expected"); | ||
| 82 | my_free(optstr); | 88 | my_free(optstr); |
| 83 | 89 | ||
| 84 | optstr = list2str(np_get_defaults("check_mysql2@./plugin.ini", "check_disk")); | 90 | optstr = list2str(np_get_defaults("check_mysql2@./plugin.ini", "check_disk")); |
| @@ -90,29 +96,39 @@ int main(int argc, char **argv) { | |||
| 90 | my_free(optstr); | 96 | my_free(optstr); |
| 91 | 97 | ||
| 92 | optstr = list2str(np_get_defaults("Section Two@./config-dos.ini", "check_disk")); | 98 | optstr = list2str(np_get_defaults("Section Two@./config-dos.ini", "check_disk")); |
| 93 | ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), "config-dos.ini's Section Two as expected"); | 99 | ok(!strcmp(optstr, "--something else=blah --remove=whitespace"), |
| 100 | "config-dos.ini's Section Two as expected"); | ||
| 94 | my_free(optstr); | 101 | my_free(optstr); |
| 95 | 102 | ||
| 96 | optstr = list2str(np_get_defaults("section_twice@./plugin.ini", "check_disk")); | 103 | optstr = list2str(np_get_defaults("section_twice@./plugin.ini", "check_disk")); |
| 97 | ok(!strcmp(optstr, "--foo=bar --bar=foo"), "plugin.ini's section_twice defined twice in the file"); | 104 | ok(!strcmp(optstr, "--foo=bar --bar=foo"), |
| 105 | "plugin.ini's section_twice defined twice in the file"); | ||
| 98 | my_free(optstr); | 106 | my_free(optstr); |
| 99 | 107 | ||
| 100 | optstr = list2str(np_get_defaults("tcp_long_lines@plugins.ini", "check_tcp")); | 108 | optstr = list2str(np_get_defaults("tcp_long_lines@plugins.ini", "check_tcp")); |
| 101 | ok(!strcmp(optstr, "--escape --send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar " | 109 | ok(!strcmp(optstr, "--escape --send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 110 | "yadda Foo bar BAZ yadda yadda yadda Foo bar " | ||
| 102 | "BAZ yadda yadda yadda Foo bar BAZ yadda yadda " | 111 | "BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 103 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " | 112 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar " |
| 113 | "BAZ yadda yadda yadda Foo bar BAZ yadda " | ||
| 104 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo " | 114 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo " |
| 105 | "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " | 115 | "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " |
| 116 | "yadda yadda Foo bar BAZ yadda yadda " | ||
| 106 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " | 117 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " |
| 107 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda --expect=Foo bar BAZ yadda yadda " | 118 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 119 | "yadda --expect=Foo bar BAZ yadda yadda " | ||
| 108 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " | 120 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " |
| 109 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo " | 121 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 122 | "yadda Foo bar BAZ yadda yadda yadda Foo " | ||
| 110 | "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " | 123 | "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 111 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " | 124 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar " |
| 125 | "BAZ yadda yadda yadda Foo bar BAZ yadda " | ||
| 112 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo " | 126 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo " |
| 113 | "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " | 127 | "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " |
| 128 | "yadda yadda Foo bar BAZ yadda yadda " | ||
| 114 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " | 129 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " |
| 115 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo " | 130 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 131 | "yadda Foo bar BAZ yadda yadda yadda Foo " | ||
| 116 | "bar BAZ yadda yadda yadda --jail"), | 132 | "bar BAZ yadda yadda yadda --jail"), |
| 117 | "Long options"); | 133 | "Long options"); |
| 118 | my_free(optstr); | 134 | my_free(optstr); |
diff --git a/lib/tests/test_opts1.c b/lib/tests/test_opts1.c index 984183d3..fa95c4d4 100644 --- a/lib/tests/test_opts1.c +++ b/lib/tests/test_opts1.c | |||
| @@ -40,37 +40,40 @@ void my_free(int *argc, char **newargv, char **argv) { | |||
| 40 | #else | 40 | #else |
| 41 | void my_free(int *argc, char **newargv, char **argv) { | 41 | void my_free(int *argc, char **newargv, char **argv) { |
| 42 | /* Free stuff (and print while we're at it) */ | 42 | /* Free stuff (and print while we're at it) */ |
| 43 | int i, freeflag = 1; | 43 | bool freeflag = true; |
| 44 | printf(" Arg(%i): ", *argc + 1); | 44 | printf(" Arg(%i): ", *argc + 1); |
| 45 | printf("'%s' ", newargv[0]); | 45 | printf("'%s' ", newargv[0]); |
| 46 | for (i = 1; i < *argc; i++) { | 46 | |
| 47 | for (int i = 1; i < *argc; i++) { | ||
| 47 | printf("'%s' ", newargv[i]); | 48 | printf("'%s' ", newargv[i]); |
| 48 | /* Stop freeing when we get to the start of the original array */ | 49 | /* Stop freeing when we get to the start of the original array */ |
| 49 | if (freeflag) { | 50 | if (freeflag) { |
| 50 | if (newargv[i] == argv[1]) | 51 | if (newargv[i] == argv[1]) { |
| 51 | freeflag = 0; | 52 | freeflag = false; |
| 52 | else | 53 | } else { |
| 53 | free(newargv[i]); | 54 | free(newargv[i]); |
| 55 | } | ||
| 54 | } | 56 | } |
| 55 | } | 57 | } |
| 56 | printf("\n"); | 58 | printf("\n"); |
| 57 | /* Free only if it's a different array */ | 59 | /* Free only if it's a different array */ |
| 58 | if (newargv != argv) | 60 | if (newargv != argv) { |
| 59 | free(newargv); | 61 | free(newargv); |
| 62 | } | ||
| 60 | *argc = 0; | 63 | *argc = 0; |
| 61 | } | 64 | } |
| 62 | #endif | 65 | #endif |
| 63 | 66 | ||
| 64 | int array_diff(int i1, char **a1, int i2, char **a2) { | 67 | int array_diff(int i1, char **a1, int i2, char **a2) { |
| 65 | int i; | ||
| 66 | |||
| 67 | if (i1 != i2) { | 68 | if (i1 != i2) { |
| 68 | printf(" Argument count doesn't match!\n"); | 69 | printf(" Argument count doesn't match!\n"); |
| 69 | return 0; | 70 | return 0; |
| 70 | } | 71 | } |
| 71 | for (i = 0; i <= i1; i++) { | 72 | |
| 72 | if (a1[i] == NULL && a2[i] == NULL) | 73 | for (int i = 0; i <= i1; i++) { |
| 74 | if (a1[i] == NULL && a2[i] == NULL) { | ||
| 73 | continue; | 75 | continue; |
| 76 | } | ||
| 74 | if (a1[i] == NULL || a2[i] == NULL) { | 77 | if (a1[i] == NULL || a2[i] == NULL) { |
| 75 | printf(" Argument # %i null in one array!\n", i); | 78 | printf(" Argument # %i null in one array!\n", i); |
| 76 | return 0; | 79 | return 0; |
| @@ -84,11 +87,10 @@ int array_diff(int i1, char **a1, int i2, char **a2) { | |||
| 84 | } | 87 | } |
| 85 | 88 | ||
| 86 | int main(int argc, char **argv) { | 89 | int main(int argc, char **argv) { |
| 87 | char **argv_new = NULL; | ||
| 88 | int i, argc_test; | ||
| 89 | |||
| 90 | plan_tests(5); | 90 | plan_tests(5); |
| 91 | 91 | ||
| 92 | char **argv_new = NULL; | ||
| 93 | int argc_test; | ||
| 92 | { | 94 | { |
| 93 | char *argv_test[] = {"prog_name", (char *)NULL}; | 95 | char *argv_test[] = {"prog_name", (char *)NULL}; |
| 94 | argc_test = 1; | 96 | argc_test = 1; |
| @@ -110,27 +112,36 @@ int main(int argc, char **argv) { | |||
| 110 | { | 112 | { |
| 111 | char *argv_test[] = {"prog_name", "--extra-opts=@./config-opts.ini", (char *)NULL}; | 113 | char *argv_test[] = {"prog_name", "--extra-opts=@./config-opts.ini", (char *)NULL}; |
| 112 | argc_test = 2; | 114 | argc_test = 2; |
| 113 | char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", (char *)NULL}; | 115 | char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", |
| 116 | (char *)NULL}; | ||
| 114 | argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); | 117 | argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); |
| 115 | ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts using default section"); | 118 | ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts using default section"); |
| 116 | my_free(&argc_test, argv_new, argv_test); | 119 | my_free(&argc_test, argv_new, argv_test); |
| 117 | } | 120 | } |
| 118 | 121 | ||
| 119 | { | 122 | { |
| 120 | char *argv_test[] = {"prog_name", "--extra-opts=sect1@./config-opts.ini", "--extra-opts", "sect2@./config-opts.ini", (char *)NULL}; | 123 | char *argv_test[] = {"prog_name", "--extra-opts=sect1@./config-opts.ini", "--extra-opts", |
| 124 | "sect2@./config-opts.ini", (char *)NULL}; | ||
| 121 | argc_test = 4; | 125 | argc_test = 4; |
| 122 | char *argv_known[] = {"prog_name", "--one=two", "--something else=oops", "--this=that", (char *)NULL}; | 126 | char *argv_known[] = {"prog_name", "--one=two", "--something else=oops", "--this=that", |
| 127 | (char *)NULL}; | ||
| 123 | argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); | 128 | argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); |
| 124 | ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts specified twice"); | 129 | ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts specified twice"); |
| 125 | my_free(&argc_test, argv_new, argv_test); | 130 | my_free(&argc_test, argv_new, argv_test); |
| 126 | } | 131 | } |
| 127 | 132 | ||
| 128 | { | 133 | { |
| 129 | char *argv_test[] = {"prog_name", "--arg1=val1", "--extra-opts=@./config-opts.ini", "--extra-opts", "sect1@./config-opts.ini", | 134 | char *argv_test[] = {"prog_name", |
| 130 | "--arg2", (char *)NULL}; | 135 | "--arg1=val1", |
| 136 | "--extra-opts=@./config-opts.ini", | ||
| 137 | "--extra-opts", | ||
| 138 | "sect1@./config-opts.ini", | ||
| 139 | "--arg2", | ||
| 140 | (char *)NULL}; | ||
| 131 | argc_test = 6; | 141 | argc_test = 6; |
| 132 | char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", "--one=two", | 142 | char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", |
| 133 | "--arg1=val1", "--arg2", (char *)NULL}; | 143 | "--blank", "--one=two", "--arg1=val1", |
| 144 | "--arg2", (char *)NULL}; | ||
| 134 | argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); | 145 | argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); |
| 135 | ok(array_diff(argc_test, argv_new, 7, argv_known), "twice extra opts using two sections"); | 146 | ok(array_diff(argc_test, argv_new, 7, argv_known), "twice extra opts using two sections"); |
| 136 | my_free(&argc_test, argv_new, argv_test); | 147 | my_free(&argc_test, argv_new, argv_test); |
diff --git a/lib/tests/test_opts2.c b/lib/tests/test_opts2.c index 23496617..3dd1b039 100644 --- a/lib/tests/test_opts2.c +++ b/lib/tests/test_opts2.c | |||
| @@ -23,36 +23,39 @@ | |||
| 23 | 23 | ||
| 24 | void my_free(int *argc, char **newargv, char **argv) { | 24 | void my_free(int *argc, char **newargv, char **argv) { |
| 25 | /* Free stuff (and print while we're at it) */ | 25 | /* Free stuff (and print while we're at it) */ |
| 26 | int i, freeflag = 1; | 26 | bool freeflag = true; |
| 27 | |||
| 27 | printf(" Arg(%i): ", *argc + 1); | 28 | printf(" Arg(%i): ", *argc + 1); |
| 28 | printf("'%s' ", newargv[0]); | 29 | printf("'%s' ", newargv[0]); |
| 29 | for (i = 1; i < *argc; i++) { | 30 | for (int i = 1; i < *argc; i++) { |
| 30 | printf("'%s' ", newargv[i]); | 31 | printf("'%s' ", newargv[i]); |
| 31 | /* Stop freeing when we get to the start of the original array */ | 32 | /* Stop freeing when we get to the start of the original array */ |
| 32 | if (freeflag) { | 33 | if (freeflag) { |
| 33 | if (newargv[i] == argv[1]) | 34 | if (newargv[i] == argv[1]) { |
| 34 | freeflag = 0; | 35 | freeflag = false; |
| 35 | else | 36 | } else { |
| 36 | free(newargv[i]); | 37 | free(newargv[i]); |
| 38 | } | ||
| 37 | } | 39 | } |
| 38 | } | 40 | } |
| 39 | printf("\n"); | 41 | printf("\n"); |
| 40 | /* Free only if it's a different array */ | 42 | /* Free only if it's a different array */ |
| 41 | if (newargv != argv) | 43 | if (newargv != argv) { |
| 42 | free(newargv); | 44 | free(newargv); |
| 45 | } | ||
| 43 | *argc = 0; | 46 | *argc = 0; |
| 44 | } | 47 | } |
| 45 | 48 | ||
| 46 | int array_diff(int i1, char **a1, int i2, char **a2) { | 49 | int array_diff(int i1, char **a1, int i2, char **a2) { |
| 47 | int i; | ||
| 48 | |||
| 49 | if (i1 != i2) { | 50 | if (i1 != i2) { |
| 50 | printf(" Argument count doesn't match!\n"); | 51 | printf(" Argument count doesn't match!\n"); |
| 51 | return 0; | 52 | return 0; |
| 52 | } | 53 | } |
| 53 | for (i = 0; i <= i1; i++) { | 54 | |
| 54 | if (a1[i] == NULL && a2[i] == NULL) | 55 | for (int i = 0; i <= i1; i++) { |
| 56 | if (a1[i] == NULL && a2[i] == NULL) { | ||
| 55 | continue; | 57 | continue; |
| 58 | } | ||
| 56 | if (a1[i] == NULL || a2[i] == NULL) { | 59 | if (a1[i] == NULL || a2[i] == NULL) { |
| 57 | printf(" Argument # %i null in one array!\n", i); | 60 | printf(" Argument # %i null in one array!\n", i); |
| 58 | return 0; | 61 | return 0; |
| @@ -66,11 +69,10 @@ int array_diff(int i1, char **a1, int i2, char **a2) { | |||
| 66 | } | 69 | } |
| 67 | 70 | ||
| 68 | int main(int argc, char **argv) { | 71 | int main(int argc, char **argv) { |
| 69 | char **argv_new = NULL; | ||
| 70 | int i, argc_test; | ||
| 71 | |||
| 72 | plan_tests(5); | 72 | plan_tests(5); |
| 73 | 73 | ||
| 74 | char **argv_new = NULL; | ||
| 75 | int argc_test; | ||
| 74 | { | 76 | { |
| 75 | char *argv_test[] = {"prog_name", "arg1", "--extra-opts", "--arg3", "val2", (char *)NULL}; | 77 | char *argv_test[] = {"prog_name", "arg1", "--extra-opts", "--arg3", "val2", (char *)NULL}; |
| 76 | argc_test = 5; | 78 | argc_test = 5; |
| @@ -90,7 +92,8 @@ int main(int argc, char **argv) { | |||
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | { | 94 | { |
| 93 | char *argv_test[] = {"prog_name", "arg1", "--extra-opts=section1", "--arg3", "val2", (char *)NULL}; | 95 | char *argv_test[] = {"prog_name", "arg1", "--extra-opts=section1", |
| 96 | "--arg3", "val2", (char *)NULL}; | ||
| 94 | argc_test = 5; | 97 | argc_test = 5; |
| 95 | char *argv_known[] = {"prog_name", "--foobar=baz", "arg1", "--arg3", "val2", (char *)NULL}; | 98 | char *argv_known[] = {"prog_name", "--foobar=baz", "arg1", "--arg3", "val2", (char *)NULL}; |
| 96 | argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); | 99 | argv_new = np_extra_opts(&argc_test, argv_test, "check_disk"); |
| @@ -108,30 +111,39 @@ int main(int argc, char **argv) { | |||
| 108 | } | 111 | } |
| 109 | 112 | ||
| 110 | { | 113 | { |
| 111 | char *argv_test[] = {"check_tcp", "--extra-opts", "--extra-opts=tcp_long_lines", (char *)NULL}; | 114 | char *argv_test[] = {"check_tcp", "--extra-opts", "--extra-opts=tcp_long_lines", |
| 115 | (char *)NULL}; | ||
| 112 | argc_test = 3; | 116 | argc_test = 3; |
| 113 | char *argv_known[] = { | 117 | char *argv_known[] = {"check_tcp", |
| 114 | "check_tcp", | 118 | "--timeout=10", |
| 115 | "--timeout=10", | 119 | "--escape", |
| 116 | "--escape", | 120 | "--send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda " |
| 117 | "--send=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " | 121 | "Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 118 | "yadda Foo bar BAZ yadda " | 122 | "yadda Foo bar BAZ yadda " |
| 119 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " | 123 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 120 | "yadda Foo bar BAZ " | 124 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 121 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " | 125 | "yadda Foo bar BAZ " |
| 122 | "yadda yadda Foo bar " | 126 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " |
| 123 | "BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda", | 127 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " |
| 124 | "--expect=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " | 128 | "yadda yadda Foo bar " |
| 125 | "yadda Foo bar BAZ yadda " | 129 | "BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " |
| 126 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " | 130 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda", |
| 127 | "yadda Foo bar BAZ " | 131 | "--expect=Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 128 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " | 132 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 129 | "yadda yadda Foo bar " | 133 | "yadda Foo bar BAZ yadda " |
| 130 | "BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " | 134 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 131 | "yadda yadda yadda Foo " | 135 | "yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda " |
| 132 | "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda", | 136 | "yadda Foo bar BAZ " |
| 133 | "--jail", | 137 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " |
| 134 | (char *)NULL}; | 138 | "yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ yadda " |
| 139 | "yadda yadda Foo bar " | ||
| 140 | "BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " | ||
| 141 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " | ||
| 142 | "yadda yadda yadda Foo " | ||
| 143 | "bar BAZ yadda yadda yadda Foo bar BAZ yadda yadda yadda Foo bar BAZ " | ||
| 144 | "yadda yadda yadda Foo bar BAZ yadda yadda yadda", | ||
| 145 | "--jail", | ||
| 146 | (char *)NULL}; | ||
| 135 | argv_new = np_extra_opts(&argc_test, argv_test, "check_tcp"); | 147 | argv_new = np_extra_opts(&argc_test, argv_test, "check_tcp"); |
| 136 | ok(array_diff(argc_test, argv_new, 6, argv_known), "Long lines test"); | 148 | ok(array_diff(argc_test, argv_new, 6, argv_known), "Long lines test"); |
| 137 | my_free(&argc_test, argv_new, argv_test); | 149 | my_free(&argc_test, argv_new, argv_test); |
diff --git a/lib/tests/test_tcp.c b/lib/tests/test_tcp.c index 1b3003e9..37c818c9 100644 --- a/lib/tests/test_tcp.c +++ b/lib/tests/test_tcp.c | |||
| @@ -21,30 +21,38 @@ | |||
| 21 | #include "tap.h" | 21 | #include "tap.h" |
| 22 | 22 | ||
| 23 | int main(void) { | 23 | int main(void) { |
| 24 | char **server_expect; | ||
| 25 | int server_expect_count = 3; | ||
| 26 | |||
| 27 | plan_tests(9); | 24 | plan_tests(9); |
| 28 | 25 | ||
| 26 | char **server_expect; | ||
| 27 | const int server_expect_count = 3; | ||
| 29 | server_expect = malloc(sizeof(char *) * server_expect_count); | 28 | server_expect = malloc(sizeof(char *) * server_expect_count); |
| 30 | 29 | ||
| 31 | server_expect[0] = strdup("AA"); | 30 | server_expect[0] = strdup("AA"); |
| 32 | server_expect[1] = strdup("bb"); | 31 | server_expect[1] = strdup("bb"); |
| 33 | server_expect[2] = strdup("CC"); | 32 | server_expect[2] = strdup("CC"); |
| 34 | 33 | ||
| 35 | ok(np_expect_match("AA bb CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_SUCCESS, | 34 | ok(np_expect_match("AA bb CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == |
| 35 | NP_MATCH_SUCCESS, | ||
| 36 | "Test matching any string at the beginning (first expect string)"); | 36 | "Test matching any string at the beginning (first expect string)"); |
| 37 | ok(np_expect_match("bb AA CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_SUCCESS, | 37 | ok(np_expect_match("bb AA CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == |
| 38 | NP_MATCH_SUCCESS, | ||
| 38 | "Test matching any string at the beginning (second expect string)"); | 39 | "Test matching any string at the beginning (second expect string)"); |
| 39 | ok(np_expect_match("b", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_RETRY, | 40 | ok(np_expect_match("b", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_RETRY, |
| 40 | "Test matching any string at the beginning (substring match)"); | 41 | "Test matching any string at the beginning (substring match)"); |
| 41 | ok(np_expect_match("XX bb AA CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_FAILURE, | 42 | ok(np_expect_match("XX bb AA CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == |
| 43 | NP_MATCH_FAILURE, | ||
| 42 | "Test with strings not matching at the beginning"); | 44 | "Test with strings not matching at the beginning"); |
| 43 | ok(np_expect_match("XX CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == NP_MATCH_FAILURE, "Test matching any string"); | 45 | ok(np_expect_match("XX CC XX", server_expect, server_expect_count, NP_MATCH_EXACT) == |
| 44 | ok(np_expect_match("XX", server_expect, server_expect_count, 0) == NP_MATCH_RETRY, "Test not matching any string"); | 46 | NP_MATCH_FAILURE, |
| 45 | ok(np_expect_match("XX AA bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_SUCCESS, | 47 | "Test matching any string"); |
| 48 | ok(np_expect_match("XX", server_expect, server_expect_count, 0) == NP_MATCH_RETRY, | ||
| 49 | "Test not matching any string"); | ||
| 50 | ok(np_expect_match("XX AA bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == | ||
| 51 | NP_MATCH_SUCCESS, | ||
| 46 | "Test matching all strings"); | 52 | "Test matching all strings"); |
| 47 | ok(np_expect_match("XX bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_RETRY, "Test not matching all strings"); | 53 | ok(np_expect_match("XX bb CC XX", server_expect, server_expect_count, NP_MATCH_ALL) == |
| 54 | NP_MATCH_RETRY, | ||
| 55 | "Test not matching all strings"); | ||
| 48 | ok(np_expect_match("XX XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_RETRY, | 56 | ok(np_expect_match("XX XX", server_expect, server_expect_count, NP_MATCH_ALL) == NP_MATCH_RETRY, |
| 49 | "Test not matching any string (testing all)"); | 57 | "Test not matching any string (testing all)"); |
| 50 | 58 | ||
diff --git a/lib/tests/test_utils.c b/lib/tests/test_utils.c index c3150f00..8040dec8 100644 --- a/lib/tests/test_utils.c +++ b/lib/tests/test_utils.c | |||
| @@ -28,17 +28,7 @@ | |||
| 28 | #include "utils_base.c" | 28 | #include "utils_base.c" |
| 29 | 29 | ||
| 30 | int main(int argc, char **argv) { | 30 | int main(int argc, char **argv) { |
| 31 | char state_path[1024]; | 31 | plan_tests(155); |
| 32 | range *range; | ||
| 33 | double temp; | ||
| 34 | thresholds *thresholds = NULL; | ||
| 35 | int i, rc; | ||
| 36 | char *temp_string; | ||
| 37 | state_key *temp_state_key = NULL; | ||
| 38 | state_data *temp_state_data; | ||
| 39 | time_t current_time; | ||
| 40 | |||
| 41 | plan_tests(185); | ||
| 42 | 32 | ||
| 43 | ok(this_monitoring_plugin == NULL, "monitoring_plugin not initialised"); | 33 | ok(this_monitoring_plugin == NULL, "monitoring_plugin not initialised"); |
| 44 | 34 | ||
| @@ -57,7 +47,7 @@ int main(int argc, char **argv) { | |||
| 57 | 47 | ||
| 58 | np_set_args(argc, argv); | 48 | np_set_args(argc, argv); |
| 59 | 49 | ||
| 60 | range = parse_range_string("6"); | 50 | range *range = parse_range_string("6"); |
| 61 | ok(range != NULL, "'6' is valid range"); | 51 | ok(range != NULL, "'6' is valid range"); |
| 62 | ok(range->start == 0, "Start correct"); | 52 | ok(range->start == 0, "Start correct"); |
| 63 | ok(range->start_infinity == false, "Not using negative infinity"); | 53 | ok(range->start_infinity == false, "Not using negative infinity"); |
| @@ -97,7 +87,7 @@ int main(int argc, char **argv) { | |||
| 97 | free(range); | 87 | free(range); |
| 98 | 88 | ||
| 99 | range = parse_range_string("12345678901234567890:"); | 89 | range = parse_range_string("12345678901234567890:"); |
| 100 | temp = atof("12345678901234567890"); /* Can't just use this because number too large */ | 90 | double temp = atof("12345678901234567890"); /* Can't just use this because number too large */ |
| 101 | ok(range != NULL, "'12345678901234567890:' is valid range"); | 91 | ok(range != NULL, "'12345678901234567890:' is valid range"); |
| 102 | ok(range->start == temp, "Start correct"); | 92 | ok(range->start == temp, "Start correct"); |
| 103 | ok(range->start_infinity == false, "Not using negative infinity"); | 93 | ok(range->start_infinity == false, "Not using negative infinity"); |
| @@ -158,32 +148,34 @@ int main(int argc, char **argv) { | |||
| 158 | range = parse_range_string("2:1"); | 148 | range = parse_range_string("2:1"); |
| 159 | ok(range == NULL, "'2:1' rejected"); | 149 | ok(range == NULL, "'2:1' rejected"); |
| 160 | 150 | ||
| 161 | rc = _set_thresholds(&thresholds, NULL, NULL); | 151 | thresholds *thresholds = NULL; |
| 162 | ok(rc == 0, "Thresholds (NULL, NULL) set"); | 152 | int returnCode; |
| 153 | returnCode = _set_thresholds(&thresholds, NULL, NULL); | ||
| 154 | ok(returnCode == 0, "Thresholds (NULL, NULL) set"); | ||
| 163 | ok(thresholds->warning == NULL, "Warning not set"); | 155 | ok(thresholds->warning == NULL, "Warning not set"); |
| 164 | ok(thresholds->critical == NULL, "Critical not set"); | 156 | ok(thresholds->critical == NULL, "Critical not set"); |
| 165 | 157 | ||
| 166 | rc = _set_thresholds(&thresholds, NULL, "80"); | 158 | returnCode = _set_thresholds(&thresholds, NULL, "80"); |
| 167 | ok(rc == 0, "Thresholds (NULL, '80') set"); | 159 | ok(returnCode == 0, "Thresholds (NULL, '80') set"); |
| 168 | ok(thresholds->warning == NULL, "Warning not set"); | 160 | ok(thresholds->warning == NULL, "Warning not set"); |
| 169 | ok(thresholds->critical->end == 80, "Critical set correctly"); | 161 | ok(thresholds->critical->end == 80, "Critical set correctly"); |
| 170 | 162 | ||
| 171 | rc = _set_thresholds(&thresholds, "5:33", NULL); | 163 | returnCode = _set_thresholds(&thresholds, "5:33", NULL); |
| 172 | ok(rc == 0, "Thresholds ('5:33', NULL) set"); | 164 | ok(returnCode == 0, "Thresholds ('5:33', NULL) set"); |
| 173 | ok(thresholds->warning->start == 5, "Warning start set"); | 165 | ok(thresholds->warning->start == 5, "Warning start set"); |
| 174 | ok(thresholds->warning->end == 33, "Warning end set"); | 166 | ok(thresholds->warning->end == 33, "Warning end set"); |
| 175 | ok(thresholds->critical == NULL, "Critical not set"); | 167 | ok(thresholds->critical == NULL, "Critical not set"); |
| 176 | 168 | ||
| 177 | rc = _set_thresholds(&thresholds, "30", "60"); | 169 | returnCode = _set_thresholds(&thresholds, "30", "60"); |
| 178 | ok(rc == 0, "Thresholds ('30', '60') set"); | 170 | ok(returnCode == 0, "Thresholds ('30', '60') set"); |
| 179 | ok(thresholds->warning->end == 30, "Warning set correctly"); | 171 | ok(thresholds->warning->end == 30, "Warning set correctly"); |
| 180 | ok(thresholds->critical->end == 60, "Critical set correctly"); | 172 | ok(thresholds->critical->end == 60, "Critical set correctly"); |
| 181 | ok(get_status(15.3, thresholds) == STATE_OK, "15.3 - ok"); | 173 | ok(get_status(15.3, thresholds) == STATE_OK, "15.3 - ok"); |
| 182 | ok(get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning"); | 174 | ok(get_status(30.0001, thresholds) == STATE_WARNING, "30.0001 - warning"); |
| 183 | ok(get_status(69, thresholds) == STATE_CRITICAL, "69 - critical"); | 175 | ok(get_status(69, thresholds) == STATE_CRITICAL, "69 - critical"); |
| 184 | 176 | ||
| 185 | rc = _set_thresholds(&thresholds, "-10:-2", "-30:20"); | 177 | returnCode = _set_thresholds(&thresholds, "-10:-2", "-30:20"); |
| 186 | ok(rc == 0, "Thresholds ('-30:20', '-10:-2') set"); | 178 | ok(returnCode == 0, "Thresholds ('-30:20', '-10:-2') set"); |
| 187 | ok(thresholds->warning->start == -10, "Warning start set correctly"); | 179 | ok(thresholds->warning->start == -10, "Warning start set correctly"); |
| 188 | ok(thresholds->warning->end == -2, "Warning end set correctly"); | 180 | ok(thresholds->warning->end == -2, "Warning end set correctly"); |
| 189 | ok(thresholds->critical->start == -30, "Critical start set correctly"); | 181 | ok(thresholds->critical->start == -30, "Critical start set correctly"); |
| @@ -304,164 +296,28 @@ int main(int argc, char **argv) { | |||
| 304 | test = np_extract_ntpvar("", "foo"); | 296 | test = np_extract_ntpvar("", "foo"); |
| 305 | ok(!test, "Empty string return NULL"); | 297 | ok(!test, "Empty string return NULL"); |
| 306 | 298 | ||
| 307 | /* This is the result of running ./test_utils */ | ||
| 308 | temp_string = (char *)_np_state_generate_key(); | ||
| 309 | ok(!strcmp(temp_string, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), "Got hash with exe and no parameters") || | ||
| 310 | diag("You are probably running in wrong directory. Must run as ./test_utils"); | ||
| 311 | |||
| 312 | this_monitoring_plugin->argc = 4; | ||
| 313 | this_monitoring_plugin->argv[0] = "./test_utils"; | ||
| 314 | this_monitoring_plugin->argv[1] = "here"; | ||
| 315 | this_monitoring_plugin->argv[2] = "--and"; | ||
| 316 | this_monitoring_plugin->argv[3] = "now"; | ||
| 317 | temp_string = (char *)_np_state_generate_key(); | ||
| 318 | ok(!strcmp(temp_string, "bd72da9f78ff1419fad921ea5e43ce56508aef6c"), "Got based on expected argv"); | ||
| 319 | |||
| 320 | unsetenv("MP_STATE_PATH"); | ||
| 321 | temp_string = (char *)_np_state_calculate_location_prefix(); | ||
| 322 | ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory"); | ||
| 323 | |||
| 324 | setenv("MP_STATE_PATH", "", 1); | ||
| 325 | temp_string = (char *)_np_state_calculate_location_prefix(); | ||
| 326 | ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory even with empty string"); | ||
| 327 | |||
| 328 | setenv("MP_STATE_PATH", "/usr/local/nagios/var", 1); | ||
| 329 | temp_string = (char *)_np_state_calculate_location_prefix(); | ||
| 330 | ok(!strcmp(temp_string, "/usr/local/nagios/var"), "Got default directory"); | ||
| 331 | |||
| 332 | ok(temp_state_key == NULL, "temp_state_key initially empty"); | ||
| 333 | |||
| 334 | this_monitoring_plugin->argc = 1; | ||
| 335 | this_monitoring_plugin->argv[0] = "./test_utils"; | ||
| 336 | np_enable_state(NULL, 51); | ||
| 337 | temp_state_key = this_monitoring_plugin->state; | ||
| 338 | ok(!strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name"); | ||
| 339 | ok(!strcmp(temp_state_key->name, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), "Got generated filename"); | ||
| 340 | |||
| 341 | np_enable_state("allowedchars_in_keyname", 77); | ||
| 342 | temp_state_key = this_monitoring_plugin->state; | ||
| 343 | sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/allowedchars_in_keyname", (unsigned long)geteuid()); | ||
| 344 | ok(!strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name"); | ||
| 345 | ok(!strcmp(temp_state_key->name, "allowedchars_in_keyname"), "Got key name with valid chars"); | ||
| 346 | ok(!strcmp(temp_state_key->_filename, state_path), "Got internal filename"); | ||
| 347 | |||
| 348 | /* Don't do this test just yet. Will die */ | ||
| 349 | /* | ||
| 350 | np_enable_state("bad^chars$in@here", 77); | ||
| 351 | temp_state_key = this_monitoring_plugin->state; | ||
| 352 | ok( !strcmp(temp_state_key->name, "bad_chars_in_here"), "Got key name with bad chars replaced" ); | ||
| 353 | */ | ||
| 354 | |||
| 355 | np_enable_state("funnykeyname", 54); | ||
| 356 | temp_state_key = this_monitoring_plugin->state; | ||
| 357 | sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/funnykeyname", (unsigned long)geteuid()); | ||
| 358 | ok(!strcmp(temp_state_key->plugin_name, "check_test"), "Got plugin name"); | ||
| 359 | ok(!strcmp(temp_state_key->name, "funnykeyname"), "Got key name"); | ||
| 360 | |||
| 361 | ok(!strcmp(temp_state_key->_filename, state_path), "Got internal filename"); | ||
| 362 | ok(temp_state_key->data_version == 54, "Version set"); | ||
| 363 | |||
| 364 | temp_state_data = np_state_read(); | ||
| 365 | ok(temp_state_data == NULL, "Got no state data as file does not exist"); | ||
| 366 | |||
| 367 | /* | ||
| 368 | temp_fp = fopen("var/statefile", "r"); | ||
| 369 | if (temp_fp==NULL) | ||
| 370 | printf("Error opening. errno=%d\n", errno); | ||
| 371 | printf("temp_fp=%s\n", temp_fp); | ||
| 372 | ok( _np_state_read_file(temp_fp) == true, "Can read state file" ); | ||
| 373 | fclose(temp_fp); | ||
| 374 | */ | ||
| 375 | |||
| 376 | temp_state_key->_filename = "var/statefile"; | ||
| 377 | temp_state_data = np_state_read(); | ||
| 378 | ok(this_monitoring_plugin->state->state_data != NULL, "Got state data now") || | ||
| 379 | diag("Are you running in right directory? Will get coredump next if not"); | ||
| 380 | ok(this_monitoring_plugin->state->state_data->time == 1234567890, "Got time"); | ||
| 381 | ok(!strcmp((char *)this_monitoring_plugin->state->state_data->data, "String to read"), "Data as expected"); | ||
| 382 | |||
| 383 | temp_state_key->data_version = 53; | ||
| 384 | temp_state_data = np_state_read(); | ||
| 385 | ok(temp_state_data == NULL, "Older data version gives NULL"); | ||
| 386 | temp_state_key->data_version = 54; | ||
| 387 | |||
| 388 | temp_state_key->_filename = "var/nonexistent"; | ||
| 389 | temp_state_data = np_state_read(); | ||
| 390 | ok(temp_state_data == NULL, "Missing file gives NULL"); | ||
| 391 | ok(this_monitoring_plugin->state->state_data == NULL, "No state information"); | ||
| 392 | |||
| 393 | temp_state_key->_filename = "var/oldformat"; | ||
| 394 | temp_state_data = np_state_read(); | ||
| 395 | ok(temp_state_data == NULL, "Old file format gives NULL"); | ||
| 396 | |||
| 397 | temp_state_key->_filename = "var/baddate"; | ||
| 398 | temp_state_data = np_state_read(); | ||
| 399 | ok(temp_state_data == NULL, "Bad date gives NULL"); | ||
| 400 | |||
| 401 | temp_state_key->_filename = "var/missingdataline"; | ||
| 402 | temp_state_data = np_state_read(); | ||
| 403 | ok(temp_state_data == NULL, "Missing data line gives NULL"); | ||
| 404 | |||
| 405 | unlink("var/generated"); | ||
| 406 | temp_state_key->_filename = "var/generated"; | ||
| 407 | current_time = 1234567890; | ||
| 408 | np_state_write_string(current_time, "String to read"); | ||
| 409 | ok(system("cmp var/generated var/statefile") == 0, "Generated file same as expected"); | ||
| 410 | |||
| 411 | unlink("var/generated_directory/statefile"); | ||
| 412 | unlink("var/generated_directory"); | ||
| 413 | temp_state_key->_filename = "var/generated_directory/statefile"; | ||
| 414 | current_time = 1234567890; | ||
| 415 | np_state_write_string(current_time, "String to read"); | ||
| 416 | ok(system("cmp var/generated_directory/statefile var/statefile") == 0, "Have created directory"); | ||
| 417 | |||
| 418 | /* This test to check cannot write to dir - can't automate yet */ | ||
| 419 | /* | ||
| 420 | unlink("var/generated_bad_dir"); | ||
| 421 | mkdir("var/generated_bad_dir", S_IRUSR); | ||
| 422 | np_state_write_string(current_time, "String to read"); | ||
| 423 | */ | ||
| 424 | |||
| 425 | temp_state_key->_filename = "var/generated"; | ||
| 426 | time(¤t_time); | ||
| 427 | np_state_write_string(0, "String to read"); | ||
| 428 | temp_state_data = np_state_read(); | ||
| 429 | /* Check time is set to current_time */ | ||
| 430 | ok(system("cmp var/generated var/statefile > /dev/null") != 0, "Generated file should be different this time"); | ||
| 431 | ok(this_monitoring_plugin->state->state_data->time - current_time <= 1, "Has time generated from current time"); | ||
| 432 | |||
| 433 | /* Don't know how to automatically test this. Need to be able to redefine die and catch the error */ | ||
| 434 | /* | ||
| 435 | temp_state_key->_filename="/dev/do/not/expect/to/be/able/to/write"; | ||
| 436 | np_state_write_string(0, "Bad file"); | ||
| 437 | */ | ||
| 438 | |||
| 439 | np_cleanup(); | ||
| 440 | |||
| 441 | ok(this_monitoring_plugin == NULL, "Free'd this_monitoring_plugin"); | ||
| 442 | |||
| 443 | ok(mp_suid() == false, "Test aren't suid"); | 299 | ok(mp_suid() == false, "Test aren't suid"); |
| 444 | 300 | ||
| 445 | /* base states with random case */ | 301 | /* base states with random case */ |
| 446 | char *states[] = {"Ok", "wArnINg", "cRiTIcaL", "UnKNoWN", NULL}; | 302 | char *states[] = {"Ok", "wArnINg", "cRiTIcaL", "UnKNoWN", NULL}; |
| 447 | 303 | ||
| 448 | for (i = 0; states[i] != NULL; i++) { | 304 | for (int i = 0; states[i] != NULL; i++) { |
| 449 | /* out of the random case states, create the lower and upper versions + numeric string one */ | 305 | /* out of the random case states, create the lower and upper versions + numeric string one |
| 306 | */ | ||
| 450 | char *statelower = strdup(states[i]); | 307 | char *statelower = strdup(states[i]); |
| 451 | char *stateupper = strdup(states[i]); | 308 | char *stateupper = strdup(states[i]); |
| 452 | char statenum[2]; | 309 | char statenum[2]; |
| 453 | char *temp_ptr; | 310 | for (char *temp_ptr = statelower; *temp_ptr; temp_ptr++) { |
| 454 | for (temp_ptr = statelower; *temp_ptr; temp_ptr++) { | 311 | *temp_ptr = (char)tolower(*temp_ptr); |
| 455 | *temp_ptr = tolower(*temp_ptr); | ||
| 456 | } | 312 | } |
| 457 | for (temp_ptr = stateupper; *temp_ptr; temp_ptr++) { | 313 | for (char *temp_ptr = stateupper; *temp_ptr; temp_ptr++) { |
| 458 | *temp_ptr = toupper(*temp_ptr); | 314 | *temp_ptr = (char)toupper(*temp_ptr); |
| 459 | } | 315 | } |
| 460 | snprintf(statenum, 2, "%i", i); | 316 | snprintf(statenum, 2, "%i", i); |
| 461 | 317 | ||
| 462 | /* Base test names, we'll append the state string */ | 318 | /* Base test names, we'll append the state string */ |
| 463 | char testname[64] = "Translate state string: "; | 319 | char testname[64] = "Translate state string: "; |
| 464 | int tlen = strlen(testname); | 320 | size_t tlen = strlen(testname); |
| 465 | 321 | ||
| 466 | strcpy(testname + tlen, states[i]); | 322 | strcpy(testname + tlen, states[i]); |
| 467 | ok(i == mp_translate_state(states[i]), testname); | 323 | ok(i == mp_translate_state(states[i]), testname); |
diff --git a/lib/thresholds.c b/lib/thresholds.c index ddefae37..de2b9315 100644 --- a/lib/thresholds.c +++ b/lib/thresholds.c | |||
| @@ -51,9 +51,21 @@ mp_state_enum mp_get_pd_status(mp_perfdata perfdata) { | |||
| 51 | } | 51 | } |
| 52 | if (perfdata.warn_present) { | 52 | if (perfdata.warn_present) { |
| 53 | if (mp_check_range(perfdata.value, perfdata.warn)) { | 53 | if (mp_check_range(perfdata.value, perfdata.warn)) { |
| 54 | return STATE_CRITICAL; | 54 | return STATE_WARNING; |
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | return STATE_OK; | 58 | return STATE_OK; |
| 59 | } | 59 | } |
| 60 | |||
| 61 | mp_thresholds mp_thresholds_set_warn(mp_thresholds thlds, mp_range warn) { | ||
| 62 | thlds.warning = warn; | ||
| 63 | thlds.warning_is_set = true; | ||
| 64 | return thlds; | ||
| 65 | } | ||
| 66 | |||
| 67 | mp_thresholds mp_thresholds_set_crit(mp_thresholds thlds, mp_range crit) { | ||
| 68 | thlds.critical = crit; | ||
| 69 | thlds.critical_is_set = true; | ||
| 70 | return thlds; | ||
| 71 | } | ||
diff --git a/lib/thresholds.h b/lib/thresholds.h index 4e7defee..f8647681 100644 --- a/lib/thresholds.h +++ b/lib/thresholds.h | |||
| @@ -6,12 +6,12 @@ | |||
| 6 | /* | 6 | /* |
| 7 | * Old threshold type using the old range type | 7 | * Old threshold type using the old range type |
| 8 | */ | 8 | */ |
| 9 | typedef struct thresholds_struct { | 9 | typedef struct { |
| 10 | range *warning; | 10 | range *warning; |
| 11 | range *critical; | 11 | range *critical; |
| 12 | } thresholds; | 12 | } thresholds; |
| 13 | 13 | ||
| 14 | typedef struct mp_thresholds_struct { | 14 | typedef struct { |
| 15 | bool warning_is_set; | 15 | bool warning_is_set; |
| 16 | mp_range warning; | 16 | mp_range warning; |
| 17 | bool critical_is_set; | 17 | bool critical_is_set; |
| @@ -24,5 +24,8 @@ mp_perfdata mp_pd_set_thresholds(mp_perfdata /* pd */, mp_thresholds /* th */); | |||
| 24 | 24 | ||
| 25 | mp_state_enum mp_get_pd_status(mp_perfdata /* pd */); | 25 | mp_state_enum mp_get_pd_status(mp_perfdata /* pd */); |
| 26 | 26 | ||
| 27 | mp_thresholds mp_thresholds_set_warn(mp_thresholds thlds, mp_range warn); | ||
| 28 | mp_thresholds mp_thresholds_set_crit(mp_thresholds thlds, mp_range crit); | ||
| 29 | |||
| 27 | char *fmt_threshold_warning(thresholds th); | 30 | char *fmt_threshold_warning(thresholds th); |
| 28 | char *fmt_threshold_critical(thresholds th); | 31 | char *fmt_threshold_critical(thresholds th); |
diff --git a/lib/utils_base.c b/lib/utils_base.c index ff9540c7..28e6dc47 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
| 26 | 26 | ||
| 27 | #include "../plugins/common.h" | 27 | #include "../plugins/common.h" |
| 28 | #include "states.h" | ||
| 28 | #include <stdarg.h> | 29 | #include <stdarg.h> |
| 29 | #include "utils_base.h" | 30 | #include "utils_base.h" |
| 30 | #include <ctype.h> | 31 | #include <ctype.h> |
| @@ -33,20 +34,20 @@ | |||
| 33 | #include <unistd.h> | 34 | #include <unistd.h> |
| 34 | #include <sys/types.h> | 35 | #include <sys/types.h> |
| 35 | 36 | ||
| 36 | #define np_free(ptr) \ | 37 | #define np_free(ptr) \ |
| 37 | { \ | 38 | { \ |
| 38 | if (ptr) { \ | 39 | if (ptr) { \ |
| 39 | free(ptr); \ | 40 | free(ptr); \ |
| 40 | ptr = NULL; \ | 41 | ptr = NULL; \ |
| 41 | } \ | 42 | } \ |
| 42 | } | 43 | } |
| 43 | 44 | ||
| 44 | monitoring_plugin *this_monitoring_plugin = NULL; | 45 | monitoring_plugin *this_monitoring_plugin = NULL; |
| 45 | 46 | ||
| 46 | int timeout_state = STATE_CRITICAL; | 47 | mp_state_enum timeout_state = STATE_CRITICAL; |
| 47 | unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT; | 48 | unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT; |
| 48 | 49 | ||
| 49 | bool _np_state_read_file(FILE *); | 50 | bool _np_state_read_file(FILE *state_file); |
| 50 | 51 | ||
| 51 | void np_init(char *plugin_name, int argc, char **argv) { | 52 | void np_init(char *plugin_name, int argc, char **argv) { |
| 52 | if (this_monitoring_plugin == NULL) { | 53 | if (this_monitoring_plugin == NULL) { |
| @@ -74,14 +75,6 @@ void np_set_args(int argc, char **argv) { | |||
| 74 | 75 | ||
| 75 | void np_cleanup(void) { | 76 | void np_cleanup(void) { |
| 76 | if (this_monitoring_plugin != NULL) { | 77 | if (this_monitoring_plugin != NULL) { |
| 77 | if (this_monitoring_plugin->state != NULL) { | ||
| 78 | if (this_monitoring_plugin->state->state_data) { | ||
| 79 | np_free(this_monitoring_plugin->state->state_data->data); | ||
| 80 | np_free(this_monitoring_plugin->state->state_data); | ||
| 81 | } | ||
| 82 | np_free(this_monitoring_plugin->state->name); | ||
| 83 | np_free(this_monitoring_plugin->state); | ||
| 84 | } | ||
| 85 | np_free(this_monitoring_plugin->plugin_name); | 78 | np_free(this_monitoring_plugin->plugin_name); |
| 86 | np_free(this_monitoring_plugin); | 79 | np_free(this_monitoring_plugin); |
| 87 | } | 80 | } |
| @@ -153,7 +146,8 @@ range *parse_range_string(char *str) { | |||
| 153 | set_range_end(temp_range, end); | 146 | set_range_end(temp_range, end); |
| 154 | } | 147 | } |
| 155 | 148 | ||
| 156 | if (temp_range->start_infinity == true || temp_range->end_infinity == true || temp_range->start <= temp_range->end) { | 149 | if (temp_range->start_infinity || temp_range->end_infinity || |
| 150 | temp_range->start <= temp_range->end) { | ||
| 157 | return temp_range; | 151 | return temp_range; |
| 158 | } | 152 | } |
| 159 | free(temp_range); | 153 | free(temp_range); |
| @@ -205,12 +199,14 @@ void print_thresholds(const char *threshold_name, thresholds *my_threshold) { | |||
| 205 | printf("Threshold not set"); | 199 | printf("Threshold not set"); |
| 206 | } else { | 200 | } else { |
| 207 | if (my_threshold->warning) { | 201 | if (my_threshold->warning) { |
| 208 | printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end); | 202 | printf("Warning: start=%g end=%g; ", my_threshold->warning->start, |
| 203 | my_threshold->warning->end); | ||
| 209 | } else { | 204 | } else { |
| 210 | printf("Warning not set; "); | 205 | printf("Warning not set; "); |
| 211 | } | 206 | } |
| 212 | if (my_threshold->critical) { | 207 | if (my_threshold->critical) { |
| 213 | printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end); | 208 | printf("Critical: start=%g end=%g", my_threshold->critical->start, |
| 209 | my_threshold->critical->end); | ||
| 214 | } else { | 210 | } else { |
| 215 | printf("Critical not set"); | 211 | printf("Critical not set"); |
| 216 | } | 212 | } |
| @@ -222,36 +218,26 @@ void print_thresholds(const char *threshold_name, thresholds *my_threshold) { | |||
| 222 | bool mp_check_range(const mp_perfdata_value value, const mp_range my_range) { | 218 | bool mp_check_range(const mp_perfdata_value value, const mp_range my_range) { |
| 223 | bool is_inside = false; | 219 | bool is_inside = false; |
| 224 | 220 | ||
| 225 | if (my_range.end_infinity == false && my_range.start_infinity == false) { | 221 | if (!my_range.end_infinity && !my_range.start_infinity) { |
| 226 | // range: .........|---inside---|........... | 222 | // range: .........|---inside---|........... |
| 227 | // value | 223 | // value |
| 228 | if ((cmp_perfdata_value(my_range.start, value) < 1) && (cmp_perfdata_value(value, my_range.end) <= 0)) { | 224 | is_inside = ((cmp_perfdata_value(value, my_range.start) >= 0) && |
| 229 | is_inside = true; | 225 | (cmp_perfdata_value(value, my_range.end) <= 0)); |
| 230 | } else { | 226 | } else if (!my_range.start_infinity && my_range.end_infinity) { |
| 231 | is_inside = false; | ||
| 232 | } | ||
| 233 | } else if (my_range.start_infinity == false && my_range.end_infinity == true) { | ||
| 234 | // range: .........|---inside--------- | 227 | // range: .........|---inside--------- |
| 235 | // value | 228 | // value |
| 236 | if (cmp_perfdata_value(my_range.start, value) < 0) { | 229 | is_inside = (cmp_perfdata_value(value, my_range.start) >= 0); |
| 237 | is_inside = true; | 230 | } else if (my_range.start_infinity && !my_range.end_infinity) { |
| 238 | } else { | ||
| 239 | is_inside = false; | ||
| 240 | } | ||
| 241 | } else if (my_range.start_infinity == true && my_range.end_infinity == false) { | ||
| 242 | // range: -inside--------|.................... | 231 | // range: -inside--------|.................... |
| 243 | // value | 232 | // value |
| 244 | if (cmp_perfdata_value(value, my_range.end) == -1) { | 233 | is_inside = (cmp_perfdata_value(value, my_range.end) == -1); |
| 245 | is_inside = true; | ||
| 246 | } else { | ||
| 247 | is_inside = false; | ||
| 248 | } | ||
| 249 | } else { | 234 | } else { |
| 250 | // range from -inf to inf, so always inside | 235 | // range from -inf to inf, so always inside |
| 251 | is_inside = true; | 236 | is_inside = true; |
| 252 | } | 237 | } |
| 253 | 238 | ||
| 254 | if ((is_inside && my_range.alert_on_inside_range == INSIDE) || (!is_inside && my_range.alert_on_inside_range == OUTSIDE)) { | 239 | if ((is_inside && my_range.alert_on_inside_range == INSIDE) || |
| 240 | (!is_inside && my_range.alert_on_inside_range == OUTSIDE)) { | ||
| 255 | return true; | 241 | return true; |
| 256 | } | 242 | } |
| 257 | 243 | ||
| @@ -268,21 +254,21 @@ bool check_range(double value, range *my_range) { | |||
| 268 | yes = false; | 254 | yes = false; |
| 269 | } | 255 | } |
| 270 | 256 | ||
| 271 | if (my_range->end_infinity == false && my_range->start_infinity == false) { | 257 | if (!my_range->end_infinity && !my_range->start_infinity) { |
| 272 | if ((my_range->start <= value) && (value <= my_range->end)) { | 258 | if ((my_range->start <= value) && (value <= my_range->end)) { |
| 273 | return no; | 259 | return no; |
| 274 | } | 260 | } |
| 275 | return yes; | 261 | return yes; |
| 276 | } | 262 | } |
| 277 | 263 | ||
| 278 | if (my_range->start_infinity == false && my_range->end_infinity == true) { | 264 | if (!my_range->start_infinity && my_range->end_infinity) { |
| 279 | if (my_range->start <= value) { | 265 | if (my_range->start <= value) { |
| 280 | return no; | 266 | return no; |
| 281 | } | 267 | } |
| 282 | return yes; | 268 | return yes; |
| 283 | } | 269 | } |
| 284 | 270 | ||
| 285 | if (my_range->start_infinity == true && my_range->end_infinity == false) { | 271 | if (my_range->start_infinity && !my_range->end_infinity) { |
| 286 | if (value <= my_range->end) { | 272 | if (value <= my_range->end) { |
| 287 | return no; | 273 | return no; |
| 288 | } | 274 | } |
| @@ -292,14 +278,14 @@ bool check_range(double value, range *my_range) { | |||
| 292 | } | 278 | } |
| 293 | 279 | ||
| 294 | /* Returns status */ | 280 | /* Returns status */ |
| 295 | int get_status(double value, thresholds *my_thresholds) { | 281 | mp_state_enum get_status(double value, thresholds *my_thresholds) { |
| 296 | if (my_thresholds->critical != NULL) { | 282 | if (my_thresholds->critical != NULL) { |
| 297 | if (check_range(value, my_thresholds->critical) == true) { | 283 | if (check_range(value, my_thresholds->critical)) { |
| 298 | return STATE_CRITICAL; | 284 | return STATE_CRITICAL; |
| 299 | } | 285 | } |
| 300 | } | 286 | } |
| 301 | if (my_thresholds->warning != NULL) { | 287 | if (my_thresholds->warning != NULL) { |
| 302 | if (check_range(value, my_thresholds->warning) == true) { | 288 | if (check_range(value, my_thresholds->warning)) { |
| 303 | return STATE_WARNING; | 289 | return STATE_WARNING; |
| 304 | } | 290 | } |
| 305 | } | 291 | } |
| @@ -308,32 +294,31 @@ int get_status(double value, thresholds *my_thresholds) { | |||
| 308 | 294 | ||
| 309 | char *np_escaped_string(const char *string) { | 295 | char *np_escaped_string(const char *string) { |
| 310 | char *data; | 296 | char *data; |
| 311 | int i; | 297 | int write_index = 0; |
| 312 | int j = 0; | ||
| 313 | data = strdup(string); | 298 | data = strdup(string); |
| 314 | for (i = 0; data[i]; i++) { | 299 | for (int i = 0; data[i]; i++) { |
| 315 | if (data[i] == '\\') { | 300 | if (data[i] == '\\') { |
| 316 | switch (data[++i]) { | 301 | switch (data[++i]) { |
| 317 | case 'n': | 302 | case 'n': |
| 318 | data[j++] = '\n'; | 303 | data[write_index++] = '\n'; |
| 319 | break; | 304 | break; |
| 320 | case 'r': | 305 | case 'r': |
| 321 | data[j++] = '\r'; | 306 | data[write_index++] = '\r'; |
| 322 | break; | 307 | break; |
| 323 | case 't': | 308 | case 't': |
| 324 | data[j++] = '\t'; | 309 | data[write_index++] = '\t'; |
| 325 | break; | 310 | break; |
| 326 | case '\\': | 311 | case '\\': |
| 327 | data[j++] = '\\'; | 312 | data[write_index++] = '\\'; |
| 328 | break; | 313 | break; |
| 329 | default: | 314 | default: |
| 330 | data[j++] = data[i]; | 315 | data[write_index++] = data[i]; |
| 331 | } | 316 | } |
| 332 | } else { | 317 | } else { |
| 333 | data[j++] = data[i]; | 318 | data[write_index++] = data[i]; |
| 334 | } | 319 | } |
| 335 | } | 320 | } |
| 336 | data[j] = '\0'; | 321 | data[write_index] = '\0'; |
| 337 | return data; | 322 | return data; |
| 338 | } | 323 | } |
| 339 | 324 | ||
| @@ -348,33 +333,35 @@ int np_check_if_root(void) { return (geteuid() == 0); } | |||
| 348 | char *np_extract_value(const char *varlist, const char *name, char sep) { | 333 | char *np_extract_value(const char *varlist, const char *name, char sep) { |
| 349 | char *tmp = NULL; | 334 | char *tmp = NULL; |
| 350 | char *value = NULL; | 335 | char *value = NULL; |
| 351 | int i; | ||
| 352 | 336 | ||
| 353 | while (1) { | 337 | while (true) { |
| 354 | /* Strip any leading space */ | 338 | /* Strip any leading space */ |
| 355 | for (; isspace(varlist[0]); varlist++) | 339 | for (; isspace(varlist[0]); varlist++) { |
| 356 | ; | 340 | ; |
| 341 | } | ||
| 357 | 342 | ||
| 358 | if (strncmp(name, varlist, strlen(name)) == 0) { | 343 | if (strncmp(name, varlist, strlen(name)) == 0) { |
| 359 | varlist += strlen(name); | 344 | varlist += strlen(name); |
| 360 | /* strip trailing spaces */ | 345 | /* strip trailing spaces */ |
| 361 | for (; isspace(varlist[0]); varlist++) | 346 | for (; isspace(varlist[0]); varlist++) { |
| 362 | ; | 347 | ; |
| 348 | } | ||
| 363 | 349 | ||
| 364 | if (varlist[0] == '=') { | 350 | if (varlist[0] == '=') { |
| 365 | /* We matched the key, go past the = sign */ | 351 | /* We matched the key, go past the = sign */ |
| 366 | varlist++; | 352 | varlist++; |
| 367 | /* strip leading spaces */ | 353 | /* strip leading spaces */ |
| 368 | for (; isspace(varlist[0]); varlist++) | 354 | for (; isspace(varlist[0]); varlist++) { |
| 369 | ; | 355 | ; |
| 356 | } | ||
| 370 | 357 | ||
| 371 | if ((tmp = index(varlist, sep))) { | 358 | if ((tmp = index(varlist, sep))) { |
| 372 | /* Value is delimited by a comma */ | 359 | /* Value is delimited by a comma */ |
| 373 | if (tmp - varlist == 0) { | 360 | if (tmp - varlist == 0) { |
| 374 | continue; | 361 | continue; |
| 375 | } | 362 | } |
| 376 | value = (char *)calloc(1, tmp - varlist + 1); | 363 | value = (char *)calloc(1, (unsigned long)(tmp - varlist + 1)); |
| 377 | strncpy(value, varlist, tmp - varlist); | 364 | strncpy(value, varlist, (unsigned long)(tmp - varlist)); |
| 378 | value[tmp - varlist] = '\0'; | 365 | value[tmp - varlist] = '\0'; |
| 379 | } else { | 366 | } else { |
| 380 | /* Value is delimited by a \0 */ | 367 | /* Value is delimited by a \0 */ |
| @@ -399,7 +386,7 @@ char *np_extract_value(const char *varlist, const char *name, char sep) { | |||
| 399 | 386 | ||
| 400 | /* Clean-up trailing spaces/newlines */ | 387 | /* Clean-up trailing spaces/newlines */ |
| 401 | if (value) { | 388 | if (value) { |
| 402 | for (i = strlen(value) - 1; isspace(value[i]); i--) { | 389 | for (unsigned long i = strlen(value) - 1; isspace(value[i]); i--) { |
| 403 | value[i] = '\0'; | 390 | value[i] = '\0'; |
| 404 | } | 391 | } |
| 405 | } | 392 | } |
| @@ -407,7 +394,7 @@ char *np_extract_value(const char *varlist, const char *name, char sep) { | |||
| 407 | return value; | 394 | return value; |
| 408 | } | 395 | } |
| 409 | 396 | ||
| 410 | const char *state_text(int result) { | 397 | const char *state_text(mp_state_enum result) { |
| 411 | switch (result) { | 398 | switch (result) { |
| 412 | case STATE_OK: | 399 | case STATE_OK: |
| 413 | return "OK"; | 400 | return "OK"; |
| @@ -441,349 +428,3 @@ int mp_translate_state(char *state_text) { | |||
| 441 | } | 428 | } |
| 442 | return ERROR; | 429 | return ERROR; |
| 443 | } | 430 | } |
| 444 | |||
| 445 | /* | ||
| 446 | * Returns a string to use as a keyname, based on an md5 hash of argv, thus | ||
| 447 | * hopefully a unique key per service/plugin invocation. Use the extra-opts | ||
| 448 | * parse of argv, so that uniqueness in parameters are reflected there. | ||
| 449 | */ | ||
| 450 | char *_np_state_generate_key(void) { | ||
| 451 | int i; | ||
| 452 | char **argv = this_monitoring_plugin->argv; | ||
| 453 | char keyname[41]; | ||
| 454 | char *p = NULL; | ||
| 455 | |||
| 456 | unsigned char result[256]; | ||
| 457 | |||
| 458 | #ifdef USE_OPENSSL | ||
| 459 | /* | ||
| 460 | * This code path is chosen if openssl is available (which should be the most common | ||
| 461 | * scenario). Alternatively, the gnulib implementation/ | ||
| 462 | * | ||
| 463 | */ | ||
| 464 | EVP_MD_CTX *ctx = EVP_MD_CTX_new(); | ||
| 465 | |||
| 466 | EVP_DigestInit(ctx, EVP_sha256()); | ||
| 467 | |||
| 468 | for (i = 0; i < this_monitoring_plugin->argc; i++) { | ||
| 469 | EVP_DigestUpdate(ctx, argv[i], strlen(argv[i])); | ||
| 470 | } | ||
| 471 | |||
| 472 | EVP_DigestFinal(ctx, result, NULL); | ||
| 473 | #else | ||
| 474 | |||
| 475 | struct sha256_ctx ctx; | ||
| 476 | |||
| 477 | for (i = 0; i < this_monitoring_plugin->argc; i++) { | ||
| 478 | sha256_process_bytes(argv[i], strlen(argv[i]), &ctx); | ||
| 479 | } | ||
| 480 | |||
| 481 | sha256_finish_ctx(&ctx, result); | ||
| 482 | #endif // FOUNDOPENSSL | ||
| 483 | |||
| 484 | for (i = 0; i < 20; ++i) { | ||
| 485 | sprintf(&keyname[2 * i], "%02x", result[i]); | ||
| 486 | } | ||
| 487 | |||
| 488 | keyname[40] = '\0'; | ||
| 489 | |||
| 490 | p = strdup(keyname); | ||
| 491 | if (p == NULL) { | ||
| 492 | die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); | ||
| 493 | } | ||
| 494 | return p; | ||
| 495 | } | ||
| 496 | |||
| 497 | void _cleanup_state_data(void) { | ||
| 498 | if (this_monitoring_plugin->state->state_data != NULL) { | ||
| 499 | np_free(this_monitoring_plugin->state->state_data->data); | ||
| 500 | np_free(this_monitoring_plugin->state->state_data); | ||
| 501 | } | ||
| 502 | } | ||
| 503 | |||
| 504 | /* | ||
| 505 | * Internal function. Returns either: | ||
| 506 | * envvar NAGIOS_PLUGIN_STATE_DIRECTORY | ||
| 507 | * statically compiled shared state directory | ||
| 508 | */ | ||
| 509 | char *_np_state_calculate_location_prefix(void) { | ||
| 510 | char *env_dir; | ||
| 511 | |||
| 512 | /* Do not allow passing MP_STATE_PATH in setuid plugins | ||
| 513 | * for security reasons */ | ||
| 514 | if (!mp_suid()) { | ||
| 515 | env_dir = getenv("MP_STATE_PATH"); | ||
| 516 | if (env_dir && env_dir[0] != '\0') { | ||
| 517 | return env_dir; | ||
| 518 | } | ||
| 519 | /* This is the former ENV, for backward-compatibility */ | ||
| 520 | env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY"); | ||
| 521 | if (env_dir && env_dir[0] != '\0') { | ||
| 522 | return env_dir; | ||
| 523 | } | ||
| 524 | } | ||
| 525 | |||
| 526 | return NP_STATE_DIR_PREFIX; | ||
| 527 | } | ||
| 528 | |||
| 529 | /* | ||
| 530 | * Initiatializer for state routines. | ||
| 531 | * Sets variables. Generates filename. Returns np_state_key. die with | ||
| 532 | * UNKNOWN if exception | ||
| 533 | */ | ||
| 534 | void np_enable_state(char *keyname, int expected_data_version) { | ||
| 535 | state_key *this_state = NULL; | ||
| 536 | char *temp_filename = NULL; | ||
| 537 | char *temp_keyname = NULL; | ||
| 538 | char *p = NULL; | ||
| 539 | int ret; | ||
| 540 | |||
| 541 | if (this_monitoring_plugin == NULL) { | ||
| 542 | die(STATE_UNKNOWN, _("This requires np_init to be called")); | ||
| 543 | } | ||
| 544 | |||
| 545 | this_state = (state_key *)calloc(1, sizeof(state_key)); | ||
| 546 | if (this_state == NULL) { | ||
| 547 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 548 | } | ||
| 549 | |||
| 550 | if (keyname == NULL) { | ||
| 551 | temp_keyname = _np_state_generate_key(); | ||
| 552 | } else { | ||
| 553 | temp_keyname = strdup(keyname); | ||
| 554 | if (temp_keyname == NULL) { | ||
| 555 | die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); | ||
| 556 | } | ||
| 557 | } | ||
| 558 | /* Die if invalid characters used for keyname */ | ||
| 559 | p = temp_keyname; | ||
| 560 | while (*p != '\0') { | ||
| 561 | if (!(isalnum(*p) || *p == '_')) { | ||
| 562 | die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'")); | ||
| 563 | } | ||
| 564 | p++; | ||
| 565 | } | ||
| 566 | this_state->name = temp_keyname; | ||
| 567 | this_state->plugin_name = this_monitoring_plugin->plugin_name; | ||
| 568 | this_state->data_version = expected_data_version; | ||
| 569 | this_state->state_data = NULL; | ||
| 570 | |||
| 571 | /* Calculate filename */ | ||
| 572 | ret = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), (unsigned long)geteuid(), | ||
| 573 | this_monitoring_plugin->plugin_name, this_state->name); | ||
| 574 | if (ret < 0) { | ||
| 575 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 576 | } | ||
| 577 | |||
| 578 | this_state->_filename = temp_filename; | ||
| 579 | |||
| 580 | this_monitoring_plugin->state = this_state; | ||
| 581 | } | ||
| 582 | |||
| 583 | /* | ||
| 584 | * Will return NULL if no data is available (first run). If key currently | ||
| 585 | * exists, read data. If state file format version is not expected, return | ||
| 586 | * as if no data. Get state data version number and compares to expected. | ||
| 587 | * If numerically lower, then return as no previous state. die with UNKNOWN | ||
| 588 | * if exceptional error. | ||
| 589 | */ | ||
| 590 | state_data *np_state_read(void) { | ||
| 591 | state_data *this_state_data = NULL; | ||
| 592 | FILE *statefile; | ||
| 593 | bool rc = false; | ||
| 594 | |||
| 595 | if (this_monitoring_plugin == NULL) { | ||
| 596 | die(STATE_UNKNOWN, _("This requires np_init to be called")); | ||
| 597 | } | ||
| 598 | |||
| 599 | /* Open file. If this fails, no previous state found */ | ||
| 600 | statefile = fopen(this_monitoring_plugin->state->_filename, "r"); | ||
| 601 | if (statefile != NULL) { | ||
| 602 | |||
| 603 | this_state_data = (state_data *)calloc(1, sizeof(state_data)); | ||
| 604 | if (this_state_data == NULL) { | ||
| 605 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 606 | } | ||
| 607 | |||
| 608 | this_state_data->data = NULL; | ||
| 609 | this_monitoring_plugin->state->state_data = this_state_data; | ||
| 610 | |||
| 611 | rc = _np_state_read_file(statefile); | ||
| 612 | |||
| 613 | fclose(statefile); | ||
| 614 | } | ||
| 615 | |||
| 616 | if (!rc) { | ||
| 617 | _cleanup_state_data(); | ||
| 618 | } | ||
| 619 | |||
| 620 | return this_monitoring_plugin->state->state_data; | ||
| 621 | } | ||
| 622 | |||
| 623 | /* | ||
| 624 | * Read the state file | ||
| 625 | */ | ||
| 626 | bool _np_state_read_file(FILE *f) { | ||
| 627 | bool status = false; | ||
| 628 | size_t pos; | ||
| 629 | char *line; | ||
| 630 | int i; | ||
| 631 | int failure = 0; | ||
| 632 | time_t current_time, data_time; | ||
| 633 | enum { | ||
| 634 | STATE_FILE_VERSION, | ||
| 635 | STATE_DATA_VERSION, | ||
| 636 | STATE_DATA_TIME, | ||
| 637 | STATE_DATA_TEXT, | ||
| 638 | STATE_DATA_END | ||
| 639 | } expected = STATE_FILE_VERSION; | ||
| 640 | |||
| 641 | time(¤t_time); | ||
| 642 | |||
| 643 | /* Note: This introduces a limit of 1024 bytes in the string data */ | ||
| 644 | line = (char *)calloc(1, 1024); | ||
| 645 | if (line == NULL) { | ||
| 646 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 647 | } | ||
| 648 | |||
| 649 | while (!failure && (fgets(line, 1024, f)) != NULL) { | ||
| 650 | pos = strlen(line); | ||
| 651 | if (line[pos - 1] == '\n') { | ||
| 652 | line[pos - 1] = '\0'; | ||
| 653 | } | ||
| 654 | |||
| 655 | if (line[0] == '#') { | ||
| 656 | continue; | ||
| 657 | } | ||
| 658 | |||
| 659 | switch (expected) { | ||
| 660 | case STATE_FILE_VERSION: | ||
| 661 | i = atoi(line); | ||
| 662 | if (i != NP_STATE_FORMAT_VERSION) { | ||
| 663 | failure++; | ||
| 664 | } else { | ||
| 665 | expected = STATE_DATA_VERSION; | ||
| 666 | } | ||
| 667 | break; | ||
| 668 | case STATE_DATA_VERSION: | ||
| 669 | i = atoi(line); | ||
| 670 | if (i != this_monitoring_plugin->state->data_version) { | ||
| 671 | failure++; | ||
| 672 | } else { | ||
| 673 | expected = STATE_DATA_TIME; | ||
| 674 | } | ||
| 675 | break; | ||
| 676 | case STATE_DATA_TIME: | ||
| 677 | /* If time > now, error */ | ||
| 678 | data_time = strtoul(line, NULL, 10); | ||
| 679 | if (data_time > current_time) { | ||
| 680 | failure++; | ||
| 681 | } else { | ||
| 682 | this_monitoring_plugin->state->state_data->time = data_time; | ||
| 683 | expected = STATE_DATA_TEXT; | ||
| 684 | } | ||
| 685 | break; | ||
| 686 | case STATE_DATA_TEXT: | ||
| 687 | this_monitoring_plugin->state->state_data->data = strdup(line); | ||
| 688 | if (this_monitoring_plugin->state->state_data->data == NULL) { | ||
| 689 | die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); | ||
| 690 | } | ||
| 691 | expected = STATE_DATA_END; | ||
| 692 | status = true; | ||
| 693 | break; | ||
| 694 | case STATE_DATA_END:; | ||
| 695 | } | ||
| 696 | } | ||
| 697 | |||
| 698 | np_free(line); | ||
| 699 | return status; | ||
| 700 | } | ||
| 701 | |||
| 702 | /* | ||
| 703 | * If time=NULL, use current time. Create state file, with state format | ||
| 704 | * version, default text. Writes version, time, and data. Avoid locking | ||
| 705 | * problems - use mv to write and then swap. Possible loss of state data if | ||
| 706 | * two things writing to same key at same time. | ||
| 707 | * Will die with UNKNOWN if errors | ||
| 708 | */ | ||
| 709 | void np_state_write_string(time_t data_time, char *data_string) { | ||
| 710 | FILE *fp; | ||
| 711 | char *temp_file = NULL; | ||
| 712 | int fd = 0, result = 0; | ||
| 713 | time_t current_time; | ||
| 714 | char *directories = NULL; | ||
| 715 | char *p = NULL; | ||
| 716 | |||
| 717 | if (data_time == 0) { | ||
| 718 | time(¤t_time); | ||
| 719 | } else { | ||
| 720 | current_time = data_time; | ||
| 721 | } | ||
| 722 | |||
| 723 | /* If file doesn't currently exist, create directories */ | ||
| 724 | if (access(this_monitoring_plugin->state->_filename, F_OK) != 0) { | ||
| 725 | result = asprintf(&directories, "%s", this_monitoring_plugin->state->_filename); | ||
| 726 | if (result < 0) { | ||
| 727 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 728 | } | ||
| 729 | |||
| 730 | for (p = directories + 1; *p; p++) { | ||
| 731 | if (*p == '/') { | ||
| 732 | *p = '\0'; | ||
| 733 | if ((access(directories, F_OK) != 0) && (mkdir(directories, S_IRWXU) != 0)) { | ||
| 734 | /* Can't free this! Otherwise error message is wrong! */ | ||
| 735 | /* np_free(directories); */ | ||
| 736 | die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories); | ||
| 737 | } | ||
| 738 | *p = '/'; | ||
| 739 | } | ||
| 740 | } | ||
| 741 | np_free(directories); | ||
| 742 | } | ||
| 743 | |||
| 744 | result = asprintf(&temp_file, "%s.XXXXXX", this_monitoring_plugin->state->_filename); | ||
| 745 | if (result < 0) { | ||
| 746 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 747 | } | ||
| 748 | |||
| 749 | if ((fd = mkstemp(temp_file)) == -1) { | ||
| 750 | np_free(temp_file); | ||
| 751 | die(STATE_UNKNOWN, _("Cannot create temporary filename")); | ||
| 752 | } | ||
| 753 | |||
| 754 | fp = (FILE *)fdopen(fd, "w"); | ||
| 755 | if (fp == NULL) { | ||
| 756 | close(fd); | ||
| 757 | unlink(temp_file); | ||
| 758 | np_free(temp_file); | ||
| 759 | die(STATE_UNKNOWN, _("Unable to open temporary state file")); | ||
| 760 | } | ||
| 761 | |||
| 762 | fprintf(fp, "# NP State file\n"); | ||
| 763 | fprintf(fp, "%d\n", NP_STATE_FORMAT_VERSION); | ||
| 764 | fprintf(fp, "%d\n", this_monitoring_plugin->state->data_version); | ||
| 765 | fprintf(fp, "%lu\n", current_time); | ||
| 766 | fprintf(fp, "%s\n", data_string); | ||
| 767 | |||
| 768 | fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP); | ||
| 769 | |||
| 770 | fflush(fp); | ||
| 771 | |||
| 772 | result = fclose(fp); | ||
| 773 | |||
| 774 | fsync(fd); | ||
| 775 | |||
| 776 | if (result != 0) { | ||
| 777 | unlink(temp_file); | ||
| 778 | np_free(temp_file); | ||
| 779 | die(STATE_UNKNOWN, _("Error writing temp file")); | ||
| 780 | } | ||
| 781 | |||
| 782 | if (rename(temp_file, this_monitoring_plugin->state->_filename) != 0) { | ||
| 783 | unlink(temp_file); | ||
| 784 | np_free(temp_file); | ||
| 785 | die(STATE_UNKNOWN, _("Cannot rename state temp file")); | ||
| 786 | } | ||
| 787 | |||
| 788 | np_free(temp_file); | ||
| 789 | } | ||
diff --git a/lib/utils_base.h b/lib/utils_base.h index 123066f8..27884bf0 100644 --- a/lib/utils_base.h +++ b/lib/utils_base.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include "./perfdata.h" | 8 | #include "./perfdata.h" |
| 9 | #include "./thresholds.h" | 9 | #include "./thresholds.h" |
| 10 | 10 | #include "states.h" | |
| 11 | 11 | ||
| 12 | #ifndef USE_OPENSSL | 12 | #ifndef USE_OPENSSL |
| 13 | # include "sha256.h" | 13 | # include "sha256.h" |
| @@ -26,25 +26,8 @@ | |||
| 26 | #define OUTSIDE 0 | 26 | #define OUTSIDE 0 |
| 27 | #define INSIDE 1 | 27 | #define INSIDE 1 |
| 28 | 28 | ||
| 29 | #define NP_STATE_FORMAT_VERSION 1 | ||
| 30 | |||
| 31 | typedef struct state_data_struct { | ||
| 32 | time_t time; | ||
| 33 | void *data; | ||
| 34 | int length; /* Of binary data */ | ||
| 35 | } state_data; | ||
| 36 | |||
| 37 | typedef struct state_key_struct { | ||
| 38 | char *name; | ||
| 39 | char *plugin_name; | ||
| 40 | int data_version; | ||
| 41 | char *_filename; | ||
| 42 | state_data *state_data; | ||
| 43 | } state_key; | ||
| 44 | |||
| 45 | typedef struct np_struct { | 29 | typedef struct np_struct { |
| 46 | char *plugin_name; | 30 | char *plugin_name; |
| 47 | state_key *state; | ||
| 48 | int argc; | 31 | int argc; |
| 49 | char **argv; | 32 | char **argv; |
| 50 | } monitoring_plugin; | 33 | } monitoring_plugin; |
| @@ -55,10 +38,10 @@ void set_thresholds(thresholds **, char *, char *); | |||
| 55 | void print_thresholds(const char *, thresholds *); | 38 | void print_thresholds(const char *, thresholds *); |
| 56 | bool check_range(double, range *); | 39 | bool check_range(double, range *); |
| 57 | bool mp_check_range(mp_perfdata_value, mp_range); | 40 | bool mp_check_range(mp_perfdata_value, mp_range); |
| 58 | int get_status(double, thresholds *); | 41 | mp_state_enum get_status(double, thresholds *); |
| 59 | 42 | ||
| 60 | /* Handle timeouts */ | 43 | /* Handle timeouts */ |
| 61 | extern int timeout_state; | 44 | extern mp_state_enum timeout_state; |
| 62 | extern unsigned int timeout_interval; | 45 | extern unsigned int timeout_interval; |
| 63 | 46 | ||
| 64 | /* All possible characters in a threshold range */ | 47 | /* All possible characters in a threshold range */ |
| @@ -100,13 +83,9 @@ char *np_extract_value(const char *, const char *, char); | |||
| 100 | */ | 83 | */ |
| 101 | int mp_translate_state(char *); | 84 | int mp_translate_state(char *); |
| 102 | 85 | ||
| 103 | void np_enable_state(char *, int); | ||
| 104 | state_data *np_state_read(void); | ||
| 105 | void np_state_write_string(time_t, char *); | ||
| 106 | |||
| 107 | void np_init(char *, int argc, char **argv); | 86 | void np_init(char *, int argc, char **argv); |
| 108 | void np_set_args(int argc, char **argv); | 87 | void np_set_args(int argc, char **argv); |
| 109 | void np_cleanup(void); | 88 | void np_cleanup(void); |
| 110 | const char *state_text(int); | 89 | const char *state_text(mp_state_enum); |
| 111 | 90 | ||
| 112 | #endif /* _UTILS_BASE_ */ | 91 | #endif /* _UTILS_BASE_ */ |
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c index 18350ac0..23d42168 100644 --- a/lib/utils_cmd.c +++ b/lib/utils_cmd.c | |||
| @@ -40,7 +40,6 @@ | |||
| 40 | 40 | ||
| 41 | /** includes **/ | 41 | /** includes **/ |
| 42 | #include "common.h" | 42 | #include "common.h" |
| 43 | #include "utils.h" | ||
| 44 | #include "utils_cmd.h" | 43 | #include "utils_cmd.h" |
| 45 | /* This variable must be global, since there's no way the caller | 44 | /* This variable must be global, since there's no way the caller |
| 46 | * can forcibly slay a dead or ungainly running program otherwise. | 45 | * can forcibly slay a dead or ungainly running program otherwise. |
| @@ -57,21 +56,19 @@ static pid_t *_cmd_pids = NULL; | |||
| 57 | #include "./maxfd.h" | 56 | #include "./maxfd.h" |
| 58 | 57 | ||
| 59 | #include <fcntl.h> | 58 | #include <fcntl.h> |
| 59 | #include <stddef.h> | ||
| 60 | 60 | ||
| 61 | #ifdef HAVE_SYS_WAIT_H | 61 | #ifdef HAVE_SYS_WAIT_H |
| 62 | # include <sys/wait.h> | 62 | # include <sys/wait.h> |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | /* used in _cmd_open to pass the environment to commands */ | ||
| 66 | extern char **environ; | ||
| 67 | |||
| 68 | /** macros **/ | 65 | /** macros **/ |
| 69 | #ifndef WEXITSTATUS | 66 | #ifndef WEXITSTATUS |
| 70 | # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) | 67 | # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) |
| 71 | #endif | 68 | #endif |
| 72 | 69 | ||
| 73 | #ifndef WIFEXITED | 70 | #ifndef WIFEXITED |
| 74 | # define WIFEXITED(stat_val) (((stat_val)&255) == 0) | 71 | # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) |
| 75 | #endif | 72 | #endif |
| 76 | 73 | ||
| 77 | /* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */ | 74 | /* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */ |
| @@ -80,14 +77,13 @@ extern char **environ; | |||
| 80 | #endif | 77 | #endif |
| 81 | 78 | ||
| 82 | /** prototypes **/ | 79 | /** prototypes **/ |
| 83 | static int _cmd_open(char *const *, int *, int *) __attribute__((__nonnull__(1, 2, 3))); | 80 | static int _cmd_open(char *const *argv, int *pfd, int *pfderr) |
| 84 | 81 | __attribute__((__nonnull__(1, 2, 3))); | |
| 85 | static int _cmd_fetch_output(int, output *, int) __attribute__((__nonnull__(2))); | ||
| 86 | 82 | ||
| 87 | static int _cmd_close(int); | 83 | static int _cmd_fetch_output(int fileDescriptor, output *cmd_output, int flags) |
| 84 | __attribute__((__nonnull__(2))); | ||
| 88 | 85 | ||
| 89 | /* prototype imported from utils.h */ | 86 | static int _cmd_close(int fileDescriptor); |
| 90 | extern void die(int, const char *, ...) __attribute__((__noreturn__, __format__(__printf__, 2, 3))); | ||
| 91 | 87 | ||
| 92 | /* this function is NOT async-safe. It is exported so multithreaded | 88 | /* this function is NOT async-safe. It is exported so multithreaded |
| 93 | * plugins (or other apps) can call it prior to running any commands | 89 | * plugins (or other apps) can call it prior to running any commands |
| @@ -103,26 +99,100 @@ void cmd_init(void) { | |||
| 103 | maxfd = MAXFD_LIMIT; | 99 | maxfd = MAXFD_LIMIT; |
| 104 | } | 100 | } |
| 105 | 101 | ||
| 106 | if (!_cmd_pids) | 102 | if (!_cmd_pids) { |
| 107 | _cmd_pids = calloc(maxfd, sizeof(pid_t)); | 103 | _cmd_pids = calloc(maxfd, sizeof(pid_t)); |
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | typedef struct { | ||
| 108 | int stdout_pipe_fd[2]; | ||
| 109 | int stderr_pipe_fd[2]; | ||
| 110 | int file_descriptor; | ||
| 111 | int error_code; | ||
| 112 | } int_cmd_open_result; | ||
| 113 | static int_cmd_open_result _cmd_open2(char *const *argv) { | ||
| 114 | #ifdef RLIMIT_CORE | ||
| 115 | struct rlimit limit; | ||
| 116 | #endif | ||
| 117 | |||
| 118 | if (!_cmd_pids) { | ||
| 119 | CMD_INIT; | ||
| 120 | } | ||
| 121 | |||
| 122 | setenv("LC_ALL", "C", 1); | ||
| 123 | |||
| 124 | int_cmd_open_result result = { | ||
| 125 | .error_code = 0, | ||
| 126 | .stdout_pipe_fd = {0, 0}, | ||
| 127 | .stderr_pipe_fd = {0, 0}, | ||
| 128 | }; | ||
| 129 | pid_t pid; | ||
| 130 | if (pipe(result.stdout_pipe_fd) < 0 || pipe(result.stderr_pipe_fd) < 0 || (pid = fork()) < 0) { | ||
| 131 | result.error_code = -1; | ||
| 132 | return result; /* errno set by the failing function */ | ||
| 133 | } | ||
| 134 | |||
| 135 | /* child runs exceve() and _exit. */ | ||
| 136 | if (pid == 0) { | ||
| 137 | #ifdef RLIMIT_CORE | ||
| 138 | /* the program we execve shouldn't leave core files */ | ||
| 139 | getrlimit(RLIMIT_CORE, &limit); | ||
| 140 | limit.rlim_cur = 0; | ||
| 141 | setrlimit(RLIMIT_CORE, &limit); | ||
| 142 | #endif | ||
| 143 | close(result.stdout_pipe_fd[0]); | ||
| 144 | if (result.stdout_pipe_fd[1] != STDOUT_FILENO) { | ||
| 145 | dup2(result.stdout_pipe_fd[1], STDOUT_FILENO); | ||
| 146 | close(result.stdout_pipe_fd[1]); | ||
| 147 | } | ||
| 148 | close(result.stderr_pipe_fd[0]); | ||
| 149 | if (result.stderr_pipe_fd[1] != STDERR_FILENO) { | ||
| 150 | dup2(result.stderr_pipe_fd[1], STDERR_FILENO); | ||
| 151 | close(result.stderr_pipe_fd[1]); | ||
| 152 | } | ||
| 153 | |||
| 154 | /* close all descriptors in _cmd_pids[] | ||
| 155 | * This is executed in a separate address space (pure child), | ||
| 156 | * so we don't have to worry about async safety */ | ||
| 157 | long maxfd = mp_open_max(); | ||
| 158 | for (int i = 0; i < maxfd; i++) { | ||
| 159 | if (_cmd_pids[i] > 0) { | ||
| 160 | close(i); | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | execve(argv[0], argv, environ); | ||
| 165 | _exit(STATE_UNKNOWN); | ||
| 166 | } | ||
| 167 | |||
| 168 | /* parent picks up execution here */ | ||
| 169 | /* close children descriptors in our address space */ | ||
| 170 | close(result.stdout_pipe_fd[1]); | ||
| 171 | close(result.stderr_pipe_fd[1]); | ||
| 172 | |||
| 173 | /* tag our file's entry in the pid-list and return it */ | ||
| 174 | _cmd_pids[result.stdout_pipe_fd[0]] = pid; | ||
| 175 | |||
| 176 | result.file_descriptor = result.stdout_pipe_fd[0]; | ||
| 177 | return result; | ||
| 108 | } | 178 | } |
| 109 | 179 | ||
| 110 | /* Start running a command, array style */ | 180 | /* Start running a command, array style */ |
| 111 | static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { | 181 | static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { |
| 112 | pid_t pid; | ||
| 113 | #ifdef RLIMIT_CORE | 182 | #ifdef RLIMIT_CORE |
| 114 | struct rlimit limit; | 183 | struct rlimit limit; |
| 115 | #endif | 184 | #endif |
| 116 | 185 | ||
| 117 | int i = 0; | 186 | if (!_cmd_pids) { |
| 118 | |||
| 119 | if (!_cmd_pids) | ||
| 120 | CMD_INIT; | 187 | CMD_INIT; |
| 188 | } | ||
| 121 | 189 | ||
| 122 | setenv("LC_ALL", "C", 1); | 190 | setenv("LC_ALL", "C", 1); |
| 123 | 191 | ||
| 124 | if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) | 192 | pid_t pid; |
| 193 | if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) { | ||
| 125 | return -1; /* errno set by the failing function */ | 194 | return -1; /* errno set by the failing function */ |
| 195 | } | ||
| 126 | 196 | ||
| 127 | /* child runs exceve() and _exit. */ | 197 | /* child runs exceve() and _exit. */ |
| 128 | if (pid == 0) { | 198 | if (pid == 0) { |
| @@ -147,9 +217,11 @@ static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { | |||
| 147 | * This is executed in a separate address space (pure child), | 217 | * This is executed in a separate address space (pure child), |
| 148 | * so we don't have to worry about async safety */ | 218 | * so we don't have to worry about async safety */ |
| 149 | long maxfd = mp_open_max(); | 219 | long maxfd = mp_open_max(); |
| 150 | for (i = 0; i < maxfd; i++) | 220 | for (int i = 0; i < maxfd; i++) { |
| 151 | if (_cmd_pids[i] > 0) | 221 | if (_cmd_pids[i] > 0) { |
| 152 | close(i); | 222 | close(i); |
| 223 | } | ||
| 224 | } | ||
| 153 | 225 | ||
| 154 | execve(argv[0], argv, environ); | 226 | execve(argv[0], argv, environ); |
| 155 | _exit(STATE_UNKNOWN); | 227 | _exit(STATE_UNKNOWN); |
| @@ -166,88 +238,171 @@ static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { | |||
| 166 | return pfd[0]; | 238 | return pfd[0]; |
| 167 | } | 239 | } |
| 168 | 240 | ||
| 169 | static int _cmd_close(int fd) { | 241 | static int _cmd_close(int fileDescriptor) { |
| 170 | int status; | ||
| 171 | pid_t pid; | 242 | pid_t pid; |
| 172 | 243 | ||
| 173 | /* make sure the provided fd was opened */ | 244 | /* make sure the provided fd was opened */ |
| 174 | long maxfd = mp_open_max(); | 245 | long maxfd = mp_open_max(); |
| 175 | if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0) | 246 | if (fileDescriptor < 0 || fileDescriptor > maxfd || !_cmd_pids || |
| 247 | (pid = _cmd_pids[fileDescriptor]) == 0) { | ||
| 176 | return -1; | 248 | return -1; |
| 249 | } | ||
| 177 | 250 | ||
| 178 | _cmd_pids[fd] = 0; | 251 | _cmd_pids[fileDescriptor] = 0; |
| 179 | if (close(fd) == -1) | 252 | if (close(fileDescriptor) == -1) { |
| 180 | return -1; | 253 | return -1; |
| 254 | } | ||
| 181 | 255 | ||
| 182 | /* EINTR is ok (sort of), everything else is bad */ | 256 | /* EINTR is ok (sort of), everything else is bad */ |
| 183 | while (waitpid(pid, &status, 0) < 0) | 257 | int status; |
| 184 | if (errno != EINTR) | 258 | while (waitpid(pid, &status, 0) < 0) { |
| 259 | if (errno != EINTR) { | ||
| 185 | return -1; | 260 | return -1; |
| 261 | } | ||
| 262 | } | ||
| 186 | 263 | ||
| 187 | /* return child's termination status */ | 264 | /* return child's termination status */ |
| 188 | return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1; | 265 | return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1; |
| 189 | } | 266 | } |
| 190 | 267 | ||
| 191 | static int _cmd_fetch_output(int fd, output *op, int flags) { | 268 | typedef struct { |
| 192 | size_t len = 0, i = 0, lineno = 0; | 269 | int error_code; |
| 193 | size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */ | 270 | output output_container; |
| 194 | char *buf = NULL; | 271 | } int_cmd_fetch_output2; |
| 195 | int ret; | 272 | static int_cmd_fetch_output2 _cmd_fetch_output2(int fileDescriptor, int flags) { |
| 196 | char tmpbuf[4096]; | 273 | char tmpbuf[4096]; |
| 197 | 274 | ||
| 198 | op->buf = NULL; | 275 | int_cmd_fetch_output2 result = { |
| 199 | op->buflen = 0; | 276 | .error_code = 0, |
| 200 | while ((ret = read(fd, tmpbuf, sizeof(tmpbuf))) > 0) { | 277 | .output_container = |
| 201 | len = (size_t)ret; | 278 | { |
| 202 | op->buf = realloc(op->buf, op->buflen + len + 1); | 279 | .buf = NULL, |
| 203 | memcpy(op->buf + op->buflen, tmpbuf, len); | 280 | .buflen = 0, |
| 204 | op->buflen += len; | 281 | .line = NULL, |
| 282 | .lines = 0, | ||
| 283 | }, | ||
| 284 | }; | ||
| 285 | ssize_t ret; | ||
| 286 | while ((ret = read(fileDescriptor, tmpbuf, sizeof(tmpbuf))) > 0) { | ||
| 287 | size_t len = (size_t)ret; | ||
| 288 | result.output_container.buf = | ||
| 289 | realloc(result.output_container.buf, result.output_container.buflen + len + 1); | ||
| 290 | memcpy(result.output_container.buf + result.output_container.buflen, tmpbuf, len); | ||
| 291 | result.output_container.buflen += len; | ||
| 292 | } | ||
| 293 | |||
| 294 | if (ret < 0) { | ||
| 295 | printf("read() returned %zd: %s\n", ret, strerror(errno)); | ||
| 296 | result.error_code = -1; | ||
| 297 | return result; | ||
| 298 | } | ||
| 299 | |||
| 300 | /* some plugins may want to keep output unbroken, and some commands | ||
| 301 | * will yield no output, so return here for those */ | ||
| 302 | if (flags & CMD_NO_ARRAYS || !result.output_container.buf || !result.output_container.buflen) { | ||
| 303 | return result; | ||
| 304 | } | ||
| 305 | |||
| 306 | /* and some may want both */ | ||
| 307 | char *buf = NULL; | ||
| 308 | if (flags & CMD_NO_ASSOC) { | ||
| 309 | buf = malloc(result.output_container.buflen); | ||
| 310 | memcpy(buf, result.output_container.buf, result.output_container.buflen); | ||
| 311 | } else { | ||
| 312 | buf = result.output_container.buf; | ||
| 313 | } | ||
| 314 | |||
| 315 | result.output_container.line = NULL; | ||
| 316 | size_t ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */ | ||
| 317 | size_t rsf = 6; | ||
| 318 | size_t lineno = 0; | ||
| 319 | for (size_t i = 0; i < result.output_container.buflen;) { | ||
| 320 | /* make sure we have enough memory */ | ||
| 321 | if (lineno >= ary_size) { | ||
| 322 | /* ary_size must never be zero */ | ||
| 323 | do { | ||
| 324 | ary_size = result.output_container.buflen >> --rsf; | ||
| 325 | } while (!ary_size); | ||
| 326 | |||
| 327 | result.output_container.line = | ||
| 328 | realloc(result.output_container.line, ary_size * sizeof(char *)); | ||
| 329 | } | ||
| 330 | |||
| 331 | /* set the pointer to the string */ | ||
| 332 | result.output_container.line[lineno] = &buf[i]; | ||
| 333 | |||
| 334 | /* hop to next newline or end of buffer */ | ||
| 335 | while (buf[i] != '\n' && i < result.output_container.buflen) { | ||
| 336 | i++; | ||
| 337 | } | ||
| 338 | buf[i] = '\0'; | ||
| 339 | |||
| 340 | lineno++; | ||
| 205 | i++; | 341 | i++; |
| 206 | } | 342 | } |
| 207 | 343 | ||
| 344 | result.output_container.lines = lineno; | ||
| 345 | |||
| 346 | return result; | ||
| 347 | } | ||
| 348 | |||
| 349 | static int _cmd_fetch_output(int fileDescriptor, output *cmd_output, int flags) { | ||
| 350 | char tmpbuf[4096]; | ||
| 351 | cmd_output->buf = NULL; | ||
| 352 | cmd_output->buflen = 0; | ||
| 353 | ssize_t ret; | ||
| 354 | while ((ret = read(fileDescriptor, tmpbuf, sizeof(tmpbuf))) > 0) { | ||
| 355 | size_t len = (size_t)ret; | ||
| 356 | cmd_output->buf = realloc(cmd_output->buf, cmd_output->buflen + len + 1); | ||
| 357 | memcpy(cmd_output->buf + cmd_output->buflen, tmpbuf, len); | ||
| 358 | cmd_output->buflen += len; | ||
| 359 | } | ||
| 360 | |||
| 208 | if (ret < 0) { | 361 | if (ret < 0) { |
| 209 | printf("read() returned %d: %s\n", ret, strerror(errno)); | 362 | printf("read() returned %zd: %s\n", ret, strerror(errno)); |
| 210 | return ret; | 363 | return ret; |
| 211 | } | 364 | } |
| 212 | 365 | ||
| 213 | /* some plugins may want to keep output unbroken, and some commands | 366 | /* some plugins may want to keep output unbroken, and some commands |
| 214 | * will yield no output, so return here for those */ | 367 | * will yield no output, so return here for those */ |
| 215 | if (flags & CMD_NO_ARRAYS || !op->buf || !op->buflen) | 368 | if (flags & CMD_NO_ARRAYS || !cmd_output->buf || !cmd_output->buflen) { |
| 216 | return op->buflen; | 369 | return cmd_output->buflen; |
| 370 | } | ||
| 217 | 371 | ||
| 218 | /* and some may want both */ | 372 | /* and some may want both */ |
| 373 | char *buf = NULL; | ||
| 219 | if (flags & CMD_NO_ASSOC) { | 374 | if (flags & CMD_NO_ASSOC) { |
| 220 | buf = malloc(op->buflen); | 375 | buf = malloc(cmd_output->buflen); |
| 221 | memcpy(buf, op->buf, op->buflen); | 376 | memcpy(buf, cmd_output->buf, cmd_output->buflen); |
| 222 | } else | 377 | } else { |
| 223 | buf = op->buf; | 378 | buf = cmd_output->buf; |
| 224 | 379 | } | |
| 225 | op->line = NULL; | 380 | |
| 226 | op->lens = NULL; | 381 | cmd_output->line = NULL; |
| 227 | i = 0; | 382 | size_t i = 0; |
| 228 | while (i < op->buflen) { | 383 | size_t ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */ |
| 384 | size_t rsf = 6; | ||
| 385 | size_t lineno = 0; | ||
| 386 | while (i < cmd_output->buflen) { | ||
| 229 | /* make sure we have enough memory */ | 387 | /* make sure we have enough memory */ |
| 230 | if (lineno >= ary_size) { | 388 | if (lineno >= ary_size) { |
| 231 | /* ary_size must never be zero */ | 389 | /* ary_size must never be zero */ |
| 232 | do { | 390 | do { |
| 233 | ary_size = op->buflen >> --rsf; | 391 | ary_size = cmd_output->buflen >> --rsf; |
| 234 | } while (!ary_size); | 392 | } while (!ary_size); |
| 235 | 393 | ||
| 236 | op->line = realloc(op->line, ary_size * sizeof(char *)); | 394 | cmd_output->line = realloc(cmd_output->line, ary_size * sizeof(char *)); |
| 237 | op->lens = realloc(op->lens, ary_size * sizeof(size_t)); | ||
| 238 | } | 395 | } |
| 239 | 396 | ||
| 240 | /* set the pointer to the string */ | 397 | /* set the pointer to the string */ |
| 241 | op->line[lineno] = &buf[i]; | 398 | cmd_output->line[lineno] = &buf[i]; |
| 242 | 399 | ||
| 243 | /* hop to next newline or end of buffer */ | 400 | /* hop to next newline or end of buffer */ |
| 244 | while (buf[i] != '\n' && i < op->buflen) | 401 | while (buf[i] != '\n' && i < cmd_output->buflen) { |
| 245 | i++; | 402 | i++; |
| 403 | } | ||
| 246 | buf[i] = '\0'; | 404 | buf[i] = '\0'; |
| 247 | 405 | ||
| 248 | /* calculate the string length using pointer difference */ | ||
| 249 | op->lens[lineno] = (size_t)&buf[i] - (size_t)op->line[lineno]; | ||
| 250 | |||
| 251 | lineno++; | 406 | lineno++; |
| 252 | i++; | 407 | i++; |
| 253 | } | 408 | } |
| @@ -256,41 +411,42 @@ static int _cmd_fetch_output(int fd, output *op, int flags) { | |||
| 256 | } | 411 | } |
| 257 | 412 | ||
| 258 | int cmd_run(const char *cmdstring, output *out, output *err, int flags) { | 413 | int cmd_run(const char *cmdstring, output *out, output *err, int flags) { |
| 259 | int i = 0, argc; | 414 | if (cmdstring == NULL) { |
| 260 | size_t cmdlen; | ||
| 261 | char **argv = NULL; | ||
| 262 | char *cmd = NULL; | ||
| 263 | char *str = NULL; | ||
| 264 | |||
| 265 | if (cmdstring == NULL) | ||
| 266 | return -1; | 415 | return -1; |
| 416 | } | ||
| 267 | 417 | ||
| 268 | /* initialize the structs */ | 418 | /* initialize the structs */ |
| 269 | if (out) | 419 | if (out) { |
| 270 | memset(out, 0, sizeof(output)); | 420 | memset(out, 0, sizeof(output)); |
| 271 | if (err) | 421 | } |
| 422 | if (err) { | ||
| 272 | memset(err, 0, sizeof(output)); | 423 | memset(err, 0, sizeof(output)); |
| 424 | } | ||
| 273 | 425 | ||
| 274 | /* make copy of command string so strtok() doesn't silently modify it */ | 426 | /* make copy of command string so strtok() doesn't silently modify it */ |
| 275 | /* (the calling program may want to access it later) */ | 427 | /* (the calling program may want to access it later) */ |
| 276 | cmdlen = strlen(cmdstring); | 428 | size_t cmdlen = strlen(cmdstring); |
| 277 | if ((cmd = malloc(cmdlen + 1)) == NULL) | 429 | char *cmd = NULL; |
| 430 | if ((cmd = malloc(cmdlen + 1)) == NULL) { | ||
| 278 | return -1; | 431 | return -1; |
| 432 | } | ||
| 279 | memcpy(cmd, cmdstring, cmdlen); | 433 | memcpy(cmd, cmdstring, cmdlen); |
| 280 | cmd[cmdlen] = '\0'; | 434 | cmd[cmdlen] = '\0'; |
| 281 | 435 | ||
| 282 | /* This is not a shell, so we don't handle "???" */ | 436 | /* This is not a shell, so we don't handle "???" */ |
| 283 | if (strstr(cmdstring, "\"")) | 437 | if (strstr(cmdstring, "\"")) { |
| 284 | return -1; | 438 | return -1; |
| 439 | } | ||
| 285 | 440 | ||
| 286 | /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ | 441 | /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ |
| 287 | if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) | 442 | if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) { |
| 288 | return -1; | 443 | return -1; |
| 444 | } | ||
| 289 | 445 | ||
| 290 | /* each arg must be whitespace-separated, so args can be a maximum | 446 | /* each arg must be whitespace-separated, so args can be a maximum |
| 291 | * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ | 447 | * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ |
| 292 | argc = (cmdlen >> 1) + 2; | 448 | int argc = (cmdlen >> 1) + 2; |
| 293 | argv = calloc((size_t)argc, sizeof(char *)); | 449 | char **argv = calloc((size_t)argc, sizeof(char *)); |
| 294 | 450 | ||
| 295 | if (argv == NULL) { | 451 | if (argv == NULL) { |
| 296 | printf("%s\n", _("Could not malloc argv array in popen()")); | 452 | printf("%s\n", _("Could not malloc argv array in popen()")); |
| @@ -298,14 +454,16 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { | |||
| 298 | } | 454 | } |
| 299 | 455 | ||
| 300 | /* get command arguments (stupidly, but fairly quickly) */ | 456 | /* get command arguments (stupidly, but fairly quickly) */ |
| 457 | int i = 0; | ||
| 301 | while (cmd) { | 458 | while (cmd) { |
| 302 | str = cmd; | 459 | char *str = cmd; |
| 303 | str += strspn(str, " \t\r\n"); /* trim any leading whitespace */ | 460 | str += strspn(str, " \t\r\n"); /* trim any leading whitespace */ |
| 304 | 461 | ||
| 305 | if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ | 462 | if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ |
| 306 | str++; | 463 | str++; |
| 307 | if (!strstr(str, "'")) | 464 | if (!strstr(str, "'")) { |
| 308 | return -1; /* balanced? */ | 465 | return -1; /* balanced? */ |
| 466 | } | ||
| 309 | cmd = 1 + strstr(str, "'"); | 467 | cmd = 1 + strstr(str, "'"); |
| 310 | str[strcspn(str, "'")] = 0; | 468 | str[strcspn(str, "'")] = 0; |
| 311 | } else { | 469 | } else { |
| @@ -317,8 +475,9 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { | |||
| 317 | } | 475 | } |
| 318 | } | 476 | } |
| 319 | 477 | ||
| 320 | if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) | 478 | if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) { |
| 321 | cmd = NULL; | 479 | cmd = NULL; |
| 480 | } | ||
| 322 | 481 | ||
| 323 | argv[i++] = str; | 482 | argv[i++] = str; |
| 324 | } | 483 | } |
| @@ -326,54 +485,199 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { | |||
| 326 | return cmd_run_array(argv, out, err, flags); | 485 | return cmd_run_array(argv, out, err, flags); |
| 327 | } | 486 | } |
| 328 | 487 | ||
| 329 | int cmd_run_array(char *const *argv, output *out, output *err, int flags) { | 488 | cmd_run_result cmd_run2(const char *cmd_string, int flags) { |
| 330 | int fd, pfd_out[2], pfd_err[2]; | 489 | cmd_run_result result = { |
| 490 | .cmd_error_code = 0, | ||
| 491 | .error_code = 0, | ||
| 492 | .err = | ||
| 493 | { | ||
| 494 | .buf = NULL, | ||
| 495 | .buflen = 0, | ||
| 496 | .line = NULL, | ||
| 497 | .lines = 0, | ||
| 498 | }, | ||
| 499 | .out = | ||
| 500 | { | ||
| 501 | .buf = NULL, | ||
| 502 | .buflen = 0, | ||
| 503 | .line = NULL, | ||
| 504 | .lines = 0, | ||
| 505 | }, | ||
| 506 | }; | ||
| 507 | |||
| 508 | if (cmd_string == NULL) { | ||
| 509 | result.error_code = -1; | ||
| 510 | return result; | ||
| 511 | } | ||
| 512 | |||
| 513 | /* make copy of command string so strtok() doesn't silently modify it */ | ||
| 514 | /* (the calling program may want to access it later) */ | ||
| 515 | char *cmd = strdup(cmd_string); | ||
| 516 | if (cmd == NULL) { | ||
| 517 | result.error_code = -1; | ||
| 518 | return result; | ||
| 519 | } | ||
| 520 | |||
| 521 | /* This is not a shell, so we don't handle "???" */ | ||
| 522 | if (strstr(cmd, "\"")) { | ||
| 523 | result.error_code = -1; | ||
| 524 | return result; | ||
| 525 | } | ||
| 526 | |||
| 527 | /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ | ||
| 528 | if (strstr(cmd, " ' ") || strstr(cmd, "'''")) { | ||
| 529 | result.error_code = -1; | ||
| 530 | return result; | ||
| 531 | } | ||
| 532 | |||
| 533 | /* each arg must be whitespace-separated, so args can be a maximum | ||
| 534 | * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ | ||
| 535 | size_t cmdlen = strlen(cmd_string); | ||
| 536 | size_t argc = (cmdlen >> 1) + 2; | ||
| 537 | char **argv = calloc(argc, sizeof(char *)); | ||
| 538 | |||
| 539 | if (argv == NULL) { | ||
| 540 | printf("%s\n", _("Could not malloc argv array in popen()")); | ||
| 541 | result.error_code = -1; | ||
| 542 | return result; | ||
| 543 | } | ||
| 331 | 544 | ||
| 545 | /* get command arguments (stupidly, but fairly quickly) */ | ||
| 546 | for (int i = 0; cmd; i++) { | ||
| 547 | char *str = cmd; | ||
| 548 | str += strspn(str, " \t\r\n"); /* trim any leading whitespace */ | ||
| 549 | |||
| 550 | if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ | ||
| 551 | str++; | ||
| 552 | if (!strstr(str, "'")) { | ||
| 553 | result.error_code = -1; | ||
| 554 | return result; /* balanced? */ | ||
| 555 | } | ||
| 556 | |||
| 557 | cmd = 1 + strstr(str, "'"); | ||
| 558 | str[strcspn(str, "'")] = 0; | ||
| 559 | } else { | ||
| 560 | if (strpbrk(str, " \t\r\n")) { | ||
| 561 | cmd = 1 + strpbrk(str, " \t\r\n"); | ||
| 562 | str[strcspn(str, " \t\r\n")] = 0; | ||
| 563 | } else { | ||
| 564 | cmd = NULL; | ||
| 565 | } | ||
| 566 | } | ||
| 567 | |||
| 568 | if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) { | ||
| 569 | cmd = NULL; | ||
| 570 | } | ||
| 571 | |||
| 572 | argv[i++] = str; | ||
| 573 | } | ||
| 574 | |||
| 575 | result = cmd_run_array2(argv, flags); | ||
| 576 | |||
| 577 | return result; | ||
| 578 | } | ||
| 579 | |||
| 580 | cmd_run_result cmd_run_array2(char *const *cmd, int flags) { | ||
| 581 | cmd_run_result result = { | ||
| 582 | .cmd_error_code = 0, | ||
| 583 | .error_code = 0, | ||
| 584 | .err = | ||
| 585 | { | ||
| 586 | .buf = NULL, | ||
| 587 | .buflen = 0, | ||
| 588 | .line = NULL, | ||
| 589 | .lines = 0, | ||
| 590 | }, | ||
| 591 | .out = | ||
| 592 | { | ||
| 593 | .buf = NULL, | ||
| 594 | .buflen = 0, | ||
| 595 | .line = NULL, | ||
| 596 | .lines = 0, | ||
| 597 | }, | ||
| 598 | }; | ||
| 599 | |||
| 600 | int_cmd_open_result cmd_open_result = _cmd_open2(cmd); | ||
| 601 | if (cmd_open_result.error_code != 0) { | ||
| 602 | // result.error_code = -1; | ||
| 603 | // return result; | ||
| 604 | // TODO properly handle this without dying | ||
| 605 | die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd[0]); | ||
| 606 | } | ||
| 607 | |||
| 608 | int file_descriptor = cmd_open_result.file_descriptor; | ||
| 609 | int pfd_out[2] = {cmd_open_result.stdout_pipe_fd[0], cmd_open_result.stdout_pipe_fd[1]}; | ||
| 610 | int pfd_err[2] = {cmd_open_result.stderr_pipe_fd[0], cmd_open_result.stderr_pipe_fd[1]}; | ||
| 611 | |||
| 612 | int_cmd_fetch_output2 tmp_stdout = _cmd_fetch_output2(pfd_out[0], flags); | ||
| 613 | result.out = tmp_stdout.output_container; | ||
| 614 | int_cmd_fetch_output2 tmp_stderr = _cmd_fetch_output2(pfd_err[0], flags); | ||
| 615 | result.err = tmp_stderr.output_container; | ||
| 616 | |||
| 617 | result.cmd_error_code = _cmd_close(file_descriptor); | ||
| 618 | return result; | ||
| 619 | } | ||
| 620 | |||
| 621 | int cmd_run_array(char *const *argv, output *out, output *err, int flags) { | ||
| 332 | /* initialize the structs */ | 622 | /* initialize the structs */ |
| 333 | if (out) | 623 | if (out) { |
| 334 | memset(out, 0, sizeof(output)); | 624 | memset(out, 0, sizeof(output)); |
| 335 | if (err) | 625 | } |
| 626 | if (err) { | ||
| 336 | memset(err, 0, sizeof(output)); | 627 | memset(err, 0, sizeof(output)); |
| 628 | } | ||
| 337 | 629 | ||
| 338 | if ((fd = _cmd_open(argv, pfd_out, pfd_err)) == -1) | 630 | int fd; |
| 631 | int pfd_out[2]; | ||
| 632 | int pfd_err[2]; | ||
| 633 | if ((fd = _cmd_open(argv, pfd_out, pfd_err)) == -1) { | ||
| 339 | die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]); | 634 | die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]); |
| 635 | } | ||
| 340 | 636 | ||
| 341 | if (out) | 637 | if (out) { |
| 342 | out->lines = _cmd_fetch_output(pfd_out[0], out, flags); | 638 | out->lines = _cmd_fetch_output(pfd_out[0], out, flags); |
| 343 | if (err) | 639 | } |
| 640 | if (err) { | ||
| 344 | err->lines = _cmd_fetch_output(pfd_err[0], err, flags); | 641 | err->lines = _cmd_fetch_output(pfd_err[0], err, flags); |
| 642 | } | ||
| 345 | 643 | ||
| 346 | return _cmd_close(fd); | 644 | return _cmd_close(fd); |
| 347 | } | 645 | } |
| 348 | 646 | ||
| 349 | int cmd_file_read(char *filename, output *out, int flags) { | 647 | int cmd_file_read(const char *filename, output *out, int flags) { |
| 350 | int fd; | 648 | int fd; |
| 351 | if (out) | 649 | if (out) { |
| 352 | memset(out, 0, sizeof(output)); | 650 | memset(out, 0, sizeof(output)); |
| 651 | } | ||
| 353 | 652 | ||
| 354 | if ((fd = open(filename, O_RDONLY)) == -1) { | 653 | if ((fd = open(filename, O_RDONLY)) == -1) { |
| 355 | die(STATE_UNKNOWN, _("Error opening %s: %s"), filename, strerror(errno)); | 654 | die(STATE_UNKNOWN, _("Error opening %s: %s"), filename, strerror(errno)); |
| 356 | } | 655 | } |
| 357 | 656 | ||
| 358 | if (out) | 657 | if (out) { |
| 359 | out->lines = _cmd_fetch_output(fd, out, flags); | 658 | out->lines = _cmd_fetch_output(fd, out, flags); |
| 659 | } | ||
| 360 | 660 | ||
| 361 | if (close(fd) == -1) | 661 | if (close(fd) == -1) { |
| 362 | die(STATE_UNKNOWN, _("Error closing %s: %s"), filename, strerror(errno)); | 662 | die(STATE_UNKNOWN, _("Error closing %s: %s"), filename, strerror(errno)); |
| 663 | } | ||
| 363 | 664 | ||
| 364 | return 0; | 665 | return 0; |
| 365 | } | 666 | } |
| 366 | 667 | ||
| 367 | void timeout_alarm_handler(int signo) { | 668 | void timeout_alarm_handler(int signo) { |
| 368 | if (signo == SIGALRM) { | 669 | if (signo == SIGALRM) { |
| 369 | printf(_("%s - Plugin timed out after %d seconds\n"), state_text(timeout_state), timeout_interval); | 670 | printf(_("%s - Plugin timed out after %d seconds\n"), state_text(timeout_state), |
| 671 | timeout_interval); | ||
| 370 | 672 | ||
| 371 | long maxfd = mp_open_max(); | 673 | long maxfd = mp_open_max(); |
| 372 | if (_cmd_pids) | 674 | if (_cmd_pids) { |
| 373 | for (long int i = 0; i < maxfd; i++) { | 675 | for (long int i = 0; i < maxfd; i++) { |
| 374 | if (_cmd_pids[i] != 0) | 676 | if (_cmd_pids[i] != 0) { |
| 375 | kill(_cmd_pids[i], SIGKILL); | 677 | kill(_cmd_pids[i], SIGKILL); |
| 678 | } | ||
| 376 | } | 679 | } |
| 680 | } | ||
| 377 | 681 | ||
| 378 | exit(timeout_state); | 682 | exit(timeout_state); |
| 379 | } | 683 | } |
diff --git a/lib/utils_cmd.h b/lib/utils_cmd.h index d00069c9..04a624b8 100644 --- a/lib/utils_cmd.h +++ b/lib/utils_cmd.h | |||
| @@ -5,22 +5,30 @@ | |||
| 5 | * Header file for Monitoring Plugins utils_cmd.c | 5 | * Header file for Monitoring Plugins utils_cmd.c |
| 6 | * | 6 | * |
| 7 | */ | 7 | */ |
| 8 | #include "../config.h" | ||
| 9 | #include <stddef.h> | ||
| 8 | 10 | ||
| 9 | /** types **/ | 11 | /** types **/ |
| 10 | struct output { | 12 | typedef struct { |
| 11 | char *buf; /* output buffer */ | 13 | char *buf; /* output buffer */ |
| 12 | size_t buflen; /* output buffer content length */ | 14 | size_t buflen; /* output buffer content length */ |
| 13 | char **line; /* array of lines (points to buf) */ | 15 | char **line; /* array of lines (points to buf) */ |
| 14 | size_t *lens; /* string lengths */ | ||
| 15 | size_t lines; /* lines of output */ | 16 | size_t lines; /* lines of output */ |
| 16 | }; | 17 | } output; |
| 17 | |||
| 18 | typedef struct output output; | ||
| 19 | 18 | ||
| 20 | /** prototypes **/ | 19 | /** prototypes **/ |
| 21 | int cmd_run(const char *, output *, output *, int); | 20 | int cmd_run(const char *, output *, output *, int); |
| 22 | int cmd_run_array(char *const *, output *, output *, int); | 21 | int cmd_run_array(char *const *, output *, output *, int); |
| 23 | int cmd_file_read(char *, output *, int); | 22 | int cmd_file_read(const char *, output *, int); |
| 23 | |||
| 24 | typedef struct { | ||
| 25 | int error_code; | ||
| 26 | int cmd_error_code; | ||
| 27 | output out; | ||
| 28 | output err; | ||
| 29 | } cmd_run_result; | ||
| 30 | cmd_run_result cmd_run2(const char *cmd, int flags); | ||
| 31 | cmd_run_result cmd_run_array2(char * const *cmd, int flags); | ||
| 24 | 32 | ||
| 25 | /* only multi-threaded plugins need to bother with this */ | 33 | /* only multi-threaded plugins need to bother with this */ |
| 26 | void cmd_init(void); | 34 | void cmd_init(void); |
diff --git a/lib/utils_disk.c b/lib/utils_disk.c deleted file mode 100644 index 2b761f5e..00000000 --- a/lib/utils_disk.c +++ /dev/null | |||
| @@ -1,255 +0,0 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Library for check_disk | ||
| 4 | * | ||
| 5 | * License: GPL | ||
| 6 | * Copyright (c) 1999-2024 Monitoring Plugins Development Team | ||
| 7 | * | ||
| 8 | * Description: | ||
| 9 | * | ||
| 10 | * This file contains utilities for check_disk. These are tested by libtap | ||
| 11 | * | ||
| 12 | * | ||
| 13 | * This program is free software: you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation, either version 3 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 25 | * | ||
| 26 | * | ||
| 27 | *****************************************************************************/ | ||
| 28 | |||
| 29 | #include "common.h" | ||
| 30 | #include "utils_disk.h" | ||
| 31 | #include "gl/fsusage.h" | ||
| 32 | #include <string.h> | ||
| 33 | |||
| 34 | void np_add_name(struct name_list **list, const char *name) { | ||
| 35 | struct name_list *new_entry; | ||
| 36 | new_entry = (struct name_list *)malloc(sizeof *new_entry); | ||
| 37 | new_entry->name = (char *)name; | ||
| 38 | new_entry->next = *list; | ||
| 39 | *list = new_entry; | ||
| 40 | } | ||
| 41 | |||
| 42 | /* @brief Initialises a new regex at the begin of list via regcomp(3) | ||
| 43 | * | ||
| 44 | * @details if the regex fails to compile the error code of regcomp(3) is returned | ||
| 45 | * and list is not modified, otherwise list is modified to point to the new | ||
| 46 | * element | ||
| 47 | * @param list Pointer to a linked list of regex_list elements | ||
| 48 | * @param regex the string containing the regex which should be inserted into the list | ||
| 49 | * @param clags the cflags parameter for regcomp(3) | ||
| 50 | */ | ||
| 51 | int np_add_regex(struct regex_list **list, const char *regex, int cflags) { | ||
| 52 | struct regex_list *new_entry = (struct regex_list *)malloc(sizeof *new_entry); | ||
| 53 | |||
| 54 | if (new_entry == NULL) { | ||
| 55 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 56 | } | ||
| 57 | |||
| 58 | int regcomp_result = regcomp(&new_entry->regex, regex, cflags); | ||
| 59 | |||
| 60 | if (!regcomp_result) { | ||
| 61 | // regcomp succeeded | ||
| 62 | new_entry->next = *list; | ||
| 63 | *list = new_entry; | ||
| 64 | |||
| 65 | return 0; | ||
| 66 | } else { | ||
| 67 | // regcomp failed | ||
| 68 | free(new_entry); | ||
| 69 | |||
| 70 | return regcomp_result; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | /* Initialises a new parameter at the end of list */ | ||
| 75 | struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name) { | ||
| 76 | struct parameter_list *current = *list; | ||
| 77 | struct parameter_list *new_path; | ||
| 78 | new_path = (struct parameter_list *)malloc(sizeof *new_path); | ||
| 79 | new_path->name = (char *)malloc(strlen(name) + 1); | ||
| 80 | new_path->best_match = NULL; | ||
| 81 | new_path->name_next = NULL; | ||
| 82 | new_path->name_prev = NULL; | ||
| 83 | new_path->freespace_bytes = NULL; | ||
| 84 | new_path->freespace_units = NULL; | ||
| 85 | new_path->freespace_percent = NULL; | ||
| 86 | new_path->usedspace_bytes = NULL; | ||
| 87 | new_path->usedspace_units = NULL; | ||
| 88 | new_path->usedspace_percent = NULL; | ||
| 89 | new_path->usedinodes_percent = NULL; | ||
| 90 | new_path->freeinodes_percent = NULL; | ||
| 91 | new_path->group = NULL; | ||
| 92 | new_path->dfree_pct = -1; | ||
| 93 | new_path->dused_pct = -1; | ||
| 94 | new_path->total = 0; | ||
| 95 | new_path->available = 0; | ||
| 96 | new_path->available_to_root = 0; | ||
| 97 | new_path->used = 0; | ||
| 98 | new_path->dused_units = 0; | ||
| 99 | new_path->dfree_units = 0; | ||
| 100 | new_path->dtotal_units = 0; | ||
| 101 | new_path->inodes_total = 0; | ||
| 102 | new_path->inodes_free = 0; | ||
| 103 | new_path->inodes_free_to_root = 0; | ||
| 104 | new_path->inodes_used = 0; | ||
| 105 | new_path->dused_inodes_percent = 0; | ||
| 106 | new_path->dfree_inodes_percent = 0; | ||
| 107 | |||
| 108 | strcpy(new_path->name, name); | ||
| 109 | |||
| 110 | if (current == NULL) { | ||
| 111 | *list = new_path; | ||
| 112 | new_path->name_prev = NULL; | ||
| 113 | } else { | ||
| 114 | while (current->name_next) { | ||
| 115 | current = current->name_next; | ||
| 116 | } | ||
| 117 | current->name_next = new_path; | ||
| 118 | new_path->name_prev = current; | ||
| 119 | } | ||
| 120 | return new_path; | ||
| 121 | } | ||
| 122 | |||
| 123 | /* Delete a given parameter from list and return pointer to next element*/ | ||
| 124 | struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev) { | ||
| 125 | if (item == NULL) { | ||
| 126 | return NULL; | ||
| 127 | } | ||
| 128 | struct parameter_list *next; | ||
| 129 | |||
| 130 | if (item->name_next) | ||
| 131 | next = item->name_next; | ||
| 132 | else | ||
| 133 | next = NULL; | ||
| 134 | |||
| 135 | if (next) | ||
| 136 | next->name_prev = prev; | ||
| 137 | |||
| 138 | if (prev) | ||
| 139 | prev->name_next = next; | ||
| 140 | |||
| 141 | if (item->name) { | ||
| 142 | free(item->name); | ||
| 143 | } | ||
| 144 | free(item); | ||
| 145 | |||
| 146 | return next; | ||
| 147 | } | ||
| 148 | |||
| 149 | /* returns a pointer to the struct found in the list */ | ||
| 150 | struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name) { | ||
| 151 | struct parameter_list *temp_list; | ||
| 152 | for (temp_list = list; temp_list; temp_list = temp_list->name_next) { | ||
| 153 | if (!strcmp(temp_list->name, name)) | ||
| 154 | return temp_list; | ||
| 155 | } | ||
| 156 | |||
| 157 | return NULL; | ||
| 158 | } | ||
| 159 | |||
| 160 | void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact) { | ||
| 161 | struct parameter_list *d; | ||
| 162 | for (d = desired; d; d = d->name_next) { | ||
| 163 | if (!d->best_match) { | ||
| 164 | struct mount_entry *me; | ||
| 165 | size_t name_len = strlen(d->name); | ||
| 166 | size_t best_match_len = 0; | ||
| 167 | struct mount_entry *best_match = NULL; | ||
| 168 | struct fs_usage fsp; | ||
| 169 | |||
| 170 | /* set best match if path name exactly matches a mounted device name */ | ||
| 171 | for (me = mount_list; me; me = me->me_next) { | ||
| 172 | if (strcmp(me->me_devname, d->name) == 0) { | ||
| 173 | if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { | ||
| 174 | best_match = me; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | /* set best match by directory name if no match was found by devname */ | ||
| 180 | if (!best_match) { | ||
| 181 | for (me = mount_list; me; me = me->me_next) { | ||
| 182 | size_t len = strlen(me->me_mountdir); | ||
| 183 | if ((!exact && | ||
| 184 | (best_match_len <= len && len <= name_len && (len == 1 || strncmp(me->me_mountdir, d->name, len) == 0))) || | ||
| 185 | (exact && strcmp(me->me_mountdir, d->name) == 0)) { | ||
| 186 | if (get_fs_usage(me->me_mountdir, me->me_devname, &fsp) >= 0) { | ||
| 187 | best_match = me; | ||
| 188 | best_match_len = len; | ||
| 189 | } | ||
| 190 | } | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | if (best_match) { | ||
| 195 | d->best_match = best_match; | ||
| 196 | } else { | ||
| 197 | d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ | ||
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | /* Returns true if name is in list */ | ||
| 204 | bool np_find_name(struct name_list *list, const char *name) { | ||
| 205 | const struct name_list *n; | ||
| 206 | |||
| 207 | if (list == NULL || name == NULL) { | ||
| 208 | return false; | ||
| 209 | } | ||
| 210 | for (n = list; n; n = n->next) { | ||
| 211 | if (!strcmp(name, n->name)) { | ||
| 212 | return true; | ||
| 213 | } | ||
| 214 | } | ||
| 215 | return false; | ||
| 216 | } | ||
| 217 | |||
| 218 | /* Returns true if name is in list */ | ||
| 219 | bool np_find_regmatch(struct regex_list *list, const char *name) { | ||
| 220 | int len; | ||
| 221 | regmatch_t m; | ||
| 222 | |||
| 223 | if (name == NULL) { | ||
| 224 | return false; | ||
| 225 | } | ||
| 226 | |||
| 227 | len = strlen(name); | ||
| 228 | |||
| 229 | for (; list; list = list->next) { | ||
| 230 | /* Emulate a full match as if surrounded with ^( )$ | ||
| 231 | by checking whether the match spans the whole name */ | ||
| 232 | if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) { | ||
| 233 | return true; | ||
| 234 | } | ||
| 235 | } | ||
| 236 | |||
| 237 | return false; | ||
| 238 | } | ||
| 239 | |||
| 240 | bool np_seen_name(struct name_list *list, const char *name) { | ||
| 241 | const struct name_list *s; | ||
| 242 | for (s = list; s; s = s->next) { | ||
| 243 | if (!strcmp(s->name, name)) { | ||
| 244 | return true; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | return false; | ||
| 248 | } | ||
| 249 | |||
| 250 | bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { | ||
| 251 | if (regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0 || regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0) { | ||
| 252 | return true; | ||
| 253 | } | ||
| 254 | return false; | ||
| 255 | } | ||
diff --git a/lib/utils_disk.h b/lib/utils_disk.h deleted file mode 100644 index c5e81dc1..00000000 --- a/lib/utils_disk.h +++ /dev/null | |||
| @@ -1,48 +0,0 @@ | |||
| 1 | /* Header file for utils_disk */ | ||
| 2 | |||
| 3 | #include "mountlist.h" | ||
| 4 | #include "utils_base.h" | ||
| 5 | #include "regex.h" | ||
| 6 | |||
| 7 | struct name_list { | ||
| 8 | char *name; | ||
| 9 | struct name_list *next; | ||
| 10 | }; | ||
| 11 | |||
| 12 | struct regex_list { | ||
| 13 | regex_t regex; | ||
| 14 | struct regex_list *next; | ||
| 15 | }; | ||
| 16 | |||
| 17 | struct parameter_list { | ||
| 18 | char *name; | ||
| 19 | thresholds *freespace_bytes; | ||
| 20 | thresholds *freespace_units; | ||
| 21 | thresholds *freespace_percent; | ||
| 22 | thresholds *usedspace_bytes; | ||
| 23 | thresholds *usedspace_units; | ||
| 24 | thresholds *usedspace_percent; | ||
| 25 | thresholds *usedinodes_percent; | ||
| 26 | thresholds *freeinodes_percent; | ||
| 27 | char *group; | ||
| 28 | struct mount_entry *best_match; | ||
| 29 | struct parameter_list *name_next; | ||
| 30 | struct parameter_list *name_prev; | ||
| 31 | uintmax_t total, available, available_to_root, used, inodes_free, inodes_free_to_root, inodes_used, inodes_total; | ||
| 32 | double dfree_pct, dused_pct; | ||
| 33 | uint64_t dused_units, dfree_units, dtotal_units; | ||
| 34 | double dused_inodes_percent, dfree_inodes_percent; | ||
| 35 | }; | ||
| 36 | |||
| 37 | void np_add_name(struct name_list **list, const char *name); | ||
| 38 | bool np_find_name(struct name_list *list, const char *name); | ||
| 39 | bool np_seen_name(struct name_list *list, const char *name); | ||
| 40 | int np_add_regex(struct regex_list **list, const char *regex, int cflags); | ||
| 41 | bool np_find_regmatch(struct regex_list *list, const char *name); | ||
| 42 | struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); | ||
| 43 | struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); | ||
| 44 | struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); | ||
| 45 | |||
| 46 | int search_parameter_list(struct parameter_list *list, const char *name); | ||
| 47 | void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, bool exact); | ||
| 48 | bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re); | ||
diff --git a/lib/utils_tcp.c b/lib/utils_tcp.c index daae1d54..a82d5a3f 100644 --- a/lib/utils_tcp.c +++ b/lib/utils_tcp.c | |||
| @@ -26,28 +26,35 @@ | |||
| 26 | * | 26 | * |
| 27 | *****************************************************************************/ | 27 | *****************************************************************************/ |
| 28 | 28 | ||
| 29 | #include "common.h" | 29 | #include "../config.h" |
| 30 | #include "utils_tcp.h" | 30 | #include "utils_tcp.h" |
| 31 | #include <stdio.h> | ||
| 32 | #include <string.h> | ||
| 31 | 33 | ||
| 32 | #define VERBOSE(message) \ | 34 | #define VERBOSE(message) \ |
| 33 | do { \ | 35 | do { \ |
| 34 | if (flags & NP_MATCH_VERBOSE) \ | 36 | if (flags & NP_MATCH_VERBOSE) \ |
| 35 | puts(message); \ | 37 | puts(message); \ |
| 36 | } while (0) | 38 | } while (0) |
| 37 | 39 | ||
| 38 | enum np_match_result np_expect_match(char *status, char **server_expect, int expect_count, int flags) { | 40 | enum np_match_result np_expect_match(char *status, char **server_expect, int expect_count, |
| 39 | int i, match = 0, partial = 0; | 41 | int flags) { |
| 40 | 42 | int match = 0; | |
| 41 | for (i = 0; i < expect_count; i++) { | 43 | int partial = 0; |
| 42 | if (flags & NP_MATCH_VERBOSE) | 44 | for (int i = 0; i < expect_count; i++) { |
| 43 | printf("looking for [%s] %s [%s]\n", server_expect[i], (flags & NP_MATCH_EXACT) ? "in beginning of" : "anywhere in", status); | 45 | if (flags & NP_MATCH_VERBOSE) { |
| 46 | printf("looking for [%s] %s [%s]\n", server_expect[i], | ||
| 47 | (flags & NP_MATCH_EXACT) ? "in beginning of" : "anywhere in", status); | ||
| 48 | } | ||
| 44 | 49 | ||
| 45 | if (flags & NP_MATCH_EXACT) { | 50 | if (flags & NP_MATCH_EXACT) { |
| 46 | if (strncmp(status, server_expect[i], strlen(server_expect[i])) == 0) { | 51 | if (strncmp(status, server_expect[i], strlen(server_expect[i])) == 0) { |
| 47 | VERBOSE("found it"); | 52 | VERBOSE("found it"); |
| 48 | match++; | 53 | match++; |
| 49 | continue; | 54 | continue; |
| 50 | } else if (strncmp(status, server_expect[i], strlen(status)) == 0) { | 55 | } |
| 56 | |||
| 57 | if (strncmp(status, server_expect[i], strlen(status)) == 0) { | ||
| 51 | VERBOSE("found a substring"); | 58 | VERBOSE("found a substring"); |
| 52 | partial++; | 59 | partial++; |
| 53 | continue; | 60 | continue; |
| @@ -60,10 +67,12 @@ enum np_match_result np_expect_match(char *status, char **server_expect, int exp | |||
| 60 | VERBOSE("couldn't find it"); | 67 | VERBOSE("couldn't find it"); |
| 61 | } | 68 | } |
| 62 | 69 | ||
| 63 | if ((flags & NP_MATCH_ALL && match == expect_count) || (!(flags & NP_MATCH_ALL) && match >= 1)) | 70 | if ((flags & NP_MATCH_ALL && match == expect_count) || |
| 71 | (!(flags & NP_MATCH_ALL) && match >= 1)) { | ||
| 64 | return NP_MATCH_SUCCESS; | 72 | return NP_MATCH_SUCCESS; |
| 65 | else if (partial > 0 || !(flags & NP_MATCH_EXACT)) | 73 | } |
| 74 | if (partial > 0 || !(flags & NP_MATCH_EXACT)) { | ||
| 66 | return NP_MATCH_RETRY; | 75 | return NP_MATCH_RETRY; |
| 67 | else | 76 | } |
| 68 | return NP_MATCH_FAILURE; | 77 | return NP_MATCH_FAILURE; |
| 69 | } | 78 | } |
diff --git a/lib/utils_tcp.h b/lib/utils_tcp.h index d5999e9b..e5cdbb82 100644 --- a/lib/utils_tcp.h +++ b/lib/utils_tcp.h | |||
| @@ -11,9 +11,11 @@ | |||
| 11 | * server. | 11 | * server. |
| 12 | */ | 12 | */ |
| 13 | enum np_match_result { | 13 | enum np_match_result { |
| 14 | NP_MATCH_NONE, | ||
| 14 | NP_MATCH_FAILURE, | 15 | NP_MATCH_FAILURE, |
| 15 | NP_MATCH_SUCCESS, | 16 | NP_MATCH_SUCCESS, |
| 16 | NP_MATCH_RETRY | 17 | NP_MATCH_RETRY |
| 17 | }; | 18 | }; |
| 18 | 19 | ||
| 19 | enum np_match_result np_expect_match(char *status, char **server_expect, int server_expect_count, int flags); | 20 | enum np_match_result np_expect_match(char *status, char **server_expect, int server_expect_count, |
| 21 | int flags); | ||
diff --git a/plugins-root/Makefile.am b/plugins-root/Makefile.am index a80229e2..b6342909 100644 --- a/plugins-root/Makefile.am +++ b/plugins-root/Makefile.am | |||
| @@ -24,7 +24,9 @@ noinst_PROGRAMS = check_dhcp check_icmp @EXTRAS_ROOT@ | |||
| 24 | 24 | ||
| 25 | EXTRA_PROGRAMS = pst3 | 25 | EXTRA_PROGRAMS = pst3 |
| 26 | 26 | ||
| 27 | EXTRA_DIST = t pst3.c | 27 | EXTRA_DIST = t pst3.c \ |
| 28 | check_icmp.d \ | ||
| 29 | check_dhcp.d | ||
| 28 | 30 | ||
| 29 | BASEOBJS = ../plugins/utils.o ../lib/libmonitoringplug.a ../gl/libgnu.a | 31 | BASEOBJS = ../plugins/utils.o ../lib/libmonitoringplug.a ../gl/libgnu.a |
| 30 | NETOBJS = ../plugins/netutils.o $(BASEOBJS) $(EXTRA_NETOBJS) | 32 | NETOBJS = ../plugins/netutils.o $(BASEOBJS) $(EXTRA_NETOBJS) |
| @@ -82,6 +84,7 @@ install-exec-local: $(noinst_PROGRAMS) | |||
| 82 | # the actual targets | 84 | # the actual targets |
| 83 | check_dhcp_LDADD = @LTLIBINTL@ $(NETLIBS) $(LIB_CRYPTO) | 85 | check_dhcp_LDADD = @LTLIBINTL@ $(NETLIBS) $(LIB_CRYPTO) |
| 84 | check_icmp_LDADD = @LTLIBINTL@ $(NETLIBS) $(SOCKETLIBS) $(LIB_CRYPTO) | 86 | check_icmp_LDADD = @LTLIBINTL@ $(NETLIBS) $(SOCKETLIBS) $(LIB_CRYPTO) |
| 87 | check_icmp_SOURCES = check_icmp.c check_icmp.d/check_icmp_helpers.c | ||
| 85 | 88 | ||
| 86 | # -m64 needed at compiler and linker phase | 89 | # -m64 needed at compiler and linker phase |
| 87 | pst3_CFLAGS = @PST3CFLAGS@ | 90 | pst3_CFLAGS = @PST3CFLAGS@ |
| @@ -89,7 +92,7 @@ pst3_LDFLAGS = @PST3CFLAGS@ | |||
| 89 | # pst3 must not use monitoringplug/gnulib includes! | 92 | # pst3 must not use monitoringplug/gnulib includes! |
| 90 | pst3_CPPFLAGS = | 93 | pst3_CPPFLAGS = |
| 91 | 94 | ||
| 92 | check_dhcp_DEPENDENCIES = check_dhcp.c $(NETOBJS) $(DEPLIBS) | 95 | check_dhcp_DEPENDENCIES = check_dhcp.c $(NETOBJS) $(DEPLIBS) |
| 93 | check_icmp_DEPENDENCIES = check_icmp.c $(NETOBJS) | 96 | check_icmp_DEPENDENCIES = check_icmp.c $(NETOBJS) |
| 94 | 97 | ||
| 95 | clean-local: | 98 | clean-local: |
diff --git a/plugins-root/check_dhcp.c b/plugins-root/check_dhcp.c index 6802232e..9a96547f 100644 --- a/plugins-root/check_dhcp.c +++ b/plugins-root/check_dhcp.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org) | 6 | * Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org) |
| 7 | * Copyright (c) 2001-2023 Monitoring Plugins Development Team | 7 | * Copyright (c) 2001-2025 Monitoring Plugins Development Team |
| 8 | * | 8 | * |
| 9 | * Description: | 9 | * Description: |
| 10 | * | 10 | * |
| @@ -34,13 +34,17 @@ | |||
| 34 | *****************************************************************************/ | 34 | *****************************************************************************/ |
| 35 | 35 | ||
| 36 | const char *progname = "check_dhcp"; | 36 | const char *progname = "check_dhcp"; |
| 37 | const char *copyright = "2001-2024"; | 37 | const char *copyright = "2001-2025"; |
| 38 | const char *email = "devel@monitoring-plugins.org"; | 38 | const char *email = "devel@monitoring-plugins.org"; |
| 39 | 39 | ||
| 40 | #include "common.h" | 40 | #include "../plugins/common.h" |
| 41 | #include "netutils.h" | 41 | #include "../plugins/utils.h" |
| 42 | #include "utils.h" | 42 | #include "./check_dhcp.d/config.h" |
| 43 | #include "../lib/output.h" | ||
| 44 | #include "../lib/utils_base.h" | ||
| 43 | 45 | ||
| 46 | #include "states.h" | ||
| 47 | #include <stdint.h> | ||
| 44 | #include <ctype.h> | 48 | #include <ctype.h> |
| 45 | #include <stdio.h> | 49 | #include <stdio.h> |
| 46 | #include <stdlib.h> | 50 | #include <stdlib.h> |
| @@ -111,8 +115,9 @@ static long mac_addr_dlpi(const char *, int, u_char *); | |||
| 111 | 115 | ||
| 112 | /**** Common definitions ****/ | 116 | /**** Common definitions ****/ |
| 113 | 117 | ||
| 114 | #define OK 0 | 118 | #define OK 0 |
| 115 | #define ERROR -1 | 119 | #define ERROR -1 |
| 120 | #define MAC_ADDR_LEN 6 | ||
| 116 | 121 | ||
| 117 | /**** DHCP definitions ****/ | 122 | /**** DHCP definitions ****/ |
| 118 | 123 | ||
| @@ -122,17 +127,17 @@ static long mac_addr_dlpi(const char *, int, u_char *); | |||
| 122 | #define MAX_DHCP_OPTIONS_LENGTH 312 | 127 | #define MAX_DHCP_OPTIONS_LENGTH 312 |
| 123 | 128 | ||
| 124 | typedef struct dhcp_packet_struct { | 129 | typedef struct dhcp_packet_struct { |
| 125 | uint8_t op; /* packet type */ | 130 | uint8_t op; /* packet type */ |
| 126 | uint8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ | 131 | uint8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ |
| 127 | uint8_t hlen; /* length of hardware address (of this machine) */ | 132 | uint8_t hlen; /* length of hardware address (of this machine) */ |
| 128 | uint8_t hops; /* hops */ | 133 | uint8_t hops; /* hops */ |
| 129 | uint32_t xid; /* random transaction id number - chosen by this machine */ | 134 | uint32_t xid; /* random transaction id number - chosen by this machine */ |
| 130 | uint16_t secs; /* seconds used in timing */ | 135 | uint16_t secs; /* seconds used in timing */ |
| 131 | uint16_t flags; /* flags */ | 136 | uint16_t flags; /* flags */ |
| 132 | struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ | 137 | struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ |
| 133 | struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ | 138 | struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ |
| 134 | struct in_addr siaddr; /* IP address of next server */ | 139 | struct in_addr siaddr; /* IP address of next server */ |
| 135 | struct in_addr giaddr; /* IP address of DHCP relay */ | 140 | struct in_addr giaddr; /* IP address of DHCP relay */ |
| 136 | unsigned char chaddr[MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ | 141 | unsigned char chaddr[MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ |
| 137 | char sname[MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ | 142 | char sname[MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ |
| 138 | char file[MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ | 143 | char file[MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ |
| @@ -149,12 +154,6 @@ typedef struct dhcp_offer_struct { | |||
| 149 | struct dhcp_offer_struct *next; | 154 | struct dhcp_offer_struct *next; |
| 150 | } dhcp_offer; | 155 | } dhcp_offer; |
| 151 | 156 | ||
| 152 | typedef struct requested_server_struct { | ||
| 153 | struct in_addr server_address; | ||
| 154 | bool answered; | ||
| 155 | struct requested_server_struct *next; | ||
| 156 | } requested_server; | ||
| 157 | |||
| 158 | #define BOOTREQUEST 1 | 157 | #define BOOTREQUEST 1 |
| 159 | #define BOOTREPLY 2 | 158 | #define BOOTREPLY 2 |
| 160 | 159 | ||
| @@ -186,65 +185,69 @@ typedef struct requested_server_struct { | |||
| 186 | #define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */ | 185 | #define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */ |
| 187 | #define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ | 186 | #define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ |
| 188 | 187 | ||
| 189 | static bool unicast = false; /* unicast mode: mimic a DHCP relay */ | ||
| 190 | static bool exclusive = false; /* exclusive mode aka "rogue DHCP server detection" */ | ||
| 191 | static struct in_addr my_ip; /* our address (required for relay) */ | ||
| 192 | static struct in_addr dhcp_ip; /* server to query (if in unicast mode) */ | ||
| 193 | static unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH] = ""; | ||
| 194 | static unsigned char *user_specified_mac = NULL; | ||
| 195 | |||
| 196 | static char network_interface_name[IFNAMSIZ] = "eth0"; | ||
| 197 | |||
| 198 | static uint32_t packet_xid = 0; | ||
| 199 | |||
| 200 | static uint32_t dhcp_lease_time = 0; | ||
| 201 | static uint32_t dhcp_renewal_time = 0; | ||
| 202 | static uint32_t dhcp_rebinding_time = 0; | ||
| 203 | |||
| 204 | static int dhcpoffer_timeout = 2; | ||
| 205 | |||
| 206 | static dhcp_offer *dhcp_offer_list = NULL; | ||
| 207 | static requested_server *requested_server_list = NULL; | ||
| 208 | |||
| 209 | static int valid_responses = 0; /* number of valid DHCPOFFERs we received */ | ||
| 210 | static int requested_servers = 0; | ||
| 211 | static int requested_responses = 0; | ||
| 212 | |||
| 213 | static bool request_specific_address = false; | ||
| 214 | static bool received_requested_address = false; | ||
| 215 | static int verbose = 0; | 188 | static int verbose = 0; |
| 216 | static struct in_addr requested_address; | ||
| 217 | 189 | ||
| 218 | static int process_arguments(int, char **); | 190 | typedef struct process_arguments_wrapper { |
| 219 | static int call_getopt(int, char **); | 191 | int error; |
| 220 | static int validate_arguments(int); | 192 | check_dhcp_config config; |
| 193 | } process_arguments_wrapper; | ||
| 194 | |||
| 195 | static process_arguments_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 221 | void print_usage(void); | 196 | void print_usage(void); |
| 222 | static void print_help(void); | 197 | static void print_help(void); |
| 223 | 198 | ||
| 224 | static void resolve_host(const char *in, struct in_addr *out); | 199 | static void resolve_host(const char * /*in*/, struct in_addr * /*out*/); |
| 225 | static unsigned char *mac_aton(const char *); | 200 | static unsigned char *mac_aton(const char * /*string*/); |
| 226 | static void print_hardware_address(const unsigned char *); | 201 | static void print_hardware_address(const unsigned char * /*address*/); |
| 227 | static int get_hardware_address(int, char *); | 202 | static int get_hardware_address(int /*sock*/, char * /*interface_name*/, |
| 228 | static int get_ip_address(int, char *); | 203 | unsigned char *client_hardware_address); |
| 229 | 204 | ||
| 230 | static int send_dhcp_discover(int); | 205 | typedef struct get_ip_address_wrapper { |
| 231 | static int get_dhcp_offer(int); | 206 | int error; |
| 232 | 207 | struct in_addr my_ip; | |
| 233 | static int get_results(void); | 208 | } get_ip_address_wrapper; |
| 234 | 209 | static get_ip_address_wrapper get_ip_address(int /*sock*/, char * /*interface_name*/); | |
| 235 | static int add_dhcp_offer(struct in_addr, dhcp_packet *); | 210 | |
| 236 | static int free_dhcp_offer_list(void); | 211 | typedef struct send_dhcp_discover_wrapper { |
| 237 | static int free_requested_server_list(void); | 212 | int error; |
| 238 | 213 | uint32_t packet_xid; | |
| 239 | static int create_dhcp_socket(void); | 214 | } send_dhcp_discover_wrapper; |
| 240 | static int close_dhcp_socket(int); | 215 | static send_dhcp_discover_wrapper |
| 241 | static int send_dhcp_packet(void *, int, int, struct sockaddr_in *); | 216 | send_dhcp_discover(int socket, bool unicast, struct in_addr dhcp_ip, |
| 242 | static int receive_dhcp_packet(void *, int, int, int, struct sockaddr_in *); | 217 | struct in_addr requested_address, bool request_specific_address, |
| 218 | struct in_addr my_ip, unsigned char *client_hardware_address); | ||
| 219 | typedef struct get_dhcp_offer_wrapper { | ||
| 220 | int error; | ||
| 221 | int valid_responses; | ||
| 222 | dhcp_offer *dhcp_offer_list; | ||
| 223 | } get_dhcp_offer_wrapper; | ||
| 224 | static get_dhcp_offer_wrapper get_dhcp_offer(int /*sock*/, int dhcpoffer_timeout, | ||
| 225 | uint32_t packet_xid, dhcp_offer *dhcp_offer_list, | ||
| 226 | const unsigned char *client_hardware_address); | ||
| 227 | |||
| 228 | static mp_subcheck get_results(bool exclusive, int requested_servers, | ||
| 229 | struct in_addr requested_address, bool request_specific_address, | ||
| 230 | requested_server *requested_server_list, int valid_responses, | ||
| 231 | dhcp_offer *dhcp_offer_list); | ||
| 232 | |||
| 233 | typedef struct add_dhcp_offer_wrapper { | ||
| 234 | int error; | ||
| 235 | dhcp_offer *dhcp_offer_list; | ||
| 236 | } add_dhcp_offer_wrapper; | ||
| 237 | static add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr /*source*/, | ||
| 238 | dhcp_packet * /*offer_packet*/, | ||
| 239 | dhcp_offer *dhcp_offer_list); | ||
| 240 | static int free_dhcp_offer_list(dhcp_offer *dhcp_offer_list); | ||
| 241 | static int free_requested_server_list(requested_server *requested_server_list); | ||
| 242 | |||
| 243 | static int create_dhcp_socket(bool /*unicast*/, char *network_interface_name); | ||
| 244 | static int close_dhcp_socket(int /*sock*/); | ||
| 245 | static int send_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/, | ||
| 246 | struct sockaddr_in * /*dest*/); | ||
| 247 | static int receive_dhcp_packet(void * /*buffer*/, int /*buffer_size*/, int /*sock*/, | ||
| 248 | int /*timeout*/, struct sockaddr_in * /*address*/); | ||
| 243 | 249 | ||
| 244 | int main(int argc, char **argv) { | 250 | int main(int argc, char **argv) { |
| 245 | int dhcp_socket; | ||
| 246 | int result = STATE_UNKNOWN; | ||
| 247 | |||
| 248 | setlocale(LC_ALL, ""); | 251 | setlocale(LC_ALL, ""); |
| 249 | bindtextdomain(PACKAGE, LOCALEDIR); | 252 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 250 | textdomain(PACKAGE); | 253 | textdomain(PACKAGE); |
| @@ -252,43 +255,84 @@ int main(int argc, char **argv) { | |||
| 252 | /* Parse extra opts if any */ | 255 | /* Parse extra opts if any */ |
| 253 | argv = np_extra_opts(&argc, argv, progname); | 256 | argv = np_extra_opts(&argc, argv, progname); |
| 254 | 257 | ||
| 255 | if (process_arguments(argc, argv) != OK) { | 258 | process_arguments_wrapper tmp = process_arguments(argc, argv); |
| 259 | |||
| 260 | if (tmp.error != OK) { | ||
| 256 | usage4(_("Could not parse arguments")); | 261 | usage4(_("Could not parse arguments")); |
| 257 | } | 262 | } |
| 258 | 263 | ||
| 264 | check_dhcp_config config = tmp.config; | ||
| 265 | if (config.output_format_is_set) { | ||
| 266 | mp_set_format(config.output_format); | ||
| 267 | } | ||
| 268 | |||
| 259 | /* create socket for DHCP communications */ | 269 | /* create socket for DHCP communications */ |
| 260 | dhcp_socket = create_dhcp_socket(); | 270 | int dhcp_socket = create_dhcp_socket(config.unicast_mode, config.network_interface_name); |
| 261 | 271 | ||
| 262 | /* get hardware address of client machine */ | 272 | /* get hardware address of client machine */ |
| 263 | if (user_specified_mac != NULL) | 273 | unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH] = ""; |
| 264 | memcpy(client_hardware_address, user_specified_mac, 6); | 274 | if (config.user_specified_mac != NULL) { |
| 265 | else | 275 | memcpy(client_hardware_address, config.user_specified_mac, MAC_ADDR_LEN); |
| 266 | get_hardware_address(dhcp_socket, network_interface_name); | 276 | } else { |
| 277 | get_hardware_address(dhcp_socket, config.network_interface_name, client_hardware_address); | ||
| 278 | } | ||
| 267 | 279 | ||
| 268 | if (unicast) /* get IP address of client machine */ | 280 | struct in_addr my_ip = {0}; |
| 269 | get_ip_address(dhcp_socket, network_interface_name); | 281 | |
| 282 | if (config.unicast_mode) { /* get IP address of client machine */ | ||
| 283 | get_ip_address_wrapper tmp_get_ip = | ||
| 284 | get_ip_address(dhcp_socket, config.network_interface_name); | ||
| 285 | if (tmp_get_ip.error == OK) { | ||
| 286 | my_ip = tmp_get_ip.my_ip; | ||
| 287 | } else { | ||
| 288 | // TODO failed to get own IP | ||
| 289 | die(STATE_UNKNOWN, "Failed to retrieve my own IP address in unicast mode"); | ||
| 290 | } | ||
| 291 | } | ||
| 270 | 292 | ||
| 271 | /* send DHCPDISCOVER packet */ | 293 | /* send DHCPDISCOVER packet */ |
| 272 | send_dhcp_discover(dhcp_socket); | 294 | send_dhcp_discover_wrapper disco_res = send_dhcp_discover( |
| 295 | dhcp_socket, config.unicast_mode, config.dhcp_ip, config.requested_address, | ||
| 296 | config.request_specific_address, my_ip, client_hardware_address); | ||
| 297 | |||
| 298 | if (disco_res.error != OK) { | ||
| 299 | // DO something? | ||
| 300 | die(STATE_UNKNOWN, "Failed to send DHCP discover"); | ||
| 301 | } | ||
| 273 | 302 | ||
| 274 | /* wait for a DHCPOFFER packet */ | 303 | /* wait for a DHCPOFFER packet */ |
| 275 | get_dhcp_offer(dhcp_socket); | 304 | get_dhcp_offer_wrapper offer_res = get_dhcp_offer( |
| 305 | dhcp_socket, config.dhcpoffer_timeout, disco_res.packet_xid, NULL, client_hardware_address); | ||
| 306 | |||
| 307 | int valid_responses = 0; | ||
| 308 | dhcp_offer *dhcp_offer_list = NULL; | ||
| 309 | if (offer_res.error == OK) { | ||
| 310 | valid_responses = offer_res.valid_responses; | ||
| 311 | dhcp_offer_list = offer_res.dhcp_offer_list; | ||
| 312 | } else { | ||
| 313 | die(STATE_UNKNOWN, "Failed to get DHCP offers"); | ||
| 314 | } | ||
| 276 | 315 | ||
| 277 | /* close socket we created */ | 316 | /* close socket we created */ |
| 278 | close_dhcp_socket(dhcp_socket); | 317 | close_dhcp_socket(dhcp_socket); |
| 279 | 318 | ||
| 280 | /* determine state/plugin output to return */ | 319 | mp_check overall = mp_check_init(); |
| 281 | result = get_results(); | ||
| 282 | 320 | ||
| 321 | /* determine state/plugin output to return */ | ||
| 322 | mp_subcheck sc_res = | ||
| 323 | get_results(config.exclusive_mode, config.num_of_requested_servers, | ||
| 324 | config.requested_address, config.request_specific_address, | ||
| 325 | config.requested_server_list, valid_responses, dhcp_offer_list); | ||
| 326 | mp_add_subcheck_to_check(&overall, sc_res); | ||
| 283 | /* free allocated memory */ | 327 | /* free allocated memory */ |
| 284 | free_dhcp_offer_list(); | 328 | free_dhcp_offer_list(dhcp_offer_list); |
| 285 | free_requested_server_list(); | 329 | free_requested_server_list(config.requested_server_list); |
| 286 | 330 | ||
| 287 | return result; | 331 | mp_exit(overall); |
| 288 | } | 332 | } |
| 289 | 333 | ||
| 290 | /* determines hardware address on client machine */ | 334 | /* determines hardware address on client machine */ |
| 291 | static int get_hardware_address(int sock, char *interface_name) { | 335 | int get_hardware_address(int sock, char *interface_name, unsigned char *client_hardware_address) { |
| 292 | 336 | ||
| 293 | #if defined(__linux__) | 337 | #if defined(__linux__) |
| 294 | struct ifreq ifr; | 338 | struct ifreq ifr; |
| @@ -302,7 +346,7 @@ static int get_hardware_address(int sock, char *interface_name) { | |||
| 302 | exit(STATE_UNKNOWN); | 346 | exit(STATE_UNKNOWN); |
| 303 | } | 347 | } |
| 304 | 348 | ||
| 305 | memcpy(&client_hardware_address[0], &ifr.ifr_hwaddr.sa_data, 6); | 349 | memcpy(&client_hardware_address[0], &ifr.ifr_hwaddr.sa_data, MAC_ADDR_LEN); |
| 306 | 350 | ||
| 307 | #elif defined(__bsd__) | 351 | #elif defined(__bsd__) |
| 308 | /* King 2004 see ACKNOWLEDGEMENTS */ | 352 | /* King 2004 see ACKNOWLEDGEMENTS */ |
| @@ -326,17 +370,20 @@ static int get_hardware_address(int sock, char *interface_name) { | |||
| 326 | } | 370 | } |
| 327 | 371 | ||
| 328 | if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { | 372 | if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { |
| 329 | printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno)); | 373 | printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), |
| 374 | interface_name, strerror(errno)); | ||
| 330 | exit(STATE_UNKNOWN); | 375 | exit(STATE_UNKNOWN); |
| 331 | } | 376 | } |
| 332 | 377 | ||
| 333 | if ((buf = malloc(len)) == NULL) { | 378 | if ((buf = malloc(len)) == NULL) { |
| 334 | printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno)); | 379 | printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), |
| 380 | interface_name, strerror(errno)); | ||
| 335 | exit(4); | 381 | exit(4); |
| 336 | } | 382 | } |
| 337 | 383 | ||
| 338 | if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { | 384 | if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { |
| 339 | printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno)); | 385 | printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), |
| 386 | interface_name, strerror(errno)); | ||
| 340 | exit(STATE_UNKNOWN); | 387 | exit(STATE_UNKNOWN); |
| 341 | } | 388 | } |
| 342 | 389 | ||
| @@ -358,20 +405,25 @@ static int get_hardware_address(int sock, char *interface_name) { | |||
| 358 | int i; | 405 | int i; |
| 359 | p = interface_name + strlen(interface_name) - 1; | 406 | p = interface_name + strlen(interface_name) - 1; |
| 360 | for (i = strlen(interface_name) - 1; i > 0; p--) { | 407 | for (i = strlen(interface_name) - 1; i > 0; p--) { |
| 361 | if (isalpha(*p)) | 408 | if (isalpha(*p)) { |
| 362 | break; | 409 | break; |
| 410 | } | ||
| 363 | } | 411 | } |
| 364 | p++; | 412 | p++; |
| 365 | if (p != interface_name) { | 413 | if (p != interface_name) { |
| 366 | unit = atoi(p); | 414 | unit = atoi(p); |
| 367 | strncat(dev, interface_name, 6); | 415 | strncat(dev, interface_name, 6); |
| 368 | } else { | 416 | } else { |
| 369 | printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name); | 417 | printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg " |
| 418 | "lnc0.\n"), | ||
| 419 | interface_name); | ||
| 370 | exit(STATE_UNKNOWN); | 420 | exit(STATE_UNKNOWN); |
| 371 | } | 421 | } |
| 372 | stat = mac_addr_dlpi(dev, unit, client_hardware_address); | 422 | stat = mac_addr_dlpi(dev, unit, client_hardware_address); |
| 373 | if (stat != 0) { | 423 | if (stat != 0) { |
| 374 | printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); | 424 | printf( |
| 425 | _("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), | ||
| 426 | dev, unit); | ||
| 375 | exit(STATE_UNKNOWN); | 427 | exit(STATE_UNKNOWN); |
| 376 | } | 428 | } |
| 377 | 429 | ||
| @@ -383,7 +435,9 @@ static int get_hardware_address(int sock, char *interface_name) { | |||
| 383 | 435 | ||
| 384 | stat = mac_addr_dlpi(dev, unit, client_hardware_address); | 436 | stat = mac_addr_dlpi(dev, unit, client_hardware_address); |
| 385 | if (stat != 0) { | 437 | if (stat != 0) { |
| 386 | printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); | 438 | printf( |
| 439 | _("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), | ||
| 440 | dev, unit); | ||
| 387 | exit(STATE_UNKNOWN); | 441 | exit(STATE_UNKNOWN); |
| 388 | } | 442 | } |
| 389 | /* Kompf 2000-2003 */ | 443 | /* Kompf 2000-2003 */ |
| @@ -393,14 +447,15 @@ static int get_hardware_address(int sock, char *interface_name) { | |||
| 393 | exit(STATE_UNKNOWN); | 447 | exit(STATE_UNKNOWN); |
| 394 | #endif | 448 | #endif |
| 395 | 449 | ||
| 396 | if (verbose) | 450 | if (verbose) { |
| 397 | print_hardware_address(client_hardware_address); | 451 | print_hardware_address(client_hardware_address); |
| 452 | } | ||
| 398 | 453 | ||
| 399 | return OK; | 454 | return OK; |
| 400 | } | 455 | } |
| 401 | 456 | ||
| 402 | /* determines IP address of the client interface */ | 457 | /* determines IP address of the client interface */ |
| 403 | static int get_ip_address(int sock, char *interface_name) { | 458 | get_ip_address_wrapper get_ip_address(int sock, char *interface_name) { |
| 404 | #if defined(SIOCGIFADDR) | 459 | #if defined(SIOCGIFADDR) |
| 405 | struct ifreq ifr; | 460 | struct ifreq ifr; |
| 406 | 461 | ||
| @@ -412,28 +467,30 @@ static int get_ip_address(int sock, char *interface_name) { | |||
| 412 | exit(STATE_UNKNOWN); | 467 | exit(STATE_UNKNOWN); |
| 413 | } | 468 | } |
| 414 | 469 | ||
| 415 | my_ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; | ||
| 416 | |||
| 417 | #else | 470 | #else |
| 418 | printf(_("Error: Cannot get interface IP address on this platform.\n")); | 471 | printf(_("Error: Cannot get interface IP address on this platform.\n")); |
| 419 | exit(STATE_UNKNOWN); | 472 | exit(STATE_UNKNOWN); |
| 420 | #endif | 473 | #endif |
| 421 | 474 | ||
| 422 | if (verbose) | 475 | get_ip_address_wrapper result = { |
| 423 | printf(_("Pretending to be relay client %s\n"), inet_ntoa(my_ip)); | 476 | .error = OK, |
| 477 | .my_ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr, | ||
| 478 | }; | ||
| 424 | 479 | ||
| 425 | return OK; | 480 | if (verbose) { |
| 481 | printf(_("Pretending to be relay client %s\n"), inet_ntoa(result.my_ip)); | ||
| 482 | } | ||
| 483 | |||
| 484 | return result; | ||
| 426 | } | 485 | } |
| 427 | 486 | ||
| 428 | /* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ | 487 | /* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ |
| 429 | static int send_dhcp_discover(int sock) { | 488 | static send_dhcp_discover_wrapper send_dhcp_discover(int sock, bool unicast, struct in_addr dhcp_ip, |
| 430 | dhcp_packet discover_packet; | 489 | struct in_addr requested_address, |
| 431 | struct sockaddr_in sockaddr_broadcast; | 490 | bool request_specific_address, |
| 432 | unsigned short opts; | 491 | struct in_addr my_ip, |
| 433 | 492 | unsigned char *client_hardware_address) { | |
| 434 | /* clear the packet data structure */ | 493 | dhcp_packet discover_packet = {0}; |
| 435 | bzero(&discover_packet, sizeof(discover_packet)); | ||
| 436 | |||
| 437 | /* boot request flag (backward compatible with BOOTP servers) */ | 494 | /* boot request flag (backward compatible with BOOTP servers) */ |
| 438 | discover_packet.op = BOOTREQUEST; | 495 | discover_packet.op = BOOTREQUEST; |
| 439 | 496 | ||
| @@ -443,12 +500,15 @@ static int send_dhcp_discover(int sock) { | |||
| 443 | /* length of our hardware address */ | 500 | /* length of our hardware address */ |
| 444 | discover_packet.hlen = ETHERNET_HARDWARE_ADDRESS_LENGTH; | 501 | discover_packet.hlen = ETHERNET_HARDWARE_ADDRESS_LENGTH; |
| 445 | 502 | ||
| 503 | send_dhcp_discover_wrapper result = { | ||
| 504 | .error = OK, | ||
| 505 | }; | ||
| 446 | /* | 506 | /* |
| 447 | * transaction ID is supposed to be random. | 507 | * transaction ID is supposed to be random. |
| 448 | */ | 508 | */ |
| 449 | srand(time(NULL) ^ getpid()); | 509 | srand(time(NULL) ^ getpid()); |
| 450 | packet_xid = random(); | 510 | result.packet_xid = random(); |
| 451 | discover_packet.xid = htonl(packet_xid); | 511 | discover_packet.xid = htonl(result.packet_xid); |
| 452 | 512 | ||
| 453 | /*discover_packet.secs=htons(65535);*/ | 513 | /*discover_packet.secs=htons(65535);*/ |
| 454 | discover_packet.secs = 0xFF; | 514 | discover_packet.secs = 0xFF; |
| @@ -468,10 +528,11 @@ static int send_dhcp_discover(int sock) { | |||
| 468 | discover_packet.options[2] = '\x53'; | 528 | discover_packet.options[2] = '\x53'; |
| 469 | discover_packet.options[3] = '\x63'; | 529 | discover_packet.options[3] = '\x63'; |
| 470 | 530 | ||
| 471 | opts = 4; | 531 | unsigned short opts = 4; |
| 472 | /* DHCP message type is embedded in options field */ | 532 | /* DHCP message type is embedded in options field */ |
| 473 | discover_packet.options[opts++] = DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ | 533 | discover_packet.options[opts++] = |
| 474 | discover_packet.options[opts++] = '\x01'; /* DHCP message option length in bytes */ | 534 | DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ |
| 535 | discover_packet.options[opts++] = '\x01'; /* DHCP message option length in bytes */ | ||
| 475 | discover_packet.options[opts++] = DHCPDISCOVER; | 536 | discover_packet.options[opts++] = DHCPDISCOVER; |
| 476 | 537 | ||
| 477 | /* the IP address we're requesting */ | 538 | /* the IP address we're requesting */ |
| @@ -484,21 +545,25 @@ static int send_dhcp_discover(int sock) { | |||
| 484 | discover_packet.options[opts++] = (char)DHCP_OPTION_END; | 545 | discover_packet.options[opts++] = (char)DHCP_OPTION_END; |
| 485 | 546 | ||
| 486 | /* unicast fields */ | 547 | /* unicast fields */ |
| 487 | if (unicast) | 548 | if (unicast) { |
| 488 | discover_packet.giaddr.s_addr = my_ip.s_addr; | 549 | discover_packet.giaddr.s_addr = my_ip.s_addr; |
| 550 | } | ||
| 489 | 551 | ||
| 490 | /* see RFC 1542, 4.1.1 */ | 552 | /* see RFC 1542, 4.1.1 */ |
| 491 | discover_packet.hops = unicast ? 1 : 0; | 553 | discover_packet.hops = unicast ? 1 : 0; |
| 492 | 554 | ||
| 493 | /* send the DHCPDISCOVER packet to broadcast address */ | 555 | /* send the DHCPDISCOVER packet to broadcast address */ |
| 494 | sockaddr_broadcast.sin_family = AF_INET; | 556 | struct sockaddr_in sockaddr_broadcast = { |
| 495 | sockaddr_broadcast.sin_port = htons(DHCP_SERVER_PORT); | 557 | .sin_family = AF_INET, |
| 496 | sockaddr_broadcast.sin_addr.s_addr = unicast ? dhcp_ip.s_addr : INADDR_BROADCAST; | 558 | .sin_port = htons(DHCP_SERVER_PORT), |
| 497 | bzero(&sockaddr_broadcast.sin_zero, sizeof(sockaddr_broadcast.sin_zero)); | 559 | .sin_addr.s_addr = unicast ? dhcp_ip.s_addr : INADDR_BROADCAST, |
| 560 | }; | ||
| 498 | 561 | ||
| 499 | if (verbose) { | 562 | if (verbose) { |
| 500 | printf(_("DHCPDISCOVER to %s port %d\n"), inet_ntoa(sockaddr_broadcast.sin_addr), ntohs(sockaddr_broadcast.sin_port)); | 563 | printf(_("DHCPDISCOVER to %s port %d\n"), inet_ntoa(sockaddr_broadcast.sin_addr), |
| 501 | printf("DHCPDISCOVER XID: %u (0x%X)\n", ntohl(discover_packet.xid), ntohl(discover_packet.xid)); | 564 | ntohs(sockaddr_broadcast.sin_port)); |
| 565 | printf("DHCPDISCOVER XID: %u (0x%X)\n", ntohl(discover_packet.xid), | ||
| 566 | ntohl(discover_packet.xid)); | ||
| 502 | printf("DHCDISCOVER ciaddr: %s\n", inet_ntoa(discover_packet.ciaddr)); | 567 | printf("DHCDISCOVER ciaddr: %s\n", inet_ntoa(discover_packet.ciaddr)); |
| 503 | printf("DHCDISCOVER yiaddr: %s\n", inet_ntoa(discover_packet.yiaddr)); | 568 | printf("DHCDISCOVER yiaddr: %s\n", inet_ntoa(discover_packet.yiaddr)); |
| 504 | printf("DHCDISCOVER siaddr: %s\n", inet_ntoa(discover_packet.siaddr)); | 569 | printf("DHCDISCOVER siaddr: %s\n", inet_ntoa(discover_packet.siaddr)); |
| @@ -508,56 +573,58 @@ static int send_dhcp_discover(int sock) { | |||
| 508 | /* send the DHCPDISCOVER packet out */ | 573 | /* send the DHCPDISCOVER packet out */ |
| 509 | send_dhcp_packet(&discover_packet, sizeof(discover_packet), sock, &sockaddr_broadcast); | 574 | send_dhcp_packet(&discover_packet, sizeof(discover_packet), sock, &sockaddr_broadcast); |
| 510 | 575 | ||
| 511 | if (verbose) | 576 | if (verbose) { |
| 512 | printf("\n\n"); | 577 | printf("\n\n"); |
| 578 | } | ||
| 513 | 579 | ||
| 514 | return OK; | 580 | return result; |
| 515 | } | 581 | } |
| 516 | 582 | ||
| 517 | /* waits for a DHCPOFFER message from one or more DHCP servers */ | 583 | /* waits for a DHCPOFFER message from one or more DHCP servers */ |
| 518 | static int get_dhcp_offer(int sock) { | 584 | get_dhcp_offer_wrapper get_dhcp_offer(int sock, int dhcpoffer_timeout, uint32_t packet_xid, |
| 519 | dhcp_packet offer_packet; | 585 | dhcp_offer *dhcp_offer_list, |
| 520 | struct sockaddr_in source; | 586 | const unsigned char *client_hardware_address) { |
| 521 | struct sockaddr_in via; | ||
| 522 | int result = OK; | ||
| 523 | int responses = 0; | ||
| 524 | int x; | ||
| 525 | time_t start_time; | 587 | time_t start_time; |
| 526 | time_t current_time; | ||
| 527 | |||
| 528 | time(&start_time); | 588 | time(&start_time); |
| 529 | 589 | ||
| 590 | int result = OK; | ||
| 591 | int responses = 0; | ||
| 592 | int valid_responses = 0; | ||
| 530 | /* receive as many responses as we can */ | 593 | /* receive as many responses as we can */ |
| 531 | for (responses = 0, valid_responses = 0;;) { | 594 | for (;;) { |
| 532 | 595 | time_t current_time; | |
| 533 | time(¤t_time); | 596 | time(¤t_time); |
| 534 | if ((current_time - start_time) >= dhcpoffer_timeout) | 597 | if ((current_time - start_time) >= dhcpoffer_timeout) { |
| 535 | break; | 598 | break; |
| 599 | } | ||
| 536 | 600 | ||
| 537 | if (verbose) | 601 | if (verbose) { |
| 538 | printf("\n\n"); | 602 | printf("\n\n"); |
| 603 | } | ||
| 539 | 604 | ||
| 540 | bzero(&source, sizeof(source)); | 605 | struct sockaddr_in source = {0}; |
| 541 | bzero(&via, sizeof(via)); | 606 | dhcp_packet offer_packet = {0}; |
| 542 | bzero(&offer_packet, sizeof(offer_packet)); | ||
| 543 | 607 | ||
| 544 | result = OK; | 608 | result = OK; |
| 545 | result = receive_dhcp_packet(&offer_packet, sizeof(offer_packet), sock, dhcpoffer_timeout, &source); | 609 | result = receive_dhcp_packet(&offer_packet, sizeof(offer_packet), sock, dhcpoffer_timeout, |
| 610 | &source); | ||
| 546 | 611 | ||
| 547 | if (result != OK) { | 612 | if (result != OK) { |
| 548 | if (verbose) | 613 | if (verbose) { |
| 549 | printf(_("Result=ERROR\n")); | 614 | printf(_("Result=ERROR\n")); |
| 615 | } | ||
| 550 | 616 | ||
| 551 | continue; | 617 | continue; |
| 552 | } else { | 618 | } |
| 553 | if (verbose) | 619 | if (verbose) { |
| 554 | printf(_("Result=OK\n")); | 620 | printf(_("Result=OK\n")); |
| 555 | |||
| 556 | responses++; | ||
| 557 | } | 621 | } |
| 558 | 622 | ||
| 623 | responses++; | ||
| 624 | |||
| 559 | /* The "source" is either a server or a relay. */ | 625 | /* The "source" is either a server or a relay. */ |
| 560 | /* Save a copy of "source" into "via" even if it's via itself */ | 626 | /* Save a copy of "source" into "via" even if it's via itself */ |
| 627 | struct sockaddr_in via = {0}; | ||
| 561 | memcpy(&via, &source, sizeof(source)); | 628 | memcpy(&via, &source, sizeof(source)); |
| 562 | 629 | ||
| 563 | if (verbose) { | 630 | if (verbose) { |
| @@ -568,30 +635,38 @@ static int get_dhcp_offer(int sock) { | |||
| 568 | 635 | ||
| 569 | /* check packet xid to see if its the same as the one we used in the discover packet */ | 636 | /* check packet xid to see if its the same as the one we used in the discover packet */ |
| 570 | if (ntohl(offer_packet.xid) != packet_xid) { | 637 | if (ntohl(offer_packet.xid) != packet_xid) { |
| 571 | if (verbose) | 638 | if (verbose) { |
| 572 | printf(_("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"), ntohl(offer_packet.xid), packet_xid); | 639 | printf( |
| 640 | _("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"), | ||
| 641 | ntohl(offer_packet.xid), packet_xid); | ||
| 642 | } | ||
| 573 | 643 | ||
| 574 | continue; | 644 | continue; |
| 575 | } | 645 | } |
| 576 | 646 | ||
| 577 | /* check hardware address */ | 647 | /* check hardware address */ |
| 578 | result = OK; | 648 | result = OK; |
| 579 | if (verbose) | 649 | if (verbose) { |
| 580 | printf("DHCPOFFER chaddr: "); | 650 | printf("DHCPOFFER chaddr: "); |
| 651 | } | ||
| 581 | 652 | ||
| 582 | for (x = 0; x < ETHERNET_HARDWARE_ADDRESS_LENGTH; x++) { | 653 | for (int i = 0; i < ETHERNET_HARDWARE_ADDRESS_LENGTH; i++) { |
| 583 | if (verbose) | 654 | if (verbose) { |
| 584 | printf("%02X", (unsigned char)offer_packet.chaddr[x]); | 655 | printf("%02X", offer_packet.chaddr[i]); |
| 656 | } | ||
| 585 | 657 | ||
| 586 | if (offer_packet.chaddr[x] != client_hardware_address[x]) | 658 | if (offer_packet.chaddr[i] != client_hardware_address[i]) { |
| 587 | result = ERROR; | 659 | result = ERROR; |
| 660 | } | ||
| 588 | } | 661 | } |
| 589 | if (verbose) | 662 | if (verbose) { |
| 590 | printf("\n"); | 663 | printf("\n"); |
| 664 | } | ||
| 591 | 665 | ||
| 592 | if (result == ERROR) { | 666 | if (result == ERROR) { |
| 593 | if (verbose) | 667 | if (verbose) { |
| 594 | printf(_("DHCPOFFER hardware address did not match our own - ignoring packet\n")); | 668 | printf(_("DHCPOFFER hardware address did not match our own - ignoring packet\n")); |
| 669 | } | ||
| 595 | 670 | ||
| 596 | continue; | 671 | continue; |
| 597 | } | 672 | } |
| @@ -603,7 +678,13 @@ static int get_dhcp_offer(int sock) { | |||
| 603 | printf("DHCPOFFER giaddr: %s\n", inet_ntoa(offer_packet.giaddr)); | 678 | printf("DHCPOFFER giaddr: %s\n", inet_ntoa(offer_packet.giaddr)); |
| 604 | } | 679 | } |
| 605 | 680 | ||
| 606 | add_dhcp_offer(source.sin_addr, &offer_packet); | 681 | add_dhcp_offer_wrapper add_res = |
| 682 | add_dhcp_offer(source.sin_addr, &offer_packet, dhcp_offer_list); | ||
| 683 | if (add_res.error != OK) { | ||
| 684 | // TODO | ||
| 685 | } else { | ||
| 686 | dhcp_offer_list = add_res.dhcp_offer_list; | ||
| 687 | } | ||
| 607 | 688 | ||
| 608 | valid_responses++; | 689 | valid_responses++; |
| 609 | } | 690 | } |
| @@ -613,104 +694,104 @@ static int get_dhcp_offer(int sock) { | |||
| 613 | printf(_("Valid responses for this machine: %d\n"), valid_responses); | 694 | printf(_("Valid responses for this machine: %d\n"), valid_responses); |
| 614 | } | 695 | } |
| 615 | 696 | ||
| 616 | return OK; | 697 | get_dhcp_offer_wrapper ret_val = { |
| 698 | .error = OK, | ||
| 699 | .valid_responses = valid_responses, | ||
| 700 | .dhcp_offer_list = dhcp_offer_list, | ||
| 701 | }; | ||
| 702 | return ret_val; | ||
| 617 | } | 703 | } |
| 618 | 704 | ||
| 619 | /* sends a DHCP packet */ | 705 | /* sends a DHCP packet */ |
| 620 | static int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest) { | 706 | int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest) { |
| 621 | int result; | 707 | int result = |
| 622 | 708 | sendto(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)dest, sizeof(*dest)); | |
| 623 | result = sendto(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)dest, sizeof(*dest)); | ||
| 624 | 709 | ||
| 625 | if (verbose) | 710 | if (verbose) { |
| 626 | printf(_("send_dhcp_packet result: %d\n"), result); | 711 | printf(_("send_dhcp_packet result: %d\n"), result); |
| 712 | } | ||
| 627 | 713 | ||
| 628 | if (result < 0) | 714 | if (result < 0) { |
| 629 | return ERROR; | 715 | return ERROR; |
| 716 | } | ||
| 630 | 717 | ||
| 631 | return OK; | 718 | return OK; |
| 632 | } | 719 | } |
| 633 | 720 | ||
| 634 | /* receives a DHCP packet */ | 721 | /* receives a DHCP packet */ |
| 635 | static int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address) { | 722 | int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, |
| 636 | struct timeval tv; | 723 | struct sockaddr_in *address) { |
| 637 | fd_set readfds; | ||
| 638 | fd_set oobfds; | ||
| 639 | int recv_result; | ||
| 640 | socklen_t address_size; | ||
| 641 | struct sockaddr_in source_address; | ||
| 642 | int nfound; | ||
| 643 | |||
| 644 | /* wait for data to arrive (up time timeout) */ | 724 | /* wait for data to arrive (up time timeout) */ |
| 645 | tv.tv_sec = timeout; | 725 | struct timeval timeout_val = { |
| 646 | tv.tv_usec = 0; | 726 | .tv_sec = timeout, |
| 727 | .tv_usec = 0, | ||
| 728 | }; | ||
| 729 | fd_set readfds; | ||
| 647 | FD_ZERO(&readfds); | 730 | FD_ZERO(&readfds); |
| 731 | fd_set oobfds; | ||
| 648 | FD_ZERO(&oobfds); | 732 | FD_ZERO(&oobfds); |
| 649 | FD_SET(sock, &readfds); | 733 | FD_SET(sock, &readfds); |
| 650 | FD_SET(sock, &oobfds); | 734 | FD_SET(sock, &oobfds); |
| 651 | nfound = select(sock + 1, &readfds, NULL, &oobfds, &tv); | 735 | int nfound = select(sock + 1, &readfds, NULL, &oobfds, &timeout_val); |
| 652 | 736 | ||
| 653 | /* make sure some data has arrived */ | 737 | /* make sure some data has arrived */ |
| 654 | if (!FD_ISSET(sock, &readfds)) { | 738 | if (!FD_ISSET(sock, &readfds)) { |
| 655 | if (verbose) | 739 | if (verbose) { |
| 656 | printf(_("No (more) data received (nfound: %d)\n"), nfound); | 740 | printf(_("No (more) data received (nfound: %d)\n"), nfound); |
| 741 | } | ||
| 657 | return ERROR; | 742 | return ERROR; |
| 658 | } | 743 | } |
| 659 | 744 | ||
| 660 | else { | 745 | struct sockaddr_in source_address = {0}; |
| 661 | bzero(&source_address, sizeof(source_address)); | 746 | socklen_t address_size = sizeof(source_address); |
| 662 | address_size = sizeof(source_address); | 747 | int recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, |
| 663 | recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)&source_address, &address_size); | 748 | (struct sockaddr *)&source_address, &address_size); |
| 664 | if (verbose) | 749 | if (verbose) { |
| 665 | printf("recv_result: %d\n", recv_result); | 750 | printf("recv_result: %d\n", recv_result); |
| 666 | 751 | } | |
| 667 | if (recv_result == -1) { | ||
| 668 | if (verbose) { | ||
| 669 | printf(_("recvfrom() failed, ")); | ||
| 670 | printf("errno: (%d) -> %s\n", errno, strerror(errno)); | ||
| 671 | } | ||
| 672 | return ERROR; | ||
| 673 | } else { | ||
| 674 | if (verbose) { | ||
| 675 | printf(_("receive_dhcp_packet() result: %d\n"), recv_result); | ||
| 676 | printf(_("receive_dhcp_packet() source: %s\n"), inet_ntoa(source_address.sin_addr)); | ||
| 677 | } | ||
| 678 | 752 | ||
| 679 | memcpy(address, &source_address, sizeof(source_address)); | 753 | if (recv_result == -1) { |
| 680 | return OK; | 754 | if (verbose) { |
| 755 | printf(_("recvfrom() failed, ")); | ||
| 756 | printf("errno: (%d) -> %s\n", errno, strerror(errno)); | ||
| 681 | } | 757 | } |
| 758 | return ERROR; | ||
| 759 | } | ||
| 760 | if (verbose) { | ||
| 761 | printf(_("receive_dhcp_packet() result: %d\n"), recv_result); | ||
| 762 | printf(_("receive_dhcp_packet() source: %s\n"), inet_ntoa(source_address.sin_addr)); | ||
| 682 | } | 763 | } |
| 683 | 764 | ||
| 765 | memcpy(address, &source_address, sizeof(source_address)); | ||
| 684 | return OK; | 766 | return OK; |
| 685 | } | 767 | } |
| 686 | 768 | ||
| 687 | /* creates a socket for DHCP communication */ | 769 | /* creates a socket for DHCP communication */ |
| 688 | static int create_dhcp_socket(void) { | 770 | int create_dhcp_socket(bool unicast, char *network_interface_name) { |
| 689 | struct sockaddr_in myname; | ||
| 690 | struct ifreq interface; | ||
| 691 | int sock; | ||
| 692 | int flag = 1; | ||
| 693 | |||
| 694 | /* Set up the address we're going to bind to. */ | 771 | /* Set up the address we're going to bind to. */ |
| 695 | bzero(&myname, sizeof(myname)); | ||
| 696 | myname.sin_family = AF_INET; | ||
| 697 | /* listen to DHCP server port if we're in unicast mode */ | 772 | /* listen to DHCP server port if we're in unicast mode */ |
| 698 | myname.sin_port = htons(unicast ? DHCP_SERVER_PORT : DHCP_CLIENT_PORT); | 773 | struct sockaddr_in myname = { |
| 699 | myname.sin_addr.s_addr = unicast ? my_ip.s_addr : INADDR_ANY; | 774 | .sin_family = AF_INET, |
| 700 | bzero(&myname.sin_zero, sizeof(myname.sin_zero)); | 775 | .sin_port = htons(unicast ? DHCP_SERVER_PORT : DHCP_CLIENT_PORT), |
| 776 | // TODO previously the next line was trying to use our own IP, we was not set | ||
| 777 | // until some point later, so it was removed. Recheck whether it is actually | ||
| 778 | // necessary/useful | ||
| 779 | .sin_addr.s_addr = INADDR_ANY, | ||
| 780 | }; | ||
| 701 | 781 | ||
| 702 | /* create a socket for DHCP communications */ | 782 | /* create a socket for DHCP communications */ |
| 703 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | 783 | int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
| 704 | if (sock < 0) { | 784 | if (sock < 0) { |
| 705 | printf(_("Error: Could not create socket!\n")); | 785 | printf(_("Error: Could not create socket!\n")); |
| 706 | exit(STATE_UNKNOWN); | 786 | exit(STATE_UNKNOWN); |
| 707 | } | 787 | } |
| 708 | 788 | ||
| 709 | if (verbose) | 789 | if (verbose) { |
| 710 | printf("DHCP socket: %d\n", sock); | 790 | printf("DHCP socket: %d\n", sock); |
| 791 | } | ||
| 711 | 792 | ||
| 712 | /* set the reuse address flag so we don't get errors when restarting */ | 793 | /* set the reuse address flag so we don't get errors when restarting */ |
| 713 | flag = 1; | 794 | int flag = 1; |
| 714 | if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0) { | 795 | if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0) { |
| 715 | printf(_("Error: Could not set reuse address option on DHCP socket!\n")); | 796 | printf(_("Error: Could not set reuse address option on DHCP socket!\n")); |
| 716 | exit(STATE_UNKNOWN); | 797 | exit(STATE_UNKNOWN); |
| @@ -722,12 +803,14 @@ static int create_dhcp_socket(void) { | |||
| 722 | exit(STATE_UNKNOWN); | 803 | exit(STATE_UNKNOWN); |
| 723 | } | 804 | } |
| 724 | 805 | ||
| 806 | struct ifreq interface; | ||
| 725 | /* bind socket to interface */ | 807 | /* bind socket to interface */ |
| 726 | #if defined(__linux__) | 808 | #if defined(__linux__) |
| 727 | strncpy(interface.ifr_ifrn.ifrn_name, network_interface_name, IFNAMSIZ - 1); | 809 | strncpy(interface.ifr_ifrn.ifrn_name, network_interface_name, IFNAMSIZ - 1); |
| 728 | interface.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = '\0'; | 810 | interface.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = '\0'; |
| 729 | if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { | 811 | if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { |
| 730 | printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"), network_interface_name); | 812 | printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"), |
| 813 | network_interface_name); | ||
| 731 | exit(STATE_UNKNOWN); | 814 | exit(STATE_UNKNOWN); |
| 732 | } | 815 | } |
| 733 | 816 | ||
| @@ -738,7 +821,8 @@ static int create_dhcp_socket(void) { | |||
| 738 | 821 | ||
| 739 | /* bind the socket */ | 822 | /* bind the socket */ |
| 740 | if (bind(sock, (struct sockaddr *)&myname, sizeof(myname)) < 0) { | 823 | if (bind(sock, (struct sockaddr *)&myname, sizeof(myname)) < 0) { |
| 741 | printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"), DHCP_CLIENT_PORT); | 824 | printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"), |
| 825 | DHCP_CLIENT_PORT); | ||
| 742 | exit(STATE_UNKNOWN); | 826 | exit(STATE_UNKNOWN); |
| 743 | } | 827 | } |
| 744 | 828 | ||
| @@ -746,105 +830,121 @@ static int create_dhcp_socket(void) { | |||
| 746 | } | 830 | } |
| 747 | 831 | ||
| 748 | /* closes DHCP socket */ | 832 | /* closes DHCP socket */ |
| 749 | static int close_dhcp_socket(int sock) { | 833 | int close_dhcp_socket(int sock) { |
| 750 | |||
| 751 | close(sock); | 834 | close(sock); |
| 752 | |||
| 753 | return OK; | 835 | return OK; |
| 754 | } | 836 | } |
| 755 | 837 | ||
| 756 | /* adds a requested server address to list in memory */ | 838 | /* adds a requested server address to list in memory */ |
| 757 | static int add_requested_server(struct in_addr server_address) { | 839 | int add_requested_server(struct in_addr server_address, int *requested_servers, |
| 758 | requested_server *new_server; | 840 | requested_server **requested_server_list) { |
| 759 | 841 | requested_server *new_server = (requested_server *)malloc(sizeof(requested_server)); | |
| 760 | new_server = (requested_server *)malloc(sizeof(requested_server)); | 842 | if (new_server == NULL) { |
| 761 | if (new_server == NULL) | ||
| 762 | return ERROR; | 843 | return ERROR; |
| 844 | } | ||
| 763 | 845 | ||
| 764 | new_server->server_address = server_address; | 846 | new_server->server_address = server_address; |
| 765 | new_server->answered = false; | 847 | new_server->answered = false; |
| 766 | 848 | ||
| 767 | new_server->next = requested_server_list; | 849 | new_server->next = *requested_server_list; |
| 768 | requested_server_list = new_server; | 850 | *requested_server_list = new_server; |
| 769 | 851 | ||
| 770 | requested_servers++; | 852 | *requested_servers += 1; |
| 771 | 853 | ||
| 772 | if (verbose) | 854 | if (verbose) { |
| 773 | printf(_("Requested server address: %s\n"), inet_ntoa(new_server->server_address)); | 855 | printf(_("Requested server address: %s\n"), inet_ntoa(new_server->server_address)); |
| 856 | } | ||
| 774 | 857 | ||
| 775 | return OK; | 858 | return OK; |
| 776 | } | 859 | } |
| 777 | 860 | ||
| 778 | /* adds a DHCP OFFER to list in memory */ | 861 | /* adds a DHCP OFFER to list in memory */ |
| 779 | static int add_dhcp_offer(struct in_addr source, dhcp_packet *offer_packet) { | 862 | add_dhcp_offer_wrapper add_dhcp_offer(struct in_addr source, dhcp_packet *offer_packet, |
| 863 | dhcp_offer *dhcp_offer_list) { | ||
| 864 | if (offer_packet == NULL) { | ||
| 865 | add_dhcp_offer_wrapper tmp = { | ||
| 866 | .error = ERROR, | ||
| 867 | }; | ||
| 868 | return tmp; | ||
| 869 | } | ||
| 870 | |||
| 871 | uint32_t dhcp_lease_time = 0; | ||
| 872 | uint32_t dhcp_renewal_time = 0; | ||
| 873 | uint32_t dhcp_rebinding_time = 0; | ||
| 780 | dhcp_offer *new_offer; | 874 | dhcp_offer *new_offer; |
| 781 | int x; | ||
| 782 | unsigned option_type; | ||
| 783 | unsigned option_length; | ||
| 784 | struct in_addr serv_ident = {0}; | 875 | struct in_addr serv_ident = {0}; |
| 785 | |||
| 786 | if (offer_packet == NULL) | ||
| 787 | return ERROR; | ||
| 788 | |||
| 789 | /* process all DHCP options present in the packet */ | 876 | /* process all DHCP options present in the packet */ |
| 790 | for (x = 4; x < MAX_DHCP_OPTIONS_LENGTH - 1;) { | 877 | for (int dchp_opt_idx = 4; dchp_opt_idx < MAX_DHCP_OPTIONS_LENGTH - 1;) { |
| 791 | 878 | ||
| 792 | if ((int)offer_packet->options[x] == -1) | 879 | if ((int)offer_packet->options[dchp_opt_idx] == -1) { |
| 793 | break; | 880 | break; |
| 881 | } | ||
| 794 | 882 | ||
| 795 | /* get option type */ | 883 | /* get option type */ |
| 796 | option_type = offer_packet->options[x++]; | 884 | unsigned option_type = offer_packet->options[dchp_opt_idx++]; |
| 797 | 885 | ||
| 798 | /* get option length */ | 886 | /* get option length */ |
| 799 | option_length = offer_packet->options[x++]; | 887 | unsigned option_length = offer_packet->options[dchp_opt_idx++]; |
| 800 | 888 | ||
| 801 | if (verbose) | 889 | if (verbose) { |
| 802 | printf("Option: %d (0x%02X)\n", option_type, option_length); | 890 | printf("Option: %d (0x%02X)\n", option_type, option_length); |
| 891 | } | ||
| 803 | 892 | ||
| 804 | /* get option data */ | 893 | /* get option data */ |
| 805 | switch (option_type) { | 894 | switch (option_type) { |
| 806 | case DHCP_OPTION_LEASE_TIME: | 895 | case DHCP_OPTION_LEASE_TIME: |
| 807 | memcpy(&dhcp_lease_time, &offer_packet->options[x], sizeof(dhcp_lease_time)); | 896 | memcpy(&dhcp_lease_time, &offer_packet->options[dchp_opt_idx], sizeof(dhcp_lease_time)); |
| 808 | dhcp_lease_time = ntohl(dhcp_lease_time); | 897 | dhcp_lease_time = ntohl(dhcp_lease_time); |
| 809 | break; | 898 | break; |
| 810 | case DHCP_OPTION_RENEWAL_TIME: | 899 | case DHCP_OPTION_RENEWAL_TIME: |
| 811 | memcpy(&dhcp_renewal_time, &offer_packet->options[x], sizeof(dhcp_renewal_time)); | 900 | memcpy(&dhcp_renewal_time, &offer_packet->options[dchp_opt_idx], |
| 901 | sizeof(dhcp_renewal_time)); | ||
| 812 | dhcp_renewal_time = ntohl(dhcp_renewal_time); | 902 | dhcp_renewal_time = ntohl(dhcp_renewal_time); |
| 813 | break; | 903 | break; |
| 814 | case DHCP_OPTION_REBINDING_TIME: | 904 | case DHCP_OPTION_REBINDING_TIME: |
| 815 | memcpy(&dhcp_rebinding_time, &offer_packet->options[x], sizeof(dhcp_rebinding_time)); | 905 | memcpy(&dhcp_rebinding_time, &offer_packet->options[dchp_opt_idx], |
| 906 | sizeof(dhcp_rebinding_time)); | ||
| 816 | dhcp_rebinding_time = ntohl(dhcp_rebinding_time); | 907 | dhcp_rebinding_time = ntohl(dhcp_rebinding_time); |
| 817 | break; | 908 | break; |
| 818 | case DHCP_OPTION_SERVER_IDENTIFIER: | 909 | case DHCP_OPTION_SERVER_IDENTIFIER: |
| 819 | memcpy(&serv_ident.s_addr, &offer_packet->options[x], sizeof(serv_ident.s_addr)); | 910 | memcpy(&serv_ident.s_addr, &offer_packet->options[dchp_opt_idx], |
| 911 | sizeof(serv_ident.s_addr)); | ||
| 820 | break; | 912 | break; |
| 821 | } | 913 | } |
| 822 | 914 | ||
| 823 | /* skip option data we're ignoring */ | 915 | /* skip option data we're ignoring */ |
| 824 | if (option_type == 0) /* "pad" option, see RFC 2132 (3.1) */ | 916 | if (option_type == 0) { /* "pad" option, see RFC 2132 (3.1) */ |
| 825 | x += 1; | 917 | dchp_opt_idx += 1; |
| 826 | else | 918 | } else { |
| 827 | x += option_length; | 919 | dchp_opt_idx += option_length; |
| 920 | } | ||
| 828 | } | 921 | } |
| 829 | 922 | ||
| 830 | if (verbose) { | 923 | if (verbose) { |
| 831 | if (dhcp_lease_time == DHCP_INFINITE_TIME) | 924 | if (dhcp_lease_time == DHCP_INFINITE_TIME) { |
| 832 | printf(_("Lease Time: Infinite\n")); | 925 | printf(_("Lease Time: Infinite\n")); |
| 833 | else | 926 | } else { |
| 834 | printf(_("Lease Time: %lu seconds\n"), (unsigned long)dhcp_lease_time); | 927 | printf(_("Lease Time: %lu seconds\n"), (unsigned long)dhcp_lease_time); |
| 835 | if (dhcp_renewal_time == DHCP_INFINITE_TIME) | 928 | } |
| 929 | if (dhcp_renewal_time == DHCP_INFINITE_TIME) { | ||
| 836 | printf(_("Renewal Time: Infinite\n")); | 930 | printf(_("Renewal Time: Infinite\n")); |
| 837 | else | 931 | } else { |
| 838 | printf(_("Renewal Time: %lu seconds\n"), (unsigned long)dhcp_renewal_time); | 932 | printf(_("Renewal Time: %lu seconds\n"), (unsigned long)dhcp_renewal_time); |
| 839 | if (dhcp_rebinding_time == DHCP_INFINITE_TIME) | 933 | } |
| 934 | if (dhcp_rebinding_time == DHCP_INFINITE_TIME) { | ||
| 840 | printf(_("Rebinding Time: Infinite\n")); | 935 | printf(_("Rebinding Time: Infinite\n")); |
| 936 | } | ||
| 841 | printf(_("Rebinding Time: %lu seconds\n"), (unsigned long)dhcp_rebinding_time); | 937 | printf(_("Rebinding Time: %lu seconds\n"), (unsigned long)dhcp_rebinding_time); |
| 842 | } | 938 | } |
| 843 | 939 | ||
| 844 | new_offer = (dhcp_offer *)malloc(sizeof(dhcp_offer)); | 940 | new_offer = (dhcp_offer *)malloc(sizeof(dhcp_offer)); |
| 845 | 941 | ||
| 846 | if (new_offer == NULL) | 942 | if (new_offer == NULL) { |
| 847 | return ERROR; | 943 | add_dhcp_offer_wrapper tmp = { |
| 944 | .error = ERROR, | ||
| 945 | }; | ||
| 946 | return tmp; | ||
| 947 | } | ||
| 848 | 948 | ||
| 849 | /* | 949 | /* |
| 850 | * RFC 2131 (2.) says: "DHCP clarifies the interpretation of the | 950 | * RFC 2131 (2.) says: "DHCP clarifies the interpretation of the |
| @@ -874,15 +974,18 @@ static int add_dhcp_offer(struct in_addr source, dhcp_packet *offer_packet) { | |||
| 874 | new_offer->next = dhcp_offer_list; | 974 | new_offer->next = dhcp_offer_list; |
| 875 | dhcp_offer_list = new_offer; | 975 | dhcp_offer_list = new_offer; |
| 876 | 976 | ||
| 877 | return OK; | 977 | add_dhcp_offer_wrapper result = { |
| 978 | .error = OK, | ||
| 979 | .dhcp_offer_list = dhcp_offer_list, | ||
| 980 | }; | ||
| 981 | |||
| 982 | return result; | ||
| 878 | } | 983 | } |
| 879 | 984 | ||
| 880 | /* frees memory allocated to DHCP OFFER list */ | 985 | /* frees memory allocated to DHCP OFFER list */ |
| 881 | static int free_dhcp_offer_list(void) { | 986 | int free_dhcp_offer_list(dhcp_offer *dhcp_offer_list) { |
| 882 | dhcp_offer *this_offer; | ||
| 883 | dhcp_offer *next_offer; | 987 | dhcp_offer *next_offer; |
| 884 | 988 | for (dhcp_offer *this_offer = dhcp_offer_list; this_offer != NULL; this_offer = next_offer) { | |
| 885 | for (this_offer = dhcp_offer_list; this_offer != NULL; this_offer = next_offer) { | ||
| 886 | next_offer = this_offer->next; | 989 | next_offer = this_offer->next; |
| 887 | free(this_offer); | 990 | free(this_offer); |
| 888 | } | 991 | } |
| @@ -891,11 +994,10 @@ static int free_dhcp_offer_list(void) { | |||
| 891 | } | 994 | } |
| 892 | 995 | ||
| 893 | /* frees memory allocated to requested server list */ | 996 | /* frees memory allocated to requested server list */ |
| 894 | static int free_requested_server_list(void) { | 997 | int free_requested_server_list(requested_server *requested_server_list) { |
| 895 | requested_server *this_server; | ||
| 896 | requested_server *next_server; | 998 | requested_server *next_server; |
| 897 | 999 | for (requested_server *this_server = requested_server_list; this_server != NULL; | |
| 898 | for (this_server = requested_server_list; this_server != NULL; this_server = next_server) { | 1000 | this_server = next_server) { |
| 899 | next_server = this_server->next; | 1001 | next_server = this_server->next; |
| 900 | free(this_server); | 1002 | free(this_server); |
| 901 | } | 1003 | } |
| @@ -904,39 +1006,68 @@ static int free_requested_server_list(void) { | |||
| 904 | } | 1006 | } |
| 905 | 1007 | ||
| 906 | /* gets state and plugin output to return */ | 1008 | /* gets state and plugin output to return */ |
| 907 | static int get_results(void) { | 1009 | mp_subcheck get_results(bool exclusive, const int requested_servers, |
| 908 | dhcp_offer *temp_offer, *undesired_offer = NULL; | 1010 | const struct in_addr requested_address, bool request_specific_address, |
| 909 | requested_server *temp_server; | 1011 | requested_server *requested_server_list, int valid_responses, |
| 910 | int result; | 1012 | dhcp_offer *dhcp_offer_list) { |
| 911 | uint32_t max_lease_time = 0; | 1013 | mp_subcheck sc_dhcp_results = mp_subcheck_init(); |
| 1014 | sc_dhcp_results = mp_set_subcheck_default_state(sc_dhcp_results, STATE_OK); | ||
| 912 | 1015 | ||
| 913 | received_requested_address = false; | 1016 | /* we didn't receive any DHCPOFFERs */ |
| 914 | 1017 | if (dhcp_offer_list == NULL) { | |
| 915 | /* checks responses from requested servers */ | 1018 | sc_dhcp_results = mp_set_subcheck_state(sc_dhcp_results, STATE_CRITICAL); |
| 916 | requested_responses = 0; | 1019 | xasprintf(&sc_dhcp_results.output, "%s", "No DHCPOFFERs were received"); |
| 917 | if (requested_servers > 0) { | 1020 | return sc_dhcp_results; |
| 1021 | } | ||
| 918 | 1022 | ||
| 919 | for (temp_server = requested_server_list; temp_server != NULL; temp_server = temp_server->next) { | 1023 | if (valid_responses == 0) { |
| 1024 | // No valid responses at all, so early exit here | ||
| 1025 | sc_dhcp_results = mp_set_subcheck_state(sc_dhcp_results, STATE_CRITICAL); | ||
| 1026 | xasprintf(&sc_dhcp_results.output, "No valid responses received"); | ||
| 1027 | return sc_dhcp_results; | ||
| 1028 | } | ||
| 920 | 1029 | ||
| 921 | for (temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) { | 1030 | if (valid_responses == 1) { |
| 1031 | xasprintf(&sc_dhcp_results.output, "Received %d DHCPOFFER", valid_responses); | ||
| 1032 | } else { | ||
| 1033 | xasprintf(&sc_dhcp_results.output, "Received %d DHCPOFFERs", valid_responses); | ||
| 1034 | } | ||
| 922 | 1035 | ||
| 1036 | bool received_requested_address = false; | ||
| 1037 | dhcp_offer *undesired_offer = NULL; | ||
| 1038 | uint32_t max_lease_time = 0; | ||
| 1039 | /* checks responses from requested servers */ | ||
| 1040 | int requested_responses = 0; | ||
| 1041 | if (requested_servers > 0) { | ||
| 1042 | for (requested_server *temp_server = requested_server_list; temp_server != NULL; | ||
| 1043 | temp_server = temp_server->next) { | ||
| 1044 | for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; | ||
| 1045 | temp_offer = temp_offer->next) { | ||
| 923 | /* get max lease time we were offered */ | 1046 | /* get max lease time we were offered */ |
| 924 | if (temp_offer->lease_time > max_lease_time || temp_offer->lease_time == DHCP_INFINITE_TIME) | 1047 | if (temp_offer->lease_time > max_lease_time || |
| 1048 | temp_offer->lease_time == DHCP_INFINITE_TIME) { | ||
| 925 | max_lease_time = temp_offer->lease_time; | 1049 | max_lease_time = temp_offer->lease_time; |
| 1050 | } | ||
| 926 | 1051 | ||
| 927 | /* see if we got the address we requested */ | 1052 | /* see if we got the address we requested */ |
| 928 | if (!memcmp(&requested_address, &temp_offer->offered_address, sizeof(requested_address))) | 1053 | if (!memcmp(&requested_address, &temp_offer->offered_address, |
| 1054 | sizeof(requested_address))) { | ||
| 929 | received_requested_address = true; | 1055 | received_requested_address = true; |
| 1056 | } | ||
| 930 | 1057 | ||
| 931 | /* see if the servers we wanted a response from talked to us or not */ | 1058 | /* see if the servers we wanted a response from, talked to us or not */ |
| 932 | if (!memcmp(&temp_offer->server_address, &temp_server->server_address, sizeof(temp_server->server_address))) { | 1059 | if (!memcmp(&temp_offer->server_address, &temp_server->server_address, |
| 1060 | sizeof(temp_server->server_address))) { | ||
| 933 | if (verbose) { | 1061 | if (verbose) { |
| 934 | printf(_("DHCP Server Match: Offerer=%s"), inet_ntoa(temp_offer->server_address)); | 1062 | printf(_("DHCP Server Match: Offerer=%s"), |
| 1063 | inet_ntoa(temp_offer->server_address)); | ||
| 935 | printf(_(" Requested=%s"), inet_ntoa(temp_server->server_address)); | 1064 | printf(_(" Requested=%s"), inet_ntoa(temp_server->server_address)); |
| 936 | if (temp_server->answered) | 1065 | if (temp_server->answered) { |
| 937 | printf(_(" (duplicate)")); | 1066 | printf(_(" (duplicate)")); |
| 1067 | } | ||
| 938 | printf(_("\n")); | 1068 | printf(_("\n")); |
| 939 | } | 1069 | } |
| 1070 | |||
| 940 | if (!temp_server->answered) { | 1071 | if (!temp_server->answered) { |
| 941 | requested_responses++; | 1072 | requested_responses++; |
| 942 | temp_server->answered = true; | 1073 | temp_server->answered = true; |
| @@ -947,160 +1078,188 @@ static int get_results(void) { | |||
| 947 | } | 1078 | } |
| 948 | 1079 | ||
| 949 | /* exclusive mode: check for undesired offers */ | 1080 | /* exclusive mode: check for undesired offers */ |
| 950 | for (temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) { | 1081 | for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; |
| 1082 | temp_offer = temp_offer->next) { | ||
| 951 | if (!temp_offer->desired) { | 1083 | if (!temp_offer->desired) { |
| 952 | undesired_offer = temp_offer; /* Checks only for the first undesired offer */ | 1084 | undesired_offer = temp_offer; /* Checks only for the first undesired offer */ |
| 953 | break; /* no further checks needed */ | 1085 | break; /* no further checks needed */ |
| 954 | } | 1086 | } |
| 955 | } | 1087 | } |
| 956 | } | ||
| 957 | 1088 | ||
| 958 | /* else check and see if we got our requested address from any server */ | 1089 | mp_subcheck sc_rqust_srvs = mp_subcheck_init(); |
| 959 | else { | 1090 | xasprintf(&sc_rqust_srvs.output, "%d of %d requested servers responded", |
| 1091 | requested_responses, requested_servers); | ||
| 960 | 1092 | ||
| 961 | for (temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) { | 1093 | if (requested_responses == requested_servers) { |
| 1094 | sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, STATE_OK); | ||
| 1095 | } else if (requested_responses == 0) { | ||
| 1096 | sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, STATE_CRITICAL); | ||
| 1097 | } else if (requested_responses < requested_servers) { | ||
| 1098 | sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, STATE_WARNING); | ||
| 1099 | } else { | ||
| 1100 | // We received more(!) responses than we asked for? | ||
| 1101 | // This case shouldn't happen, but is here for completion | ||
| 1102 | sc_rqust_srvs = mp_set_subcheck_state(sc_rqust_srvs, STATE_WARNING); | ||
| 1103 | } | ||
| 1104 | mp_add_subcheck_to_subcheck(&sc_dhcp_results, sc_rqust_srvs); | ||
| 962 | 1105 | ||
| 1106 | } else { | ||
| 1107 | /* else check and see if we got our requested address from any server */ | ||
| 1108 | for (dhcp_offer *temp_offer = dhcp_offer_list; temp_offer != NULL; | ||
| 1109 | temp_offer = temp_offer->next) { | ||
| 963 | /* get max lease time we were offered */ | 1110 | /* get max lease time we were offered */ |
| 964 | if (temp_offer->lease_time > max_lease_time || temp_offer->lease_time == DHCP_INFINITE_TIME) | 1111 | if (temp_offer->lease_time > max_lease_time || |
| 1112 | temp_offer->lease_time == DHCP_INFINITE_TIME) { | ||
| 965 | max_lease_time = temp_offer->lease_time; | 1113 | max_lease_time = temp_offer->lease_time; |
| 1114 | } | ||
| 966 | 1115 | ||
| 967 | /* see if we got the address we requested */ | 1116 | /* see if we got the address we requested */ |
| 968 | if (!memcmp(&requested_address, &temp_offer->offered_address, sizeof(requested_address))) | 1117 | if (!memcmp(&requested_address, &temp_offer->offered_address, |
| 1118 | sizeof(requested_address))) { | ||
| 969 | received_requested_address = true; | 1119 | received_requested_address = true; |
| 1120 | } | ||
| 970 | } | 1121 | } |
| 971 | } | 1122 | } |
| 972 | 1123 | ||
| 973 | result = STATE_OK; | 1124 | if (max_lease_time == DHCP_INFINITE_TIME) { |
| 974 | if (valid_responses == 0) | 1125 | xasprintf(&sc_dhcp_results.output, "%s, max lease time = Infinity", sc_dhcp_results.output); |
| 975 | result = STATE_CRITICAL; | 1126 | } else { |
| 976 | else if (requested_servers > 0 && requested_responses == 0) | 1127 | xasprintf(&sc_dhcp_results.output, "%s, max lease time = %" PRIu32 " seconds", |
| 977 | result = STATE_CRITICAL; | 1128 | sc_dhcp_results.output, max_lease_time); |
| 978 | else if (requested_responses < requested_servers) | ||
| 979 | result = STATE_WARNING; | ||
| 980 | else if (request_specific_address && !received_requested_address) | ||
| 981 | result = STATE_WARNING; | ||
| 982 | |||
| 983 | if (exclusive && undesired_offer) | ||
| 984 | result = STATE_CRITICAL; | ||
| 985 | |||
| 986 | if (result == 0) /* garrett honeycutt 2005 */ | ||
| 987 | printf("OK: "); | ||
| 988 | else if (result == 1) | ||
| 989 | printf("WARNING: "); | ||
| 990 | else if (result == 2) | ||
| 991 | printf("CRITICAL: "); | ||
| 992 | else if (result == 3) | ||
| 993 | printf("UNKNOWN: "); | ||
| 994 | |||
| 995 | /* we didn't receive any DHCPOFFERs */ | ||
| 996 | if (dhcp_offer_list == NULL) { | ||
| 997 | printf(_("No DHCPOFFERs were received.\n")); | ||
| 998 | return result; | ||
| 999 | } | 1129 | } |
| 1000 | 1130 | ||
| 1001 | printf(_("Received %d DHCPOFFER(s)"), valid_responses); | 1131 | if (exclusive) { |
| 1132 | mp_subcheck sc_rogue_server = mp_subcheck_init(); | ||
| 1002 | 1133 | ||
| 1003 | if (exclusive && undesired_offer) { | 1134 | if (undesired_offer != NULL) { |
| 1004 | printf(_(", Rogue DHCP Server detected! Server %s"), inet_ntoa(undesired_offer->server_address)); | 1135 | // We wanted to get a DHCPOFFER exclusively from one machine, but another one |
| 1005 | printf(_(" offered %s \n"), inet_ntoa(undesired_offer->offered_address)); | 1136 | // sent one (too) |
| 1006 | return result; | 1137 | sc_rogue_server = mp_set_subcheck_state(sc_rogue_server, STATE_CRITICAL); |
| 1007 | } | ||
| 1008 | 1138 | ||
| 1009 | if (requested_servers > 0) | 1139 | // Get the addresses for printout |
| 1010 | printf(_(", %s%d of %d requested servers responded"), ((requested_responses < requested_servers) && requested_responses > 0) ? "only " : "", requested_responses, | 1140 | // 1.address of the sending server |
| 1011 | requested_servers); | 1141 | char server_address[INET_ADDRSTRLEN]; |
| 1142 | const char *server_address_transformed = inet_ntop( | ||
| 1143 | AF_INET, &undesired_offer->server_address, server_address, sizeof(server_address)); | ||
| 1012 | 1144 | ||
| 1013 | if (request_specific_address) | 1145 | if (server_address != server_address_transformed) { |
| 1014 | printf(_(", requested address (%s) was %soffered"), inet_ntoa(requested_address), (received_requested_address) ? "" : _("not ")); | 1146 | die(STATE_UNKNOWN, "inet_ntop failed"); |
| 1147 | } | ||
| 1015 | 1148 | ||
| 1016 | printf(_(", max lease time = ")); | 1149 | // 2.address offered |
| 1017 | if (max_lease_time == DHCP_INFINITE_TIME) | 1150 | char offered_address[INET_ADDRSTRLEN]; |
| 1018 | printf(_("Infinity")); | 1151 | const char *offered_address_transformed = |
| 1019 | else | 1152 | inet_ntop(AF_INET, &undesired_offer->offered_address, offered_address, |
| 1020 | printf("%lu sec", (unsigned long)max_lease_time); | 1153 | sizeof(offered_address)); |
| 1021 | 1154 | ||
| 1022 | printf(".\n"); | 1155 | if (offered_address != offered_address_transformed) { |
| 1156 | die(STATE_UNKNOWN, "inet_ntop failed"); | ||
| 1157 | } | ||
| 1023 | 1158 | ||
| 1024 | return result; | 1159 | xasprintf(&sc_rogue_server.output, "Rogue DHCP Server detected! Server %s offered %s", |
| 1160 | server_address, offered_address); | ||
| 1161 | } else { | ||
| 1162 | sc_rogue_server = mp_set_subcheck_state(sc_rogue_server, STATE_OK); | ||
| 1163 | xasprintf(&sc_rogue_server.output, "No Rogue DHCP Server detected"); | ||
| 1164 | } | ||
| 1165 | mp_add_subcheck_to_subcheck(&sc_dhcp_results, sc_rogue_server); | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | if (request_specific_address) { | ||
| 1169 | mp_subcheck sc_rqustd_addr = mp_subcheck_init(); | ||
| 1170 | |||
| 1171 | if (received_requested_address) { | ||
| 1172 | sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, STATE_OK); | ||
| 1173 | xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was offered", | ||
| 1174 | inet_ntoa(requested_address)); | ||
| 1175 | } else { | ||
| 1176 | sc_rqustd_addr = mp_set_subcheck_state(sc_rqustd_addr, STATE_WARNING); | ||
| 1177 | xasprintf(&sc_rqustd_addr.output, "Requested address (%s) was NOT offered", | ||
| 1178 | inet_ntoa(requested_address)); | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | mp_add_subcheck_to_subcheck(&sc_dhcp_results, sc_rqustd_addr); | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | return sc_dhcp_results; | ||
| 1025 | } | 1185 | } |
| 1026 | 1186 | ||
| 1027 | /* process command-line arguments */ | 1187 | /* process command-line arguments */ |
| 1028 | static int process_arguments(int argc, char **argv) { | 1188 | process_arguments_wrapper process_arguments(int argc, char **argv) { |
| 1029 | if (argc < 1) | 1189 | if (argc < 1) { |
| 1030 | return ERROR; | 1190 | process_arguments_wrapper tmp = { |
| 1191 | .error = ERROR, | ||
| 1192 | }; | ||
| 1193 | return tmp; | ||
| 1194 | } | ||
| 1031 | 1195 | ||
| 1032 | call_getopt(argc, argv); | 1196 | enum { |
| 1033 | return validate_arguments(argc); | 1197 | output_format_index = CHAR_MAX + 1, |
| 1034 | } | 1198 | }; |
| 1035 | 1199 | ||
| 1036 | static int call_getopt(int argc, char **argv) { | ||
| 1037 | extern int optind; | ||
| 1038 | int option_index = 0; | 1200 | int option_index = 0; |
| 1039 | static struct option long_options[] = {{"serverip", required_argument, 0, 's'}, | 1201 | static struct option long_options[] = { |
| 1040 | {"requestedip", required_argument, 0, 'r'}, | 1202 | {"serverip", required_argument, 0, 's'}, |
| 1041 | {"timeout", required_argument, 0, 't'}, | 1203 | {"requestedip", required_argument, 0, 'r'}, |
| 1042 | {"interface", required_argument, 0, 'i'}, | 1204 | {"timeout", required_argument, 0, 't'}, |
| 1043 | {"mac", required_argument, 0, 'm'}, | 1205 | {"interface", required_argument, 0, 'i'}, |
| 1044 | {"unicast", no_argument, 0, 'u'}, | 1206 | {"mac", required_argument, 0, 'm'}, |
| 1045 | {"exclusive", no_argument, 0, 'x'}, | 1207 | {"unicast", no_argument, 0, 'u'}, |
| 1046 | {"verbose", no_argument, 0, 'v'}, | 1208 | {"exclusive", no_argument, 0, 'x'}, |
| 1047 | {"version", no_argument, 0, 'V'}, | 1209 | {"verbose", no_argument, 0, 'v'}, |
| 1048 | {"help", no_argument, 0, 'h'}, | 1210 | {"version", no_argument, 0, 'V'}, |
| 1049 | {0, 0, 0, 0}}; | 1211 | {"help", no_argument, 0, 'h'}, |
| 1050 | 1212 | {"output-format", required_argument, 0, output_format_index}, | |
| 1051 | int c = 0; | 1213 | {0, 0, 0, 0}}; |
| 1214 | |||
| 1215 | check_dhcp_config config = check_dhcp_config_init(); | ||
| 1216 | int option_char = 0; | ||
| 1052 | while (true) { | 1217 | while (true) { |
| 1053 | c = getopt_long(argc, argv, "+hVvxt:s:r:t:i:m:u", long_options, &option_index); | 1218 | option_char = getopt_long(argc, argv, "+hVvxt:s:r:t:i:m:u", long_options, &option_index); |
| 1054 | 1219 | ||
| 1055 | if (c == -1 || c == EOF || c == 1) | 1220 | if (option_char == -1 || option_char == EOF || option_char == 1) { |
| 1056 | break; | 1221 | break; |
| 1222 | } | ||
| 1057 | 1223 | ||
| 1058 | switch (c) { | 1224 | switch (option_char) { |
| 1059 | |||
| 1060 | case 's': /* DHCP server address */ | 1225 | case 's': /* DHCP server address */ |
| 1061 | resolve_host(optarg, &dhcp_ip); | 1226 | resolve_host(optarg, &config.dhcp_ip); |
| 1062 | add_requested_server(dhcp_ip); | 1227 | add_requested_server(config.dhcp_ip, &config.num_of_requested_servers, |
| 1228 | &config.requested_server_list); | ||
| 1063 | break; | 1229 | break; |
| 1064 | 1230 | ||
| 1065 | case 'r': /* address we are requested from DHCP servers */ | 1231 | case 'r': /* address we are requested from DHCP servers */ |
| 1066 | resolve_host(optarg, &requested_address); | 1232 | resolve_host(optarg, &config.requested_address); |
| 1067 | request_specific_address = true; | 1233 | config.request_specific_address = true; |
| 1068 | break; | 1234 | break; |
| 1069 | 1235 | ||
| 1070 | case 't': /* timeout */ | 1236 | case 't': /* timeout */ |
| 1071 | 1237 | if (atoi(optarg) > 0) { | |
| 1072 | /* | 1238 | config.dhcpoffer_timeout = atoi(optarg); |
| 1073 | if(is_intnonneg(optarg)) | 1239 | } |
| 1074 | */ | ||
| 1075 | if (atoi(optarg) > 0) | ||
| 1076 | dhcpoffer_timeout = atoi(optarg); | ||
| 1077 | /* | ||
| 1078 | else | ||
| 1079 | usage("Time interval must be a nonnegative integer\n"); | ||
| 1080 | */ | ||
| 1081 | break; | 1240 | break; |
| 1082 | 1241 | ||
| 1083 | case 'm': /* MAC address */ | 1242 | case 'm': /* MAC address */ |
| 1084 | 1243 | if ((config.user_specified_mac = mac_aton(optarg)) == NULL) { | |
| 1085 | if ((user_specified_mac = mac_aton(optarg)) == NULL) | ||
| 1086 | usage("Cannot parse MAC address.\n"); | 1244 | usage("Cannot parse MAC address.\n"); |
| 1087 | if (verbose) | 1245 | } |
| 1088 | print_hardware_address(user_specified_mac); | 1246 | if (verbose) { |
| 1089 | 1247 | print_hardware_address(config.user_specified_mac); | |
| 1248 | } | ||
| 1090 | break; | 1249 | break; |
| 1091 | 1250 | ||
| 1092 | case 'i': /* interface name */ | 1251 | case 'i': /* interface name */ |
| 1093 | 1252 | strncpy(config.network_interface_name, optarg, | |
| 1094 | strncpy(network_interface_name, optarg, sizeof(network_interface_name) - 1); | 1253 | sizeof(config.network_interface_name) - 1); |
| 1095 | network_interface_name[sizeof(network_interface_name) - 1] = '\x0'; | 1254 | config.network_interface_name[sizeof(config.network_interface_name) - 1] = '\x0'; |
| 1096 | |||
| 1097 | break; | 1255 | break; |
| 1098 | 1256 | ||
| 1099 | case 'u': /* unicast testing */ | 1257 | case 'u': /* unicast testing */ |
| 1100 | unicast = true; | 1258 | config.unicast_mode = true; |
| 1101 | break; | 1259 | break; |
| 1260 | |||
| 1102 | case 'x': /* exclusive testing aka "rogue DHCP server detection" */ | 1261 | case 'x': /* exclusive testing aka "rogue DHCP server detection" */ |
| 1103 | exclusive = true; | 1262 | config.exclusive_mode = true; |
| 1104 | break; | 1263 | break; |
| 1105 | 1264 | ||
| 1106 | case 'V': /* version */ | 1265 | case 'V': /* version */ |
| @@ -1114,6 +1273,18 @@ static int call_getopt(int argc, char **argv) { | |||
| 1114 | case 'v': /* verbose */ | 1273 | case 'v': /* verbose */ |
| 1115 | verbose = 1; | 1274 | verbose = 1; |
| 1116 | break; | 1275 | break; |
| 1276 | case output_format_index: { | ||
| 1277 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 1278 | if (!parser.parsing_success) { | ||
| 1279 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 1280 | printf("Invalid output format: %s\n", optarg); | ||
| 1281 | exit(STATE_UNKNOWN); | ||
| 1282 | } | ||
| 1283 | |||
| 1284 | config.output_format_is_set = true; | ||
| 1285 | config.output_format = parser.output_format; | ||
| 1286 | break; | ||
| 1287 | } | ||
| 1117 | case '?': /* help */ | 1288 | case '?': /* help */ |
| 1118 | usage5(); | 1289 | usage5(); |
| 1119 | break; | 1290 | break; |
| @@ -1122,15 +1293,16 @@ static int call_getopt(int argc, char **argv) { | |||
| 1122 | break; | 1293 | break; |
| 1123 | } | 1294 | } |
| 1124 | } | 1295 | } |
| 1125 | return optind; | ||
| 1126 | } | ||
| 1127 | 1296 | ||
| 1128 | static int validate_arguments(int argc) { | 1297 | if (argc - optind > 0) { |
| 1129 | |||
| 1130 | if (argc - optind > 0) | ||
| 1131 | usage(_("Got unexpected non-option argument")); | 1298 | usage(_("Got unexpected non-option argument")); |
| 1299 | } | ||
| 1132 | 1300 | ||
| 1133 | return OK; | 1301 | process_arguments_wrapper result = { |
| 1302 | .config = config, | ||
| 1303 | .error = OK, | ||
| 1304 | }; | ||
| 1305 | return result; | ||
| 1134 | } | 1306 | } |
| 1135 | 1307 | ||
| 1136 | #if defined(__sun__) || defined(__solaris__) || defined(__hpux__) | 1308 | #if defined(__sun__) || defined(__solaris__) || defined(__hpux__) |
| @@ -1180,7 +1352,8 @@ static int put_ctrl(int fd, int len, int pri) { | |||
| 1180 | 1352 | ||
| 1181 | ctl.len = len; | 1353 | ctl.len = len; |
| 1182 | if (putmsg(fd, &ctl, 0, pri) < 0) { | 1354 | if (putmsg(fd, &ctl, 0, pri) < 0) { |
| 1183 | printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), strerror(errno)); | 1355 | printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), |
| 1356 | strerror(errno)); | ||
| 1184 | exit(STATE_UNKNOWN); | 1357 | exit(STATE_UNKNOWN); |
| 1185 | } | 1358 | } |
| 1186 | 1359 | ||
| @@ -1193,7 +1366,8 @@ static int put_both(int fd, int clen, int dlen, int pri) { | |||
| 1193 | ctl.len = clen; | 1366 | ctl.len = clen; |
| 1194 | dat.len = dlen; | 1367 | dat.len = dlen; |
| 1195 | if (putmsg(fd, &ctl, &dat, pri) < 0) { | 1368 | if (putmsg(fd, &ctl, &dat, pri) < 0) { |
| 1196 | printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), strerror(errno)); | 1369 | printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), |
| 1370 | strerror(errno)); | ||
| 1197 | exit(STATE_UNKNOWN); | 1371 | exit(STATE_UNKNOWN); |
| 1198 | } | 1372 | } |
| 1199 | 1373 | ||
| @@ -1205,7 +1379,8 @@ static int dl_open(const char *dev, int unit, int *fd) { | |||
| 1205 | dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area; | 1379 | dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area; |
| 1206 | 1380 | ||
| 1207 | if ((*fd = open(dev, O_RDWR)) == -1) { | 1381 | if ((*fd = open(dev, O_RDWR)) == -1) { |
| 1208 | printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), dev, strerror(errno)); | 1382 | printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), |
| 1383 | dev, strerror(errno)); | ||
| 1209 | exit(STATE_UNKNOWN); | 1384 | exit(STATE_UNKNOWN); |
| 1210 | } | 1385 | } |
| 1211 | attach_req->dl_primitive = DL_ATTACH_REQ; | 1386 | attach_req->dl_primitive = DL_ATTACH_REQ; |
| @@ -1229,7 +1404,8 @@ static int dl_bind(int fd, int sap, u_char *addr) { | |||
| 1229 | put_ctrl(fd, sizeof(dl_bind_req_t), 0); | 1404 | put_ctrl(fd, sizeof(dl_bind_req_t), 0); |
| 1230 | get_msg(fd); | 1405 | get_msg(fd); |
| 1231 | if (GOT_ERR == check_ctrl(DL_BIND_ACK)) { | 1406 | if (GOT_ERR == check_ctrl(DL_BIND_ACK)) { |
| 1232 | printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), strerror(errno)); | 1407 | printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), |
| 1408 | strerror(errno)); | ||
| 1233 | exit(STATE_UNKNOWN); | 1409 | exit(STATE_UNKNOWN); |
| 1234 | } | 1410 | } |
| 1235 | bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, bind_ack->dl_addr_length); | 1411 | bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, bind_ack->dl_addr_length); |
| @@ -1249,7 +1425,7 @@ static int dl_bind(int fd, int sap, u_char *addr) { | |||
| 1249 | * | 1425 | * |
| 1250 | ***********************************************************************/ | 1426 | ***********************************************************************/ |
| 1251 | 1427 | ||
| 1252 | static long mac_addr_dlpi(const char *dev, int unit, u_char *addr) { | 1428 | long mac_addr_dlpi(const char *dev, int unit, u_char *addr) { |
| 1253 | int fd; | 1429 | int fd; |
| 1254 | u_char mac_addr[25]; | 1430 | u_char mac_addr[25]; |
| 1255 | 1431 | ||
| @@ -1268,51 +1444,53 @@ static long mac_addr_dlpi(const char *dev, int unit, u_char *addr) { | |||
| 1268 | #endif | 1444 | #endif |
| 1269 | 1445 | ||
| 1270 | /* resolve host name or die (TODO: move this to netutils.c!) */ | 1446 | /* resolve host name or die (TODO: move this to netutils.c!) */ |
| 1271 | static void resolve_host(const char *in, struct in_addr *out) { | 1447 | void resolve_host(const char *name, struct in_addr *out) { |
| 1272 | struct addrinfo hints, *ai; | 1448 | struct addrinfo hints = { |
| 1449 | .ai_family = PF_INET, | ||
| 1450 | }; | ||
| 1451 | struct addrinfo *addr_info; | ||
| 1273 | 1452 | ||
| 1274 | memset(&hints, 0, sizeof(hints)); | 1453 | if (getaddrinfo(name, NULL, &hints, &addr_info) != 0) { |
| 1275 | hints.ai_family = PF_INET; | ||
| 1276 | if (getaddrinfo(in, NULL, &hints, &ai) != 0) | ||
| 1277 | usage_va(_("Invalid hostname/address - %s"), optarg); | 1454 | usage_va(_("Invalid hostname/address - %s"), optarg); |
| 1455 | } | ||
| 1278 | 1456 | ||
| 1279 | memcpy(out, &((struct sockaddr_in *)ai->ai_addr)->sin_addr, sizeof(*out)); | 1457 | memcpy(out, &((struct sockaddr_in *)addr_info->ai_addr)->sin_addr, sizeof(*out)); |
| 1280 | freeaddrinfo(ai); | 1458 | freeaddrinfo(addr_info); |
| 1281 | } | 1459 | } |
| 1282 | 1460 | ||
| 1283 | /* parse MAC address string, return 6 bytes (unterminated) or NULL */ | 1461 | /* parse MAC address string, return 6 bytes (unterminated) or NULL */ |
| 1284 | static unsigned char *mac_aton(const char *string) { | 1462 | unsigned char *mac_aton(const char *string) { |
| 1285 | static unsigned char result[6]; | 1463 | static unsigned char result[MAC_ADDR_LEN]; |
| 1286 | char tmp[3]; | 1464 | char tmp[3]; |
| 1287 | unsigned i, j; | 1465 | unsigned byte_counter = 0; |
| 1288 | 1466 | ||
| 1289 | for (i = 0, j = 0; string[i] != '\0' && j < sizeof(result); i++) { | 1467 | for (int i = 0; string[i] != '\0' && byte_counter < sizeof(result); i++) { |
| 1290 | /* ignore ':' and any other non-hex character */ | 1468 | /* ignore ':' and any other non-hex character */ |
| 1291 | if (!isxdigit(string[i]) || !isxdigit(string[i + 1])) | 1469 | if (!isxdigit(string[i]) || !isxdigit(string[i + 1])) { |
| 1292 | continue; | 1470 | continue; |
| 1471 | } | ||
| 1293 | tmp[0] = string[i]; | 1472 | tmp[0] = string[i]; |
| 1294 | tmp[1] = string[i + 1]; | 1473 | tmp[1] = string[i + 1]; |
| 1295 | tmp[2] = '\0'; | 1474 | tmp[2] = '\0'; |
| 1296 | result[j] = strtol(tmp, (char **)NULL, 16); | 1475 | result[byte_counter] = strtol(tmp, (char **)NULL, 16); |
| 1297 | i++; | 1476 | i++; |
| 1298 | j++; | 1477 | byte_counter++; |
| 1299 | } | 1478 | } |
| 1300 | 1479 | ||
| 1301 | return (j == 6) ? result : NULL; | 1480 | return (byte_counter == MAC_ADDR_LEN) ? result : NULL; |
| 1302 | } | 1481 | } |
| 1303 | 1482 | ||
| 1304 | static void print_hardware_address(const unsigned char *address) { | 1483 | void print_hardware_address(const unsigned char *address) { |
| 1305 | int i; | ||
| 1306 | 1484 | ||
| 1307 | printf(_("Hardware address: ")); | 1485 | printf(_("Hardware address: ")); |
| 1308 | for (i = 0; i < 5; i++) | 1486 | for (int addr_idx = 0; addr_idx < MAC_ADDR_LEN; addr_idx++) { |
| 1309 | printf("%2.2x:", address[i]); | 1487 | printf("%2.2x:", address[addr_idx]); |
| 1310 | printf("%2.2x", address[i]); | 1488 | } |
| 1311 | putchar('\n'); | 1489 | putchar('\n'); |
| 1312 | } | 1490 | } |
| 1313 | 1491 | ||
| 1314 | /* print usage help */ | 1492 | /* print usage help */ |
| 1315 | static void print_help(void) { | 1493 | void print_help(void) { |
| 1316 | 1494 | ||
| 1317 | print_revision(progname, NP_VERSION); | 1495 | print_revision(progname, NP_VERSION); |
| 1318 | 1496 | ||
| @@ -1328,6 +1506,7 @@ static void print_help(void) { | |||
| 1328 | printf(UT_HELP_VRSN); | 1506 | printf(UT_HELP_VRSN); |
| 1329 | printf(UT_EXTRA_OPTS); | 1507 | printf(UT_EXTRA_OPTS); |
| 1330 | 1508 | ||
| 1509 | printf(UT_OUTPUT_FORMAT); | ||
| 1331 | printf(UT_VERBOSE); | 1510 | printf(UT_VERBOSE); |
| 1332 | 1511 | ||
| 1333 | printf(" %s\n", "-s, --serverip=IPADDRESS"); | 1512 | printf(" %s\n", "-s, --serverip=IPADDRESS"); |
| @@ -1343,10 +1522,10 @@ static void print_help(void) { | |||
| 1343 | printf(" %s\n", "-u, --unicast"); | 1522 | printf(" %s\n", "-u, --unicast"); |
| 1344 | printf(" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s")); | 1523 | printf(" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s")); |
| 1345 | printf(" %s\n", "-x, --exclusive"); | 1524 | printf(" %s\n", "-x, --exclusive"); |
| 1346 | printf(" %s\n", _("Only requested DHCP server may response (rogue DHCP server detection), requires -s")); | 1525 | printf(" %s\n", |
| 1526 | _("Only requested DHCP server may response (rogue DHCP server detection), requires -s")); | ||
| 1347 | 1527 | ||
| 1348 | printf(UT_SUPPORT); | 1528 | printf(UT_SUPPORT); |
| 1349 | return; | ||
| 1350 | } | 1529 | } |
| 1351 | 1530 | ||
| 1352 | void print_usage(void) { | 1531 | void print_usage(void) { |
| @@ -1354,6 +1533,4 @@ void print_usage(void) { | |||
| 1354 | printf("%s\n", _("Usage:")); | 1533 | printf("%s\n", _("Usage:")); |
| 1355 | printf(" %s [-v] [-u] [-x] [-s serverip] [-r requestedip] [-t timeout]\n", progname); | 1534 | printf(" %s [-v] [-u] [-x] [-s serverip] [-r requestedip] [-t timeout]\n", progname); |
| 1356 | printf(" [-i interface] [-m mac]\n"); | 1535 | printf(" [-i interface] [-m mac]\n"); |
| 1357 | |||
| 1358 | return; | ||
| 1359 | } | 1536 | } |
diff --git a/plugins-root/check_dhcp.d/config.h b/plugins-root/check_dhcp.d/config.h new file mode 100644 index 00000000..f189068b --- /dev/null +++ b/plugins-root/check_dhcp.d/config.h | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include "../lib/states.h" | ||
| 5 | #include <stdbool.h> | ||
| 6 | #include <netinet/in.h> | ||
| 7 | #include "net/if.h" | ||
| 8 | #include "output.h" | ||
| 9 | |||
| 10 | typedef struct requested_server_struct { | ||
| 11 | struct in_addr server_address; | ||
| 12 | bool answered; | ||
| 13 | struct requested_server_struct *next; | ||
| 14 | } requested_server; | ||
| 15 | |||
| 16 | typedef struct check_dhcp_config { | ||
| 17 | bool unicast_mode; /* unicast mode: mimic a DHCP relay */ | ||
| 18 | bool exclusive_mode; /* exclusive mode aka "rogue DHCP server detection" */ | ||
| 19 | int num_of_requested_servers; | ||
| 20 | struct in_addr dhcp_ip; /* server to query (if in unicast mode) */ | ||
| 21 | struct in_addr requested_address; | ||
| 22 | bool request_specific_address; | ||
| 23 | |||
| 24 | int dhcpoffer_timeout; | ||
| 25 | unsigned char *user_specified_mac; | ||
| 26 | char network_interface_name[IFNAMSIZ]; | ||
| 27 | requested_server *requested_server_list; | ||
| 28 | |||
| 29 | mp_output_format output_format; | ||
| 30 | bool output_format_is_set; | ||
| 31 | } check_dhcp_config; | ||
| 32 | |||
| 33 | check_dhcp_config check_dhcp_config_init(void) { | ||
| 34 | check_dhcp_config tmp = { | ||
| 35 | .unicast_mode = false, | ||
| 36 | .exclusive_mode = false, | ||
| 37 | .num_of_requested_servers = 0, | ||
| 38 | .dhcp_ip = {0}, | ||
| 39 | .requested_address = {0}, | ||
| 40 | .request_specific_address = false, | ||
| 41 | |||
| 42 | .dhcpoffer_timeout = 2, | ||
| 43 | .user_specified_mac = NULL, | ||
| 44 | .network_interface_name = "eth0", | ||
| 45 | .requested_server_list = NULL, | ||
| 46 | |||
| 47 | .output_format_is_set = false, | ||
| 48 | }; | ||
| 49 | return tmp; | ||
| 50 | } | ||
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index dcaceddb..35cae3ed 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
| @@ -46,12 +46,17 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 46 | #include "../plugins/common.h" | 46 | #include "../plugins/common.h" |
| 47 | #include "netutils.h" | 47 | #include "netutils.h" |
| 48 | #include "utils.h" | 48 | #include "utils.h" |
| 49 | #include "output.h" | ||
| 50 | #include "perfdata.h" | ||
| 49 | 51 | ||
| 50 | #if HAVE_SYS_SOCKIO_H | 52 | #if HAVE_SYS_SOCKIO_H |
| 51 | # include <sys/sockio.h> | 53 | # include <sys/sockio.h> |
| 52 | #endif | 54 | #endif |
| 53 | 55 | ||
| 54 | #include <sys/time.h> | 56 | #include <sys/time.h> |
| 57 | #if defined(SIOCGIFADDR) | ||
| 58 | #include <sys/ioctl.h> | ||
| 59 | #endif /* SIOCGIFADDR */ | ||
| 55 | #include <errno.h> | 60 | #include <errno.h> |
| 56 | #include <signal.h> | 61 | #include <signal.h> |
| 57 | #include <ctype.h> | 62 | #include <ctype.h> |
| @@ -65,6 +70,17 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 65 | #include <netinet/icmp6.h> | 70 | #include <netinet/icmp6.h> |
| 66 | #include <arpa/inet.h> | 71 | #include <arpa/inet.h> |
| 67 | #include <math.h> | 72 | #include <math.h> |
| 73 | #include <netdb.h> | ||
| 74 | #include <sys/types.h> | ||
| 75 | #include <unistd.h> | ||
| 76 | #include <stdint.h> | ||
| 77 | #include <sys/socket.h> | ||
| 78 | #include <assert.h> | ||
| 79 | #include <sys/select.h> | ||
| 80 | |||
| 81 | #include "../lib/states.h" | ||
| 82 | #include "./check_icmp.d/config.h" | ||
| 83 | #include "./check_icmp.d/check_icmp_helpers.h" | ||
| 68 | 84 | ||
| 69 | /** sometimes undefined system macros (quite a few, actually) **/ | 85 | /** sometimes undefined system macros (quite a few, actually) **/ |
| 70 | #ifndef MAXTTL | 86 | #ifndef MAXTTL |
| @@ -96,56 +112,8 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 96 | # define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 | 112 | # define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 |
| 97 | #endif | 113 | #endif |
| 98 | 114 | ||
| 99 | typedef unsigned short range_t; /* type for get_range() -- unimplemented */ | ||
| 100 | |||
| 101 | typedef struct rta_host { | ||
| 102 | unsigned short id; /* id in **table, and icmp pkts */ | ||
| 103 | char *name; /* arg used for adding this host */ | ||
| 104 | char *msg; /* icmp error message, if any */ | ||
| 105 | struct sockaddr_storage saddr_in; /* the address of this host */ | ||
| 106 | struct sockaddr_storage error_addr; /* stores address of error replies */ | ||
| 107 | unsigned long long time_waited; /* total time waited, in usecs */ | ||
| 108 | unsigned int icmp_sent, icmp_recv, icmp_lost; /* counters */ | ||
| 109 | unsigned char icmp_type, icmp_code; /* type and code from errors */ | ||
| 110 | unsigned short flags; /* control/status flags */ | ||
| 111 | double rta; /* measured RTA */ | ||
| 112 | int rta_status; // check result for RTA checks | ||
| 113 | double rtmax; /* max rtt */ | ||
| 114 | double rtmin; /* min rtt */ | ||
| 115 | double jitter; /* measured jitter */ | ||
| 116 | int jitter_status; // check result for Jitter checks | ||
| 117 | double jitter_max; /* jitter rtt maximum */ | ||
| 118 | double jitter_min; /* jitter rtt minimum */ | ||
| 119 | double EffectiveLatency; | ||
| 120 | double mos; /* Mean opnion score */ | ||
| 121 | int mos_status; // check result for MOS checks | ||
| 122 | double score; /* score */ | ||
| 123 | int score_status; // check result for score checks | ||
| 124 | u_int last_tdiff; | ||
| 125 | u_int last_icmp_seq; /* Last ICMP_SEQ to check out of order pkts */ | ||
| 126 | unsigned char pl; /* measured packet loss */ | ||
| 127 | int pl_status; // check result for packet loss checks | ||
| 128 | struct rta_host *next; /* linked list */ | ||
| 129 | int order_status; // check result for packet order checks | ||
| 130 | } rta_host; | ||
| 131 | |||
| 132 | #define FLAG_LOST_CAUSE 0x01 /* decidedly dead target. */ | 115 | #define FLAG_LOST_CAUSE 0x01 /* decidedly dead target. */ |
| 133 | 116 | ||
| 134 | /* threshold structure. all values are maximum allowed, exclusive */ | ||
| 135 | typedef struct threshold { | ||
| 136 | unsigned char pl; /* max allowed packet loss in percent */ | ||
| 137 | unsigned int rta; /* roundtrip time average, microseconds */ | ||
| 138 | double jitter; /* jitter time average, microseconds */ | ||
| 139 | double mos; /* MOS */ | ||
| 140 | double score; /* Score */ | ||
| 141 | } threshold; | ||
| 142 | |||
| 143 | /* the data structure */ | ||
| 144 | typedef struct icmp_ping_data { | ||
| 145 | struct timeval stime; /* timestamp (saved in protocol struct as well) */ | ||
| 146 | unsigned short ping_id; | ||
| 147 | } icmp_ping_data; | ||
| 148 | |||
| 149 | typedef union ip_hdr { | 117 | typedef union ip_hdr { |
| 150 | struct ip ip; | 118 | struct ip ip; |
| 151 | struct ip6_hdr ip6; | 119 | struct ip6_hdr ip6; |
| @@ -158,24 +126,6 @@ typedef union icmp_packet { | |||
| 158 | u_short *cksum_in; | 126 | u_short *cksum_in; |
| 159 | } icmp_packet; | 127 | } icmp_packet; |
| 160 | 128 | ||
| 161 | /* the different modes of this program are as follows: | ||
| 162 | * MODE_RTA: send all packets no matter what (mimic check_icmp and check_ping) | ||
| 163 | * MODE_HOSTCHECK: Return immediately upon any sign of life | ||
| 164 | * In addition, sends packets to ALL addresses assigned | ||
| 165 | * to this host (as returned by gethostbyname() or | ||
| 166 | * gethostbyaddr() and expects one host only to be checked at | ||
| 167 | * a time. Therefore, any packet response what so ever will | ||
| 168 | * count as a sign of life, even when received outside | ||
| 169 | * crit.rta limit. Do not misspell any additional IP's. | ||
| 170 | * MODE_ALL: Requires packets from ALL requested IP to return OK (default). | ||
| 171 | * MODE_ICMP: implement something similar to check_icmp (MODE_RTA without | ||
| 172 | * tcp and udp args does this) | ||
| 173 | */ | ||
| 174 | #define MODE_RTA 0 | ||
| 175 | #define MODE_HOSTCHECK 1 | ||
| 176 | #define MODE_ALL 2 | ||
| 177 | #define MODE_ICMP 3 | ||
| 178 | |||
| 179 | enum enum_threshold_mode { | 129 | enum enum_threshold_mode { |
| 180 | const_rta_mode, | 130 | const_rta_mode, |
| 181 | const_packet_loss_mode, | 131 | const_packet_loss_mode, |
| @@ -186,89 +136,487 @@ enum enum_threshold_mode { | |||
| 186 | 136 | ||
| 187 | typedef enum enum_threshold_mode threshold_mode; | 137 | typedef enum enum_threshold_mode threshold_mode; |
| 188 | 138 | ||
| 189 | /* the different ping types we can do | ||
| 190 | * TODO: investigate ARP ping as well */ | ||
| 191 | #define HAVE_ICMP 1 | ||
| 192 | #define HAVE_UDP 2 | ||
| 193 | #define HAVE_TCP 4 | ||
| 194 | #define HAVE_ARP 8 | ||
| 195 | |||
| 196 | #define MIN_PING_DATA_SIZE sizeof(struct icmp_ping_data) | ||
| 197 | #define MAX_IP_PKT_SIZE 65536 /* (theoretical) max IP packet size */ | ||
| 198 | #define IP_HDR_SIZE 20 | ||
| 199 | #define MAX_PING_DATA (MAX_IP_PKT_SIZE - IP_HDR_SIZE - ICMP_MINLEN) | ||
| 200 | #define DEFAULT_PING_DATA_SIZE (MIN_PING_DATA_SIZE + 44) | ||
| 201 | |||
| 202 | /* various target states */ | ||
| 203 | #define TSTATE_INACTIVE 0x01 /* don't ping this host anymore */ | ||
| 204 | #define TSTATE_WAITING 0x02 /* unanswered packets on the wire */ | ||
| 205 | #define TSTATE_ALIVE 0x04 /* target is alive (has answered something) */ | ||
| 206 | #define TSTATE_UNREACH 0x08 | ||
| 207 | |||
| 208 | /** prototypes **/ | 139 | /** prototypes **/ |
| 209 | void print_help(void); | 140 | void print_help(); |
| 210 | void print_usage(void); | 141 | void print_usage(void); |
| 211 | static u_int get_timevar(const char *); | 142 | |
| 212 | static u_int get_timevaldiff(struct timeval *, struct timeval *); | 143 | /* Time related */ |
| 213 | static in_addr_t get_ip_address(const char *); | 144 | typedef struct { |
| 214 | static int wait_for_reply(int, u_int); | 145 | int error_code; |
| 215 | static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *, struct timeval *); | 146 | time_t time_range; |
| 216 | static int send_icmp_ping(int, struct rta_host *); | 147 | } get_timevar_wrapper; |
| 217 | static int get_threshold(char *str, threshold *th); | 148 | static get_timevar_wrapper get_timevar(const char *str); |
| 218 | static bool get_threshold2(char *str, size_t length, threshold *, threshold *, threshold_mode mode); | 149 | static time_t get_timevaldiff(struct timeval earlier, struct timeval later); |
| 219 | static bool parse_threshold2_helper(char *s, size_t length, threshold *thr, threshold_mode mode); | 150 | static time_t get_timevaldiff_to_now(struct timeval earlier); |
| 220 | static void run_checks(void); | 151 | |
| 221 | static void set_source_ip(char *); | 152 | static in_addr_t get_ip_address(const char *ifname, const int icmp_sock); |
| 222 | static int add_target(char *); | 153 | static void set_source_ip(char *arg, int icmp_sock, sa_family_t addr_family); |
| 223 | static int add_target_ip(char *, struct sockaddr_storage *); | 154 | |
| 224 | static int handle_random_icmp(unsigned char *, struct sockaddr_storage *); | 155 | /* Receiving data */ |
| 225 | static void parse_address(struct sockaddr_storage *, char *, int); | 156 | static int wait_for_reply(check_icmp_socket_set sockset, time_t time_interval, |
| 226 | static unsigned short icmp_checksum(uint16_t *, size_t); | 157 | unsigned short icmp_pkt_size, time_t *target_interval, uint16_t sender_id, |
| 227 | static void finish(int); | 158 | ping_target **table, unsigned short packets, |
| 228 | static void crash(const char *, ...); | 159 | unsigned short number_of_targets, check_icmp_state *program_state); |
| 229 | 160 | ||
| 230 | /** external **/ | 161 | typedef struct { |
| 231 | extern int optind; | 162 | sa_family_t recv_proto; |
| 232 | extern char *optarg; | 163 | ssize_t received; |
| 233 | extern char **environ; | 164 | } recvfrom_wto_wrapper; |
| 165 | static recvfrom_wto_wrapper recvfrom_wto(check_icmp_socket_set sockset, void *buf, unsigned int len, | ||
| 166 | struct sockaddr *saddr, time_t *timeout, | ||
| 167 | struct timeval *received_timestamp); | ||
| 168 | static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr, | ||
| 169 | time_t *target_interval, uint16_t sender_id, ping_target **table, | ||
| 170 | unsigned short packets, unsigned short number_of_targets, | ||
| 171 | check_icmp_state *program_state); | ||
| 172 | |||
| 173 | /* Sending data */ | ||
| 174 | static int send_icmp_ping(check_icmp_socket_set sockset, ping_target *host, | ||
| 175 | unsigned short icmp_pkt_size, uint16_t sender_id, | ||
| 176 | check_icmp_state *program_state); | ||
| 177 | |||
| 178 | /* Threshold related */ | ||
| 179 | typedef struct { | ||
| 180 | int errorcode; | ||
| 181 | check_icmp_threshold threshold; | ||
| 182 | } get_threshold_wrapper; | ||
| 183 | static get_threshold_wrapper get_threshold(char *str, check_icmp_threshold threshold); | ||
| 184 | |||
| 185 | typedef struct { | ||
| 186 | int errorcode; | ||
| 187 | check_icmp_threshold warn; | ||
| 188 | check_icmp_threshold crit; | ||
| 189 | } get_threshold2_wrapper; | ||
| 190 | static get_threshold2_wrapper get_threshold2(char *str, size_t length, check_icmp_threshold warn, | ||
| 191 | check_icmp_threshold crit, threshold_mode mode); | ||
| 192 | |||
| 193 | typedef struct { | ||
| 194 | int errorcode; | ||
| 195 | check_icmp_threshold result; | ||
| 196 | } parse_threshold2_helper_wrapper; | ||
| 197 | static parse_threshold2_helper_wrapper parse_threshold2_helper(char *threshold_string, | ||
| 198 | size_t length, | ||
| 199 | check_icmp_threshold thr, | ||
| 200 | threshold_mode mode); | ||
| 201 | |||
| 202 | /* main test function */ | ||
| 203 | static void run_checks(unsigned short icmp_pkt_size, time_t *target_interval, uint16_t sender_id, | ||
| 204 | check_icmp_execution_mode mode, time_t max_completion_time, | ||
| 205 | struct timeval prog_start, ping_target **table, unsigned short packets, | ||
| 206 | check_icmp_socket_set sockset, unsigned short number_of_targets, | ||
| 207 | check_icmp_state *program_state); | ||
| 208 | mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, | ||
| 209 | check_icmp_threshold warn, check_icmp_threshold crit); | ||
| 210 | |||
| 211 | typedef struct { | ||
| 212 | int targets_ok; | ||
| 213 | int targets_warn; | ||
| 214 | mp_subcheck sc_host; | ||
| 215 | } evaluate_host_wrapper; | ||
| 216 | evaluate_host_wrapper evaluate_host(check_icmp_target_container host, | ||
| 217 | check_icmp_mode_switches modes, check_icmp_threshold warn, | ||
| 218 | check_icmp_threshold crit); | ||
| 219 | |||
| 220 | /* Target acquisition */ | ||
| 221 | typedef struct { | ||
| 222 | int error_code; | ||
| 223 | check_icmp_target_container host; | ||
| 224 | bool has_v4; | ||
| 225 | bool has_v6; | ||
| 226 | } add_host_wrapper; | ||
| 227 | static add_host_wrapper add_host(char *arg, check_icmp_execution_mode mode, | ||
| 228 | sa_family_t enforced_proto); | ||
| 229 | |||
| 230 | typedef struct { | ||
| 231 | int error_code; | ||
| 232 | ping_target *targets; | ||
| 233 | unsigned int number_of_targets; | ||
| 234 | bool has_v4; | ||
| 235 | bool has_v6; | ||
| 236 | } add_target_wrapper; | ||
| 237 | static add_target_wrapper add_target(char *arg, check_icmp_execution_mode mode, | ||
| 238 | sa_family_t enforced_proto); | ||
| 239 | |||
| 240 | typedef struct { | ||
| 241 | int error_code; | ||
| 242 | ping_target *target; | ||
| 243 | } add_target_ip_wrapper; | ||
| 244 | static add_target_ip_wrapper add_target_ip(struct sockaddr_storage address); | ||
| 245 | |||
| 246 | static void parse_address(const struct sockaddr_storage *addr, char *dst, socklen_t size); | ||
| 247 | |||
| 248 | static unsigned short icmp_checksum(uint16_t *packet, size_t packet_size); | ||
| 249 | |||
| 250 | /* End of run function */ | ||
| 251 | static void finish(int sign, check_icmp_mode_switches modes, int min_hosts_alive, | ||
| 252 | check_icmp_threshold warn, check_icmp_threshold crit, | ||
| 253 | unsigned short number_of_targets, check_icmp_state *program_state, | ||
| 254 | check_icmp_target_container host_list[], unsigned short number_of_hosts, | ||
| 255 | mp_check overall[static 1]); | ||
| 256 | |||
| 257 | /* Error exit */ | ||
| 258 | static void crash(const char *fmt, ...) __attribute__((format(printf, 1, 2))); | ||
| 234 | 259 | ||
| 235 | /** global variables **/ | 260 | /** global variables **/ |
| 236 | static struct rta_host **table, *cursor, *list; | 261 | static int debug = 0; |
| 237 | 262 | ||
| 238 | static threshold crit = {.pl = 80, .rta = 500000, .jitter = 0.0, .mos = 0.0, .score = 0.0}; | 263 | extern unsigned int timeout; |
| 239 | static threshold warn = {.pl = 40, .rta = 200000, .jitter = 0.0, .mos = 0.0, .score = 0.0}; | 264 | |
| 240 | 265 | /** the working code **/ | |
| 241 | static int mode, protocols, sockets, debug = 0, timeout = 10; | 266 | static inline unsigned short targets_alive(unsigned short targets, unsigned short targets_down) { |
| 242 | static unsigned short icmp_data_size = DEFAULT_PING_DATA_SIZE; | 267 | return targets - targets_down; |
| 243 | static unsigned short icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN; | 268 | } |
| 244 | 269 | static inline unsigned int icmp_pkts_en_route(unsigned int icmp_sent, unsigned int icmp_recv, | |
| 245 | static unsigned int icmp_sent = 0, icmp_recv = 0, icmp_lost = 0, ttl = 0; | 270 | unsigned int icmp_lost) { |
| 246 | #define icmp_pkts_en_route (icmp_sent - (icmp_recv + icmp_lost)) | 271 | return icmp_sent - (icmp_recv + icmp_lost); |
| 247 | static unsigned short targets_down = 0, targets = 0, packets = 0; | 272 | } |
| 248 | #define targets_alive (targets - targets_down) | 273 | |
| 249 | static unsigned int retry_interval, pkt_interval, target_interval; | 274 | // Create configuration from cli parameters |
| 250 | static int icmp_sock, tcp_sock, udp_sock, status = STATE_OK; | 275 | typedef struct { |
| 251 | static pid_t pid; | 276 | int errorcode; |
| 252 | static struct timezone tz; | 277 | check_icmp_config config; |
| 253 | static struct timeval prog_start; | 278 | } check_icmp_config_wrapper; |
| 254 | static unsigned long long max_completion_time = 0; | 279 | check_icmp_config_wrapper process_arguments(int argc, char **argv) { |
| 255 | static unsigned int warn_down = 1, crit_down = 1; /* host down threshold values */ | 280 | /* get calling name the old-fashioned way for portability instead |
| 256 | static int min_hosts_alive = -1; | 281 | * of relying on the glibc-ism __progname */ |
| 257 | static float pkt_backoff_factor = 1.5; | 282 | char *ptr = strrchr(argv[0], '/'); |
| 258 | static float target_backoff_factor = 1.5; | 283 | if (ptr) { |
| 259 | static bool rta_mode = false; | 284 | progname = &ptr[1]; |
| 260 | static bool pl_mode = false; | 285 | } else { |
| 261 | static bool jitter_mode = false; | 286 | progname = argv[0]; |
| 262 | static bool score_mode = false; | 287 | } |
| 263 | static bool mos_mode = false; | 288 | |
| 264 | static bool order_mode = false; | 289 | check_icmp_config_wrapper result = { |
| 290 | .errorcode = OK, | ||
| 291 | .config = check_icmp_config_init(), | ||
| 292 | }; | ||
| 293 | |||
| 294 | /* use the pid to mark packets as ours */ | ||
| 295 | /* Some systems have 32-bit pid_t so mask off only 16 bits */ | ||
| 296 | result.config.sender_id = getpid() & 0xffff; | ||
| 297 | |||
| 298 | if (!strcmp(progname, "check_icmp") || !strcmp(progname, "check_ping")) { | ||
| 299 | result.config.mode = MODE_ICMP; | ||
| 300 | } else if (!strcmp(progname, "check_host")) { | ||
| 301 | result.config.mode = MODE_HOSTCHECK; | ||
| 302 | result.config.number_of_packets = 5; | ||
| 303 | result.config.crit.rta = result.config.warn.rta = 1000000; | ||
| 304 | result.config.crit.pl = result.config.warn.pl = 100; | ||
| 305 | } else if (!strcmp(progname, "check_rta_multi")) { | ||
| 306 | result.config.mode = MODE_ALL; | ||
| 307 | result.config.target_interval = 0; | ||
| 308 | result.config.number_of_packets = 5; | ||
| 309 | } | ||
| 310 | /* support "--help" and "--version" */ | ||
| 311 | if (argc == 2) { | ||
| 312 | if (!strcmp(argv[1], "--help")) { | ||
| 313 | strcpy(argv[1], "-h"); | ||
| 314 | } | ||
| 315 | if (!strcmp(argv[1], "--version")) { | ||
| 316 | strcpy(argv[1], "-V"); | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | sa_family_t enforced_ai_family = AF_UNSPEC; | ||
| 321 | |||
| 322 | enum { | ||
| 323 | output_format_index = CHAR_MAX + 1, | ||
| 324 | }; | ||
| 325 | |||
| 326 | struct option longopts[] = { | ||
| 327 | {"version", no_argument, 0, 'V'}, | ||
| 328 | {"help", no_argument, 0, 'h'}, | ||
| 329 | {"verbose", no_argument, 0, 'v'}, | ||
| 330 | {"Host", required_argument, 0, 'H'}, | ||
| 331 | {"ipv4-only", no_argument, 0, '4'}, | ||
| 332 | {"ipv6-only", no_argument, 0, '6'}, | ||
| 333 | {"warning", required_argument, 0, 'w'}, | ||
| 334 | {"critical", required_argument, 0, 'c'}, | ||
| 335 | {"rta-mode-thresholds", required_argument, 0, 'R'}, | ||
| 336 | {"packet-loss-mode-thresholds", required_argument, 0, 'P'}, | ||
| 337 | {"jitter-mode-thresholds", required_argument, 0, 'J'}, | ||
| 338 | {"mos-mode-thresholds", required_argument, 0, 'M'}, | ||
| 339 | {"score-mode-thresholds", required_argument, 0, 'S'}, | ||
| 340 | {"out-of-order-packets", no_argument, 0, 'O'}, | ||
| 341 | {"number-of-packets", required_argument, 0, 'n'}, | ||
| 342 | {"number-of-packets", required_argument, 0, 'p'}, | ||
| 343 | {"packet-interval", required_argument, 0, 'i'}, | ||
| 344 | {"target-interval", required_argument, 0, 'I'}, | ||
| 345 | {"minimal-host-alive", required_argument, 0, 'm'}, | ||
| 346 | {"outgoing-ttl", required_argument, 0, 'l'}, | ||
| 347 | {"size", required_argument, 0, 'b'}, | ||
| 348 | {"output-format", required_argument, 0, output_format_index}, | ||
| 349 | {}, | ||
| 350 | }; | ||
| 351 | |||
| 352 | // Parse protocol arguments first | ||
| 353 | // and count hosts here | ||
| 354 | char *opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:P:R:J:S:M:O64"; | ||
| 355 | for (int i = 1; i < argc; i++) { | ||
| 356 | long int arg; | ||
| 357 | while ((arg = getopt_long(argc, argv, opts_str, longopts, NULL)) != EOF) { | ||
| 358 | switch (arg) { | ||
| 359 | |||
| 360 | case '4': | ||
| 361 | if (enforced_ai_family != AF_UNSPEC) { | ||
| 362 | crash("Multiple protocol versions not supported"); | ||
| 363 | } | ||
| 364 | enforced_ai_family = AF_INET; | ||
| 365 | break; | ||
| 366 | case '6': | ||
| 367 | if (enforced_ai_family != AF_UNSPEC) { | ||
| 368 | crash("Multiple protocol versions not supported"); | ||
| 369 | } | ||
| 370 | enforced_ai_family = AF_INET6; | ||
| 371 | break; | ||
| 372 | case 'H': { | ||
| 373 | result.config.number_of_hosts++; | ||
| 374 | break; | ||
| 375 | } | ||
| 376 | case 'h': /* help */ | ||
| 377 | // Trigger help here to avoid adding hosts before that (and doing DNS queries) | ||
| 378 | print_help(); | ||
| 379 | exit(STATE_UNKNOWN); | ||
| 380 | break; | ||
| 381 | case 'v': | ||
| 382 | debug++; | ||
| 383 | break; | ||
| 384 | } | ||
| 385 | } | ||
| 386 | } | ||
| 387 | |||
| 388 | char **tmp = &argv[optind]; | ||
| 389 | while (*tmp) { | ||
| 390 | result.config.number_of_hosts++; | ||
| 391 | tmp++; | ||
| 392 | } | ||
| 393 | |||
| 394 | // Sanity check: if hostmode is selected,only a single host is allowed | ||
| 395 | if (result.config.mode == MODE_HOSTCHECK && result.config.number_of_hosts > 1) { | ||
| 396 | usage("check_host only allows a single host"); | ||
| 397 | } | ||
| 398 | |||
| 399 | // Allocate hosts | ||
| 400 | result.config.hosts = | ||
| 401 | calloc(result.config.number_of_hosts, sizeof(check_icmp_target_container)); | ||
| 402 | if (result.config.hosts == NULL) { | ||
| 403 | crash("failed to allocate memory"); | ||
| 404 | } | ||
| 405 | |||
| 406 | /* Reset argument scanning */ | ||
| 407 | optind = 1; | ||
| 408 | |||
| 409 | int host_counter = 0; | ||
| 410 | /* parse the arguments */ | ||
| 411 | for (int i = 1; i < argc; i++) { | ||
| 412 | long int arg; | ||
| 413 | while ((arg = getopt_long(argc, argv, opts_str, longopts, NULL)) != EOF) { | ||
| 414 | switch (arg) { | ||
| 415 | case 'b': { | ||
| 416 | long size = strtol(optarg, NULL, 0); | ||
| 417 | if ((unsigned long)size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) && | ||
| 418 | size < MAX_PING_DATA) { | ||
| 419 | result.config.icmp_data_size = (unsigned short)size; | ||
| 420 | } else { | ||
| 421 | usage_va("ICMP data length must be between: %lu and %lu", | ||
| 422 | sizeof(struct icmp) + sizeof(struct icmp_ping_data), | ||
| 423 | MAX_PING_DATA - 1); | ||
| 424 | } | ||
| 425 | } break; | ||
| 426 | case 'i': { | ||
| 427 | // packet_interval was unused and is now removed | ||
| 428 | } break; | ||
| 429 | case 'I': { | ||
| 430 | get_timevar_wrapper parsed_time = get_timevar(optarg); | ||
| 431 | |||
| 432 | if (parsed_time.error_code == OK) { | ||
| 433 | result.config.target_interval = parsed_time.time_range; | ||
| 434 | } else { | ||
| 435 | crash("failed to parse target interval"); | ||
| 436 | } | ||
| 437 | } break; | ||
| 438 | case 'w': { | ||
| 439 | get_threshold_wrapper warn = get_threshold(optarg, result.config.warn); | ||
| 440 | if (warn.errorcode == OK) { | ||
| 441 | result.config.warn = warn.threshold; | ||
| 442 | } else { | ||
| 443 | crash("failed to parse warning threshold"); | ||
| 444 | } | ||
| 445 | } break; | ||
| 446 | case 'c': { | ||
| 447 | get_threshold_wrapper crit = get_threshold(optarg, result.config.crit); | ||
| 448 | if (crit.errorcode == OK) { | ||
| 449 | result.config.crit = crit.threshold; | ||
| 450 | } else { | ||
| 451 | crash("failed to parse critical threshold"); | ||
| 452 | } | ||
| 453 | } break; | ||
| 454 | case 'n': | ||
| 455 | case 'p': | ||
| 456 | result.config.number_of_packets = (unsigned short)strtoul(optarg, NULL, 0); | ||
| 457 | if (result.config.number_of_packets > 20) { | ||
| 458 | errno = 0; | ||
| 459 | crash("packets is > 20 (%d)", result.config.number_of_packets); | ||
| 460 | } | ||
| 461 | break; | ||
| 462 | case 't': | ||
| 463 | // WARNING Deprecated since execution time is determined by the other factors | ||
| 464 | break; | ||
| 465 | case 'H': { | ||
| 466 | add_host_wrapper host_add_result = | ||
| 467 | add_host(optarg, result.config.mode, enforced_ai_family); | ||
| 468 | if (host_add_result.error_code == OK) { | ||
| 469 | result.config.hosts[host_counter] = host_add_result.host; | ||
| 470 | host_counter++; | ||
| 471 | |||
| 472 | if (result.config.targets != NULL) { | ||
| 473 | result.config.number_of_targets += ping_target_list_append( | ||
| 474 | result.config.targets, host_add_result.host.target_list); | ||
| 475 | } else { | ||
| 476 | result.config.targets = host_add_result.host.target_list; | ||
| 477 | result.config.number_of_targets += host_add_result.host.number_of_targets; | ||
| 478 | } | ||
| 479 | |||
| 480 | if (host_add_result.has_v4) { | ||
| 481 | result.config.need_v4 = true; | ||
| 482 | } | ||
| 483 | if (host_add_result.has_v6) { | ||
| 484 | result.config.need_v6 = true; | ||
| 485 | } | ||
| 486 | } else { | ||
| 487 | crash("Failed to add host, unable to parse it correctly"); | ||
| 488 | } | ||
| 489 | } break; | ||
| 490 | case 'l': | ||
| 491 | result.config.ttl = strtoul(optarg, NULL, 0); | ||
| 492 | break; | ||
| 493 | case 'm': | ||
| 494 | result.config.min_hosts_alive = (int)strtoul(optarg, NULL, 0); | ||
| 495 | break; | ||
| 496 | case 's': /* specify source IP address */ | ||
| 497 | result.config.source_ip = optarg; | ||
| 498 | break; | ||
| 499 | case 'V': /* version */ | ||
| 500 | print_revision(progname, NP_VERSION); | ||
| 501 | exit(STATE_UNKNOWN); | ||
| 502 | case 'R': /* RTA mode */ { | ||
| 503 | get_threshold2_wrapper rta_th = get_threshold2( | ||
| 504 | optarg, strlen(optarg), result.config.warn, result.config.crit, const_rta_mode); | ||
| 505 | |||
| 506 | if (rta_th.errorcode != OK) { | ||
| 507 | crash("Failed to parse RTA threshold"); | ||
| 508 | } | ||
| 509 | |||
| 510 | result.config.warn = rta_th.warn; | ||
| 511 | result.config.crit = rta_th.crit; | ||
| 512 | result.config.modes.rta_mode = true; | ||
| 513 | } break; | ||
| 514 | case 'P': /* packet loss mode */ { | ||
| 515 | get_threshold2_wrapper pl_th = | ||
| 516 | get_threshold2(optarg, strlen(optarg), result.config.warn, result.config.crit, | ||
| 517 | const_packet_loss_mode); | ||
| 518 | if (pl_th.errorcode != OK) { | ||
| 519 | crash("Failed to parse packet loss threshold"); | ||
| 520 | } | ||
| 521 | |||
| 522 | result.config.warn = pl_th.warn; | ||
| 523 | result.config.crit = pl_th.crit; | ||
| 524 | result.config.modes.pl_mode = true; | ||
| 525 | } break; | ||
| 526 | case 'J': /* jitter mode */ { | ||
| 527 | get_threshold2_wrapper jitter_th = | ||
| 528 | get_threshold2(optarg, strlen(optarg), result.config.warn, result.config.crit, | ||
| 529 | const_jitter_mode); | ||
| 530 | if (jitter_th.errorcode != OK) { | ||
| 531 | crash("Failed to parse jitter threshold"); | ||
| 532 | } | ||
| 533 | |||
| 534 | result.config.warn = jitter_th.warn; | ||
| 535 | result.config.crit = jitter_th.crit; | ||
| 536 | result.config.modes.jitter_mode = true; | ||
| 537 | } break; | ||
| 538 | case 'M': /* MOS mode */ { | ||
| 539 | get_threshold2_wrapper mos_th = get_threshold2( | ||
| 540 | optarg, strlen(optarg), result.config.warn, result.config.crit, const_mos_mode); | ||
| 541 | if (mos_th.errorcode != OK) { | ||
| 542 | crash("Failed to parse MOS threshold"); | ||
| 543 | } | ||
| 544 | |||
| 545 | result.config.warn = mos_th.warn; | ||
| 546 | result.config.crit = mos_th.crit; | ||
| 547 | result.config.modes.mos_mode = true; | ||
| 548 | } break; | ||
| 549 | case 'S': /* score mode */ { | ||
| 550 | get_threshold2_wrapper score_th = | ||
| 551 | get_threshold2(optarg, strlen(optarg), result.config.warn, result.config.crit, | ||
| 552 | const_score_mode); | ||
| 553 | if (score_th.errorcode != OK) { | ||
| 554 | crash("Failed to parse score threshold"); | ||
| 555 | } | ||
| 556 | |||
| 557 | result.config.warn = score_th.warn; | ||
| 558 | result.config.crit = score_th.crit; | ||
| 559 | result.config.modes.score_mode = true; | ||
| 560 | } break; | ||
| 561 | case 'O': /* out of order mode */ | ||
| 562 | result.config.modes.order_mode = true; | ||
| 563 | break; | ||
| 564 | case output_format_index: { | ||
| 565 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 566 | if (!parser.parsing_success) { | ||
| 567 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 568 | printf("Invalid output format: %s\n", optarg); | ||
| 569 | exit(STATE_UNKNOWN); | ||
| 570 | } | ||
| 571 | |||
| 572 | result.config.output_format_is_set = true; | ||
| 573 | result.config.output_format = parser.output_format; | ||
| 574 | break; | ||
| 575 | } | ||
| 576 | } | ||
| 577 | } | ||
| 578 | } | ||
| 579 | |||
| 580 | argv = &argv[optind]; | ||
| 581 | while (*argv) { | ||
| 582 | add_target(*argv, result.config.mode, enforced_ai_family); | ||
| 583 | argv++; | ||
| 584 | } | ||
| 585 | |||
| 586 | if (!result.config.number_of_targets) { | ||
| 587 | errno = 0; | ||
| 588 | crash("No hosts to check"); | ||
| 589 | } | ||
| 590 | |||
| 591 | /* stupid users should be able to give whatever thresholds they want | ||
| 592 | * (nothing will break if they do), but some anal plugin maintainer | ||
| 593 | * will probably add some printf() thing here later, so it might be | ||
| 594 | * best to at least show them where to do it. ;) */ | ||
| 595 | if (result.config.warn.pl > result.config.crit.pl) { | ||
| 596 | result.config.warn.pl = result.config.crit.pl; | ||
| 597 | } | ||
| 598 | if (result.config.warn.rta > result.config.crit.rta) { | ||
| 599 | result.config.warn.rta = result.config.crit.rta; | ||
| 600 | } | ||
| 601 | if (result.config.warn.jitter > result.config.crit.jitter) { | ||
| 602 | result.config.crit.jitter = result.config.warn.jitter; | ||
| 603 | } | ||
| 604 | if (result.config.warn.mos < result.config.crit.mos) { | ||
| 605 | result.config.warn.mos = result.config.crit.mos; | ||
| 606 | } | ||
| 607 | if (result.config.warn.score < result.config.crit.score) { | ||
| 608 | result.config.warn.score = result.config.crit.score; | ||
| 609 | } | ||
| 610 | |||
| 611 | return result; | ||
| 612 | } | ||
| 265 | 613 | ||
| 266 | /** code start **/ | 614 | /** code start **/ |
| 267 | static void crash(const char *fmt, ...) { | 615 | static void crash(const char *fmt, ...) { |
| 268 | va_list ap; | ||
| 269 | 616 | ||
| 270 | printf("%s: ", progname); | 617 | printf("%s: ", progname); |
| 271 | 618 | ||
| 619 | va_list ap; | ||
| 272 | va_start(ap, fmt); | 620 | va_start(ap, fmt); |
| 273 | vprintf(fmt, ap); | 621 | vprintf(fmt, ap); |
| 274 | va_end(ap); | 622 | va_end(ap); |
| @@ -385,18 +733,20 @@ static const char *get_icmp_error_msg(unsigned char icmp_type, unsigned char icm | |||
| 385 | return msg; | 733 | return msg; |
| 386 | } | 734 | } |
| 387 | 735 | ||
| 388 | static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr) { | 736 | static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr, |
| 389 | struct icmp p, sent_icmp; | 737 | time_t *target_interval, const uint16_t sender_id, |
| 390 | struct rta_host *host = NULL; | 738 | ping_target **table, unsigned short packets, |
| 391 | 739 | const unsigned short number_of_targets, | |
| 392 | memcpy(&p, packet, sizeof(p)); | 740 | check_icmp_state *program_state) { |
| 393 | if (p.icmp_type == ICMP_ECHO && ntohs(p.icmp_id) == pid) { | 741 | struct icmp icmp_packet; |
| 742 | memcpy(&icmp_packet, packet, sizeof(icmp_packet)); | ||
| 743 | if (icmp_packet.icmp_type == ICMP_ECHO && ntohs(icmp_packet.icmp_id) == sender_id) { | ||
| 394 | /* echo request from us to us (pinging localhost) */ | 744 | /* echo request from us to us (pinging localhost) */ |
| 395 | return 0; | 745 | return 0; |
| 396 | } | 746 | } |
| 397 | 747 | ||
| 398 | if (debug) { | 748 | if (debug) { |
| 399 | printf("handle_random_icmp(%p, %p)\n", (void *)&p, (void *)addr); | 749 | printf("handle_random_icmp(%p, %p)\n", (void *)&icmp_packet, (void *)addr); |
| 400 | } | 750 | } |
| 401 | 751 | ||
| 402 | /* only handle a few types, since others can't possibly be replies to | 752 | /* only handle a few types, since others can't possibly be replies to |
| @@ -409,14 +759,17 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 409 | * TIMXCEED actually sends a proper icmp response we will have passed | 759 | * TIMXCEED actually sends a proper icmp response we will have passed |
| 410 | * too many hops to have a hope of reaching it later, in which case it | 760 | * too many hops to have a hope of reaching it later, in which case it |
| 411 | * indicates overconfidence in the network, poor routing or both. */ | 761 | * indicates overconfidence in the network, poor routing or both. */ |
| 412 | if (p.icmp_type != ICMP_UNREACH && p.icmp_type != ICMP_TIMXCEED && p.icmp_type != ICMP_SOURCEQUENCH && p.icmp_type != ICMP_PARAMPROB) { | 762 | if (icmp_packet.icmp_type != ICMP_UNREACH && icmp_packet.icmp_type != ICMP_TIMXCEED && |
| 763 | icmp_packet.icmp_type != ICMP_SOURCEQUENCH && icmp_packet.icmp_type != ICMP_PARAMPROB) { | ||
| 413 | return 0; | 764 | return 0; |
| 414 | } | 765 | } |
| 415 | 766 | ||
| 416 | /* might be for us. At least it holds the original package (according | 767 | /* might be for us. At least it holds the original package (according |
| 417 | * to RFC 792). If it isn't, just ignore it */ | 768 | * to RFC 792). If it isn't, just ignore it */ |
| 769 | struct icmp sent_icmp; | ||
| 418 | memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp)); | 770 | memcpy(&sent_icmp, packet + 28, sizeof(sent_icmp)); |
| 419 | if (sent_icmp.icmp_type != ICMP_ECHO || ntohs(sent_icmp.icmp_id) != pid || ntohs(sent_icmp.icmp_seq) >= targets * packets) { | 771 | if (sent_icmp.icmp_type != ICMP_ECHO || ntohs(sent_icmp.icmp_id) != sender_id || |
| 772 | ntohs(sent_icmp.icmp_seq) >= number_of_targets * packets) { | ||
| 420 | if (debug) { | 773 | if (debug) { |
| 421 | printf("Packet is no response to a packet we sent\n"); | 774 | printf("Packet is no response to a packet we sent\n"); |
| 422 | } | 775 | } |
| @@ -424,14 +777,15 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 424 | } | 777 | } |
| 425 | 778 | ||
| 426 | /* it is indeed a response for us */ | 779 | /* it is indeed a response for us */ |
| 427 | host = table[ntohs(sent_icmp.icmp_seq) / packets]; | 780 | ping_target *host = table[ntohs(sent_icmp.icmp_seq) / packets]; |
| 428 | if (debug) { | 781 | if (debug) { |
| 429 | char address[INET6_ADDRSTRLEN]; | 782 | char address[INET6_ADDRSTRLEN]; |
| 430 | parse_address(addr, address, sizeof(address)); | 783 | parse_address(addr, address, sizeof(address)); |
| 431 | printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n", get_icmp_error_msg(p.icmp_type, p.icmp_code), address, host->name); | 784 | printf("Received \"%s\" from %s for ICMP ECHO sent.\n", |
| 785 | get_icmp_error_msg(icmp_packet.icmp_type, icmp_packet.icmp_code), address); | ||
| 432 | } | 786 | } |
| 433 | 787 | ||
| 434 | icmp_lost++; | 788 | program_state->icmp_lost++; |
| 435 | host->icmp_lost++; | 789 | host->icmp_lost++; |
| 436 | /* don't spend time on lost hosts any more */ | 790 | /* don't spend time on lost hosts any more */ |
| 437 | if (host->flags & FLAG_LOST_CAUSE) { | 791 | if (host->flags & FLAG_LOST_CAUSE) { |
| @@ -440,305 +794,104 @@ static int handle_random_icmp(unsigned char *packet, struct sockaddr_storage *ad | |||
| 440 | 794 | ||
| 441 | /* source quench means we're sending too fast, so increase the | 795 | /* source quench means we're sending too fast, so increase the |
| 442 | * interval and mark this packet lost */ | 796 | * interval and mark this packet lost */ |
| 443 | if (p.icmp_type == ICMP_SOURCEQUENCH) { | 797 | if (icmp_packet.icmp_type == ICMP_SOURCEQUENCH) { |
| 444 | pkt_interval *= pkt_backoff_factor; | 798 | *target_interval = (unsigned int)((double)*target_interval * TARGET_BACKOFF_FACTOR); |
| 445 | target_interval *= target_backoff_factor; | ||
| 446 | } else { | 799 | } else { |
| 447 | targets_down++; | 800 | program_state->targets_down++; |
| 448 | host->flags |= FLAG_LOST_CAUSE; | 801 | host->flags |= FLAG_LOST_CAUSE; |
| 449 | } | 802 | } |
| 450 | host->icmp_type = p.icmp_type; | 803 | host->icmp_type = icmp_packet.icmp_type; |
| 451 | host->icmp_code = p.icmp_code; | 804 | host->icmp_code = icmp_packet.icmp_code; |
| 452 | host->error_addr = *addr; | 805 | host->error_addr = *addr; |
| 453 | 806 | ||
| 454 | return 0; | 807 | return 0; |
| 455 | } | 808 | } |
| 456 | 809 | ||
| 457 | void parse_address(struct sockaddr_storage *addr, char *address, int size) { | 810 | void parse_address(const struct sockaddr_storage *addr, char *dst, socklen_t size) { |
| 458 | switch (address_family) { | 811 | switch (addr->ss_family) { |
| 459 | case AF_INET: | 812 | case AF_INET: |
| 460 | inet_ntop(address_family, &((struct sockaddr_in *)addr)->sin_addr, address, size); | 813 | inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, dst, size); |
| 461 | break; | 814 | break; |
| 462 | case AF_INET6: | 815 | case AF_INET6: |
| 463 | inet_ntop(address_family, &((struct sockaddr_in6 *)addr)->sin6_addr, address, size); | 816 | inet_ntop(AF_INET6, &((struct sockaddr_in6 *)addr)->sin6_addr, dst, size); |
| 464 | break; | 817 | break; |
| 818 | default: | ||
| 819 | assert(false); | ||
| 465 | } | 820 | } |
| 466 | } | 821 | } |
| 467 | 822 | ||
| 468 | int main(int argc, char **argv) { | 823 | int main(int argc, char **argv) { |
| 469 | int i; | ||
| 470 | char *ptr; | ||
| 471 | long int arg; | ||
| 472 | int icmp_sockerrno, udp_sockerrno, tcp_sockerrno; | ||
| 473 | int result; | ||
| 474 | struct rta_host *host; | ||
| 475 | #ifdef HAVE_SIGACTION | ||
| 476 | struct sigaction sig_action; | ||
| 477 | #endif | ||
| 478 | #ifdef SO_TIMESTAMP | ||
| 479 | int on = 1; | ||
| 480 | #endif | ||
| 481 | char *source_ip = NULL; | ||
| 482 | char *opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:P:R:J:S:M:O64"; | ||
| 483 | setlocale(LC_ALL, ""); | 824 | setlocale(LC_ALL, ""); |
| 484 | bindtextdomain(PACKAGE, LOCALEDIR); | 825 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 485 | textdomain(PACKAGE); | 826 | textdomain(PACKAGE); |
| 486 | 827 | ||
| 487 | /* we only need to be setsuid when we get the sockets, so do | 828 | /* POSIXLY_CORRECT might break things, so unset it (the portable way) */ |
| 488 | * that before pointer magic (esp. on network data) */ | 829 | environ = NULL; |
| 489 | icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0; | ||
| 490 | |||
| 491 | address_family = -1; | ||
| 492 | int icmp_proto = IPPROTO_ICMP; | ||
| 493 | 830 | ||
| 494 | /* get calling name the old-fashioned way for portability instead | 831 | /* Parse extra opts if any */ |
| 495 | * of relying on the glibc-ism __progname */ | 832 | argv = np_extra_opts(&argc, argv, progname); |
| 496 | ptr = strrchr(argv[0], '/'); | ||
| 497 | if (ptr) { | ||
| 498 | progname = &ptr[1]; | ||
| 499 | } else { | ||
| 500 | progname = argv[0]; | ||
| 501 | } | ||
| 502 | 833 | ||
| 503 | /* now set defaults. Use progname to set them initially (allows for | 834 | check_icmp_config_wrapper tmp_config = process_arguments(argc, argv); |
| 504 | * superfast check_host program when target host is up */ | ||
| 505 | cursor = list = NULL; | ||
| 506 | table = NULL; | ||
| 507 | |||
| 508 | mode = MODE_RTA; | ||
| 509 | /* Default critical thresholds */ | ||
| 510 | crit.rta = 500000; | ||
| 511 | crit.pl = 80; | ||
| 512 | crit.jitter = 50; | ||
| 513 | crit.mos = 3; | ||
| 514 | crit.score = 70; | ||
| 515 | /* Default warning thresholds */ | ||
| 516 | warn.rta = 200000; | ||
| 517 | warn.pl = 40; | ||
| 518 | warn.jitter = 40; | ||
| 519 | warn.mos = 3.5; | ||
| 520 | warn.score = 80; | ||
| 521 | |||
| 522 | protocols = HAVE_ICMP | HAVE_UDP | HAVE_TCP; | ||
| 523 | pkt_interval = 80000; /* 80 msec packet interval by default */ | ||
| 524 | packets = 5; | ||
| 525 | 835 | ||
| 526 | if (!strcmp(progname, "check_icmp") || !strcmp(progname, "check_ping")) { | 836 | if (tmp_config.errorcode != OK) { |
| 527 | mode = MODE_ICMP; | 837 | crash("failed to parse config"); |
| 528 | protocols = HAVE_ICMP; | ||
| 529 | } else if (!strcmp(progname, "check_host")) { | ||
| 530 | mode = MODE_HOSTCHECK; | ||
| 531 | pkt_interval = 1000000; | ||
| 532 | packets = 5; | ||
| 533 | crit.rta = warn.rta = 1000000; | ||
| 534 | crit.pl = warn.pl = 100; | ||
| 535 | } else if (!strcmp(progname, "check_rta_multi")) { | ||
| 536 | mode = MODE_ALL; | ||
| 537 | target_interval = 0; | ||
| 538 | pkt_interval = 50000; | ||
| 539 | packets = 5; | ||
| 540 | } | 838 | } |
| 541 | 839 | ||
| 542 | /* support "--help" and "--version" */ | 840 | const check_icmp_config config = tmp_config.config; |
| 543 | if (argc == 2) { | ||
| 544 | if (!strcmp(argv[1], "--help")) { | ||
| 545 | strcpy(argv[1], "-h"); | ||
| 546 | } | ||
| 547 | if (!strcmp(argv[1], "--version")) { | ||
| 548 | strcpy(argv[1], "-V"); | ||
| 549 | } | ||
| 550 | } | ||
| 551 | 841 | ||
| 552 | /* Parse protocol arguments first */ | 842 | if (config.output_format_is_set) { |
| 553 | for (i = 1; i < argc; i++) { | 843 | mp_set_format(config.output_format); |
| 554 | while ((arg = getopt(argc, argv, opts_str)) != EOF) { | ||
| 555 | switch (arg) { | ||
| 556 | case '4': | ||
| 557 | if (address_family != -1) { | ||
| 558 | crash("Multiple protocol versions not supported"); | ||
| 559 | } | ||
| 560 | address_family = AF_INET; | ||
| 561 | break; | ||
| 562 | case '6': | ||
| 563 | #ifdef USE_IPV6 | ||
| 564 | if (address_family != -1) { | ||
| 565 | crash("Multiple protocol versions not supported"); | ||
| 566 | } | ||
| 567 | address_family = AF_INET6; | ||
| 568 | #else | ||
| 569 | usage(_("IPv6 support not available\n")); | ||
| 570 | #endif | ||
| 571 | break; | ||
| 572 | } | ||
| 573 | } | ||
| 574 | } | 844 | } |
| 575 | 845 | ||
| 576 | /* Reset argument scanning */ | 846 | check_icmp_socket_set sockset = { |
| 577 | optind = 1; | 847 | .socket4 = -1, |
| 848 | .socket6 = -1, | ||
| 849 | }; | ||
| 578 | 850 | ||
| 579 | unsigned long size; | 851 | if (config.need_v4) { |
| 580 | bool err; | 852 | sockset.socket4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); |
| 581 | /* parse the arguments */ | 853 | if (sockset.socket4 == -1) { |
| 582 | for (i = 1; i < argc; i++) { | 854 | crash("Failed to obtain ICMP v4 socket"); |
| 583 | while ((arg = getopt(argc, argv, opts_str)) != EOF) { | 855 | } |
| 584 | switch (arg) { | ||
| 585 | case 'v': | ||
| 586 | debug++; | ||
| 587 | break; | ||
| 588 | case 'b': | ||
| 589 | size = strtol(optarg, NULL, 0); | ||
| 590 | if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) && size < MAX_PING_DATA) { | ||
| 591 | icmp_data_size = size; | ||
| 592 | icmp_pkt_size = size + ICMP_MINLEN; | ||
| 593 | } else { | ||
| 594 | usage_va("ICMP data length must be between: %lu and %lu", sizeof(struct icmp) + sizeof(struct icmp_ping_data), | ||
| 595 | MAX_PING_DATA - 1); | ||
| 596 | } | ||
| 597 | break; | ||
| 598 | case 'i': | ||
| 599 | pkt_interval = get_timevar(optarg); | ||
| 600 | break; | ||
| 601 | case 'I': | ||
| 602 | target_interval = get_timevar(optarg); | ||
| 603 | break; | ||
| 604 | case 'w': | ||
| 605 | get_threshold(optarg, &warn); | ||
| 606 | break; | ||
| 607 | case 'c': | ||
| 608 | get_threshold(optarg, &crit); | ||
| 609 | break; | ||
| 610 | case 'n': | ||
| 611 | case 'p': | ||
| 612 | packets = strtoul(optarg, NULL, 0); | ||
| 613 | break; | ||
| 614 | case 't': | ||
| 615 | timeout = strtoul(optarg, NULL, 0); | ||
| 616 | if (!timeout) { | ||
| 617 | timeout = 10; | ||
| 618 | } | ||
| 619 | break; | ||
| 620 | case 'H': | ||
| 621 | add_target(optarg); | ||
| 622 | break; | ||
| 623 | case 'l': | ||
| 624 | ttl = (int)strtoul(optarg, NULL, 0); | ||
| 625 | break; | ||
| 626 | case 'm': | ||
| 627 | min_hosts_alive = (int)strtoul(optarg, NULL, 0); | ||
| 628 | break; | ||
| 629 | case 'd': /* implement later, for cluster checks */ | ||
| 630 | warn_down = (unsigned char)strtoul(optarg, &ptr, 0); | ||
| 631 | if (ptr) { | ||
| 632 | crit_down = (unsigned char)strtoul(ptr + 1, NULL, 0); | ||
| 633 | } | ||
| 634 | break; | ||
| 635 | case 's': /* specify source IP address */ | ||
| 636 | source_ip = optarg; | ||
| 637 | break; | ||
| 638 | case 'V': /* version */ | ||
| 639 | print_revision(progname, NP_VERSION); | ||
| 640 | exit(STATE_UNKNOWN); | ||
| 641 | case 'h': /* help */ | ||
| 642 | print_help(); | ||
| 643 | exit(STATE_UNKNOWN); | ||
| 644 | break; | ||
| 645 | case 'R': /* RTA mode */ | ||
| 646 | err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_rta_mode); | ||
| 647 | if (!err) { | ||
| 648 | crash("Failed to parse RTA threshold"); | ||
| 649 | } | ||
| 650 | 856 | ||
| 651 | rta_mode = true; | 857 | if (config.source_ip) { |
| 652 | break; | ||
| 653 | case 'P': /* packet loss mode */ | ||
| 654 | err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_packet_loss_mode); | ||
| 655 | if (!err) { | ||
| 656 | crash("Failed to parse packet loss threshold"); | ||
| 657 | } | ||
| 658 | 858 | ||
| 659 | pl_mode = true; | 859 | struct in_addr tmp = {}; |
| 660 | break; | 860 | int error_code = inet_pton(AF_INET, config.source_ip, &tmp); |
| 661 | case 'J': /* jitter mode */ | 861 | if (error_code == 1) { |
| 662 | err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_jitter_mode); | 862 | set_source_ip(config.source_ip, sockset.socket4, AF_INET); |
| 663 | if (!err) { | 863 | } else { |
| 664 | crash("Failed to parse jitter threshold"); | 864 | // just try this mindlessly if it's not a v4 address |
| 665 | } | 865 | set_source_ip(config.source_ip, sockset.socket6, AF_INET6); |
| 866 | } | ||
| 867 | } | ||
| 666 | 868 | ||
| 667 | jitter_mode = true; | 869 | #ifdef SO_TIMESTAMP |
| 668 | break; | 870 | if (sockset.socket4 != -1) { |
| 669 | case 'M': /* MOS mode */ | 871 | int on = 1; |
| 670 | err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_mos_mode); | 872 | if (setsockopt(sockset.socket4, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) { |
| 671 | if (!err) { | 873 | if (debug) { |
| 672 | crash("Failed to parse MOS threshold"); | 874 | printf("Warning: no SO_TIMESTAMP support\n"); |
| 673 | } | 875 | } |
| 674 | 876 | } | |
| 675 | mos_mode = true; | 877 | } |
| 676 | break; | 878 | if (sockset.socket6 != -1) { |
| 677 | case 'S': /* score mode */ | 879 | int on = 1; |
| 678 | err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_score_mode); | 880 | if (setsockopt(sockset.socket6, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) { |
| 679 | if (!err) { | 881 | if (debug) { |
| 680 | crash("Failed to parse score threshold"); | 882 | printf("Warning: no SO_TIMESTAMP support\n"); |
| 681 | } | 883 | } |
| 682 | |||
| 683 | score_mode = true; | ||
| 684 | break; | ||
| 685 | case 'O': /* out of order mode */ | ||
| 686 | order_mode = true; | ||
| 687 | break; | ||
| 688 | } | 884 | } |
| 689 | } | 885 | } |
| 886 | #endif // SO_TIMESTAMP | ||
| 690 | } | 887 | } |
| 691 | 888 | ||
| 692 | /* POSIXLY_CORRECT might break things, so unset it (the portable way) */ | 889 | if (config.need_v6) { |
| 693 | environ = NULL; | 890 | sockset.socket6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); |
| 694 | 891 | if (sockset.socket6 == -1) { | |
| 695 | /* use the pid to mark packets as ours */ | 892 | crash("Failed to obtain ICMP v6 socket"); |
| 696 | /* Some systems have 32-bit pid_t so mask off only 16 bits */ | ||
| 697 | pid = getpid() & 0xffff; | ||
| 698 | /* printf("pid = %u\n", pid); */ | ||
| 699 | |||
| 700 | /* Parse extra opts if any */ | ||
| 701 | argv = np_extra_opts(&argc, argv, progname); | ||
| 702 | |||
| 703 | argv = &argv[optind]; | ||
| 704 | while (*argv) { | ||
| 705 | add_target(*argv); | ||
| 706 | argv++; | ||
| 707 | } | ||
| 708 | |||
| 709 | if (!targets) { | ||
| 710 | errno = 0; | ||
| 711 | crash("No hosts to check"); | ||
| 712 | } | ||
| 713 | |||
| 714 | // add_target might change address_family | ||
| 715 | switch (address_family) { | ||
| 716 | case AF_INET: | ||
| 717 | icmp_proto = IPPROTO_ICMP; | ||
| 718 | break; | ||
| 719 | case AF_INET6: | ||
| 720 | icmp_proto = IPPROTO_ICMPV6; | ||
| 721 | break; | ||
| 722 | default: | ||
| 723 | crash("Address family not supported"); | ||
| 724 | } | ||
| 725 | if ((icmp_sock = socket(address_family, SOCK_RAW, icmp_proto)) != -1) { | ||
| 726 | sockets |= HAVE_ICMP; | ||
| 727 | } else { | ||
| 728 | icmp_sockerrno = errno; | ||
| 729 | } | ||
| 730 | |||
| 731 | if (source_ip) { | ||
| 732 | set_source_ip(source_ip); | ||
| 733 | } | ||
| 734 | |||
| 735 | #ifdef SO_TIMESTAMP | ||
| 736 | if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) { | ||
| 737 | if (debug) { | ||
| 738 | printf("Warning: no SO_TIMESTAMP support\n"); | ||
| 739 | } | 893 | } |
| 740 | } | 894 | } |
| 741 | #endif // SO_TIMESTAMP | ||
| 742 | 895 | ||
| 743 | /* now drop privileges (no effect if not setsuid or geteuid() == 0) */ | 896 | /* now drop privileges (no effect if not setsuid or geteuid() == 0) */ |
| 744 | if (setuid(getuid()) == -1) { | 897 | if (setuid(getuid()) == -1) { |
| @@ -746,186 +899,179 @@ int main(int argc, char **argv) { | |||
| 746 | return 1; | 899 | return 1; |
| 747 | } | 900 | } |
| 748 | 901 | ||
| 749 | if (!sockets) { | 902 | if (sockset.socket4) { |
| 750 | if (icmp_sock == -1) { | 903 | int result = setsockopt(sockset.socket4, SOL_IP, IP_TTL, &config.ttl, sizeof(config.ttl)); |
| 751 | errno = icmp_sockerrno; | ||
| 752 | crash("Failed to obtain ICMP socket"); | ||
| 753 | return -1; | ||
| 754 | } | ||
| 755 | /* if(udp_sock == -1) { */ | ||
| 756 | /* errno = icmp_sockerrno; */ | ||
| 757 | /* crash("Failed to obtain UDP socket"); */ | ||
| 758 | /* return -1; */ | ||
| 759 | /* } */ | ||
| 760 | /* if(tcp_sock == -1) { */ | ||
| 761 | /* errno = icmp_sockerrno; */ | ||
| 762 | /* crash("Failed to obtain TCP socker"); */ | ||
| 763 | /* return -1; */ | ||
| 764 | /* } */ | ||
| 765 | } | ||
| 766 | if (!ttl) { | ||
| 767 | ttl = 64; | ||
| 768 | } | ||
| 769 | |||
| 770 | if (icmp_sock) { | ||
| 771 | result = setsockopt(icmp_sock, SOL_IP, IP_TTL, &ttl, sizeof(ttl)); | ||
| 772 | if (debug) { | 904 | if (debug) { |
| 773 | if (result == -1) { | 905 | if (result == -1) { |
| 774 | printf("setsockopt failed\n"); | 906 | printf("setsockopt failed\n"); |
| 775 | } else { | 907 | } else { |
| 776 | printf("ttl set to %u\n", ttl); | 908 | printf("ttl set to %lu\n", config.ttl); |
| 777 | } | 909 | } |
| 778 | } | 910 | } |
| 779 | } | 911 | } |
| 780 | 912 | ||
| 781 | /* stupid users should be able to give whatever thresholds they want | 913 | if (sockset.socket6) { |
| 782 | * (nothing will break if they do), but some anal plugin maintainer | 914 | int result = setsockopt(sockset.socket6, SOL_IP, IP_TTL, &config.ttl, sizeof(config.ttl)); |
| 783 | * will probably add some printf() thing here later, so it might be | 915 | if (debug) { |
| 784 | * best to at least show them where to do it. ;) */ | 916 | if (result == -1) { |
| 785 | if (warn.pl > crit.pl) { | 917 | printf("setsockopt failed\n"); |
| 786 | warn.pl = crit.pl; | 918 | } else { |
| 787 | } | 919 | printf("ttl set to %lu\n", config.ttl); |
| 788 | if (warn.rta > crit.rta) { | 920 | } |
| 789 | warn.rta = crit.rta; | 921 | } |
| 790 | } | ||
| 791 | if (warn_down > crit_down) { | ||
| 792 | crit_down = warn_down; | ||
| 793 | } | ||
| 794 | if (warn.jitter > crit.jitter) { | ||
| 795 | crit.jitter = warn.jitter; | ||
| 796 | } | ||
| 797 | if (warn.mos < crit.mos) { | ||
| 798 | warn.mos = crit.mos; | ||
| 799 | } | ||
| 800 | if (warn.score < crit.score) { | ||
| 801 | warn.score = crit.score; | ||
| 802 | } | ||
| 803 | |||
| 804 | #ifdef HAVE_SIGACTION | ||
| 805 | sig_action.sa_sigaction = NULL; | ||
| 806 | sig_action.sa_handler = finish; | ||
| 807 | sigfillset(&sig_action.sa_mask); | ||
| 808 | sig_action.sa_flags = SA_NODEFER | SA_RESTART; | ||
| 809 | sigaction(SIGINT, &sig_action, NULL); | ||
| 810 | sigaction(SIGHUP, &sig_action, NULL); | ||
| 811 | sigaction(SIGTERM, &sig_action, NULL); | ||
| 812 | sigaction(SIGALRM, &sig_action, NULL); | ||
| 813 | #else /* HAVE_SIGACTION */ | ||
| 814 | signal(SIGINT, finish); | ||
| 815 | signal(SIGHUP, finish); | ||
| 816 | signal(SIGTERM, finish); | ||
| 817 | signal(SIGALRM, finish); | ||
| 818 | #endif /* HAVE_SIGACTION */ | ||
| 819 | if (debug) { | ||
| 820 | printf("Setting alarm timeout to %u seconds\n", timeout); | ||
| 821 | } | 922 | } |
| 822 | alarm(timeout); | ||
| 823 | 923 | ||
| 824 | /* make sure we don't wait any longer than necessary */ | 924 | /* make sure we don't wait any longer than necessary */ |
| 825 | gettimeofday(&prog_start, &tz); | 925 | struct timeval prog_start; |
| 826 | max_completion_time = ((targets * packets * pkt_interval) + (targets * target_interval)) + (targets * packets * crit.rta) + crit.rta; | 926 | gettimeofday(&prog_start, NULL); |
| 927 | |||
| 928 | time_t max_completion_time = | ||
| 929 | (config.target_interval * config.number_of_targets) + | ||
| 930 | (config.crit.rta * config.number_of_targets * config.number_of_packets) + config.crit.rta; | ||
| 827 | 931 | ||
| 828 | if (debug) { | 932 | if (debug) { |
| 829 | printf("packets: %u, targets: %u\n" | 933 | printf("packets: %u, targets: %u\n" |
| 830 | "target_interval: %0.3f, pkt_interval %0.3f\n" | 934 | "target_interval: %0.3f\n" |
| 831 | "crit.rta: %0.3f\n" | 935 | "crit.rta: %0.3f\n" |
| 832 | "max_completion_time: %0.3f\n", | 936 | "max_completion_time: %0.3f\n", |
| 833 | packets, targets, (float)target_interval / 1000, (float)pkt_interval / 1000, (float)crit.rta / 1000, | 937 | config.number_of_packets, config.number_of_targets, |
| 938 | (float)config.target_interval / 1000, (float)config.crit.rta / 1000, | ||
| 834 | (float)max_completion_time / 1000); | 939 | (float)max_completion_time / 1000); |
| 835 | } | 940 | } |
| 836 | 941 | ||
| 837 | if (debug) { | 942 | if (debug) { |
| 838 | if (max_completion_time > (u_int)timeout * 1000000) { | 943 | if (max_completion_time > (timeout * 1000000)) { |
| 839 | printf("max_completion_time: %llu timeout: %u\n", max_completion_time, timeout); | 944 | printf("max_completion_time: %ld timeout: %u\n", max_completion_time, timeout); |
| 840 | printf("Timeout must be at least %llu\n", max_completion_time / 1000000 + 1); | 945 | printf("Timeout must be at least %ld\n", (max_completion_time / 1000000) + 1); |
| 841 | } | 946 | } |
| 842 | } | 947 | } |
| 843 | 948 | ||
| 844 | if (debug) { | 949 | if (debug) { |
| 845 | printf("crit = {%u, %u%%}, warn = {%u, %u%%}\n", crit.rta, crit.pl, warn.rta, warn.pl); | 950 | printf("crit = {%ld, %u%%}, warn = {%ld, %u%%}\n", config.crit.rta, config.crit.pl, |
| 846 | printf("pkt_interval: %u target_interval: %u retry_interval: %u\n", pkt_interval, target_interval, retry_interval); | 951 | config.warn.rta, config.warn.pl); |
| 847 | printf("icmp_pkt_size: %u timeout: %u\n", icmp_pkt_size, timeout); | 952 | printf("target_interval: %ld\n", config.target_interval); |
| 953 | printf("icmp_pkt_size: %u timeout: %u\n", config.icmp_data_size + ICMP_MINLEN, timeout); | ||
| 848 | } | 954 | } |
| 849 | 955 | ||
| 850 | if (packets > 20) { | 956 | if (config.min_hosts_alive < -1) { |
| 851 | errno = 0; | 957 | errno = 0; |
| 852 | crash("packets is > 20 (%d)", packets); | 958 | crash("minimum alive hosts is negative (%i)", config.min_hosts_alive); |
| 853 | } | 959 | } |
| 854 | 960 | ||
| 855 | if (min_hosts_alive < -1) { | 961 | // Build an index table of all targets |
| 856 | errno = 0; | 962 | ping_target *host = config.targets; |
| 857 | crash("minimum alive hosts is negative (%i)", min_hosts_alive); | 963 | ping_target **table = malloc(sizeof(ping_target *) * config.number_of_targets); |
| 858 | } | ||
| 859 | |||
| 860 | host = list; | ||
| 861 | table = malloc(sizeof(struct rta_host *) * targets); | ||
| 862 | if (!table) { | 964 | if (!table) { |
| 863 | crash("main(): malloc failed for host table"); | 965 | crash("main(): malloc failed for host table"); |
| 864 | } | 966 | } |
| 865 | 967 | ||
| 866 | i = 0; | 968 | unsigned short target_index = 0; |
| 867 | while (host) { | 969 | while (host) { |
| 868 | host->id = i * packets; | 970 | host->id = target_index * config.number_of_packets; |
| 869 | table[i] = host; | 971 | table[target_index] = host; |
| 870 | host = host->next; | 972 | host = host->next; |
| 871 | i++; | 973 | target_index++; |
| 872 | } | 974 | } |
| 873 | 975 | ||
| 874 | run_checks(); | 976 | time_t target_interval = config.target_interval; |
| 977 | |||
| 978 | check_icmp_state program_state = check_icmp_state_init(); | ||
| 979 | |||
| 980 | run_checks(config.icmp_data_size, &target_interval, config.sender_id, config.mode, | ||
| 981 | max_completion_time, prog_start, table, config.number_of_packets, sockset, | ||
| 982 | config.number_of_targets, &program_state); | ||
| 875 | 983 | ||
| 876 | errno = 0; | 984 | errno = 0; |
| 877 | finish(0); | ||
| 878 | 985 | ||
| 879 | return (0); | 986 | mp_check overall = mp_check_init(); |
| 880 | } | 987 | finish(0, config.modes, config.min_hosts_alive, config.warn, config.crit, |
| 988 | config.number_of_targets, &program_state, config.hosts, config.number_of_hosts, | ||
| 989 | &overall); | ||
| 990 | |||
| 991 | if (sockset.socket4) { | ||
| 992 | close(sockset.socket4); | ||
| 993 | } | ||
| 994 | if (sockset.socket6) { | ||
| 995 | close(sockset.socket6); | ||
| 996 | } | ||
| 881 | 997 | ||
| 882 | static void run_checks(void) { | 998 | mp_exit(overall); |
| 883 | u_int i, t; | 999 | } |
| 884 | u_int final_wait, time_passed; | ||
| 885 | 1000 | ||
| 1001 | static void run_checks(unsigned short icmp_pkt_size, time_t *target_interval, | ||
| 1002 | const uint16_t sender_id, const check_icmp_execution_mode mode, | ||
| 1003 | const time_t max_completion_time, const struct timeval prog_start, | ||
| 1004 | ping_target **table, const unsigned short packets, | ||
| 1005 | const check_icmp_socket_set sockset, const unsigned short number_of_targets, | ||
| 1006 | check_icmp_state *program_state) { | ||
| 886 | /* this loop might actually violate the pkt_interval or target_interval | 1007 | /* this loop might actually violate the pkt_interval or target_interval |
| 887 | * settings, but only if there aren't any packets on the wire which | 1008 | * settings, but only if there aren't any packets on the wire which |
| 888 | * indicates that the target can handle an increased packet rate */ | 1009 | * indicates that the target can handle an increased packet rate */ |
| 889 | for (i = 0; i < packets; i++) { | 1010 | for (unsigned int packet_index = 0; packet_index < packets; packet_index++) { |
| 890 | for (t = 0; t < targets; t++) { | 1011 | for (unsigned int target_index = 0; target_index < number_of_targets; target_index++) { |
| 891 | /* don't send useless packets */ | 1012 | /* don't send useless packets */ |
| 892 | if (!targets_alive) { | 1013 | if (!targets_alive(number_of_targets, program_state->targets_down)) { |
| 893 | finish(0); | 1014 | return; |
| 894 | } | 1015 | } |
| 895 | if (table[t]->flags & FLAG_LOST_CAUSE) { | 1016 | if (table[target_index]->flags & FLAG_LOST_CAUSE) { |
| 896 | if (debug) { | 1017 | if (debug) { |
| 897 | printf("%s is a lost cause. not sending any more\n", table[t]->name); | 1018 | |
| 1019 | char address[INET6_ADDRSTRLEN]; | ||
| 1020 | parse_address(&table[target_index]->address, address, sizeof(address)); | ||
| 1021 | printf("%s is a lost cause. not sending any more\n", address); | ||
| 898 | } | 1022 | } |
| 899 | continue; | 1023 | continue; |
| 900 | } | 1024 | } |
| 901 | 1025 | ||
| 902 | /* we're still in the game, so send next packet */ | 1026 | /* we're still in the game, so send next packet */ |
| 903 | (void)send_icmp_ping(icmp_sock, table[t]); | 1027 | (void)send_icmp_ping(sockset, table[target_index], icmp_pkt_size, sender_id, |
| 904 | wait_for_reply(icmp_sock, target_interval); | 1028 | program_state); |
| 1029 | |||
| 1030 | /* wrap up if all targets are declared dead */ | ||
| 1031 | if (targets_alive(number_of_targets, program_state->targets_down) || | ||
| 1032 | get_timevaldiff(prog_start, prog_start) < max_completion_time || | ||
| 1033 | !(mode == MODE_HOSTCHECK && program_state->targets_down)) { | ||
| 1034 | wait_for_reply(sockset, *target_interval, icmp_pkt_size, target_interval, sender_id, | ||
| 1035 | table, packets, number_of_targets, program_state); | ||
| 1036 | } | ||
| 1037 | } | ||
| 1038 | if (targets_alive(number_of_targets, program_state->targets_down) || | ||
| 1039 | get_timevaldiff_to_now(prog_start) < max_completion_time || | ||
| 1040 | !(mode == MODE_HOSTCHECK && program_state->targets_down)) { | ||
| 1041 | wait_for_reply(sockset, number_of_targets, icmp_pkt_size, target_interval, sender_id, | ||
| 1042 | table, packets, number_of_targets, program_state); | ||
| 905 | } | 1043 | } |
| 906 | wait_for_reply(icmp_sock, pkt_interval * targets); | ||
| 907 | } | 1044 | } |
| 908 | 1045 | ||
| 909 | if (icmp_pkts_en_route && targets_alive) { | 1046 | if (icmp_pkts_en_route(program_state->icmp_sent, program_state->icmp_recv, |
| 910 | time_passed = get_timevaldiff(NULL, NULL); | 1047 | program_state->icmp_lost) && |
| 911 | final_wait = max_completion_time - time_passed; | 1048 | targets_alive(number_of_targets, program_state->targets_down)) { |
| 1049 | time_t time_passed = get_timevaldiff_to_now(prog_start); | ||
| 1050 | time_t final_wait = max_completion_time - time_passed; | ||
| 912 | 1051 | ||
| 913 | if (debug) { | 1052 | if (debug) { |
| 914 | printf("time_passed: %u final_wait: %u max_completion_time: %llu\n", time_passed, final_wait, max_completion_time); | 1053 | printf("time_passed: %ld final_wait: %ld max_completion_time: %ld\n", time_passed, |
| 1054 | final_wait, max_completion_time); | ||
| 915 | } | 1055 | } |
| 916 | if (time_passed > max_completion_time) { | 1056 | if (time_passed > max_completion_time) { |
| 917 | if (debug) { | 1057 | if (debug) { |
| 918 | printf("Time passed. Finishing up\n"); | 1058 | printf("Time passed. Finishing up\n"); |
| 919 | } | 1059 | } |
| 920 | finish(0); | 1060 | return; |
| 921 | } | 1061 | } |
| 922 | 1062 | ||
| 923 | /* catch the packets that might come in within the timeframe, but | 1063 | /* catch the packets that might come in within the timeframe, but |
| 924 | * haven't yet */ | 1064 | * haven't yet */ |
| 925 | if (debug) { | 1065 | if (debug) { |
| 926 | printf("Waiting for %u micro-seconds (%0.3f msecs)\n", final_wait, (float)final_wait / 1000); | 1066 | printf("Waiting for %ld micro-seconds (%0.3f msecs)\n", final_wait, |
| 1067 | (float)final_wait / 1000); | ||
| 1068 | } | ||
| 1069 | if (targets_alive(number_of_targets, program_state->targets_down) || | ||
| 1070 | get_timevaldiff_to_now(prog_start) < max_completion_time || | ||
| 1071 | !(mode == MODE_HOSTCHECK && program_state->targets_down)) { | ||
| 1072 | wait_for_reply(sockset, final_wait, icmp_pkt_size, target_interval, sender_id, table, | ||
| 1073 | packets, number_of_targets, program_state); | ||
| 927 | } | 1074 | } |
| 928 | wait_for_reply(icmp_sock, final_wait); | ||
| 929 | } | 1075 | } |
| 930 | } | 1076 | } |
| 931 | 1077 | ||
| @@ -939,18 +1085,11 @@ static void run_checks(void) { | |||
| 939 | * both: | 1085 | * both: |
| 940 | * icmp echo reply : the rest | 1086 | * icmp echo reply : the rest |
| 941 | */ | 1087 | */ |
| 942 | static int wait_for_reply(int sock, u_int t) { | 1088 | static int wait_for_reply(check_icmp_socket_set sockset, const time_t time_interval, |
| 943 | int n, hlen; | 1089 | unsigned short icmp_pkt_size, time_t *target_interval, uint16_t sender_id, |
| 944 | static unsigned char buf[65536]; | 1090 | ping_target **table, const unsigned short packets, |
| 945 | struct sockaddr_storage resp_addr; | 1091 | const unsigned short number_of_targets, check_icmp_state *program_state) { |
| 946 | union ip_hdr *ip; | ||
| 947 | union icmp_packet packet; | 1092 | union icmp_packet packet; |
| 948 | struct rta_host *host; | ||
| 949 | struct icmp_ping_data data; | ||
| 950 | struct timeval wait_start, now; | ||
| 951 | u_int tdiff, i, per_pkt_wait; | ||
| 952 | double jitter_tmp; | ||
| 953 | |||
| 954 | if (!(packet.buf = malloc(icmp_pkt_size))) { | 1093 | if (!(packet.buf = malloc(icmp_pkt_size))) { |
| 955 | crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size); | 1094 | crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size); |
| 956 | return -1; /* might be reached if we're in debug mode */ | 1095 | return -1; /* might be reached if we're in debug mode */ |
| @@ -959,177 +1098,174 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 959 | memset(packet.buf, 0, icmp_pkt_size); | 1098 | memset(packet.buf, 0, icmp_pkt_size); |
| 960 | 1099 | ||
| 961 | /* if we can't listen or don't have anything to listen to, just return */ | 1100 | /* if we can't listen or don't have anything to listen to, just return */ |
| 962 | if (!t || !icmp_pkts_en_route) { | 1101 | if (!time_interval || !icmp_pkts_en_route(program_state->icmp_sent, program_state->icmp_recv, |
| 1102 | program_state->icmp_lost)) { | ||
| 963 | free(packet.buf); | 1103 | free(packet.buf); |
| 964 | return 0; | 1104 | return 0; |
| 965 | } | 1105 | } |
| 966 | 1106 | ||
| 967 | gettimeofday(&wait_start, &tz); | 1107 | // Get current time stamp |
| 968 | 1108 | struct timeval wait_start; | |
| 969 | i = t; | 1109 | gettimeofday(&wait_start, NULL); |
| 970 | per_pkt_wait = t / icmp_pkts_en_route; | ||
| 971 | while (icmp_pkts_en_route && get_timevaldiff(&wait_start, NULL) < i) { | ||
| 972 | t = per_pkt_wait; | ||
| 973 | 1110 | ||
| 974 | /* wrap up if all targets are declared dead */ | 1111 | struct sockaddr_storage resp_addr; |
| 975 | if (!targets_alive || get_timevaldiff(&prog_start, NULL) >= max_completion_time || (mode == MODE_HOSTCHECK && targets_down)) { | 1112 | time_t per_pkt_wait = |
| 976 | finish(0); | 1113 | time_interval / icmp_pkts_en_route(program_state->icmp_sent, program_state->icmp_recv, |
| 977 | } | 1114 | program_state->icmp_lost); |
| 1115 | static unsigned char buf[65536]; | ||
| 1116 | union ip_hdr *ip_header; | ||
| 1117 | struct timeval packet_received_timestamp; | ||
| 1118 | while (icmp_pkts_en_route(program_state->icmp_sent, program_state->icmp_recv, | ||
| 1119 | program_state->icmp_lost) && | ||
| 1120 | get_timevaldiff_to_now(wait_start) < time_interval) { | ||
| 1121 | time_t loop_time_interval = per_pkt_wait; | ||
| 978 | 1122 | ||
| 979 | /* reap responses until we hit a timeout */ | 1123 | /* reap responses until we hit a timeout */ |
| 980 | n = recvfrom_wto(sock, buf, sizeof(buf), (struct sockaddr *)&resp_addr, &t, &now); | 1124 | recvfrom_wto_wrapper recv_foo = |
| 981 | if (!n) { | 1125 | recvfrom_wto(sockset, buf, sizeof(buf), (struct sockaddr *)&resp_addr, |
| 1126 | &loop_time_interval, &packet_received_timestamp); | ||
| 1127 | if (!recv_foo.received) { | ||
| 982 | if (debug > 1) { | 1128 | if (debug > 1) { |
| 983 | printf("recvfrom_wto() timed out during a %u usecs wait\n", per_pkt_wait); | 1129 | printf("recvfrom_wto() timed out during a %ld usecs wait\n", per_pkt_wait); |
| 984 | } | 1130 | } |
| 985 | continue; /* timeout for this one, so keep trying */ | 1131 | continue; /* timeout for this one, so keep trying */ |
| 986 | } | 1132 | } |
| 987 | if (n < 0) { | 1133 | |
| 1134 | if (recv_foo.received < 0) { | ||
| 988 | if (debug) { | 1135 | if (debug) { |
| 989 | printf("recvfrom_wto() returned errors\n"); | 1136 | printf("recvfrom_wto() returned errors\n"); |
| 990 | } | 1137 | } |
| 991 | free(packet.buf); | 1138 | free(packet.buf); |
| 992 | return n; | 1139 | return (int)recv_foo.received; |
| 993 | } | 1140 | } |
| 994 | 1141 | ||
| 995 | // FIXME: with ipv6 we don't have an ip header here | 1142 | if (recv_foo.recv_proto != AF_INET6) { |
| 996 | if (address_family != AF_INET6) { | 1143 | ip_header = (union ip_hdr *)buf; |
| 997 | ip = (union ip_hdr *)buf; | ||
| 998 | 1144 | ||
| 999 | if (debug > 1) { | 1145 | if (debug > 1) { |
| 1000 | char address[INET6_ADDRSTRLEN]; | 1146 | char address[INET6_ADDRSTRLEN]; |
| 1001 | parse_address(&resp_addr, address, sizeof(address)); | 1147 | parse_address(&resp_addr, address, sizeof(address)); |
| 1002 | printf("received %u bytes from %s\n", address_family == AF_INET6 ? ntohs(ip->ip6.ip6_plen) : ntohs(ip->ip.ip_len), address); | 1148 | printf("received %u bytes from %s\n", |
| 1149 | address_family == AF_INET6 ? ntohs(ip_header->ip6.ip6_plen) | ||
| 1150 | : ntohs(ip_header->ip.ip_len), | ||
| 1151 | address); | ||
| 1003 | } | 1152 | } |
| 1004 | } | 1153 | } |
| 1005 | 1154 | ||
| 1006 | /* obsolete. alpha on tru64 provides the necessary defines, but isn't broken */ | 1155 | int hlen = (recv_foo.recv_proto == AF_INET6) ? 0 : ip_header->ip.ip_hl << 2; |
| 1007 | /* #if defined( __alpha__ ) && __STDC__ && !defined( __GLIBC__ ) */ | 1156 | |
| 1008 | /* alpha headers are decidedly broken. Using an ansi compiler, | 1157 | if (recv_foo.received < (hlen + ICMP_MINLEN)) { |
| 1009 | * they provide ip_vhl instead of ip_hl and ip_v, so we mask | ||
| 1010 | * off the bottom 4 bits */ | ||
| 1011 | /* hlen = (ip->ip_vhl & 0x0f) << 2; */ | ||
| 1012 | /* #else */ | ||
| 1013 | hlen = (address_family == AF_INET6) ? 0 : ip->ip.ip_hl << 2; | ||
| 1014 | /* #endif */ | ||
| 1015 | |||
| 1016 | if (n < (hlen + ICMP_MINLEN)) { | ||
| 1017 | char address[INET6_ADDRSTRLEN]; | 1158 | char address[INET6_ADDRSTRLEN]; |
| 1018 | parse_address(&resp_addr, address, sizeof(address)); | 1159 | parse_address(&resp_addr, address, sizeof(address)); |
| 1019 | crash("received packet too short for ICMP (%d bytes, expected %d) from %s\n", n, hlen + icmp_pkt_size, address); | 1160 | crash("received packet too short for ICMP (%ld bytes, expected %d) from %s\n", |
| 1161 | recv_foo.received, hlen + icmp_pkt_size, address); | ||
| 1020 | } | 1162 | } |
| 1021 | /* else if(debug) { */ | ||
| 1022 | /* printf("ip header size: %u, packet size: %u (expected %u, %u)\n", */ | ||
| 1023 | /* hlen, ntohs(ip->ip_len) - hlen, */ | ||
| 1024 | /* sizeof(struct ip), icmp_pkt_size); */ | ||
| 1025 | /* } */ | ||
| 1026 | |||
| 1027 | /* check the response */ | 1163 | /* check the response */ |
| 1028 | |||
| 1029 | memcpy(packet.buf, buf + hlen, icmp_pkt_size); | 1164 | memcpy(packet.buf, buf + hlen, icmp_pkt_size); |
| 1030 | /* address_family == AF_INET6 ? sizeof(struct icmp6_hdr) | ||
| 1031 | : sizeof(struct icmp));*/ | ||
| 1032 | 1165 | ||
| 1033 | if ((address_family == PF_INET && (ntohs(packet.icp->icmp_id) != pid || packet.icp->icmp_type != ICMP_ECHOREPLY || | 1166 | if ((recv_foo.recv_proto == AF_INET && |
| 1034 | ntohs(packet.icp->icmp_seq) >= targets * packets)) || | 1167 | (ntohs(packet.icp->icmp_id) != sender_id || packet.icp->icmp_type != ICMP_ECHOREPLY || |
| 1035 | (address_family == PF_INET6 && (ntohs(packet.icp6->icmp6_id) != pid || packet.icp6->icmp6_type != ICMP6_ECHO_REPLY || | 1168 | ntohs(packet.icp->icmp_seq) >= number_of_targets * packets)) || |
| 1036 | ntohs(packet.icp6->icmp6_seq) >= targets * packets))) { | 1169 | (recv_foo.recv_proto == AF_INET6 && |
| 1170 | (ntohs(packet.icp6->icmp6_id) != sender_id || | ||
| 1171 | packet.icp6->icmp6_type != ICMP6_ECHO_REPLY || | ||
| 1172 | ntohs(packet.icp6->icmp6_seq) >= number_of_targets * packets))) { | ||
| 1037 | if (debug > 2) { | 1173 | if (debug > 2) { |
| 1038 | printf("not a proper ICMP_ECHOREPLY\n"); | 1174 | printf("not a proper ICMP_ECHOREPLY\n"); |
| 1039 | } | 1175 | } |
| 1040 | handle_random_icmp(buf + hlen, &resp_addr); | 1176 | |
| 1177 | handle_random_icmp(buf + hlen, &resp_addr, target_interval, sender_id, table, packets, | ||
| 1178 | number_of_targets, program_state); | ||
| 1179 | |||
| 1041 | continue; | 1180 | continue; |
| 1042 | } | 1181 | } |
| 1043 | 1182 | ||
| 1044 | /* this is indeed a valid response */ | 1183 | /* this is indeed a valid response */ |
| 1045 | if (address_family == PF_INET) { | 1184 | ping_target *target; |
| 1185 | struct icmp_ping_data data; | ||
| 1186 | if (address_family == AF_INET) { | ||
| 1046 | memcpy(&data, packet.icp->icmp_data, sizeof(data)); | 1187 | memcpy(&data, packet.icp->icmp_data, sizeof(data)); |
| 1047 | if (debug > 2) { | 1188 | if (debug > 2) { |
| 1048 | printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", (unsigned long)sizeof(data), ntohs(packet.icp->icmp_id), | 1189 | printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", sizeof(data), |
| 1049 | ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum); | 1190 | ntohs(packet.icp->icmp_id), ntohs(packet.icp->icmp_seq), |
| 1191 | packet.icp->icmp_cksum); | ||
| 1050 | } | 1192 | } |
| 1051 | host = table[ntohs(packet.icp->icmp_seq) / packets]; | 1193 | target = table[ntohs(packet.icp->icmp_seq) / packets]; |
| 1052 | } else { | 1194 | } else { |
| 1053 | memcpy(&data, &packet.icp6->icmp6_dataun.icmp6_un_data8[4], sizeof(data)); | 1195 | memcpy(&data, &packet.icp6->icmp6_dataun.icmp6_un_data8[4], sizeof(data)); |
| 1054 | if (debug > 2) { | 1196 | if (debug > 2) { |
| 1055 | printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", (unsigned long)sizeof(data), ntohs(packet.icp6->icmp6_id), | 1197 | printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n", sizeof(data), |
| 1056 | ntohs(packet.icp6->icmp6_seq), packet.icp6->icmp6_cksum); | 1198 | ntohs(packet.icp6->icmp6_id), ntohs(packet.icp6->icmp6_seq), |
| 1199 | packet.icp6->icmp6_cksum); | ||
| 1057 | } | 1200 | } |
| 1058 | host = table[ntohs(packet.icp6->icmp6_seq) / packets]; | 1201 | target = table[ntohs(packet.icp6->icmp6_seq) / packets]; |
| 1059 | } | 1202 | } |
| 1060 | 1203 | ||
| 1061 | tdiff = get_timevaldiff(&data.stime, &now); | 1204 | time_t tdiff = get_timevaldiff(data.stime, packet_received_timestamp); |
| 1062 | 1205 | ||
| 1063 | if (host->last_tdiff > 0) { | 1206 | if (target->last_tdiff > 0) { |
| 1064 | /* Calculate jitter */ | 1207 | /* Calculate jitter */ |
| 1065 | if (host->last_tdiff > tdiff) { | 1208 | double jitter_tmp; |
| 1066 | jitter_tmp = host->last_tdiff - tdiff; | 1209 | if (target->last_tdiff > tdiff) { |
| 1210 | jitter_tmp = (double)(target->last_tdiff - tdiff); | ||
| 1067 | } else { | 1211 | } else { |
| 1068 | jitter_tmp = tdiff - host->last_tdiff; | 1212 | jitter_tmp = (double)(tdiff - target->last_tdiff); |
| 1069 | } | 1213 | } |
| 1070 | 1214 | ||
| 1071 | if (host->jitter == 0) { | 1215 | if (target->jitter == 0) { |
| 1072 | host->jitter = jitter_tmp; | 1216 | target->jitter = jitter_tmp; |
| 1073 | host->jitter_max = jitter_tmp; | 1217 | target->jitter_max = jitter_tmp; |
| 1074 | host->jitter_min = jitter_tmp; | 1218 | target->jitter_min = jitter_tmp; |
| 1075 | } else { | 1219 | } else { |
| 1076 | host->jitter += jitter_tmp; | 1220 | target->jitter += jitter_tmp; |
| 1077 | 1221 | ||
| 1078 | if (jitter_tmp < host->jitter_min) { | 1222 | if (jitter_tmp < target->jitter_min) { |
| 1079 | host->jitter_min = jitter_tmp; | 1223 | target->jitter_min = jitter_tmp; |
| 1080 | } | 1224 | } |
| 1081 | 1225 | ||
| 1082 | if (jitter_tmp > host->jitter_max) { | 1226 | if (jitter_tmp > target->jitter_max) { |
| 1083 | host->jitter_max = jitter_tmp; | 1227 | target->jitter_max = jitter_tmp; |
| 1084 | } | 1228 | } |
| 1085 | } | 1229 | } |
| 1086 | 1230 | ||
| 1087 | /* Check if packets in order */ | 1231 | /* Check if packets in order */ |
| 1088 | if (host->last_icmp_seq >= packet.icp->icmp_seq) { | 1232 | if (target->last_icmp_seq >= packet.icp->icmp_seq) { |
| 1089 | host->order_status = STATE_CRITICAL; | 1233 | target->found_out_of_order_packets = true; |
| 1090 | } | 1234 | } |
| 1091 | } | 1235 | } |
| 1092 | host->last_tdiff = tdiff; | 1236 | target->last_tdiff = tdiff; |
| 1093 | 1237 | ||
| 1094 | host->last_icmp_seq = packet.icp->icmp_seq; | 1238 | target->last_icmp_seq = packet.icp->icmp_seq; |
| 1095 | 1239 | ||
| 1096 | host->time_waited += tdiff; | 1240 | target->time_waited += tdiff; |
| 1097 | host->icmp_recv++; | 1241 | target->icmp_recv++; |
| 1098 | icmp_recv++; | 1242 | program_state->icmp_recv++; |
| 1099 | 1243 | ||
| 1100 | if (tdiff > (unsigned int)host->rtmax) { | 1244 | if (tdiff > (unsigned int)target->rtmax) { |
| 1101 | host->rtmax = tdiff; | 1245 | target->rtmax = (double)tdiff; |
| 1102 | } | 1246 | } |
| 1103 | 1247 | ||
| 1104 | if ((host->rtmin == INFINITY) || (tdiff < (unsigned int)host->rtmin)) { | 1248 | if ((target->rtmin == INFINITY) || (tdiff < (unsigned int)target->rtmin)) { |
| 1105 | host->rtmin = tdiff; | 1249 | target->rtmin = (double)tdiff; |
| 1106 | } | 1250 | } |
| 1107 | 1251 | ||
| 1108 | if (debug) { | 1252 | if (debug) { |
| 1109 | char address[INET6_ADDRSTRLEN]; | 1253 | char address[INET6_ADDRSTRLEN]; |
| 1110 | parse_address(&resp_addr, address, sizeof(address)); | 1254 | parse_address(&resp_addr, address, sizeof(address)); |
| 1111 | 1255 | ||
| 1112 | switch (address_family) { | 1256 | switch (recv_foo.recv_proto) { |
| 1113 | case AF_INET: { | 1257 | case AF_INET: { |
| 1114 | printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u, max: %0.3f, min: %0.3f\n", (float)tdiff / 1000, address, | 1258 | printf("%0.3f ms rtt from %s, incoming ttl: %u, max: %0.3f, min: %0.3f\n", |
| 1115 | ttl, ip->ip.ip_ttl, (float)host->rtmax / 1000, (float)host->rtmin / 1000); | 1259 | (float)tdiff / 1000, address, ip_header->ip.ip_ttl, |
| 1260 | (float)target->rtmax / 1000, (float)target->rtmin / 1000); | ||
| 1116 | break; | 1261 | break; |
| 1117 | }; | 1262 | }; |
| 1118 | case AF_INET6: { | 1263 | case AF_INET6: { |
| 1119 | printf("%0.3f ms rtt from %s, outgoing ttl: %u, max: %0.3f, min: %0.3f\n", (float)tdiff / 1000, address, ttl, | 1264 | printf("%0.3f ms rtt from %s, max: %0.3f, min: %0.3f\n", (float)tdiff / 1000, |
| 1120 | (float)host->rtmax / 1000, (float)host->rtmin / 1000); | 1265 | address, (float)target->rtmax / 1000, (float)target->rtmin / 1000); |
| 1121 | }; | 1266 | }; |
| 1122 | } | 1267 | } |
| 1123 | } | 1268 | } |
| 1124 | |||
| 1125 | /* if we're in hostcheck mode, exit with limited printouts */ | ||
| 1126 | if (mode == MODE_HOSTCHECK) { | ||
| 1127 | printf("OK - %s responds to ICMP. Packet %u, rta %0.3fms|" | ||
| 1128 | "pkt=%u;;;0;%u rta=%0.3f;%0.3f;%0.3f;;\n", | ||
| 1129 | host->name, icmp_recv, (float)tdiff / 1000, icmp_recv, packets, (float)tdiff / 1000, (float)warn.rta / 1000, | ||
| 1130 | (float)crit.rta / 1000); | ||
| 1131 | exit(STATE_OK); | ||
| 1132 | } | ||
| 1133 | } | 1269 | } |
| 1134 | 1270 | ||
| 1135 | free(packet.buf); | 1271 | free(packet.buf); |
| @@ -1137,38 +1273,28 @@ static int wait_for_reply(int sock, u_int t) { | |||
| 1137 | } | 1273 | } |
| 1138 | 1274 | ||
| 1139 | /* the ping functions */ | 1275 | /* the ping functions */ |
| 1140 | static int send_icmp_ping(int sock, struct rta_host *host) { | 1276 | static int send_icmp_ping(const check_icmp_socket_set sockset, ping_target *host, |
| 1141 | long int len; | 1277 | const unsigned short icmp_pkt_size, const uint16_t sender_id, |
| 1142 | size_t addrlen; | 1278 | check_icmp_state *program_state) { |
| 1143 | struct icmp_ping_data data; | 1279 | void *buf = calloc(1, icmp_pkt_size); |
| 1144 | struct msghdr hdr; | ||
| 1145 | struct iovec iov; | ||
| 1146 | struct timeval tv; | ||
| 1147 | void *buf = NULL; | ||
| 1148 | |||
| 1149 | if (sock == -1) { | ||
| 1150 | errno = 0; | ||
| 1151 | crash("Attempt to send on bogus socket"); | ||
| 1152 | return -1; | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | if (!buf) { | 1280 | if (!buf) { |
| 1156 | if (!(buf = malloc(icmp_pkt_size))) { | 1281 | crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size); |
| 1157 | crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", icmp_pkt_size); | 1282 | return -1; /* might be reached if we're in debug mode */ |
| 1158 | return -1; /* might be reached if we're in debug mode */ | ||
| 1159 | } | ||
| 1160 | } | 1283 | } |
| 1161 | memset(buf, 0, icmp_pkt_size); | ||
| 1162 | 1284 | ||
| 1163 | if ((gettimeofday(&tv, &tz)) == -1) { | 1285 | struct timeval current_time; |
| 1286 | if ((gettimeofday(¤t_time, NULL)) == -1) { | ||
| 1164 | free(buf); | 1287 | free(buf); |
| 1165 | return -1; | 1288 | return -1; |
| 1166 | } | 1289 | } |
| 1167 | 1290 | ||
| 1291 | struct icmp_ping_data data; | ||
| 1168 | data.ping_id = 10; /* host->icmp.icmp_sent; */ | 1292 | data.ping_id = 10; /* host->icmp.icmp_sent; */ |
| 1169 | memcpy(&data.stime, &tv, sizeof(tv)); | 1293 | memcpy(&data.stime, ¤t_time, sizeof(current_time)); |
| 1170 | 1294 | ||
| 1171 | if (address_family == AF_INET) { | 1295 | socklen_t addrlen = 0; |
| 1296 | |||
| 1297 | if (host->address.ss_family == AF_INET) { | ||
| 1172 | struct icmp *icp = (struct icmp *)buf; | 1298 | struct icmp *icp = (struct icmp *)buf; |
| 1173 | addrlen = sizeof(struct sockaddr_in); | 1299 | addrlen = sizeof(struct sockaddr_in); |
| 1174 | 1300 | ||
| @@ -1177,15 +1303,19 @@ static int send_icmp_ping(int sock, struct rta_host *host) { | |||
| 1177 | icp->icmp_type = ICMP_ECHO; | 1303 | icp->icmp_type = ICMP_ECHO; |
| 1178 | icp->icmp_code = 0; | 1304 | icp->icmp_code = 0; |
| 1179 | icp->icmp_cksum = 0; | 1305 | icp->icmp_cksum = 0; |
| 1180 | icp->icmp_id = htons(pid); | 1306 | icp->icmp_id = htons((uint16_t)sender_id); |
| 1181 | icp->icmp_seq = htons(host->id++); | 1307 | icp->icmp_seq = htons(host->id++); |
| 1182 | icp->icmp_cksum = icmp_checksum((uint16_t *)buf, (size_t)icmp_pkt_size); | 1308 | icp->icmp_cksum = icmp_checksum((uint16_t *)buf, (size_t)icmp_pkt_size); |
| 1183 | 1309 | ||
| 1184 | if (debug > 2) { | 1310 | if (debug > 2) { |
| 1185 | printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", (unsigned long)sizeof(data), | 1311 | char address[INET6_ADDRSTRLEN]; |
| 1186 | ntohs(icp->icmp_id), ntohs(icp->icmp_seq), icp->icmp_cksum, host->name); | 1312 | parse_address((&host->address), address, sizeof(address)); |
| 1313 | |||
| 1314 | printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", | ||
| 1315 | sizeof(data), ntohs(icp->icmp_id), ntohs(icp->icmp_seq), icp->icmp_cksum, | ||
| 1316 | address); | ||
| 1187 | } | 1317 | } |
| 1188 | } else { | 1318 | } else if (host->address.ss_family == AF_INET6) { |
| 1189 | struct icmp6_hdr *icp6 = (struct icmp6_hdr *)buf; | 1319 | struct icmp6_hdr *icp6 = (struct icmp6_hdr *)buf; |
| 1190 | addrlen = sizeof(struct sockaddr_in6); | 1320 | addrlen = sizeof(struct sockaddr_in6); |
| 1191 | 1321 | ||
| @@ -1194,659 +1324,431 @@ static int send_icmp_ping(int sock, struct rta_host *host) { | |||
| 1194 | icp6->icmp6_type = ICMP6_ECHO_REQUEST; | 1324 | icp6->icmp6_type = ICMP6_ECHO_REQUEST; |
| 1195 | icp6->icmp6_code = 0; | 1325 | icp6->icmp6_code = 0; |
| 1196 | icp6->icmp6_cksum = 0; | 1326 | icp6->icmp6_cksum = 0; |
| 1197 | icp6->icmp6_id = htons(pid); | 1327 | icp6->icmp6_id = htons((uint16_t)sender_id); |
| 1198 | icp6->icmp6_seq = htons(host->id++); | 1328 | icp6->icmp6_seq = htons(host->id++); |
| 1199 | // let checksum be calculated automatically | 1329 | // let checksum be calculated automatically |
| 1200 | 1330 | ||
| 1201 | if (debug > 2) { | 1331 | if (debug > 2) { |
| 1202 | printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n", (unsigned long)sizeof(data), | 1332 | char address[INET6_ADDRSTRLEN]; |
| 1203 | ntohs(icp6->icmp6_id), ntohs(icp6->icmp6_seq), icp6->icmp6_cksum, host->name); | 1333 | parse_address((&host->address), address, sizeof(address)); |
| 1334 | |||
| 1335 | printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to target %s\n", | ||
| 1336 | sizeof(data), ntohs(icp6->icmp6_id), ntohs(icp6->icmp6_seq), icp6->icmp6_cksum, | ||
| 1337 | address); | ||
| 1204 | } | 1338 | } |
| 1339 | } else { | ||
| 1340 | // unknown address family | ||
| 1341 | crash("unknown address family in %s", __func__); | ||
| 1205 | } | 1342 | } |
| 1206 | 1343 | ||
| 1344 | struct iovec iov; | ||
| 1207 | memset(&iov, 0, sizeof(iov)); | 1345 | memset(&iov, 0, sizeof(iov)); |
| 1208 | iov.iov_base = buf; | 1346 | iov.iov_base = buf; |
| 1209 | iov.iov_len = icmp_pkt_size; | 1347 | iov.iov_len = icmp_pkt_size; |
| 1210 | 1348 | ||
| 1349 | struct msghdr hdr; | ||
| 1211 | memset(&hdr, 0, sizeof(hdr)); | 1350 | memset(&hdr, 0, sizeof(hdr)); |
| 1212 | hdr.msg_name = (struct sockaddr *)&host->saddr_in; | 1351 | hdr.msg_name = (struct sockaddr *)&host->address; |
| 1213 | hdr.msg_namelen = addrlen; | 1352 | hdr.msg_namelen = addrlen; |
| 1214 | hdr.msg_iov = &iov; | 1353 | hdr.msg_iov = &iov; |
| 1215 | hdr.msg_iovlen = 1; | 1354 | hdr.msg_iovlen = 1; |
| 1216 | 1355 | ||
| 1217 | errno = 0; | 1356 | errno = 0; |
| 1218 | 1357 | ||
| 1219 | /* MSG_CONFIRM is a linux thing and only available on linux kernels >= 2.3.15, see send(2) */ | 1358 | long int len; |
| 1359 | /* MSG_CONFIRM is a linux thing and only available on linux kernels >= 2.3.15, see send(2) */ | ||
| 1360 | if (host->address.ss_family == AF_INET) { | ||
| 1361 | #ifdef MSG_CONFIRM | ||
| 1362 | len = sendmsg(sockset.socket4, &hdr, MSG_CONFIRM); | ||
| 1363 | #else | ||
| 1364 | len = sendmsg(sockset.socket4, &hdr, 0); | ||
| 1365 | #endif | ||
| 1366 | } else if (host->address.ss_family == AF_INET6) { | ||
| 1220 | #ifdef MSG_CONFIRM | 1367 | #ifdef MSG_CONFIRM |
| 1221 | len = sendmsg(sock, &hdr, MSG_CONFIRM); | 1368 | len = sendmsg(sockset.socket6, &hdr, MSG_CONFIRM); |
| 1222 | #else | 1369 | #else |
| 1223 | len = sendmsg(sock, &hdr, 0); | 1370 | len = sendmsg(sockset.socket6, &hdr, 0); |
| 1224 | #endif | 1371 | #endif |
| 1372 | } else { | ||
| 1373 | assert(false); | ||
| 1374 | } | ||
| 1225 | 1375 | ||
| 1226 | free(buf); | 1376 | free(buf); |
| 1227 | 1377 | ||
| 1228 | if (len < 0 || (unsigned int)len != icmp_pkt_size) { | 1378 | if (len < 0 || (unsigned int)len != icmp_pkt_size) { |
| 1229 | if (debug) { | 1379 | if (debug) { |
| 1230 | char address[INET6_ADDRSTRLEN]; | 1380 | char address[INET6_ADDRSTRLEN]; |
| 1231 | parse_address((struct sockaddr_storage *)&host->saddr_in, address, sizeof(address)); | 1381 | parse_address((&host->address), address, sizeof(address)); |
| 1232 | printf("Failed to send ping to %s: %s\n", address, strerror(errno)); | 1382 | printf("Failed to send ping to %s: %s\n", address, strerror(errno)); |
| 1233 | } | 1383 | } |
| 1234 | errno = 0; | 1384 | errno = 0; |
| 1235 | return -1; | 1385 | return -1; |
| 1236 | } | 1386 | } |
| 1237 | 1387 | ||
| 1238 | icmp_sent++; | 1388 | program_state->icmp_sent++; |
| 1239 | host->icmp_sent++; | 1389 | host->icmp_sent++; |
| 1240 | 1390 | ||
| 1241 | return 0; | 1391 | return 0; |
| 1242 | } | 1392 | } |
| 1243 | 1393 | ||
| 1244 | static int recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr, u_int *timo, struct timeval *tv) { | 1394 | static recvfrom_wto_wrapper recvfrom_wto(const check_icmp_socket_set sockset, void *buf, |
| 1245 | u_int slen; | 1395 | const unsigned int len, struct sockaddr *saddr, |
| 1246 | int n, ret; | 1396 | time_t *timeout, struct timeval *received_timestamp) { |
| 1247 | struct timeval to, then, now; | ||
| 1248 | fd_set rd, wr; | ||
| 1249 | #ifdef HAVE_MSGHDR_MSG_CONTROL | 1397 | #ifdef HAVE_MSGHDR_MSG_CONTROL |
| 1250 | char ans_data[4096]; | 1398 | char ans_data[4096]; |
| 1251 | #endif // HAVE_MSGHDR_MSG_CONTROL | 1399 | #endif // HAVE_MSGHDR_MSG_CONTROL |
| 1252 | struct msghdr hdr; | ||
| 1253 | struct iovec iov; | ||
| 1254 | #ifdef SO_TIMESTAMP | 1400 | #ifdef SO_TIMESTAMP |
| 1255 | struct cmsghdr *chdr; | 1401 | struct cmsghdr *chdr; |
| 1256 | #endif | 1402 | #endif |
| 1257 | 1403 | ||
| 1258 | if (!*timo) { | 1404 | recvfrom_wto_wrapper result = { |
| 1405 | .received = 0, | ||
| 1406 | .recv_proto = AF_UNSPEC, | ||
| 1407 | }; | ||
| 1408 | |||
| 1409 | if (!*timeout) { | ||
| 1259 | if (debug) { | 1410 | if (debug) { |
| 1260 | printf("*timo is not\n"); | 1411 | printf("*timeout is not\n"); |
| 1261 | } | 1412 | } |
| 1262 | return 0; | 1413 | return result; |
| 1414 | } | ||
| 1415 | |||
| 1416 | struct timeval real_timeout; | ||
| 1417 | real_timeout.tv_sec = *timeout / 1000000; | ||
| 1418 | real_timeout.tv_usec = (*timeout - (real_timeout.tv_sec * 1000000)); | ||
| 1419 | |||
| 1420 | // Dummy fds for select | ||
| 1421 | fd_set dummy_write_fds; | ||
| 1422 | FD_ZERO(&dummy_write_fds); | ||
| 1423 | |||
| 1424 | // Read fds for select with the socket | ||
| 1425 | fd_set read_fds; | ||
| 1426 | FD_ZERO(&read_fds); | ||
| 1427 | |||
| 1428 | if (sockset.socket4 != -1) { | ||
| 1429 | FD_SET(sockset.socket4, &read_fds); | ||
| 1430 | } | ||
| 1431 | if (sockset.socket6 != -1) { | ||
| 1432 | FD_SET(sockset.socket6, &read_fds); | ||
| 1263 | } | 1433 | } |
| 1264 | 1434 | ||
| 1265 | to.tv_sec = *timo / 1000000; | 1435 | int nfds = (sockset.socket4 > sockset.socket6 ? sockset.socket4 : sockset.socket6) + 1; |
| 1266 | to.tv_usec = (*timo - (to.tv_sec * 1000000)); | 1436 | |
| 1437 | struct timeval then; | ||
| 1438 | gettimeofday(&then, NULL); | ||
| 1267 | 1439 | ||
| 1268 | FD_ZERO(&rd); | ||
| 1269 | FD_ZERO(&wr); | ||
| 1270 | FD_SET(sock, &rd); | ||
| 1271 | errno = 0; | 1440 | errno = 0; |
| 1272 | gettimeofday(&then, &tz); | 1441 | int select_return = select(nfds, &read_fds, &dummy_write_fds, NULL, &real_timeout); |
| 1273 | n = select(sock + 1, &rd, &wr, NULL, &to); | 1442 | if (select_return < 0) { |
| 1274 | if (n < 0) { | ||
| 1275 | crash("select() in recvfrom_wto"); | 1443 | crash("select() in recvfrom_wto"); |
| 1276 | } | 1444 | } |
| 1277 | gettimeofday(&now, &tz); | ||
| 1278 | *timo = get_timevaldiff(&then, &now); | ||
| 1279 | 1445 | ||
| 1280 | if (!n) { | 1446 | struct timeval now; |
| 1281 | return 0; /* timeout */ | 1447 | gettimeofday(&now, NULL); |
| 1448 | *timeout = get_timevaldiff(then, now); | ||
| 1449 | |||
| 1450 | if (!select_return) { | ||
| 1451 | return result; /* timeout */ | ||
| 1282 | } | 1452 | } |
| 1283 | 1453 | ||
| 1284 | slen = sizeof(struct sockaddr_storage); | 1454 | unsigned int slen = sizeof(struct sockaddr_storage); |
| 1285 | 1455 | ||
| 1286 | memset(&iov, 0, sizeof(iov)); | 1456 | struct iovec iov = { |
| 1287 | iov.iov_base = buf; | 1457 | .iov_base = buf, |
| 1288 | iov.iov_len = len; | 1458 | .iov_len = len, |
| 1459 | }; | ||
| 1289 | 1460 | ||
| 1290 | memset(&hdr, 0, sizeof(hdr)); | 1461 | struct msghdr hdr = { |
| 1291 | hdr.msg_name = saddr; | 1462 | .msg_name = saddr, |
| 1292 | hdr.msg_namelen = slen; | 1463 | .msg_namelen = slen, |
| 1293 | hdr.msg_iov = &iov; | 1464 | .msg_iov = &iov, |
| 1294 | hdr.msg_iovlen = 1; | 1465 | .msg_iovlen = 1, |
| 1295 | #ifdef HAVE_MSGHDR_MSG_CONTROL | 1466 | #ifdef HAVE_MSGHDR_MSG_CONTROL |
| 1296 | hdr.msg_control = ans_data; | 1467 | .msg_control = ans_data, |
| 1297 | hdr.msg_controllen = sizeof(ans_data); | 1468 | .msg_controllen = sizeof(ans_data), |
| 1298 | #endif | 1469 | #endif |
| 1470 | }; | ||
| 1471 | |||
| 1472 | ssize_t ret; | ||
| 1473 | if (FD_ISSET(sockset.socket4, &read_fds)) { | ||
| 1474 | ret = recvmsg(sockset.socket4, &hdr, 0); | ||
| 1475 | result.recv_proto = AF_INET; | ||
| 1476 | } else if (FD_ISSET(sockset.socket6, &read_fds)) { | ||
| 1477 | ret = recvmsg(sockset.socket6, &hdr, 0); | ||
| 1478 | result.recv_proto = AF_INET6; | ||
| 1479 | } else { | ||
| 1480 | assert(false); | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | result.received = ret; | ||
| 1299 | 1484 | ||
| 1300 | ret = recvmsg(sock, &hdr, 0); | ||
| 1301 | #ifdef SO_TIMESTAMP | 1485 | #ifdef SO_TIMESTAMP |
| 1302 | for (chdr = CMSG_FIRSTHDR(&hdr); chdr; chdr = CMSG_NXTHDR(&hdr, chdr)) { | 1486 | for (chdr = CMSG_FIRSTHDR(&hdr); chdr; chdr = CMSG_NXTHDR(&hdr, chdr)) { |
| 1303 | if (chdr->cmsg_level == SOL_SOCKET && chdr->cmsg_type == SO_TIMESTAMP && chdr->cmsg_len >= CMSG_LEN(sizeof(struct timeval))) { | 1487 | if (chdr->cmsg_level == SOL_SOCKET && chdr->cmsg_type == SO_TIMESTAMP && |
| 1304 | memcpy(tv, CMSG_DATA(chdr), sizeof(*tv)); | 1488 | chdr->cmsg_len >= CMSG_LEN(sizeof(struct timeval))) { |
| 1489 | memcpy(received_timestamp, CMSG_DATA(chdr), sizeof(*received_timestamp)); | ||
| 1305 | break; | 1490 | break; |
| 1306 | } | 1491 | } |
| 1307 | } | 1492 | } |
| 1308 | 1493 | ||
| 1309 | if (!chdr) | 1494 | if (!chdr) { |
| 1495 | gettimeofday(received_timestamp, NULL); | ||
| 1496 | } | ||
| 1497 | #else | ||
| 1498 | gettimeofday(tv, NULL); | ||
| 1310 | #endif // SO_TIMESTAMP | 1499 | #endif // SO_TIMESTAMP |
| 1311 | gettimeofday(tv, &tz); | ||
| 1312 | return (ret); | ||
| 1313 | } | ||
| 1314 | 1500 | ||
| 1315 | static void finish(int sig) { | 1501 | return (result); |
| 1316 | u_int i = 0; | 1502 | } |
| 1317 | unsigned char pl; | ||
| 1318 | double rta; | ||
| 1319 | struct rta_host *host; | ||
| 1320 | const char *status_string[] = {"OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT"}; | ||
| 1321 | int hosts_ok = 0; | ||
| 1322 | int hosts_warn = 0; | ||
| 1323 | int this_status; | ||
| 1324 | double R; | ||
| 1325 | 1503 | ||
| 1504 | static void finish(int sig, check_icmp_mode_switches modes, int min_hosts_alive, | ||
| 1505 | check_icmp_threshold warn, check_icmp_threshold crit, | ||
| 1506 | const unsigned short number_of_targets, check_icmp_state *program_state, | ||
| 1507 | check_icmp_target_container host_list[], unsigned short number_of_hosts, | ||
| 1508 | mp_check overall[static 1]) { | ||
| 1509 | // Deactivate alarm | ||
| 1326 | alarm(0); | 1510 | alarm(0); |
| 1511 | |||
| 1327 | if (debug > 1) { | 1512 | if (debug > 1) { |
| 1328 | printf("finish(%d) called\n", sig); | 1513 | printf("finish(%d) called\n", sig); |
| 1329 | } | 1514 | } |
| 1330 | 1515 | ||
| 1331 | if (icmp_sock != -1) { | ||
| 1332 | close(icmp_sock); | ||
| 1333 | } | ||
| 1334 | if (udp_sock != -1) { | ||
| 1335 | close(udp_sock); | ||
| 1336 | } | ||
| 1337 | if (tcp_sock != -1) { | ||
| 1338 | close(tcp_sock); | ||
| 1339 | } | ||
| 1340 | |||
| 1341 | if (debug) { | 1516 | if (debug) { |
| 1342 | printf("icmp_sent: %u icmp_recv: %u icmp_lost: %u\n", icmp_sent, icmp_recv, icmp_lost); | 1517 | printf("icmp_sent: %u icmp_recv: %u icmp_lost: %u\n", program_state->icmp_sent, |
| 1343 | printf("targets: %u targets_alive: %u\n", targets, targets_alive); | 1518 | program_state->icmp_recv, program_state->icmp_lost); |
| 1519 | printf("targets: %u targets_alive: %u\n", number_of_targets, | ||
| 1520 | targets_alive(number_of_targets, program_state->targets_down)); | ||
| 1344 | } | 1521 | } |
| 1345 | 1522 | ||
| 1346 | /* iterate thrice to calculate values, give output, and print perfparse */ | 1523 | // loop over targets to evaluate each one |
| 1347 | status = STATE_OK; | 1524 | int targets_ok = 0; |
| 1348 | host = list; | 1525 | int targets_warn = 0; |
| 1349 | 1526 | for (unsigned short i = 0; i < number_of_hosts; i++) { | |
| 1350 | while (host) { | 1527 | evaluate_host_wrapper host_check = evaluate_host(host_list[i], modes, warn, crit); |
| 1351 | this_status = STATE_OK; | ||
| 1352 | |||
| 1353 | if (!host->icmp_recv) { | ||
| 1354 | /* rta 0 is ofcourse not entirely correct, but will still show up | ||
| 1355 | * conspicuously as missing entries in perfparse and cacti */ | ||
| 1356 | pl = 100; | ||
| 1357 | rta = 0; | ||
| 1358 | status = STATE_CRITICAL; | ||
| 1359 | /* up the down counter if not already counted */ | ||
| 1360 | if (!(host->flags & FLAG_LOST_CAUSE) && targets_alive) { | ||
| 1361 | targets_down++; | ||
| 1362 | } | ||
| 1363 | } else { | ||
| 1364 | pl = ((host->icmp_sent - host->icmp_recv) * 100) / host->icmp_sent; | ||
| 1365 | rta = (double)host->time_waited / host->icmp_recv; | ||
| 1366 | } | ||
| 1367 | |||
| 1368 | if (host->icmp_recv > 1) { | ||
| 1369 | /* | ||
| 1370 | * This algorithm is probably pretty much blindly copied from | ||
| 1371 | * locations like this one: https://www.slac.stanford.edu/comp/net/wan-mon/tutorial.html#mos | ||
| 1372 | * It calculates a MOS value (range of 1 to 5, where 1 is bad and 5 really good). | ||
| 1373 | * According to some quick research MOS originates from the Audio/Video transport network area. | ||
| 1374 | * Whether it can and should be computed from ICMP data, I can not say. | ||
| 1375 | * | ||
| 1376 | * Anyway the basic idea is to map a value "R" with a range of 0-100 to the MOS value | ||
| 1377 | * | ||
| 1378 | * MOS stands likely for Mean Opinion Score ( https://en.wikipedia.org/wiki/Mean_Opinion_Score ) | ||
| 1379 | * | ||
| 1380 | * More links: | ||
| 1381 | * - https://confluence.slac.stanford.edu/display/IEPM/MOS | ||
| 1382 | */ | ||
| 1383 | host->jitter = (host->jitter / (host->icmp_recv - 1) / 1000); | ||
| 1384 | |||
| 1385 | /* | ||
| 1386 | * Take the average round trip latency (in milliseconds), add | ||
| 1387 | * round trip jitter, but double the impact to latency | ||
| 1388 | * then add 10 for protocol latencies (in milliseconds). | ||
| 1389 | */ | ||
| 1390 | host->EffectiveLatency = (rta / 1000) + host->jitter * 2 + 10; | ||
| 1391 | |||
| 1392 | if (host->EffectiveLatency < 160) { | ||
| 1393 | R = 93.2 - (host->EffectiveLatency / 40); | ||
| 1394 | } else { | ||
| 1395 | R = 93.2 - ((host->EffectiveLatency - 120) / 10); | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | // Now, let us deduct 2.5 R values per percentage of packet loss (i.e. a | ||
| 1399 | // loss of 5% will be entered as 5). | ||
| 1400 | R = R - (pl * 2.5); | ||
| 1401 | 1528 | ||
| 1402 | if (R < 0) { | 1529 | targets_ok += host_check.targets_ok; |
| 1403 | R = 0; | 1530 | targets_warn += host_check.targets_warn; |
| 1404 | } | ||
| 1405 | 1531 | ||
| 1406 | host->score = R; | 1532 | mp_add_subcheck_to_check(overall, host_check.sc_host); |
| 1407 | host->mos = 1 + ((0.035) * R) + ((.000007) * R * (R - 60) * (100 - R)); | ||
| 1408 | } else { | ||
| 1409 | host->jitter = 0; | ||
| 1410 | host->jitter_min = 0; | ||
| 1411 | host->jitter_max = 0; | ||
| 1412 | host->mos = 0; | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | host->pl = pl; | ||
| 1416 | host->rta = rta; | ||
| 1417 | |||
| 1418 | /* if no new mode selected, use old schema */ | ||
| 1419 | if (!rta_mode && !pl_mode && !jitter_mode && !score_mode && !mos_mode && !order_mode) { | ||
| 1420 | rta_mode = true; | ||
| 1421 | pl_mode = true; | ||
| 1422 | } | ||
| 1423 | |||
| 1424 | /* Check which mode is on and do the warn / Crit stuff */ | ||
| 1425 | if (rta_mode) { | ||
| 1426 | if (rta >= crit.rta) { | ||
| 1427 | this_status = STATE_CRITICAL; | ||
| 1428 | status = STATE_CRITICAL; | ||
| 1429 | host->rta_status = STATE_CRITICAL; | ||
| 1430 | } else if (status != STATE_CRITICAL && (rta >= warn.rta)) { | ||
| 1431 | this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status); | ||
| 1432 | status = STATE_WARNING; | ||
| 1433 | host->rta_status = STATE_WARNING; | ||
| 1434 | } | ||
| 1435 | } | ||
| 1436 | |||
| 1437 | if (pl_mode) { | ||
| 1438 | if (pl >= crit.pl) { | ||
| 1439 | this_status = STATE_CRITICAL; | ||
| 1440 | status = STATE_CRITICAL; | ||
| 1441 | host->pl_status = STATE_CRITICAL; | ||
| 1442 | } else if (status != STATE_CRITICAL && (pl >= warn.pl)) { | ||
| 1443 | this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status); | ||
| 1444 | status = STATE_WARNING; | ||
| 1445 | host->pl_status = STATE_WARNING; | ||
| 1446 | } | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | if (jitter_mode) { | ||
| 1450 | if (host->jitter >= crit.jitter) { | ||
| 1451 | this_status = STATE_CRITICAL; | ||
| 1452 | status = STATE_CRITICAL; | ||
| 1453 | host->jitter_status = STATE_CRITICAL; | ||
| 1454 | } else if (status != STATE_CRITICAL && (host->jitter >= warn.jitter)) { | ||
| 1455 | this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status); | ||
| 1456 | status = STATE_WARNING; | ||
| 1457 | host->jitter_status = STATE_WARNING; | ||
| 1458 | } | ||
| 1459 | } | ||
| 1460 | |||
| 1461 | if (mos_mode) { | ||
| 1462 | if (host->mos <= crit.mos) { | ||
| 1463 | this_status = STATE_CRITICAL; | ||
| 1464 | status = STATE_CRITICAL; | ||
| 1465 | host->mos_status = STATE_CRITICAL; | ||
| 1466 | } else if (status != STATE_CRITICAL && (host->mos <= warn.mos)) { | ||
| 1467 | this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status); | ||
| 1468 | status = STATE_WARNING; | ||
| 1469 | host->mos_status = STATE_WARNING; | ||
| 1470 | } | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | if (score_mode) { | ||
| 1474 | if (host->score <= crit.score) { | ||
| 1475 | this_status = STATE_CRITICAL; | ||
| 1476 | status = STATE_CRITICAL; | ||
| 1477 | host->score_status = STATE_CRITICAL; | ||
| 1478 | } else if (status != STATE_CRITICAL && (host->score <= warn.score)) { | ||
| 1479 | this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status); | ||
| 1480 | status = STATE_WARNING; | ||
| 1481 | host->score_status = STATE_WARNING; | ||
| 1482 | } | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | if (this_status == STATE_WARNING) { | ||
| 1486 | hosts_warn++; | ||
| 1487 | } else if (this_status == STATE_OK) { | ||
| 1488 | hosts_ok++; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | host = host->next; | ||
| 1492 | } | 1533 | } |
| 1493 | 1534 | ||
| 1494 | /* this is inevitable */ | ||
| 1495 | if (!targets_alive) { | ||
| 1496 | status = STATE_CRITICAL; | ||
| 1497 | } | ||
| 1498 | if (min_hosts_alive > -1) { | 1535 | if (min_hosts_alive > -1) { |
| 1499 | if (hosts_ok >= min_hosts_alive) { | 1536 | mp_subcheck sc_min_targets_alive = mp_subcheck_init(); |
| 1500 | status = STATE_OK; | 1537 | sc_min_targets_alive = mp_set_subcheck_default_state(sc_min_targets_alive, STATE_OK); |
| 1501 | } else if ((hosts_ok + hosts_warn) >= min_hosts_alive) { | 1538 | |
| 1502 | status = STATE_WARNING; | 1539 | if (targets_ok >= min_hosts_alive) { |
| 1503 | } | 1540 | sc_min_targets_alive = mp_set_subcheck_state(sc_min_targets_alive, STATE_OK); |
| 1504 | } | 1541 | xasprintf(&sc_min_targets_alive.output, "%u targets OK of a minimum of %u", targets_ok, |
| 1505 | printf("%s - ", status_string[status]); | 1542 | min_hosts_alive); |
| 1506 | 1543 | ||
| 1507 | host = list; | 1544 | // Overwrite main state here |
| 1508 | while (host) { | 1545 | overall->evaluation_function = &mp_eval_ok; |
| 1509 | if (debug) { | 1546 | } else if ((targets_ok + targets_warn) >= min_hosts_alive) { |
| 1510 | puts(""); | 1547 | sc_min_targets_alive = mp_set_subcheck_state(sc_min_targets_alive, STATE_WARNING); |
| 1511 | } | 1548 | xasprintf(&sc_min_targets_alive.output, "%u targets OK or Warning of a minimum of %u", |
| 1512 | 1549 | targets_ok + targets_warn, min_hosts_alive); | |
| 1513 | if (i) { | 1550 | overall->evaluation_function = &mp_eval_warning; |
| 1514 | if (i < targets) { | 1551 | } else { |
| 1515 | printf(" :: "); | 1552 | sc_min_targets_alive = mp_set_subcheck_state(sc_min_targets_alive, STATE_CRITICAL); |
| 1516 | } else { | 1553 | xasprintf(&sc_min_targets_alive.output, "%u targets OK or Warning of a minimum of %u", |
| 1517 | printf("\n"); | 1554 | targets_ok + targets_warn, min_hosts_alive); |
| 1518 | } | 1555 | overall->evaluation_function = &mp_eval_critical; |
| 1519 | } | ||
| 1520 | |||
| 1521 | i++; | ||
| 1522 | |||
| 1523 | if (!host->icmp_recv) { | ||
| 1524 | status = STATE_CRITICAL; | ||
| 1525 | host->rtmin = 0; | ||
| 1526 | host->jitter_min = 0; | ||
| 1527 | |||
| 1528 | if (host->flags & FLAG_LOST_CAUSE) { | ||
| 1529 | char address[INET6_ADDRSTRLEN]; | ||
| 1530 | parse_address(&host->error_addr, address, sizeof(address)); | ||
| 1531 | printf("%s: %s @ %s. rta nan, lost %d%%", host->name, get_icmp_error_msg(host->icmp_type, host->icmp_code), address, 100); | ||
| 1532 | } else { /* not marked as lost cause, so we have no flags for it */ | ||
| 1533 | printf("%s: rta nan, lost 100%%", host->name); | ||
| 1534 | } | ||
| 1535 | } else { /* !icmp_recv */ | ||
| 1536 | printf("%s", host->name); | ||
| 1537 | /* rta text output */ | ||
| 1538 | if (rta_mode) { | ||
| 1539 | if (status == STATE_OK) { | ||
| 1540 | printf(" rta %0.3fms", host->rta / 1000); | ||
| 1541 | } else if (status == STATE_WARNING && host->rta_status == status) { | ||
| 1542 | printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)warn.rta / 1000); | ||
| 1543 | } else if (status == STATE_CRITICAL && host->rta_status == status) { | ||
| 1544 | printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)crit.rta / 1000); | ||
| 1545 | } | ||
| 1546 | } | ||
| 1547 | |||
| 1548 | /* pl text output */ | ||
| 1549 | if (pl_mode) { | ||
| 1550 | if (status == STATE_OK) { | ||
| 1551 | printf(" lost %u%%", host->pl); | ||
| 1552 | } else if (status == STATE_WARNING && host->pl_status == status) { | ||
| 1553 | printf(" lost %u%% > %u%%", host->pl, warn.pl); | ||
| 1554 | } else if (status == STATE_CRITICAL && host->pl_status == status) { | ||
| 1555 | printf(" lost %u%% > %u%%", host->pl, crit.pl); | ||
| 1556 | } | ||
| 1557 | } | ||
| 1558 | |||
| 1559 | /* jitter text output */ | ||
| 1560 | if (jitter_mode) { | ||
| 1561 | if (status == STATE_OK) { | ||
| 1562 | printf(" jitter %0.3fms", (float)host->jitter); | ||
| 1563 | } else if (status == STATE_WARNING && host->jitter_status == status) { | ||
| 1564 | printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, warn.jitter); | ||
| 1565 | } else if (status == STATE_CRITICAL && host->jitter_status == status) { | ||
| 1566 | printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, crit.jitter); | ||
| 1567 | } | ||
| 1568 | } | ||
| 1569 | |||
| 1570 | /* mos text output */ | ||
| 1571 | if (mos_mode) { | ||
| 1572 | if (status == STATE_OK) { | ||
| 1573 | printf(" MOS %0.1f", (float)host->mos); | ||
| 1574 | } else if (status == STATE_WARNING && host->mos_status == status) { | ||
| 1575 | printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)warn.mos); | ||
| 1576 | } else if (status == STATE_CRITICAL && host->mos_status == status) { | ||
| 1577 | printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)crit.mos); | ||
| 1578 | } | ||
| 1579 | } | ||
| 1580 | |||
| 1581 | /* score text output */ | ||
| 1582 | if (score_mode) { | ||
| 1583 | if (status == STATE_OK) { | ||
| 1584 | printf(" Score %u", (int)host->score); | ||
| 1585 | } else if (status == STATE_WARNING && host->score_status == status) { | ||
| 1586 | printf(" Score %u < %u", (int)host->score, (int)warn.score); | ||
| 1587 | } else if (status == STATE_CRITICAL && host->score_status == status) { | ||
| 1588 | printf(" Score %u < %u", (int)host->score, (int)crit.score); | ||
| 1589 | } | ||
| 1590 | } | ||
| 1591 | |||
| 1592 | /* order statis text output */ | ||
| 1593 | if (order_mode) { | ||
| 1594 | if (status == STATE_OK) { | ||
| 1595 | printf(" Packets in order"); | ||
| 1596 | } else if (status == STATE_CRITICAL && host->order_status == status) { | ||
| 1597 | printf(" Packets out of order"); | ||
| 1598 | } | ||
| 1599 | } | ||
| 1600 | } | ||
| 1601 | host = host->next; | ||
| 1602 | } | ||
| 1603 | |||
| 1604 | /* iterate once more for pretty perfparse output */ | ||
| 1605 | if (!(!rta_mode && !pl_mode && !jitter_mode && !score_mode && !mos_mode && order_mode)) { | ||
| 1606 | printf("|"); | ||
| 1607 | } | ||
| 1608 | i = 0; | ||
| 1609 | host = list; | ||
| 1610 | while (host) { | ||
| 1611 | if (debug) { | ||
| 1612 | puts(""); | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | if (rta_mode) { | ||
| 1616 | if (host->pl < 100) { | ||
| 1617 | printf("%srta=%0.3fms;%0.3f;%0.3f;0; %srtmax=%0.3fms;;;; %srtmin=%0.3fms;;;; ", (targets > 1) ? host->name : "", | ||
| 1618 | host->rta / 1000, (float)warn.rta / 1000, (float)crit.rta / 1000, (targets > 1) ? host->name : "", | ||
| 1619 | (float)host->rtmax / 1000, (targets > 1) ? host->name : "", | ||
| 1620 | (host->rtmin < INFINITY) ? (float)host->rtmin / 1000 : (float)0); | ||
| 1621 | } else { | ||
| 1622 | printf("%srta=U;;;; %srtmax=U;;;; %srtmin=U;;;; ", (targets > 1) ? host->name : "", (targets > 1) ? host->name : "", | ||
| 1623 | (targets > 1) ? host->name : ""); | ||
| 1624 | } | ||
| 1625 | } | ||
| 1626 | |||
| 1627 | if (pl_mode) { | ||
| 1628 | printf("%spl=%u%%;%u;%u;0;100 ", (targets > 1) ? host->name : "", host->pl, warn.pl, crit.pl); | ||
| 1629 | } | ||
| 1630 | |||
| 1631 | if (jitter_mode) { | ||
| 1632 | if (host->pl < 100) { | ||
| 1633 | printf("%sjitter_avg=%0.3fms;%0.3f;%0.3f;0; %sjitter_max=%0.3fms;;;; %sjitter_min=%0.3fms;;;; ", | ||
| 1634 | (targets > 1) ? host->name : "", (float)host->jitter, (float)warn.jitter, (float)crit.jitter, | ||
| 1635 | (targets > 1) ? host->name : "", (float)host->jitter_max / 1000, (targets > 1) ? host->name : "", | ||
| 1636 | (float)host->jitter_min / 1000); | ||
| 1637 | } else { | ||
| 1638 | printf("%sjitter_avg=U;;;; %sjitter_max=U;;;; %sjitter_min=U;;;; ", (targets > 1) ? host->name : "", | ||
| 1639 | (targets > 1) ? host->name : "", (targets > 1) ? host->name : ""); | ||
| 1640 | } | ||
| 1641 | } | ||
| 1642 | |||
| 1643 | if (mos_mode) { | ||
| 1644 | if (host->pl < 100) { | ||
| 1645 | printf("%smos=%0.1f;%0.1f;%0.1f;0;5 ", (targets > 1) ? host->name : "", (float)host->mos, (float)warn.mos, (float)crit.mos); | ||
| 1646 | } else { | ||
| 1647 | printf("%smos=U;;;; ", (targets > 1) ? host->name : ""); | ||
| 1648 | } | ||
| 1649 | } | ||
| 1650 | |||
| 1651 | if (score_mode) { | ||
| 1652 | if (host->pl < 100) { | ||
| 1653 | printf("%sscore=%u;%u;%u;0;100 ", (targets > 1) ? host->name : "", (int)host->score, (int)warn.score, (int)crit.score); | ||
| 1654 | } else { | ||
| 1655 | printf("%sscore=U;;;; ", (targets > 1) ? host->name : ""); | ||
| 1656 | } | ||
| 1657 | } | 1556 | } |
| 1658 | 1557 | ||
| 1659 | host = host->next; | 1558 | mp_add_subcheck_to_check(overall, sc_min_targets_alive); |
| 1660 | } | ||
| 1661 | |||
| 1662 | if (min_hosts_alive > -1) { | ||
| 1663 | if (hosts_ok >= min_hosts_alive) { | ||
| 1664 | status = STATE_OK; | ||
| 1665 | } else if ((hosts_ok + hosts_warn) >= min_hosts_alive) { | ||
| 1666 | status = STATE_WARNING; | ||
| 1667 | } | ||
| 1668 | } | 1559 | } |
| 1669 | 1560 | ||
| 1670 | /* finish with an empty line */ | 1561 | /* finish with an empty line */ |
| 1671 | puts(""); | ||
| 1672 | if (debug) { | 1562 | if (debug) { |
| 1673 | printf("targets: %u, targets_alive: %u, hosts_ok: %u, hosts_warn: %u, min_hosts_alive: %i\n", targets, targets_alive, hosts_ok, | 1563 | printf( |
| 1674 | hosts_warn, min_hosts_alive); | 1564 | "targets: %u, targets_alive: %u, hosts_ok: %u, hosts_warn: %u, min_hosts_alive: %i\n", |
| 1565 | number_of_targets, targets_alive(number_of_targets, program_state->targets_down), | ||
| 1566 | targets_ok, targets_warn, min_hosts_alive); | ||
| 1675 | } | 1567 | } |
| 1676 | |||
| 1677 | exit(status); | ||
| 1678 | } | 1568 | } |
| 1679 | 1569 | ||
| 1680 | static u_int get_timevaldiff(struct timeval *early, struct timeval *later) { | 1570 | static time_t get_timevaldiff(const struct timeval earlier, const struct timeval later) { |
| 1681 | u_int ret; | ||
| 1682 | struct timeval now; | ||
| 1683 | |||
| 1684 | if (!later) { | ||
| 1685 | gettimeofday(&now, &tz); | ||
| 1686 | later = &now; | ||
| 1687 | } | ||
| 1688 | if (!early) { | ||
| 1689 | early = &prog_start; | ||
| 1690 | } | ||
| 1691 | |||
| 1692 | /* if early > later we return 0 so as to indicate a timeout */ | 1571 | /* if early > later we return 0 so as to indicate a timeout */ |
| 1693 | if (early->tv_sec > later->tv_sec || (early->tv_sec == later->tv_sec && early->tv_usec > later->tv_usec)) { | 1572 | if (earlier.tv_sec > later.tv_sec || |
| 1573 | (earlier.tv_sec == later.tv_sec && earlier.tv_usec > later.tv_usec)) { | ||
| 1694 | return 0; | 1574 | return 0; |
| 1695 | } | 1575 | } |
| 1696 | ret = (later->tv_sec - early->tv_sec) * 1000000; | 1576 | |
| 1697 | ret += later->tv_usec - early->tv_usec; | 1577 | time_t ret = (later.tv_sec - earlier.tv_sec) * 1000000; |
| 1578 | ret += later.tv_usec - earlier.tv_usec; | ||
| 1698 | 1579 | ||
| 1699 | return ret; | 1580 | return ret; |
| 1700 | } | 1581 | } |
| 1701 | 1582 | ||
| 1702 | static int add_target_ip(char *arg, struct sockaddr_storage *in) { | 1583 | static time_t get_timevaldiff_to_now(struct timeval earlier) { |
| 1703 | struct rta_host *host; | 1584 | struct timeval now; |
| 1704 | struct sockaddr_in *sin, *host_sin; | 1585 | gettimeofday(&now, NULL); |
| 1705 | struct sockaddr_in6 *sin6, *host_sin6; | 1586 | |
| 1587 | return get_timevaldiff(earlier, now); | ||
| 1588 | } | ||
| 1589 | |||
| 1590 | static add_target_ip_wrapper add_target_ip(struct sockaddr_storage address) { | ||
| 1591 | assert((address.ss_family == AF_INET) || (address.ss_family == AF_INET6)); | ||
| 1706 | 1592 | ||
| 1707 | if (address_family == AF_INET) { | 1593 | if (debug) { |
| 1708 | sin = (struct sockaddr_in *)in; | 1594 | char straddr[INET6_ADDRSTRLEN]; |
| 1595 | parse_address((&address), straddr, sizeof(straddr)); | ||
| 1596 | printf("add_target_ip called with: %s\n", straddr); | ||
| 1597 | } | ||
| 1598 | struct sockaddr_in *sin; | ||
| 1599 | struct sockaddr_in6 *sin6; | ||
| 1600 | if (address.ss_family == AF_INET) { | ||
| 1601 | sin = (struct sockaddr_in *)&address; | ||
| 1602 | } else if (address.ss_family == AF_INET6) { | ||
| 1603 | sin6 = (struct sockaddr_in6 *)&address; | ||
| 1709 | } else { | 1604 | } else { |
| 1710 | sin6 = (struct sockaddr_in6 *)in; | 1605 | assert(false); |
| 1711 | } | 1606 | } |
| 1712 | 1607 | ||
| 1608 | add_target_ip_wrapper result = { | ||
| 1609 | .error_code = OK, | ||
| 1610 | .target = NULL, | ||
| 1611 | }; | ||
| 1612 | |||
| 1713 | /* disregard obviously stupid addresses | 1613 | /* disregard obviously stupid addresses |
| 1714 | * (I didn't find an ipv6 equivalent to INADDR_NONE) */ | 1614 | * (I didn't find an ipv6 equivalent to INADDR_NONE) */ |
| 1715 | if (((address_family == AF_INET && (sin->sin_addr.s_addr == INADDR_NONE || sin->sin_addr.s_addr == INADDR_ANY))) || | 1615 | if (((address.ss_family == AF_INET && |
| 1716 | (address_family == AF_INET6 && (sin6->sin6_addr.s6_addr == in6addr_any.s6_addr))) { | 1616 | (sin->sin_addr.s_addr == INADDR_NONE || sin->sin_addr.s_addr == INADDR_ANY))) || |
| 1717 | return -1; | 1617 | (address.ss_family == AF_INET6 && (sin6->sin6_addr.s6_addr == in6addr_any.s6_addr))) { |
| 1618 | result.error_code = ERROR; | ||
| 1619 | return result; | ||
| 1718 | } | 1620 | } |
| 1719 | 1621 | ||
| 1720 | /* no point in adding two identical IP's, so don't. ;) */ | 1622 | // get string representation of address |
| 1721 | host = list; | 1623 | char straddr[INET6_ADDRSTRLEN]; |
| 1722 | while (host) { | 1624 | parse_address((&address), straddr, sizeof(straddr)); |
| 1723 | host_sin = (struct sockaddr_in *)&host->saddr_in; | ||
| 1724 | host_sin6 = (struct sockaddr_in6 *)&host->saddr_in; | ||
| 1725 | |||
| 1726 | if ((address_family == AF_INET && host_sin->sin_addr.s_addr == sin->sin_addr.s_addr) || | ||
| 1727 | (address_family == AF_INET6 && host_sin6->sin6_addr.s6_addr == sin6->sin6_addr.s6_addr)) { | ||
| 1728 | if (debug) { | ||
| 1729 | printf("Identical IP already exists. Not adding %s\n", arg); | ||
| 1730 | } | ||
| 1731 | return -1; | ||
| 1732 | } | ||
| 1733 | host = host->next; | ||
| 1734 | } | ||
| 1735 | 1625 | ||
| 1736 | /* add the fresh ip */ | 1626 | /* add the fresh ip */ |
| 1737 | host = (struct rta_host *)malloc(sizeof(struct rta_host)); | 1627 | ping_target *target = (ping_target *)calloc(1, sizeof(ping_target)); |
| 1738 | if (!host) { | 1628 | if (!target) { |
| 1739 | char straddr[INET6_ADDRSTRLEN]; | 1629 | crash("add_target_ip(%s): malloc(%lu) failed", straddr, sizeof(ping_target)); |
| 1740 | parse_address((struct sockaddr_storage *)&in, straddr, sizeof(straddr)); | ||
| 1741 | crash("add_target_ip(%s, %s): malloc(%lu) failed", arg, straddr, sizeof(struct rta_host)); | ||
| 1742 | } | 1630 | } |
| 1743 | memset(host, 0, sizeof(struct rta_host)); | ||
| 1744 | 1631 | ||
| 1745 | /* set the values. use calling name for output */ | 1632 | ping_target_create_wrapper target_wrapper = ping_target_create(address); |
| 1746 | host->name = strdup(arg); | ||
| 1747 | 1633 | ||
| 1748 | /* fill out the sockaddr_storage struct */ | 1634 | if (target_wrapper.errorcode == OK) { |
| 1749 | if (address_family == AF_INET) { | 1635 | *target = target_wrapper.host; |
| 1750 | host_sin = (struct sockaddr_in *)&host->saddr_in; | 1636 | result.target = target; |
| 1751 | host_sin->sin_family = AF_INET; | ||
| 1752 | host_sin->sin_addr.s_addr = sin->sin_addr.s_addr; | ||
| 1753 | } else { | 1637 | } else { |
| 1754 | host_sin6 = (struct sockaddr_in6 *)&host->saddr_in; | 1638 | result.error_code = target_wrapper.errorcode; |
| 1755 | host_sin6->sin6_family = AF_INET6; | ||
| 1756 | memcpy(host_sin6->sin6_addr.s6_addr, sin6->sin6_addr.s6_addr, sizeof host_sin6->sin6_addr.s6_addr); | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | /* fill out the sockaddr_in struct */ | ||
| 1760 | host->rtmin = INFINITY; | ||
| 1761 | host->rtmax = 0; | ||
| 1762 | host->jitter = 0; | ||
| 1763 | host->jitter_max = 0; | ||
| 1764 | host->jitter_min = INFINITY; | ||
| 1765 | host->last_tdiff = 0; | ||
| 1766 | host->order_status = STATE_OK; | ||
| 1767 | host->last_icmp_seq = 0; | ||
| 1768 | host->rta_status = 0; | ||
| 1769 | host->pl_status = 0; | ||
| 1770 | host->jitter_status = 0; | ||
| 1771 | host->mos_status = 0; | ||
| 1772 | host->score_status = 0; | ||
| 1773 | host->pl_status = 0; | ||
| 1774 | |||
| 1775 | if (!list) { | ||
| 1776 | list = cursor = host; | ||
| 1777 | } else { | ||
| 1778 | cursor->next = host; | ||
| 1779 | } | 1639 | } |
| 1780 | 1640 | ||
| 1781 | cursor = host; | 1641 | return result; |
| 1782 | targets++; | ||
| 1783 | |||
| 1784 | return 0; | ||
| 1785 | } | 1642 | } |
| 1786 | 1643 | ||
| 1787 | /* wrapper for add_target_ip */ | 1644 | /* wrapper for add_target_ip */ |
| 1788 | static int add_target(char *arg) { | 1645 | static add_target_wrapper add_target(char *arg, const check_icmp_execution_mode mode, |
| 1789 | int error, result = -1; | 1646 | sa_family_t enforced_proto) { |
| 1790 | struct sockaddr_storage ip; | 1647 | if (debug > 0) { |
| 1791 | struct addrinfo hints, *res, *p; | 1648 | printf("add_target called with argument %s\n", arg); |
| 1792 | struct sockaddr_in *sin; | 1649 | } |
| 1793 | struct sockaddr_in6 *sin6; | 1650 | |
| 1794 | 1651 | struct sockaddr_storage address_storage = {}; | |
| 1795 | switch (address_family) { | 1652 | struct sockaddr_in *sin = NULL; |
| 1796 | case -1: | 1653 | struct sockaddr_in6 *sin6 = NULL; |
| 1797 | /* -4 and -6 are not specified on cmdline */ | 1654 | int error_code = -1; |
| 1798 | address_family = AF_INET; | 1655 | |
| 1799 | sin = (struct sockaddr_in *)&ip; | 1656 | switch (enforced_proto) { |
| 1800 | result = inet_pton(address_family, arg, &sin->sin_addr); | 1657 | case AF_UNSPEC: |
| 1801 | #ifdef USE_IPV6 | 1658 | /* |
| 1802 | if (result != 1) { | 1659 | * no enforced protocol family |
| 1803 | address_family = AF_INET6; | 1660 | * try to parse the address with each one |
| 1804 | sin6 = (struct sockaddr_in6 *)&ip; | 1661 | */ |
| 1805 | result = inet_pton(address_family, arg, &sin6->sin6_addr); | 1662 | sin = (struct sockaddr_in *)&address_storage; |
| 1806 | } | 1663 | error_code = inet_pton(AF_INET, arg, &sin->sin_addr); |
| 1807 | #endif | 1664 | address_storage.ss_family = AF_INET; |
| 1808 | /* If we don't find any valid addresses, we still don't know the address_family */ | 1665 | |
| 1809 | if (result != 1) { | 1666 | if (error_code != 1) { |
| 1810 | address_family = -1; | 1667 | sin6 = (struct sockaddr_in6 *)&address_storage; |
| 1668 | error_code = inet_pton(AF_INET6, arg, &sin6->sin6_addr); | ||
| 1669 | address_storage.ss_family = AF_INET6; | ||
| 1811 | } | 1670 | } |
| 1812 | break; | 1671 | break; |
| 1813 | case AF_INET: | 1672 | case AF_INET: |
| 1814 | sin = (struct sockaddr_in *)&ip; | 1673 | sin = (struct sockaddr_in *)&address_storage; |
| 1815 | result = inet_pton(address_family, arg, &sin->sin_addr); | 1674 | error_code = inet_pton(AF_INET, arg, &sin->sin_addr); |
| 1675 | address_storage.ss_family = AF_INET; | ||
| 1816 | break; | 1676 | break; |
| 1817 | case AF_INET6: | 1677 | case AF_INET6: |
| 1818 | sin6 = (struct sockaddr_in6 *)&ip; | 1678 | sin6 = (struct sockaddr_in6 *)&address_storage; |
| 1819 | result = inet_pton(address_family, arg, &sin6->sin6_addr); | 1679 | error_code = inet_pton(AF_INET, arg, &sin6->sin6_addr); |
| 1680 | address_storage.ss_family = AF_INET6; | ||
| 1820 | break; | 1681 | break; |
| 1821 | default: | 1682 | default: |
| 1822 | crash("Address family not supported"); | 1683 | crash("Address family not supported"); |
| 1823 | } | 1684 | } |
| 1824 | 1685 | ||
| 1825 | /* don't resolve if we don't have to */ | 1686 | add_target_wrapper result = { |
| 1826 | if (result == 1) { | 1687 | .error_code = OK, |
| 1688 | .targets = NULL, | ||
| 1689 | .has_v4 = false, | ||
| 1690 | .has_v6 = false, | ||
| 1691 | }; | ||
| 1692 | |||
| 1693 | // if error_code == 1 the address was a valid address parsed above | ||
| 1694 | if (error_code == 1) { | ||
| 1827 | /* don't add all ip's if we were given a specific one */ | 1695 | /* don't add all ip's if we were given a specific one */ |
| 1828 | return add_target_ip(arg, &ip); | 1696 | add_target_ip_wrapper targeted = add_target_ip(address_storage); |
| 1829 | } else { | 1697 | |
| 1830 | errno = 0; | 1698 | if (targeted.error_code != OK) { |
| 1831 | memset(&hints, 0, sizeof(hints)); | 1699 | result.error_code = ERROR; |
| 1832 | if (address_family == -1) { | 1700 | return result; |
| 1833 | hints.ai_family = AF_UNSPEC; | ||
| 1834 | } else { | ||
| 1835 | hints.ai_family = address_family == AF_INET ? PF_INET : PF_INET6; | ||
| 1836 | } | 1701 | } |
| 1837 | hints.ai_socktype = SOCK_RAW; | 1702 | |
| 1838 | if ((error = getaddrinfo(arg, NULL, &hints, &res)) != 0) { | 1703 | if (targeted.target->address.ss_family == AF_INET) { |
| 1839 | errno = 0; | 1704 | result.has_v4 = true; |
| 1840 | crash("Failed to resolve %s: %s", arg, gai_strerror(error)); | 1705 | } else if (targeted.target->address.ss_family == AF_INET6) { |
| 1841 | return -1; | 1706 | result.has_v6 = true; |
| 1707 | } else { | ||
| 1708 | assert(false); | ||
| 1842 | } | 1709 | } |
| 1843 | address_family = res->ai_family; | 1710 | result.targets = targeted.target; |
| 1711 | result.number_of_targets = 1; | ||
| 1712 | return result; | ||
| 1713 | } | ||
| 1714 | |||
| 1715 | struct addrinfo hints = {}; | ||
| 1716 | errno = 0; | ||
| 1717 | hints.ai_family = enforced_proto; | ||
| 1718 | hints.ai_socktype = SOCK_RAW; | ||
| 1719 | |||
| 1720 | int error; | ||
| 1721 | struct addrinfo *res; | ||
| 1722 | if ((error = getaddrinfo(arg, NULL, &hints, &res)) != 0) { | ||
| 1723 | errno = 0; | ||
| 1724 | crash("Failed to resolve %s: %s", arg, gai_strerror(error)); | ||
| 1725 | result.error_code = ERROR; | ||
| 1726 | return result; | ||
| 1844 | } | 1727 | } |
| 1845 | 1728 | ||
| 1846 | /* possibly add all the IP's as targets */ | 1729 | /* possibly add all the IP's as targets */ |
| 1847 | for (p = res; p != NULL; p = p->ai_next) { | 1730 | for (struct addrinfo *address = res; address != NULL; address = address->ai_next) { |
| 1848 | memcpy(&ip, p->ai_addr, p->ai_addrlen); | 1731 | struct sockaddr_storage temporary_ip_address; |
| 1849 | add_target_ip(arg, &ip); | 1732 | memcpy(&temporary_ip_address, address->ai_addr, address->ai_addrlen); |
| 1733 | |||
| 1734 | add_target_ip_wrapper tmp = add_target_ip(temporary_ip_address); | ||
| 1735 | |||
| 1736 | if (tmp.error_code != OK) { | ||
| 1737 | // No proper error handling | ||
| 1738 | // What to do? | ||
| 1739 | } else { | ||
| 1740 | if (result.targets == NULL) { | ||
| 1741 | result.targets = tmp.target; | ||
| 1742 | result.number_of_targets = 1; | ||
| 1743 | } else { | ||
| 1744 | result.number_of_targets += ping_target_list_append(result.targets, tmp.target); | ||
| 1745 | } | ||
| 1746 | if (address->ai_family == AF_INET) { | ||
| 1747 | result.has_v4 = true; | ||
| 1748 | } else if (address->ai_family == AF_INET6) { | ||
| 1749 | result.has_v6 = true; | ||
| 1750 | } | ||
| 1751 | } | ||
| 1850 | 1752 | ||
| 1851 | /* this is silly, but it works */ | 1753 | /* this is silly, but it works */ |
| 1852 | if (mode == MODE_HOSTCHECK || mode == MODE_ALL) { | 1754 | if (mode == MODE_HOSTCHECK || mode == MODE_ALL) { |
| @@ -1855,20 +1757,22 @@ static int add_target(char *arg) { | |||
| 1855 | } | 1757 | } |
| 1856 | continue; | 1758 | continue; |
| 1857 | } | 1759 | } |
| 1760 | |||
| 1761 | // Abort after first hit if not in of the modes above | ||
| 1858 | break; | 1762 | break; |
| 1859 | } | 1763 | } |
| 1860 | freeaddrinfo(res); | 1764 | freeaddrinfo(res); |
| 1861 | 1765 | ||
| 1862 | return 0; | 1766 | return result; |
| 1863 | } | 1767 | } |
| 1864 | 1768 | ||
| 1865 | static void set_source_ip(char *arg) { | 1769 | static void set_source_ip(char *arg, const int icmp_sock, sa_family_t addr_family) { |
| 1866 | struct sockaddr_in src; | 1770 | struct sockaddr_in src; |
| 1867 | 1771 | ||
| 1868 | memset(&src, 0, sizeof(src)); | 1772 | memset(&src, 0, sizeof(src)); |
| 1869 | src.sin_family = address_family; | 1773 | src.sin_family = addr_family; |
| 1870 | if ((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE) { | 1774 | if ((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE) { |
| 1871 | src.sin_addr.s_addr = get_ip_address(arg); | 1775 | src.sin_addr.s_addr = get_ip_address(arg, icmp_sock); |
| 1872 | } | 1776 | } |
| 1873 | if (bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1) { | 1777 | if (bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1) { |
| 1874 | crash("Cannot bind to IP address %s", arg); | 1778 | crash("Cannot bind to IP address %s", arg); |
| @@ -1876,10 +1780,10 @@ static void set_source_ip(char *arg) { | |||
| 1876 | } | 1780 | } |
| 1877 | 1781 | ||
| 1878 | /* TODO: Move this to netutils.c and also change check_dhcp to use that. */ | 1782 | /* TODO: Move this to netutils.c and also change check_dhcp to use that. */ |
| 1879 | static in_addr_t get_ip_address(const char *ifname) { | 1783 | static in_addr_t get_ip_address(const char *ifname, const int icmp_sock) { |
| 1880 | // TODO: Rewrite this so the function return an error and we exit somewhere else | 1784 | // TODO: Rewrite this so the function return an error and we exit somewhere else |
| 1881 | struct sockaddr_in ip; | 1785 | struct sockaddr_in ip_address; |
| 1882 | ip.sin_addr.s_addr = 0; // Fake initialization to make compiler happy | 1786 | ip_address.sin_addr.s_addr = 0; // Fake initialization to make compiler happy |
| 1883 | #if defined(SIOCGIFADDR) | 1787 | #if defined(SIOCGIFADDR) |
| 1884 | struct ifreq ifr; | 1788 | struct ifreq ifr; |
| 1885 | 1789 | ||
| @@ -1891,13 +1795,13 @@ static in_addr_t get_ip_address(const char *ifname) { | |||
| 1891 | crash("Cannot determine IP address of interface %s", ifname); | 1795 | crash("Cannot determine IP address of interface %s", ifname); |
| 1892 | } | 1796 | } |
| 1893 | 1797 | ||
| 1894 | memcpy(&ip, &ifr.ifr_addr, sizeof(ip)); | 1798 | memcpy(&ip_address, &ifr.ifr_addr, sizeof(ip_address)); |
| 1895 | #else | 1799 | #else |
| 1896 | (void)ifname; | 1800 | (void)ifname; |
| 1897 | errno = 0; | 1801 | errno = 0; |
| 1898 | crash("Cannot get interface IP address on this platform."); | 1802 | crash("Cannot get interface IP address on this platform."); |
| 1899 | #endif | 1803 | #endif |
| 1900 | return ip.sin_addr.s_addr; | 1804 | return ip_address.sin_addr.s_addr; |
| 1901 | } | 1805 | } |
| 1902 | 1806 | ||
| 1903 | /* | 1807 | /* |
| @@ -1906,103 +1810,127 @@ static in_addr_t get_ip_address(const char *ifname) { | |||
| 1906 | * s = seconds | 1810 | * s = seconds |
| 1907 | * return value is in microseconds | 1811 | * return value is in microseconds |
| 1908 | */ | 1812 | */ |
| 1909 | static u_int get_timevar(const char *str) { | 1813 | static get_timevar_wrapper get_timevar(const char *str) { |
| 1910 | char p, u, *ptr; | 1814 | get_timevar_wrapper result = { |
| 1911 | size_t len; | 1815 | .error_code = OK, |
| 1912 | u_int i, d; /* integer and decimal, respectively */ | 1816 | .time_range = 0, |
| 1913 | u_int factor = 1000; /* default to milliseconds */ | 1817 | }; |
| 1914 | 1818 | ||
| 1915 | if (!str) { | 1819 | if (!str) { |
| 1916 | return 0; | 1820 | result.error_code = ERROR; |
| 1821 | return result; | ||
| 1917 | } | 1822 | } |
| 1918 | len = strlen(str); | 1823 | |
| 1824 | size_t len = strlen(str); | ||
| 1919 | if (!len) { | 1825 | if (!len) { |
| 1920 | return 0; | 1826 | result.error_code = ERROR; |
| 1827 | return result; | ||
| 1921 | } | 1828 | } |
| 1922 | 1829 | ||
| 1923 | /* unit might be given as ms|m (millisec), | 1830 | /* unit might be given as ms|m (millisec), |
| 1924 | * us|u (microsec) or just plain s, for seconds */ | 1831 | * us|u (microsec) or just plain s, for seconds */ |
| 1925 | p = '\0'; | 1832 | char tmp = '\0'; |
| 1926 | u = str[len - 1]; | 1833 | char unit = str[len - 1]; |
| 1927 | if (len >= 2 && !isdigit((int)str[len - 2])) { | 1834 | if (len >= 2 && !isdigit((int)str[len - 2])) { |
| 1928 | p = str[len - 2]; | 1835 | tmp = str[len - 2]; |
| 1929 | } | 1836 | } |
| 1930 | if (p && u == 's') { | 1837 | |
| 1931 | u = p; | 1838 | if (tmp && unit == 's') { |
| 1932 | } else if (!p) { | 1839 | unit = tmp; |
| 1933 | p = u; | 1840 | } else if (!tmp) { |
| 1841 | tmp = unit; | ||
| 1934 | } | 1842 | } |
| 1843 | |||
| 1935 | if (debug > 2) { | 1844 | if (debug > 2) { |
| 1936 | printf("evaluating %s, u: %c, p: %c\n", str, u, p); | 1845 | printf("evaluating %s, u: %c, p: %c\n", str, unit, tmp); |
| 1937 | } | 1846 | } |
| 1938 | 1847 | ||
| 1939 | if (u == 'u') { | 1848 | unsigned int factor = 1000; /* default to milliseconds */ |
| 1849 | if (unit == 'u') { | ||
| 1940 | factor = 1; /* microseconds */ | 1850 | factor = 1; /* microseconds */ |
| 1941 | } else if (u == 'm') { | 1851 | } else if (unit == 'm') { |
| 1942 | factor = 1000; /* milliseconds */ | 1852 | factor = 1000; /* milliseconds */ |
| 1943 | } else if (u == 's') { | 1853 | } else if (unit == 's') { |
| 1944 | factor = 1000000; /* seconds */ | 1854 | factor = 1000000; /* seconds */ |
| 1945 | } | 1855 | } |
| 1856 | |||
| 1946 | if (debug > 2) { | 1857 | if (debug > 2) { |
| 1947 | printf("factor is %u\n", factor); | 1858 | printf("factor is %u\n", factor); |
| 1948 | } | 1859 | } |
| 1949 | 1860 | ||
| 1950 | i = strtoul(str, &ptr, 0); | 1861 | char *ptr; |
| 1862 | unsigned long pre_radix; | ||
| 1863 | pre_radix = strtoul(str, &ptr, 0); | ||
| 1951 | if (!ptr || *ptr != '.' || strlen(ptr) < 2 || factor == 1) { | 1864 | if (!ptr || *ptr != '.' || strlen(ptr) < 2 || factor == 1) { |
| 1952 | return i * factor; | 1865 | result.time_range = (unsigned int)(pre_radix * factor); |
| 1866 | return result; | ||
| 1953 | } | 1867 | } |
| 1954 | 1868 | ||
| 1955 | /* time specified in usecs can't have decimal points, so ignore them */ | 1869 | /* time specified in usecs can't have decimal points, so ignore them */ |
| 1956 | if (factor == 1) { | 1870 | if (factor == 1) { |
| 1957 | return i; | 1871 | result.time_range = (unsigned int)pre_radix; |
| 1872 | return result; | ||
| 1958 | } | 1873 | } |
| 1959 | 1874 | ||
| 1960 | d = strtoul(ptr + 1, NULL, 0); | 1875 | /* integer and decimal, respectively */ |
| 1876 | unsigned int post_radix = (unsigned int)strtoul(ptr + 1, NULL, 0); | ||
| 1961 | 1877 | ||
| 1962 | /* d is decimal, so get rid of excess digits */ | 1878 | /* d is decimal, so get rid of excess digits */ |
| 1963 | while (d >= factor) { | 1879 | while (post_radix >= factor) { |
| 1964 | d /= 10; | 1880 | post_radix /= 10; |
| 1965 | } | 1881 | } |
| 1966 | 1882 | ||
| 1967 | /* the last parenthesis avoids floating point exceptions. */ | 1883 | /* the last parenthesis avoids floating point exceptions. */ |
| 1968 | return ((i * factor) + (d * (factor / 10))); | 1884 | result.time_range = (unsigned int)((pre_radix * factor) + (post_radix * (factor / 10))); |
| 1885 | return result; | ||
| 1969 | } | 1886 | } |
| 1970 | 1887 | ||
| 1971 | /* not too good at checking errors, but it'll do (main() should barfe on -1) */ | 1888 | static get_threshold_wrapper get_threshold(char *str, check_icmp_threshold threshold) { |
| 1972 | static int get_threshold(char *str, threshold *th) { | 1889 | get_threshold_wrapper result = { |
| 1973 | char *p = NULL, i = 0; | 1890 | .errorcode = OK, |
| 1891 | .threshold = threshold, | ||
| 1892 | }; | ||
| 1974 | 1893 | ||
| 1975 | if (!str || !strlen(str) || !th) { | 1894 | if (!str || !strlen(str)) { |
| 1976 | return -1; | 1895 | result.errorcode = ERROR; |
| 1896 | return result; | ||
| 1977 | } | 1897 | } |
| 1978 | 1898 | ||
| 1979 | /* pointer magic slims code by 10 lines. i is bof-stop on stupid libc's */ | 1899 | /* pointer magic slims code by 10 lines. i is bof-stop on stupid libc's */ |
| 1980 | p = &str[strlen(str) - 1]; | 1900 | bool is_at_last_char = false; |
| 1981 | while (p != &str[1]) { | 1901 | char *tmp = &str[strlen(str) - 1]; |
| 1982 | if (*p == '%') { | 1902 | while (tmp != &str[1]) { |
| 1983 | *p = '\0'; | 1903 | if (*tmp == '%') { |
| 1984 | } else if (*p == ',' && i) { | 1904 | *tmp = '\0'; |
| 1985 | *p = '\0'; /* reset it so get_timevar(str) works nicely later */ | 1905 | } else if (*tmp == ',' && is_at_last_char) { |
| 1986 | th->pl = (unsigned char)strtoul(p + 1, NULL, 0); | 1906 | *tmp = '\0'; /* reset it so get_timevar(str) works nicely later */ |
| 1907 | result.threshold.pl = (unsigned char)strtoul(tmp + 1, NULL, 0); | ||
| 1987 | break; | 1908 | break; |
| 1988 | } | 1909 | } |
| 1989 | i = 1; | 1910 | is_at_last_char = true; |
| 1990 | p--; | 1911 | tmp--; |
| 1991 | } | 1912 | } |
| 1992 | th->rta = get_timevar(str); | ||
| 1993 | 1913 | ||
| 1994 | if (!th->rta) { | 1914 | get_timevar_wrapper parsed_time = get_timevar(str); |
| 1995 | return -1; | 1915 | |
| 1916 | if (parsed_time.error_code == OK) { | ||
| 1917 | result.threshold.rta = parsed_time.time_range; | ||
| 1918 | } else { | ||
| 1919 | if (debug > 1) { | ||
| 1920 | printf("%s: failed to parse rta threshold\n", __FUNCTION__); | ||
| 1921 | } | ||
| 1922 | result.errorcode = ERROR; | ||
| 1923 | return result; | ||
| 1996 | } | 1924 | } |
| 1997 | 1925 | ||
| 1998 | if (th->rta > MAXTTL * 1000000) { | 1926 | if (result.threshold.rta > MAXTTL * 1000000) { |
| 1999 | th->rta = MAXTTL * 1000000; | 1927 | result.threshold.rta = MAXTTL * 1000000; |
| 2000 | } | 1928 | } |
| 2001 | if (th->pl > 100) { | 1929 | if (result.threshold.pl > 100) { |
| 2002 | th->pl = 100; | 1930 | result.threshold.pl = 100; |
| 2003 | } | 1931 | } |
| 2004 | 1932 | ||
| 2005 | return 0; | 1933 | return result; |
| 2006 | } | 1934 | } |
| 2007 | 1935 | ||
| 2008 | /* | 1936 | /* |
| @@ -2013,184 +1941,537 @@ static int get_threshold(char *str, threshold *th) { | |||
| 2013 | * @param[in] length strlen(str) | 1941 | * @param[in] length strlen(str) |
| 2014 | * @param[out] warn Pointer to the warn threshold struct to which the values should be assigned | 1942 | * @param[out] warn Pointer to the warn threshold struct to which the values should be assigned |
| 2015 | * @param[out] crit Pointer to the crit threshold struct to which the values should be assigned | 1943 | * @param[out] crit Pointer to the crit threshold struct to which the values should be assigned |
| 2016 | * @param[in] mode Determines whether this a threshold for rta, packet_loss, jitter, mos or score (exclusively) | 1944 | * @param[in] mode Determines whether this a threshold for rta, packet_loss, jitter, mos or score |
| 1945 | * (exclusively) | ||
| 2017 | */ | 1946 | */ |
| 2018 | static bool get_threshold2(char *str, size_t length, threshold *warn, threshold *crit, threshold_mode mode) { | 1947 | static get_threshold2_wrapper get_threshold2(char *str, size_t length, check_icmp_threshold warn, |
| 2019 | if (!str || !length || !warn || !crit) { | 1948 | check_icmp_threshold crit, threshold_mode mode) { |
| 2020 | return false; | 1949 | get_threshold2_wrapper result = { |
| 1950 | .errorcode = OK, | ||
| 1951 | .warn = warn, | ||
| 1952 | .crit = crit, | ||
| 1953 | }; | ||
| 1954 | |||
| 1955 | if (!str || !length) { | ||
| 1956 | result.errorcode = ERROR; | ||
| 1957 | return result; | ||
| 2021 | } | 1958 | } |
| 2022 | 1959 | ||
| 2023 | // p points to the last char in str | 1960 | // p points to the last char in str |
| 2024 | char *p = &str[length - 1]; | 1961 | char *work_pointer = &str[length - 1]; |
| 2025 | 1962 | ||
| 2026 | // first_iteration is bof-stop on stupid libc's | 1963 | // first_iteration is bof-stop on stupid libc's |
| 2027 | bool first_iteration = true; | 1964 | bool first_iteration = true; |
| 2028 | 1965 | ||
| 2029 | while (p != &str[0]) { | 1966 | while (work_pointer != &str[0]) { |
| 2030 | if ((*p == 'm') || (*p == '%')) { | 1967 | if ((*work_pointer == 'm') || (*work_pointer == '%')) { |
| 2031 | *p = '\0'; | 1968 | *work_pointer = '\0'; |
| 2032 | } else if (*p == ',' && !first_iteration) { | 1969 | } else if (*work_pointer == ',' && !first_iteration) { |
| 2033 | *p = '\0'; /* reset it so get_timevar(str) works nicely later */ | 1970 | *work_pointer = '\0'; /* reset it so get_timevar(str) works nicely later */ |
| 2034 | 1971 | ||
| 2035 | char *start_of_value = p + 1; | 1972 | char *start_of_value = work_pointer + 1; |
| 2036 | 1973 | ||
| 2037 | if (!parse_threshold2_helper(start_of_value, strlen(start_of_value), crit, mode)) { | 1974 | parse_threshold2_helper_wrapper tmp = |
| 2038 | return false; | 1975 | parse_threshold2_helper(start_of_value, strlen(start_of_value), result.crit, mode); |
| 1976 | if (tmp.errorcode != OK) { | ||
| 1977 | result.errorcode = ERROR; | ||
| 1978 | return result; | ||
| 2039 | } | 1979 | } |
| 1980 | result.crit = tmp.result; | ||
| 2040 | } | 1981 | } |
| 2041 | first_iteration = false; | 1982 | first_iteration = false; |
| 2042 | p--; | 1983 | work_pointer--; |
| 2043 | } | 1984 | } |
| 2044 | 1985 | ||
| 2045 | return parse_threshold2_helper(p, strlen(p), warn, mode); | 1986 | parse_threshold2_helper_wrapper tmp = |
| 1987 | parse_threshold2_helper(work_pointer, strlen(work_pointer), result.warn, mode); | ||
| 1988 | if (tmp.errorcode != OK) { | ||
| 1989 | result.errorcode = ERROR; | ||
| 1990 | } else { | ||
| 1991 | result.warn = tmp.result; | ||
| 1992 | } | ||
| 1993 | return result; | ||
| 2046 | } | 1994 | } |
| 2047 | 1995 | ||
| 2048 | static bool parse_threshold2_helper(char *s, size_t length, threshold *thr, threshold_mode mode) { | 1996 | static parse_threshold2_helper_wrapper parse_threshold2_helper(char *threshold_string, |
| 1997 | size_t length, | ||
| 1998 | check_icmp_threshold thr, | ||
| 1999 | threshold_mode mode) { | ||
| 2049 | char *resultChecker = {0}; | 2000 | char *resultChecker = {0}; |
| 2001 | parse_threshold2_helper_wrapper result = { | ||
| 2002 | .result = thr, | ||
| 2003 | .errorcode = OK, | ||
| 2004 | }; | ||
| 2050 | 2005 | ||
| 2051 | switch (mode) { | 2006 | switch (mode) { |
| 2052 | case const_rta_mode: | 2007 | case const_rta_mode: |
| 2053 | thr->rta = strtod(s, &resultChecker) * 1000; | 2008 | result.result.rta = (unsigned int)(strtod(threshold_string, &resultChecker) * 1000); |
| 2054 | break; | 2009 | break; |
| 2055 | case const_packet_loss_mode: | 2010 | case const_packet_loss_mode: |
| 2056 | thr->pl = (unsigned char)strtoul(s, &resultChecker, 0); | 2011 | result.result.pl = (unsigned char)strtoul(threshold_string, &resultChecker, 0); |
| 2057 | break; | 2012 | break; |
| 2058 | case const_jitter_mode: | 2013 | case const_jitter_mode: |
| 2059 | thr->jitter = strtod(s, &resultChecker); | 2014 | result.result.jitter = strtod(threshold_string, &resultChecker); |
| 2060 | |||
| 2061 | break; | 2015 | break; |
| 2062 | case const_mos_mode: | 2016 | case const_mos_mode: |
| 2063 | thr->mos = strtod(s, &resultChecker); | 2017 | result.result.mos = strtod(threshold_string, &resultChecker); |
| 2064 | break; | 2018 | break; |
| 2065 | case const_score_mode: | 2019 | case const_score_mode: |
| 2066 | thr->score = strtod(s, &resultChecker); | 2020 | result.result.score = strtod(threshold_string, &resultChecker); |
| 2067 | break; | 2021 | break; |
| 2068 | } | 2022 | } |
| 2069 | 2023 | ||
| 2070 | if (resultChecker == s) { | 2024 | if (resultChecker == threshold_string) { |
| 2071 | // Failed to parse | 2025 | // Failed to parse |
| 2072 | return false; | 2026 | result.errorcode = ERROR; |
| 2027 | return result; | ||
| 2073 | } | 2028 | } |
| 2074 | 2029 | ||
| 2075 | if (resultChecker != (s + length)) { | 2030 | if (resultChecker != (threshold_string + length)) { |
| 2076 | // Trailing symbols | 2031 | // Trailing symbols |
| 2077 | return false; | 2032 | result.errorcode = ERROR; |
| 2078 | } | 2033 | } |
| 2079 | 2034 | ||
| 2080 | return true; | 2035 | return result; |
| 2081 | } | 2036 | } |
| 2082 | 2037 | ||
| 2083 | unsigned short icmp_checksum(uint16_t *p, size_t n) { | 2038 | unsigned short icmp_checksum(uint16_t *packet, size_t packet_size) { |
| 2084 | unsigned short cksum; | ||
| 2085 | long sum = 0; | 2039 | long sum = 0; |
| 2086 | 2040 | ||
| 2087 | /* sizeof(uint16_t) == 2 */ | 2041 | /* sizeof(uint16_t) == 2 */ |
| 2088 | while (n >= 2) { | 2042 | while (packet_size >= 2) { |
| 2089 | sum += *(p++); | 2043 | sum += *(packet++); |
| 2090 | n -= 2; | 2044 | packet_size -= 2; |
| 2091 | } | 2045 | } |
| 2092 | 2046 | ||
| 2093 | /* mop up the occasional odd byte */ | 2047 | /* mop up the occasional odd byte */ |
| 2094 | if (n == 1) { | 2048 | if (packet_size == 1) { |
| 2095 | sum += *((uint8_t *)p - 1); | 2049 | sum += *((uint8_t *)packet - 1); |
| 2096 | } | 2050 | } |
| 2097 | 2051 | ||
| 2098 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ | 2052 | sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ |
| 2099 | sum += (sum >> 16); /* add carry */ | 2053 | sum += (sum >> 16); /* add carry */ |
| 2100 | cksum = ~sum; /* ones-complement, trunc to 16 bits */ | 2054 | unsigned short cksum; |
| 2055 | cksum = (unsigned short)~sum; /* ones-complement, trunc to 16 bits */ | ||
| 2101 | 2056 | ||
| 2102 | return cksum; | 2057 | return cksum; |
| 2103 | } | 2058 | } |
| 2104 | 2059 | ||
| 2105 | void print_help(void) { | 2060 | void print_help(void) { |
| 2106 | /*print_revision (progname);*/ /* FIXME: Why? */ | 2061 | // print_revision (progname); /* FIXME: Why? */ |
| 2107 | printf("Copyright (c) 2005 Andreas Ericsson <ae@op5.se>\n"); | 2062 | printf("Copyright (c) 2005 Andreas Ericsson <ae@op5.se>\n"); |
| 2108 | 2063 | ||
| 2109 | printf(COPYRIGHT, copyright, email); | 2064 | printf(COPYRIGHT, copyright, email); |
| 2110 | 2065 | ||
| 2111 | printf("\n\n"); | ||
| 2112 | |||
| 2113 | print_usage(); | 2066 | print_usage(); |
| 2114 | 2067 | ||
| 2115 | printf(UT_HELP_VRSN); | 2068 | printf(UT_HELP_VRSN); |
| 2116 | printf(UT_EXTRA_OPTS); | 2069 | printf(UT_EXTRA_OPTS); |
| 2117 | 2070 | ||
| 2118 | printf(" %s\n", "-H"); | 2071 | printf(" -H, --Host=HOST\n"); |
| 2119 | printf(" %s\n", _("specify a target")); | 2072 | printf(" %s\n", |
| 2120 | printf(" %s\n", "[-4|-6]"); | 2073 | _("specify a target, might be one of: resolveable name | IPv6 address | IPv4 address\n" |
| 2121 | printf(" %s\n", _("Use IPv4 (default) or IPv6 to communicate with the targets")); | 2074 | " (required, can be given multiple times)")); |
| 2122 | printf(" %s\n", "-w"); | 2075 | printf(" %s\n", "[-4|-6], [--ipv4-only|--ipv6-only]"); |
| 2123 | printf(" %s", _("warning threshold (currently ")); | 2076 | printf(" %s\n", _("Use IPv4 or IPv6 only to communicate with the targets")); |
| 2124 | printf("%0.3fms,%u%%)\n", (float)warn.rta / 1000, warn.pl); | 2077 | printf(" %s\n", "-w, --warning=WARN_VALUE"); |
| 2125 | printf(" %s\n", "-c"); | 2078 | printf(" %s", _("warning threshold (default ")); |
| 2126 | printf(" %s", _("critical threshold (currently ")); | 2079 | printf("%0.3fms,%u%%)\n", (float)DEFAULT_WARN_RTA / 1000, DEFAULT_WARN_PL); |
| 2127 | printf("%0.3fms,%u%%)\n", (float)crit.rta / 1000, crit.pl); | 2080 | printf(" %s\n", "-c, --critical=CRIT_VALUE"); |
| 2128 | 2081 | printf(" %s", _("critical threshold (default ")); | |
| 2129 | printf(" %s\n", "-R"); | 2082 | printf("%0.3fms,%u%%)\n", (float)DEFAULT_CRIT_RTA / 1000, DEFAULT_CRIT_PL); |
| 2130 | printf(" %s\n", _("RTA, round trip average, mode warning,critical, ex. 100ms,200ms unit in ms")); | 2083 | |
| 2131 | printf(" %s\n", "-P"); | 2084 | printf(" %s\n", "-R, --rta-mode-thresholds=RTA_THRESHOLDS"); |
| 2085 | printf(" %s\n", | ||
| 2086 | _("RTA (round trip average) mode warning,critical, ex. 100ms,200ms unit in ms")); | ||
| 2087 | printf(" %s\n", "-P, --packet-loss-mode-thresholds=PACKET_LOSS_THRESHOLD"); | ||
| 2132 | printf(" %s\n", _("packet loss mode, ex. 40%,50% , unit in %")); | 2088 | printf(" %s\n", _("packet loss mode, ex. 40%,50% , unit in %")); |
| 2133 | printf(" %s\n", "-J"); | 2089 | printf(" %s\n", "-J, --jitter-mode-thresholds=JITTER_MODE_THRESHOLD"); |
| 2134 | printf(" %s\n", _("jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms ")); | 2090 | printf(" %s\n", _("jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms ")); |
| 2135 | printf(" %s\n", "-M"); | 2091 | printf(" %s\n", "-M, --mos-mode-thresholds=MOS_MODE_THRESHOLD"); |
| 2136 | printf(" %s\n", _("MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0")); | 2092 | printf(" %s\n", _("MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0")); |
| 2137 | printf(" %s\n", "-S"); | 2093 | printf(" %s\n", "-S, --score-mode-thresholds=SCORE_MODE_THRESHOLD"); |
| 2138 | printf(" %s\n", _("score mode, max value 100 warning,critical, ex. 80,70 ")); | 2094 | printf(" %s\n", _("score mode, max value 100 warning,critical, ex. 80,70 ")); |
| 2139 | printf(" %s\n", "-O"); | 2095 | printf(" %s\n", "-O, --out-of-order-packets"); |
| 2140 | printf(" %s\n", _("detect out of order ICMP packts ")); | 2096 | printf( |
| 2141 | printf(" %s\n", "-H"); | 2097 | " %s\n", |
| 2142 | printf(" %s\n", _("specify a target")); | 2098 | _("detect out of order ICMP packets, if such packets are found, the result is CRITICAL")); |
| 2143 | printf(" %s\n", "-s"); | 2099 | printf(" %s\n", "[-n|-p], --number-of-packets=NUMBER_OF_PACKETS"); |
| 2144 | printf(" %s\n", _("specify a source IP address or device name")); | 2100 | printf(" %s", _("number of packets to send (default ")); |
| 2145 | printf(" %s\n", "-n"); | 2101 | printf("%u)\n", DEFAULT_NUMBER_OF_PACKETS); |
| 2146 | printf(" %s", _("number of packets to send (currently ")); | 2102 | |
| 2147 | printf("%u)\n", packets); | ||
| 2148 | printf(" %s\n", "-p"); | ||
| 2149 | printf(" %s", _("number of packets to send (currently ")); | ||
| 2150 | printf("%u)\n", packets); | ||
| 2151 | printf(" %s\n", "-i"); | 2103 | printf(" %s\n", "-i"); |
| 2152 | printf(" %s", _("max packet interval (currently ")); | 2104 | printf(" %s", _("[DEPRECATED] packet interval (default ")); |
| 2153 | printf("%0.3fms)\n", (float)pkt_interval / 1000); | 2105 | printf("%0.3fms)\n", (float)DEFAULT_PKT_INTERVAL / 1000); |
| 2154 | printf(" %s\n", "-I"); | 2106 | printf(" %s", _("This option was never actually used and is just mentioned here for " |
| 2155 | printf(" %s", _("max target interval (currently ")); | 2107 | "historical purposes\n")); |
| 2156 | printf("%0.3fms)\n", (float)target_interval / 1000); | 2108 | |
| 2157 | printf(" %s\n", "-m"); | 2109 | printf(" %s\n", "-I, --target-interval=TARGET_INTERVAL"); |
| 2158 | printf(" %s", _("number of alive hosts required for success")); | 2110 | printf(" %s%0.3fms)\n The time interval to wait in between one target and the next\n", |
| 2111 | _("max target interval (default "), (float)DEFAULT_TARGET_INTERVAL / 1000); | ||
| 2112 | printf(" %s\n", "-m, --minimal-host-alive=MIN_ALIVE"); | ||
| 2113 | printf(" %s", _("number of alive hosts required for success. If less than MIN_ALIVE hosts " | ||
| 2114 | "are OK, but MIN_ALIVE hosts are WARNING or OK, WARNING, else CRITICAL")); | ||
| 2159 | printf("\n"); | 2115 | printf("\n"); |
| 2160 | printf(" %s\n", "-l"); | 2116 | printf(" %s\n", "-l, --outgoing-ttl=OUTGOING_TTL"); |
| 2161 | printf(" %s", _("TTL on outgoing packets (currently ")); | 2117 | printf(" %s", _("TTL on outgoing packets (default ")); |
| 2162 | printf("%u)\n", ttl); | 2118 | printf("%u)\n", DEFAULT_TTL); |
| 2163 | printf(" %s\n", "-t"); | 2119 | printf(" %s\n", "-b, --size=SIZE"); |
| 2164 | printf(" %s", _("timeout value (seconds, currently ")); | 2120 | printf(" %s\n", _("Number of icmp ping data bytes to send")); |
| 2165 | printf("%u)\n", timeout); | 2121 | printf(" %s %lu + %d)\n", _("Packet size will be SIZE + icmp header (default"), |
| 2166 | printf(" %s\n", "-b"); | 2122 | DEFAULT_PING_DATA_SIZE, ICMP_MINLEN); |
| 2167 | printf(" %s\n", _("Number of icmp data bytes to send")); | 2123 | printf(" %s\n", "-v, --verbose"); |
| 2168 | printf(" %s %u + %d)\n", _("Packet size will be data bytes + icmp header (currently"), icmp_data_size, ICMP_MINLEN); | 2124 | printf(" %s\n", _("Verbosity, can be given multiple times (for debugging)")); |
| 2169 | printf(" %s\n", "-v"); | 2125 | |
| 2170 | printf(" %s\n", _("verbose")); | 2126 | printf(UT_OUTPUT_FORMAT); |
| 2127 | |||
| 2171 | printf("\n"); | 2128 | printf("\n"); |
| 2172 | printf("%s\n", _("Notes:")); | 2129 | printf("%s\n", _("Notes:")); |
| 2173 | printf(" %s\n", _("If none of R,P,J,M,S or O is specified, default behavior is -R -P")); | 2130 | printf(" %s\n", _("If none of R,P,J,M,S or O is specified, default behavior is -R -P")); |
| 2174 | printf(" %s\n", _("The -H switch is optional. Naming a host (or several) to check is not.")); | 2131 | printf(" %s\n", _("Naming a host (or several) to check is not.")); |
| 2175 | printf("\n"); | 2132 | printf("\n"); |
| 2176 | printf(" %s\n", _("Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%")); | 2133 | printf(" %s\n", _("Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%")); |
| 2177 | printf(" %s\n", _("packet loss. The default values should work well for most users.")); | 2134 | printf(" %s\n", _("packet loss. The default values should work well for most users.")); |
| 2178 | printf(" %s\n", _("You can specify different RTA factors using the standardized abbreviations")); | 2135 | printf(" %s\n", |
| 2179 | printf(" %s\n", _("us (microseconds), ms (milliseconds, default) or just plain s for seconds.")); | 2136 | _("You can specify different RTA factors using the standardized abbreviations")); |
| 2180 | /* -d not yet implemented */ | 2137 | printf(" %s\n", |
| 2181 | /* printf ("%s\n", _("Threshold format for -d is warn,crit. 12,14 means WARNING if >= 12 hops")); | 2138 | _("us (microseconds), ms (milliseconds, default) or just plain s for seconds.")); |
| 2182 | printf ("%s\n", _("are spent and CRITICAL if >= 14 hops are spent.")); | ||
| 2183 | printf ("%s\n\n", _("NOTE: Some systems decrease TTL when forming ICMP_ECHOREPLY, others do not."));*/ | ||
| 2184 | printf("\n"); | ||
| 2185 | printf(" %s\n", _("The -v switch can be specified several times for increased verbosity.")); | ||
| 2186 | /* printf ("%s\n", _("Long options are currently unsupported.")); | ||
| 2187 | printf ("%s\n", _("Options marked with * require an argument")); | ||
| 2188 | */ | ||
| 2189 | 2139 | ||
| 2190 | printf(UT_SUPPORT); | 2140 | printf(UT_SUPPORT); |
| 2191 | } | 2141 | } |
| 2192 | 2142 | ||
| 2193 | void print_usage(void) { | 2143 | void print_usage(void) { |
| 2194 | printf("%s\n", _("Usage:")); | 2144 | printf("%s\n", _("Usage:")); |
| 2195 | printf(" %s [options] [-H] host1 host2 hostN\n", progname); | 2145 | printf(" %s [options] [-H host1 [-H host2 [-H hostN]]]\n", progname); |
| 2146 | } | ||
| 2147 | |||
| 2148 | static add_host_wrapper add_host(char *arg, check_icmp_execution_mode mode, | ||
| 2149 | sa_family_t enforced_proto) { | ||
| 2150 | if (debug) { | ||
| 2151 | printf("add_host called with argument %s\n", arg); | ||
| 2152 | } | ||
| 2153 | |||
| 2154 | add_host_wrapper result = { | ||
| 2155 | .error_code = OK, | ||
| 2156 | .host = check_icmp_target_container_init(), | ||
| 2157 | .has_v4 = false, | ||
| 2158 | .has_v6 = false, | ||
| 2159 | }; | ||
| 2160 | |||
| 2161 | add_target_wrapper targets = add_target(arg, mode, enforced_proto); | ||
| 2162 | |||
| 2163 | if (targets.error_code != OK) { | ||
| 2164 | result.error_code = targets.error_code; | ||
| 2165 | return result; | ||
| 2166 | } | ||
| 2167 | |||
| 2168 | result.has_v4 = targets.has_v4; | ||
| 2169 | result.has_v6 = targets.has_v6; | ||
| 2170 | |||
| 2171 | result.host = check_icmp_target_container_init(); | ||
| 2172 | |||
| 2173 | result.host.name = strdup(arg); | ||
| 2174 | result.host.target_list = targets.targets; | ||
| 2175 | result.host.number_of_targets = targets.number_of_targets; | ||
| 2176 | |||
| 2177 | return result; | ||
| 2178 | } | ||
| 2179 | |||
| 2180 | mp_subcheck evaluate_target(ping_target target, check_icmp_mode_switches modes, | ||
| 2181 | check_icmp_threshold warn, check_icmp_threshold crit) { | ||
| 2182 | /* if no new mode selected, use old schema */ | ||
| 2183 | if (!modes.rta_mode && !modes.pl_mode && !modes.jitter_mode && !modes.score_mode && | ||
| 2184 | !modes.mos_mode && !modes.order_mode) { | ||
| 2185 | modes.rta_mode = true; | ||
| 2186 | modes.pl_mode = true; | ||
| 2187 | } | ||
| 2188 | |||
| 2189 | mp_subcheck result = mp_subcheck_init(); | ||
| 2190 | result = mp_set_subcheck_default_state(result, STATE_OK); | ||
| 2191 | |||
| 2192 | char address[INET6_ADDRSTRLEN]; | ||
| 2193 | memset(address, 0, INET6_ADDRSTRLEN); | ||
| 2194 | parse_address(&target.address, address, sizeof(address)); | ||
| 2195 | |||
| 2196 | xasprintf(&result.output, "%s", address); | ||
| 2197 | |||
| 2198 | double packet_loss; | ||
| 2199 | time_t rta; | ||
| 2200 | if (!target.icmp_recv) { | ||
| 2201 | /* rta 0 is of course not entirely correct, but will still show up | ||
| 2202 | * conspicuously as missing entries in perfparse and cacti */ | ||
| 2203 | packet_loss = 100; | ||
| 2204 | rta = 0; | ||
| 2205 | result = mp_set_subcheck_state(result, STATE_CRITICAL); | ||
| 2206 | /* up the down counter if not already counted */ | ||
| 2207 | |||
| 2208 | if (target.flags & FLAG_LOST_CAUSE) { | ||
| 2209 | xasprintf(&result.output, "%s: %s @ %s", result.output, | ||
| 2210 | get_icmp_error_msg(target.icmp_type, target.icmp_code), address); | ||
| 2211 | } else { /* not marked as lost cause, so we have no flags for it */ | ||
| 2212 | xasprintf(&result.output, "%s", result.output); | ||
| 2213 | } | ||
| 2214 | } else { | ||
| 2215 | packet_loss = | ||
| 2216 | (unsigned char)((target.icmp_sent - target.icmp_recv) * 100) / target.icmp_sent; | ||
| 2217 | rta = target.time_waited / target.icmp_recv; | ||
| 2218 | } | ||
| 2219 | |||
| 2220 | double EffectiveLatency; | ||
| 2221 | double mos; /* Mean opinion score */ | ||
| 2222 | double score; /* score */ | ||
| 2223 | |||
| 2224 | if (target.icmp_recv > 1) { | ||
| 2225 | /* | ||
| 2226 | * This algorithm is probably pretty much blindly copied from | ||
| 2227 | * locations like this one: | ||
| 2228 | * https://www.slac.stanford.edu/comp/net/wan-mon/tutorial.html#mos It calculates a MOS | ||
| 2229 | * value (range of 1 to 5, where 1 is bad and 5 really good). According to some quick | ||
| 2230 | * research MOS originates from the Audio/Video transport network area. Whether it can | ||
| 2231 | * and should be computed from ICMP data, I can not say. | ||
| 2232 | * | ||
| 2233 | * Anyway the basic idea is to map a value "R" with a range of 0-100 to the MOS value | ||
| 2234 | * | ||
| 2235 | * MOS stands likely for Mean Opinion Score ( | ||
| 2236 | * https://en.wikipedia.org/wiki/Mean_Opinion_Score ) | ||
| 2237 | * | ||
| 2238 | * More links: | ||
| 2239 | * - https://confluence.slac.stanford.edu/display/IEPM/MOS | ||
| 2240 | */ | ||
| 2241 | target.jitter = (target.jitter / (target.icmp_recv - 1) / 1000); | ||
| 2242 | |||
| 2243 | /* | ||
| 2244 | * Take the average round trip latency (in milliseconds), add | ||
| 2245 | * round trip jitter, but double the impact to latency | ||
| 2246 | * then add 10 for protocol latencies (in milliseconds). | ||
| 2247 | */ | ||
| 2248 | EffectiveLatency = ((double)rta / 1000) + target.jitter * 2 + 10; | ||
| 2249 | |||
| 2250 | double R; | ||
| 2251 | if (EffectiveLatency < 160) { | ||
| 2252 | R = 93.2 - (EffectiveLatency / 40); | ||
| 2253 | } else { | ||
| 2254 | R = 93.2 - ((EffectiveLatency - 120) / 10); | ||
| 2255 | } | ||
| 2256 | |||
| 2257 | // Now, let us deduct 2.5 R values per percentage of packet loss (i.e. a | ||
| 2258 | // loss of 5% will be entered as 5). | ||
| 2259 | R = R - (packet_loss * 2.5); | ||
| 2260 | |||
| 2261 | if (R < 0) { | ||
| 2262 | R = 0; | ||
| 2263 | } | ||
| 2264 | |||
| 2265 | score = R; | ||
| 2266 | mos = 1 + ((0.035) * R) + ((.000007) * R * (R - 60) * (100 - R)); | ||
| 2267 | } else { | ||
| 2268 | target.jitter = 0; | ||
| 2269 | target.jitter_min = 0; | ||
| 2270 | target.jitter_max = 0; | ||
| 2271 | mos = 0; | ||
| 2272 | } | ||
| 2273 | |||
| 2274 | /* Check which mode is on and do the warn / Crit stuff */ | ||
| 2275 | if (modes.rta_mode) { | ||
| 2276 | mp_subcheck sc_rta = mp_subcheck_init(); | ||
| 2277 | sc_rta = mp_set_subcheck_default_state(sc_rta, STATE_OK); | ||
| 2278 | xasprintf(&sc_rta.output, "rta %0.3fms", (double)rta / 1000); | ||
| 2279 | |||
| 2280 | if (rta >= crit.rta) { | ||
| 2281 | sc_rta = mp_set_subcheck_state(sc_rta, STATE_CRITICAL); | ||
| 2282 | xasprintf(&sc_rta.output, "%s >= %0.3fms", sc_rta.output, (double)crit.rta / 1000); | ||
| 2283 | } else if (rta >= warn.rta) { | ||
| 2284 | sc_rta = mp_set_subcheck_state(sc_rta, STATE_WARNING); | ||
| 2285 | xasprintf(&sc_rta.output, "%s >= %0.3fms", sc_rta.output, (double)warn.rta / 1000); | ||
| 2286 | } | ||
| 2287 | |||
| 2288 | if (packet_loss < 100) { | ||
| 2289 | mp_perfdata pd_rta = perfdata_init(); | ||
| 2290 | xasprintf(&pd_rta.label, "%srta", address); | ||
| 2291 | pd_rta.uom = strdup("ms"); | ||
| 2292 | pd_rta.value = mp_create_pd_value(rta / 1000); | ||
| 2293 | pd_rta.min = mp_create_pd_value(0); | ||
| 2294 | |||
| 2295 | pd_rta.warn = mp_range_set_end(pd_rta.warn, mp_create_pd_value(warn.rta)); | ||
| 2296 | pd_rta.crit = mp_range_set_end(pd_rta.crit, mp_create_pd_value(crit.rta)); | ||
| 2297 | mp_add_perfdata_to_subcheck(&sc_rta, pd_rta); | ||
| 2298 | |||
| 2299 | mp_perfdata pd_rt_min = perfdata_init(); | ||
| 2300 | xasprintf(&pd_rt_min.label, "%srtmin", address); | ||
| 2301 | pd_rt_min.value = mp_create_pd_value(target.rtmin / 1000); | ||
| 2302 | pd_rt_min.uom = strdup("ms"); | ||
| 2303 | mp_add_perfdata_to_subcheck(&sc_rta, pd_rt_min); | ||
| 2304 | |||
| 2305 | mp_perfdata pd_rt_max = perfdata_init(); | ||
| 2306 | xasprintf(&pd_rt_max.label, "%srtmax", address); | ||
| 2307 | pd_rt_max.value = mp_create_pd_value(target.rtmax / 1000); | ||
| 2308 | pd_rt_max.uom = strdup("ms"); | ||
| 2309 | mp_add_perfdata_to_subcheck(&sc_rta, pd_rt_max); | ||
| 2310 | } | ||
| 2311 | |||
| 2312 | mp_add_subcheck_to_subcheck(&result, sc_rta); | ||
| 2313 | } | ||
| 2314 | |||
| 2315 | if (modes.pl_mode) { | ||
| 2316 | mp_subcheck sc_pl = mp_subcheck_init(); | ||
| 2317 | sc_pl = mp_set_subcheck_default_state(sc_pl, STATE_OK); | ||
| 2318 | xasprintf(&sc_pl.output, "packet loss %.1f%%", packet_loss); | ||
| 2319 | |||
| 2320 | if (packet_loss >= crit.pl) { | ||
| 2321 | sc_pl = mp_set_subcheck_state(sc_pl, STATE_CRITICAL); | ||
| 2322 | xasprintf(&sc_pl.output, "%s >= %u%%", sc_pl.output, crit.pl); | ||
| 2323 | } else if (packet_loss >= warn.pl) { | ||
| 2324 | sc_pl = mp_set_subcheck_state(sc_pl, STATE_WARNING); | ||
| 2325 | xasprintf(&sc_pl.output, "%s >= %u%%", sc_pl.output, warn.pl); | ||
| 2326 | } | ||
| 2327 | |||
| 2328 | mp_perfdata pd_pl = perfdata_init(); | ||
| 2329 | xasprintf(&pd_pl.label, "%spl", address); | ||
| 2330 | pd_pl.uom = strdup("%"); | ||
| 2331 | |||
| 2332 | pd_pl.warn = mp_range_set_end(pd_pl.warn, mp_create_pd_value(warn.pl)); | ||
| 2333 | pd_pl.crit = mp_range_set_end(pd_pl.crit, mp_create_pd_value(crit.pl)); | ||
| 2334 | pd_pl.value = mp_create_pd_value(packet_loss); | ||
| 2335 | |||
| 2336 | mp_add_perfdata_to_subcheck(&sc_pl, pd_pl); | ||
| 2337 | |||
| 2338 | mp_add_subcheck_to_subcheck(&result, sc_pl); | ||
| 2339 | } | ||
| 2340 | |||
| 2341 | if (modes.jitter_mode) { | ||
| 2342 | mp_subcheck sc_jitter = mp_subcheck_init(); | ||
| 2343 | sc_jitter = mp_set_subcheck_default_state(sc_jitter, STATE_OK); | ||
| 2344 | xasprintf(&sc_jitter.output, "jitter %0.3fms", target.jitter); | ||
| 2345 | |||
| 2346 | if (target.jitter >= crit.jitter) { | ||
| 2347 | sc_jitter = mp_set_subcheck_state(sc_jitter, STATE_CRITICAL); | ||
| 2348 | xasprintf(&sc_jitter.output, "%s >= %0.3fms", sc_jitter.output, crit.jitter); | ||
| 2349 | } else if (target.jitter >= warn.jitter) { | ||
| 2350 | sc_jitter = mp_set_subcheck_state(sc_jitter, STATE_WARNING); | ||
| 2351 | xasprintf(&sc_jitter.output, "%s >= %0.3fms", sc_jitter.output, warn.jitter); | ||
| 2352 | } | ||
| 2353 | |||
| 2354 | if (packet_loss < 100) { | ||
| 2355 | mp_perfdata pd_jitter = perfdata_init(); | ||
| 2356 | pd_jitter.uom = strdup("ms"); | ||
| 2357 | xasprintf(&pd_jitter.label, "%sjitter_avg", address); | ||
| 2358 | pd_jitter.value = mp_create_pd_value(target.jitter); | ||
| 2359 | pd_jitter.warn = mp_range_set_end(pd_jitter.warn, mp_create_pd_value(warn.jitter)); | ||
| 2360 | pd_jitter.crit = mp_range_set_end(pd_jitter.crit, mp_create_pd_value(crit.jitter)); | ||
| 2361 | mp_add_perfdata_to_subcheck(&sc_jitter, pd_jitter); | ||
| 2362 | |||
| 2363 | mp_perfdata pd_jitter_min = perfdata_init(); | ||
| 2364 | pd_jitter_min.uom = strdup("ms"); | ||
| 2365 | xasprintf(&pd_jitter_min.label, "%sjitter_min", address); | ||
| 2366 | pd_jitter_min.value = mp_create_pd_value(target.jitter_min); | ||
| 2367 | mp_add_perfdata_to_subcheck(&sc_jitter, pd_jitter_min); | ||
| 2368 | |||
| 2369 | mp_perfdata pd_jitter_max = perfdata_init(); | ||
| 2370 | pd_jitter_max.uom = strdup("ms"); | ||
| 2371 | xasprintf(&pd_jitter_max.label, "%sjitter_max", address); | ||
| 2372 | pd_jitter_max.value = mp_create_pd_value(target.jitter_max); | ||
| 2373 | mp_add_perfdata_to_subcheck(&sc_jitter, pd_jitter_max); | ||
| 2374 | } | ||
| 2375 | mp_add_subcheck_to_subcheck(&result, sc_jitter); | ||
| 2376 | } | ||
| 2377 | |||
| 2378 | if (modes.mos_mode) { | ||
| 2379 | mp_subcheck sc_mos = mp_subcheck_init(); | ||
| 2380 | sc_mos = mp_set_subcheck_default_state(sc_mos, STATE_OK); | ||
| 2381 | xasprintf(&sc_mos.output, "MOS %0.1f", mos); | ||
| 2382 | |||
| 2383 | if (mos <= crit.mos) { | ||
| 2384 | sc_mos = mp_set_subcheck_state(sc_mos, STATE_CRITICAL); | ||
| 2385 | xasprintf(&sc_mos.output, "%s <= %0.1f", sc_mos.output, crit.mos); | ||
| 2386 | } else if (mos <= warn.mos) { | ||
| 2387 | sc_mos = mp_set_subcheck_state(sc_mos, STATE_WARNING); | ||
| 2388 | xasprintf(&sc_mos.output, "%s <= %0.1f", sc_mos.output, warn.mos); | ||
| 2389 | } | ||
| 2390 | |||
| 2391 | if (packet_loss < 100) { | ||
| 2392 | mp_perfdata pd_mos = perfdata_init(); | ||
| 2393 | xasprintf(&pd_mos.label, "%smos", address); | ||
| 2394 | pd_mos.value = mp_create_pd_value(mos); | ||
| 2395 | pd_mos.warn = mp_range_set_end(pd_mos.warn, mp_create_pd_value(warn.mos)); | ||
| 2396 | pd_mos.crit = mp_range_set_end(pd_mos.crit, mp_create_pd_value(crit.mos)); | ||
| 2397 | pd_mos.min = mp_create_pd_value(0); // MOS starts at 0 | ||
| 2398 | pd_mos.max = mp_create_pd_value(5); // MOS max is 5, by definition | ||
| 2399 | mp_add_perfdata_to_subcheck(&sc_mos, pd_mos); | ||
| 2400 | } | ||
| 2401 | mp_add_subcheck_to_subcheck(&result, sc_mos); | ||
| 2402 | } | ||
| 2403 | |||
| 2404 | if (modes.score_mode) { | ||
| 2405 | mp_subcheck sc_score = mp_subcheck_init(); | ||
| 2406 | sc_score = mp_set_subcheck_default_state(sc_score, STATE_OK); | ||
| 2407 | xasprintf(&sc_score.output, "Score %f", score); | ||
| 2408 | |||
| 2409 | if (score <= crit.score) { | ||
| 2410 | sc_score = mp_set_subcheck_state(sc_score, STATE_CRITICAL); | ||
| 2411 | xasprintf(&sc_score.output, "%s <= %f", sc_score.output, crit.score); | ||
| 2412 | } else if (score <= warn.score) { | ||
| 2413 | sc_score = mp_set_subcheck_state(sc_score, STATE_WARNING); | ||
| 2414 | xasprintf(&sc_score.output, "%s <= %f", sc_score.output, warn.score); | ||
| 2415 | } | ||
| 2416 | |||
| 2417 | if (packet_loss < 100) { | ||
| 2418 | mp_perfdata pd_score = perfdata_init(); | ||
| 2419 | xasprintf(&pd_score.label, "%sscore", address); | ||
| 2420 | pd_score.value = mp_create_pd_value(score); | ||
| 2421 | pd_score.warn = mp_range_set_end(pd_score.warn, mp_create_pd_value(warn.score)); | ||
| 2422 | pd_score.crit = mp_range_set_end(pd_score.crit, mp_create_pd_value(crit.score)); | ||
| 2423 | pd_score.min = mp_create_pd_value(0); | ||
| 2424 | pd_score.max = mp_create_pd_value(100); | ||
| 2425 | mp_add_perfdata_to_subcheck(&sc_score, pd_score); | ||
| 2426 | } | ||
| 2427 | |||
| 2428 | mp_add_subcheck_to_subcheck(&result, sc_score); | ||
| 2429 | } | ||
| 2430 | |||
| 2431 | if (modes.order_mode) { | ||
| 2432 | mp_subcheck sc_order = mp_subcheck_init(); | ||
| 2433 | sc_order = mp_set_subcheck_default_state(sc_order, STATE_OK); | ||
| 2434 | |||
| 2435 | if (target.found_out_of_order_packets) { | ||
| 2436 | mp_set_subcheck_state(sc_order, STATE_CRITICAL); | ||
| 2437 | xasprintf(&sc_order.output, "Packets out of order"); | ||
| 2438 | } else { | ||
| 2439 | xasprintf(&sc_order.output, "Packets in order"); | ||
| 2440 | } | ||
| 2441 | |||
| 2442 | mp_add_subcheck_to_subcheck(&result, sc_order); | ||
| 2443 | } | ||
| 2444 | |||
| 2445 | return result; | ||
| 2446 | } | ||
| 2447 | |||
| 2448 | evaluate_host_wrapper evaluate_host(check_icmp_target_container host, | ||
| 2449 | check_icmp_mode_switches modes, check_icmp_threshold warn, | ||
| 2450 | check_icmp_threshold crit) { | ||
| 2451 | evaluate_host_wrapper result = { | ||
| 2452 | .targets_warn = 0, | ||
| 2453 | .targets_ok = 0, | ||
| 2454 | .sc_host = mp_subcheck_init(), | ||
| 2455 | }; | ||
| 2456 | result.sc_host = mp_set_subcheck_default_state(result.sc_host, STATE_OK); | ||
| 2457 | |||
| 2458 | result.sc_host.output = strdup(host.name); | ||
| 2459 | |||
| 2460 | ping_target *target = host.target_list; | ||
| 2461 | for (unsigned int i = 0; i < host.number_of_targets; i++) { | ||
| 2462 | mp_subcheck sc_target = evaluate_target(*target, modes, warn, crit); | ||
| 2463 | |||
| 2464 | mp_state_enum target_state = mp_compute_subcheck_state(sc_target); | ||
| 2465 | |||
| 2466 | if (target_state == STATE_WARNING) { | ||
| 2467 | result.targets_warn++; | ||
| 2468 | } else if (target_state == STATE_OK) { | ||
| 2469 | result.targets_ok++; | ||
| 2470 | } | ||
| 2471 | mp_add_subcheck_to_subcheck(&result.sc_host, sc_target); | ||
| 2472 | |||
| 2473 | target = target->next; | ||
| 2474 | } | ||
| 2475 | |||
| 2476 | return result; | ||
| 2196 | } | 2477 | } |
diff --git a/plugins-root/check_icmp.d/check_icmp_helpers.c b/plugins-root/check_icmp.d/check_icmp_helpers.c new file mode 100644 index 00000000..1b96a392 --- /dev/null +++ b/plugins-root/check_icmp.d/check_icmp_helpers.c | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | #include "./config.h" | ||
| 2 | #include <math.h> | ||
| 3 | #include <netinet/in.h> | ||
| 4 | #include <sys/socket.h> | ||
| 5 | #include "./check_icmp_helpers.h" | ||
| 6 | #include "../../plugins/netutils.h" | ||
| 7 | |||
| 8 | // timeout as a global variable to make it available to the timeout handler | ||
| 9 | unsigned int timeout = DEFAULT_TIMEOUT; | ||
| 10 | |||
| 11 | check_icmp_config check_icmp_config_init() { | ||
| 12 | check_icmp_config tmp = { | ||
| 13 | .modes = | ||
| 14 | { | ||
| 15 | .order_mode = false, | ||
| 16 | .mos_mode = false, | ||
| 17 | .rta_mode = false, | ||
| 18 | .pl_mode = false, | ||
| 19 | .jitter_mode = false, | ||
| 20 | .score_mode = false, | ||
| 21 | }, | ||
| 22 | |||
| 23 | .min_hosts_alive = -1, | ||
| 24 | .crit = {.pl = DEFAULT_CRIT_PL, | ||
| 25 | .rta = DEFAULT_CRIT_RTA, | ||
| 26 | .jitter = 50.0, | ||
| 27 | .mos = 3.0, | ||
| 28 | .score = 70.0}, | ||
| 29 | .warn = {.pl = DEFAULT_WARN_PL, | ||
| 30 | .rta = DEFAULT_WARN_RTA, | ||
| 31 | .jitter = 40.0, | ||
| 32 | .mos = 3.5, | ||
| 33 | .score = 80.0}, | ||
| 34 | |||
| 35 | .ttl = DEFAULT_TTL, | ||
| 36 | .icmp_data_size = DEFAULT_PING_DATA_SIZE, | ||
| 37 | .target_interval = 0, | ||
| 38 | .number_of_packets = DEFAULT_NUMBER_OF_PACKETS, | ||
| 39 | |||
| 40 | .source_ip = NULL, | ||
| 41 | .need_v4 = false, | ||
| 42 | .need_v6 = false, | ||
| 43 | |||
| 44 | .sender_id = 0, | ||
| 45 | |||
| 46 | .mode = MODE_RTA, | ||
| 47 | |||
| 48 | .number_of_targets = 0, | ||
| 49 | .targets = NULL, | ||
| 50 | |||
| 51 | .number_of_hosts = 0, | ||
| 52 | .hosts = NULL, | ||
| 53 | |||
| 54 | .output_format_is_set = false, | ||
| 55 | }; | ||
| 56 | return tmp; | ||
| 57 | } | ||
| 58 | |||
| 59 | ping_target ping_target_init() { | ||
| 60 | ping_target tmp = { | ||
| 61 | .rtmin = INFINITY, | ||
| 62 | |||
| 63 | .jitter_min = INFINITY, | ||
| 64 | |||
| 65 | .found_out_of_order_packets = false, | ||
| 66 | }; | ||
| 67 | |||
| 68 | return tmp; | ||
| 69 | } | ||
| 70 | |||
| 71 | check_icmp_state check_icmp_state_init() { | ||
| 72 | check_icmp_state tmp = {.icmp_sent = 0, .icmp_lost = 0, .icmp_recv = 0, .targets_down = 0}; | ||
| 73 | |||
| 74 | return tmp; | ||
| 75 | } | ||
| 76 | |||
| 77 | ping_target_create_wrapper ping_target_create(struct sockaddr_storage address) { | ||
| 78 | ping_target_create_wrapper result = { | ||
| 79 | .errorcode = 0, | ||
| 80 | }; | ||
| 81 | |||
| 82 | struct sockaddr_storage *tmp_addr = &address; | ||
| 83 | |||
| 84 | /* disregard obviously stupid addresses | ||
| 85 | * (I didn't find an ipv6 equivalent to INADDR_NONE) */ | ||
| 86 | if (((tmp_addr->ss_family == AF_INET && | ||
| 87 | (((struct sockaddr_in *)tmp_addr)->sin_addr.s_addr == INADDR_NONE || | ||
| 88 | ((struct sockaddr_in *)tmp_addr)->sin_addr.s_addr == INADDR_ANY))) || | ||
| 89 | (tmp_addr->ss_family == AF_INET6 && | ||
| 90 | (((struct sockaddr_in6 *)tmp_addr)->sin6_addr.s6_addr == in6addr_any.s6_addr))) { | ||
| 91 | result.errorcode = 1; | ||
| 92 | return result; | ||
| 93 | } | ||
| 94 | |||
| 95 | /* add the fresh ip */ | ||
| 96 | ping_target target = ping_target_init(); | ||
| 97 | |||
| 98 | /* fill out the sockaddr_storage struct */ | ||
| 99 | target.address = address; | ||
| 100 | |||
| 101 | result.host = target; | ||
| 102 | |||
| 103 | return result; | ||
| 104 | } | ||
| 105 | |||
| 106 | check_icmp_target_container check_icmp_target_container_init() { | ||
| 107 | check_icmp_target_container tmp = { | ||
| 108 | .name = NULL, | ||
| 109 | .number_of_targets = 0, | ||
| 110 | .target_list = NULL, | ||
| 111 | }; | ||
| 112 | return tmp; | ||
| 113 | } | ||
| 114 | |||
| 115 | unsigned int ping_target_list_append(ping_target *list, ping_target *elem) { | ||
| 116 | if (elem == NULL || list == NULL) { | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | while (list->next != NULL) { | ||
| 121 | list = list->next; | ||
| 122 | } | ||
| 123 | |||
| 124 | list->next = elem; | ||
| 125 | |||
| 126 | unsigned int result = 1; | ||
| 127 | |||
| 128 | while (elem->next != NULL) { | ||
| 129 | result++; | ||
| 130 | elem = elem->next; | ||
| 131 | } | ||
| 132 | |||
| 133 | return result; | ||
| 134 | } | ||
diff --git a/plugins-root/check_icmp.d/check_icmp_helpers.h b/plugins-root/check_icmp.d/check_icmp_helpers.h new file mode 100644 index 00000000..dc6ea40b --- /dev/null +++ b/plugins-root/check_icmp.d/check_icmp_helpers.h | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../lib/states.h" | ||
| 4 | #include <netinet/in_systm.h> | ||
| 5 | #include <netinet/in.h> | ||
| 6 | #include <netinet/ip.h> | ||
| 7 | #include <netinet/ip6.h> | ||
| 8 | #include <netinet/ip_icmp.h> | ||
| 9 | #include <netinet/icmp6.h> | ||
| 10 | #include <arpa/inet.h> | ||
| 11 | |||
| 12 | typedef struct ping_target { | ||
| 13 | unsigned short id; /* id in **table, and icmp pkts */ | ||
| 14 | char *msg; /* icmp error message, if any */ | ||
| 15 | |||
| 16 | struct sockaddr_storage address; /* the address of this host */ | ||
| 17 | struct sockaddr_storage error_addr; /* stores address of error replies */ | ||
| 18 | time_t time_waited; /* total time waited, in usecs */ | ||
| 19 | unsigned int icmp_sent, icmp_recv, icmp_lost; /* counters */ | ||
| 20 | unsigned char icmp_type, icmp_code; /* type and code from errors */ | ||
| 21 | unsigned short flags; /* control/status flags */ | ||
| 22 | |||
| 23 | double rtmax; /* max rtt */ | ||
| 24 | double rtmin; /* min rtt */ | ||
| 25 | |||
| 26 | double jitter; /* measured jitter */ | ||
| 27 | double jitter_max; /* jitter rtt maximum */ | ||
| 28 | double jitter_min; /* jitter rtt minimum */ | ||
| 29 | |||
| 30 | time_t last_tdiff; | ||
| 31 | unsigned int last_icmp_seq; /* Last ICMP_SEQ to check out of order pkts */ | ||
| 32 | |||
| 33 | bool found_out_of_order_packets; | ||
| 34 | |||
| 35 | struct ping_target *next; | ||
| 36 | } ping_target; | ||
| 37 | |||
| 38 | ping_target ping_target_init(); | ||
| 39 | |||
| 40 | typedef struct { | ||
| 41 | char *name; | ||
| 42 | ping_target *target_list; | ||
| 43 | unsigned int number_of_targets; | ||
| 44 | } check_icmp_target_container; | ||
| 45 | |||
| 46 | check_icmp_target_container check_icmp_target_container_init(); | ||
| 47 | |||
| 48 | typedef struct { | ||
| 49 | unsigned int icmp_sent; | ||
| 50 | unsigned int icmp_recv; | ||
| 51 | unsigned int icmp_lost; | ||
| 52 | unsigned short targets_down; | ||
| 53 | } check_icmp_state; | ||
| 54 | |||
| 55 | check_icmp_state check_icmp_state_init(); | ||
| 56 | |||
| 57 | typedef struct { | ||
| 58 | int errorcode; | ||
| 59 | ping_target host; | ||
| 60 | } ping_target_create_wrapper; | ||
| 61 | |||
| 62 | typedef struct { | ||
| 63 | int socket4; | ||
| 64 | int socket6; | ||
| 65 | } check_icmp_socket_set; | ||
| 66 | |||
| 67 | ping_target_create_wrapper ping_target_create(struct sockaddr_storage address); | ||
| 68 | unsigned int ping_target_list_append(ping_target *list, ping_target *elem); | ||
diff --git a/plugins-root/check_icmp.d/config.h b/plugins-root/check_icmp.d/config.h new file mode 100644 index 00000000..be388d0a --- /dev/null +++ b/plugins-root/check_icmp.d/config.h | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include "../../lib/states.h" | ||
| 5 | #include <stddef.h> | ||
| 6 | #include <netinet/in_systm.h> | ||
| 7 | #include <netinet/in.h> | ||
| 8 | #include <netinet/ip.h> | ||
| 9 | #include <netinet/ip6.h> | ||
| 10 | #include <netinet/ip_icmp.h> | ||
| 11 | #include <netinet/icmp6.h> | ||
| 12 | #include <arpa/inet.h> | ||
| 13 | #include <stdint.h> | ||
| 14 | #include "./check_icmp_helpers.h" | ||
| 15 | #include "output.h" | ||
| 16 | |||
| 17 | /* threshold structure. all values are maximum allowed, exclusive */ | ||
| 18 | typedef struct { | ||
| 19 | unsigned char pl; /* max allowed packet loss in percent */ | ||
| 20 | time_t rta; /* roundtrip time average, microseconds */ | ||
| 21 | double jitter; /* jitter time average, microseconds */ | ||
| 22 | double mos; /* MOS */ | ||
| 23 | double score; /* Score */ | ||
| 24 | } check_icmp_threshold; | ||
| 25 | |||
| 26 | /* the different modes of this program are as follows: | ||
| 27 | * MODE_RTA: send all packets no matter what (mimic check_icmp and check_ping) | ||
| 28 | * MODE_HOSTCHECK: Return immediately upon any sign of life | ||
| 29 | * In addition, sends packets to ALL addresses assigned | ||
| 30 | * to this host (as returned by gethostbyname() or | ||
| 31 | * gethostbyaddr() and expects one host only to be checked at | ||
| 32 | * a time. Therefore, any packet response what so ever will | ||
| 33 | * count as a sign of life, even when received outside | ||
| 34 | * crit.rta limit. Do not misspell any additional IP's. | ||
| 35 | * MODE_ALL: Requires packets from ALL requested IP to return OK (default). | ||
| 36 | * MODE_ICMP: Default Mode | ||
| 37 | */ | ||
| 38 | typedef enum { | ||
| 39 | MODE_RTA, | ||
| 40 | MODE_HOSTCHECK, | ||
| 41 | MODE_ALL, | ||
| 42 | MODE_ICMP, | ||
| 43 | } check_icmp_execution_mode; | ||
| 44 | |||
| 45 | typedef struct { | ||
| 46 | bool order_mode; | ||
| 47 | bool mos_mode; | ||
| 48 | bool rta_mode; | ||
| 49 | bool pl_mode; | ||
| 50 | bool jitter_mode; | ||
| 51 | bool score_mode; | ||
| 52 | } check_icmp_mode_switches; | ||
| 53 | |||
| 54 | typedef struct { | ||
| 55 | check_icmp_mode_switches modes; | ||
| 56 | |||
| 57 | int min_hosts_alive; | ||
| 58 | check_icmp_threshold crit; | ||
| 59 | check_icmp_threshold warn; | ||
| 60 | |||
| 61 | unsigned long ttl; | ||
| 62 | unsigned short icmp_data_size; | ||
| 63 | time_t target_interval; | ||
| 64 | unsigned short number_of_packets; | ||
| 65 | |||
| 66 | char *source_ip; | ||
| 67 | bool need_v4; | ||
| 68 | bool need_v6; | ||
| 69 | |||
| 70 | uint16_t sender_id; // PID of the main process, which is used as an ID in packets | ||
| 71 | |||
| 72 | check_icmp_execution_mode mode; | ||
| 73 | |||
| 74 | unsigned short number_of_targets; | ||
| 75 | ping_target *targets; | ||
| 76 | |||
| 77 | unsigned short number_of_hosts; | ||
| 78 | check_icmp_target_container *hosts; | ||
| 79 | |||
| 80 | mp_output_format output_format; | ||
| 81 | bool output_format_is_set; | ||
| 82 | } check_icmp_config; | ||
| 83 | |||
| 84 | check_icmp_config check_icmp_config_init(); | ||
| 85 | |||
| 86 | /* the data structure */ | ||
| 87 | typedef struct icmp_ping_data { | ||
| 88 | struct timeval stime; /* timestamp (saved in protocol struct as well) */ | ||
| 89 | unsigned short ping_id; | ||
| 90 | } icmp_ping_data; | ||
| 91 | |||
| 92 | #define MAX_IP_PKT_SIZE 65536 /* (theoretical) max IP packet size */ | ||
| 93 | #define IP_HDR_SIZE 20 | ||
| 94 | #define MAX_PING_DATA (MAX_IP_PKT_SIZE - IP_HDR_SIZE - ICMP_MINLEN) | ||
| 95 | #define MIN_PING_DATA_SIZE sizeof(struct icmp_ping_data) | ||
| 96 | #define DEFAULT_PING_DATA_SIZE (MIN_PING_DATA_SIZE + 44) | ||
| 97 | |||
| 98 | /* 80 msec packet interval by default */ | ||
| 99 | // DEPRECATED, remove when removing the option | ||
| 100 | #define DEFAULT_PKT_INTERVAL 80000 | ||
| 101 | |||
| 102 | #define DEFAULT_TARGET_INTERVAL 0 | ||
| 103 | |||
| 104 | #define DEFAULT_WARN_RTA 200000 | ||
| 105 | #define DEFAULT_CRIT_RTA 500000 | ||
| 106 | #define DEFAULT_WARN_PL 40 | ||
| 107 | #define DEFAULT_CRIT_PL 80 | ||
| 108 | |||
| 109 | #define DEFAULT_TIMEOUT 10 | ||
| 110 | #define DEFAULT_TTL 64 | ||
| 111 | |||
| 112 | #define DEFAULT_NUMBER_OF_PACKETS 5 | ||
| 113 | |||
| 114 | #define PACKET_BACKOFF_FACTOR 1.5 | ||
| 115 | #define TARGET_BACKOFF_FACTOR 1.5 | ||
diff --git a/plugins-root/pst3.c b/plugins-root/pst3.c index 1f69f3a6..1bfe3d35 100644 --- a/plugins-root/pst3.c +++ b/plugins-root/pst3.c | |||
| @@ -1,45 +1,45 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * pst3 | 3 | * pst3 |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 2008 Monitoring Plugins Development Team | 6 | * Copyright (c) 2008 Monitoring Plugins Development Team |
| 7 | * | 7 | * |
| 8 | * Description: | 8 | * Description: |
| 9 | * | 9 | * |
| 10 | * This file contains the pst3 executable. This is a replacement ps command | 10 | * This file contains the pst3 executable. This is a replacement ps command |
| 11 | * for Solaris to get output which provides a long argument listing, which | 11 | * for Solaris to get output which provides a long argument listing, which |
| 12 | * is not possible with the standard ps command (due to truncation). /usr/ucb/ps | 12 | * is not possible with the standard ps command (due to truncation). /usr/ucb/ps |
| 13 | * also has issues where some fields run into each other. | 13 | * also has issues where some fields run into each other. |
| 14 | * | 14 | * |
| 15 | * This executable works by reading process address structures, so needs | 15 | * This executable works by reading process address structures, so needs |
| 16 | * to be executed as root | 16 | * to be executed as root |
| 17 | * | 17 | * |
| 18 | * Originally written by R.W.Ingraham | 18 | * Originally written by R.W.Ingraham |
| 19 | * Rewritten by Duncan Ferguson (Altinity Ltd, June 2008) | 19 | * Rewritten by Duncan Ferguson (Altinity Ltd, June 2008) |
| 20 | * The rewrite was necessary as /dev/kmem is not available within | 20 | * The rewrite was necessary as /dev/kmem is not available within |
| 21 | * non-global zones on Solaris 10 | 21 | * non-global zones on Solaris 10 |
| 22 | * | 22 | * |
| 23 | * Details for rewrite came from | 23 | * Details for rewrite came from |
| 24 | * source of /usr/ucb/ps on Solaris: | 24 | * source of /usr/ucb/ps on Solaris: |
| 25 | * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/ucbcmd/ps/ps.c#argvoff | 25 | * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/ucbcmd/ps/ps.c#argvoff |
| 26 | * usenet group posting | 26 | * usenet group posting |
| 27 | * http://groups.google.com/group/comp.unix.solaris/tree/browse_frm/month/2001-09/bfa40c08bac819a2?rnum=141&_done=%2Fgroup%2Fcomp.unix.solaris%2Fbrowse_frm%2Fmonth%2F2001-09%3F | 27 | * http://groups.google.com/group/comp.unix.solaris/tree/browse_frm/month/2001-09/bfa40c08bac819a2?rnum=141&_done=%2Fgroup%2Fcomp.unix.solaris%2Fbrowse_frm%2Fmonth%2F2001-09%3F |
| 28 | * | 28 | * |
| 29 | * This program is free software: you can redistribute it and/or modify | 29 | * This program is free software: you can redistribute it and/or modify |
| 30 | * it under the terms of the GNU General Public License as published by | 30 | * it under the terms of the GNU General Public License as published by |
| 31 | * the Free Software Foundation, either version 3 of the License, or | 31 | * the Free Software Foundation, either version 3 of the License, or |
| 32 | * (at your option) any later version. | 32 | * (at your option) any later version. |
| 33 | * | 33 | * |
| 34 | * This program is distributed in the hope that it will be useful, | 34 | * This program is distributed in the hope that it will be useful, |
| 35 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 35 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 37 | * GNU General Public License for more details. | 37 | * GNU General Public License for more details. |
| 38 | * | 38 | * |
| 39 | * You should have received a copy of the GNU General Public License | 39 | * You should have received a copy of the GNU General Public License |
| 40 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 40 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 41 | * | 41 | * |
| 42 | *****************************************************************************/ | 42 | *****************************************************************************/ |
| 43 | 43 | ||
| 44 | #include <stdio.h> | 44 | #include <stdio.h> |
| 45 | #include <stdlib.h> | 45 | #include <stdlib.h> |
| @@ -55,14 +55,14 @@ | |||
| 55 | * Constants | 55 | * Constants |
| 56 | */ | 56 | */ |
| 57 | 57 | ||
| 58 | #define PROC_DIR "/proc" | 58 | #define PROC_DIR "/proc" |
| 59 | #define ARGS 30 | 59 | #define ARGS 30 |
| 60 | 60 | ||
| 61 | /* | 61 | /* |
| 62 | * Globals | 62 | * Globals |
| 63 | */ | 63 | */ |
| 64 | 64 | ||
| 65 | static char * szProg; | 65 | static char *szProg; |
| 66 | 66 | ||
| 67 | /* | 67 | /* |
| 68 | * Prototypes | 68 | * Prototypes |
| @@ -71,192 +71,179 @@ void usage(); | |||
| 71 | 71 | ||
| 72 | /*----------------------------------------------------------------------------*/ | 72 | /*----------------------------------------------------------------------------*/ |
| 73 | 73 | ||
| 74 | int main (int argc, char **argv) | 74 | int main(int argc, char **argv) { |
| 75 | { | 75 | DIR *procdir; |
| 76 | DIR *procdir; | 76 | struct dirent *proc; |
| 77 | struct dirent *proc; | 77 | char ps_name[ARGS]; |
| 78 | char ps_name[ARGS]; | 78 | char as_name[ARGS]; |
| 79 | char as_name[ARGS]; | 79 | psinfo_t psinfo; |
| 80 | psinfo_t psinfo; | 80 | |
| 81 | 81 | /* Set our program name global */ | |
| 82 | /* Set our program name global */ | 82 | if ((szProg = strrchr(argv[0], '/')) != NULL) { |
| 83 | if ((szProg = strrchr(argv[0], '/')) != NULL) | 83 | szProg++; |
| 84 | szProg++; | 84 | } else { |
| 85 | else | 85 | szProg = argv[0]; |
| 86 | szProg = argv[0]; | 86 | } |
| 87 | 87 | ||
| 88 | /* if given any parameters, print out help */ | 88 | /* if given any parameters, print out help */ |
| 89 | if(argc > 1) { | 89 | if (argc > 1) { |
| 90 | (void)usage(); | 90 | (void)usage(); |
| 91 | exit(1); | 91 | exit(1); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /* Make sure that our euid is root */ | 94 | /* Make sure that our euid is root */ |
| 95 | if (geteuid() != 0) | 95 | if (geteuid() != 0) { |
| 96 | { | 96 | fprintf(stderr, "%s: This program can only be run by the root user!\n", szProg); |
| 97 | fprintf(stderr, "%s: This program can only be run by the root user!\n", szProg); | 97 | exit(1); |
| 98 | exit(1); | 98 | } |
| 99 | } | 99 | |
| 100 | 100 | if ((procdir = opendir(PROC_DIR)) == NULL) { | |
| 101 | if ((procdir = opendir(PROC_DIR)) == NULL) { | 101 | fprintf(stderr, "%s: cannot open PROC directory %s\n", szProg, PROC_DIR); |
| 102 | fprintf(stderr, "%s: cannot open PROC directory %s\n", szProg, PROC_DIR); | 102 | exit(1); |
| 103 | exit(1); | 103 | } |
| 104 | } | 104 | |
| 105 | 105 | /* Display column headings */ | |
| 106 | /* Display column headings */ | 106 | printf("%c %5s %5s %5s %6s %6s %4s %s %s\n", 'S', "UID", "PID", "PPID", "VSZ", "RSS", "%CPU", |
| 107 | printf("%c %5s %5s %5s %6s %6s %4s %s %s\n", | 107 | "COMMAND", "ARGS"); |
| 108 | 'S', | 108 | |
| 109 | "UID", | 109 | /* Zip through all of the process entries */ |
| 110 | "PID", | 110 | while ((proc = readdir(procdir))) { |
| 111 | "PPID", | 111 | int ps_fd; |
| 112 | "VSZ", | 112 | int as_fd; |
| 113 | "RSS", | 113 | off_t argoff; |
| 114 | "%CPU", | 114 | int i; |
| 115 | "COMMAND", | 115 | char *args; |
| 116 | "ARGS" | 116 | char *procname; |
| 117 | ); | 117 | char *ptr; |
| 118 | 118 | int argslen; | |
| 119 | /* Zip through all of the process entries */ | 119 | uintptr_t args_addr; |
| 120 | while((proc = readdir(procdir))) { | 120 | ; |
| 121 | int ps_fd; | 121 | uintptr_t *args_vecs; |
| 122 | int as_fd; | 122 | ; |
| 123 | off_t argoff; | 123 | int args_count; |
| 124 | int i; | 124 | |
| 125 | char *args; | 125 | if (proc->d_name[0] == '.') { |
| 126 | char *procname; | 126 | continue; |
| 127 | char *ptr; | 127 | } |
| 128 | int argslen; | 128 | |
| 129 | uintptr_t args_addr;; | 129 | sprintf(ps_name, "%s/%s/%s", PROC_DIR, proc->d_name, "psinfo"); |
| 130 | uintptr_t *args_vecs;; | 130 | sprintf(as_name, "%s/%s/%s", PROC_DIR, proc->d_name, "as"); |
| 131 | int args_count; | 131 | try_again: |
| 132 | 132 | if ((ps_fd = open(ps_name, O_RDONLY)) == -1) { | |
| 133 | if(proc->d_name[0] == '.') | 133 | continue; |
| 134 | continue; | 134 | } |
| 135 | 135 | ||
| 136 | sprintf(ps_name,"%s/%s/%s",PROC_DIR,proc->d_name,"psinfo"); | 136 | if ((as_fd = open(as_name, O_RDONLY)) == -1) { |
| 137 | sprintf(as_name,"%s/%s/%s",PROC_DIR,proc->d_name,"as"); | 137 | close(ps_fd); |
| 138 | try_again: | 138 | continue; |
| 139 | if((ps_fd = open(ps_name, O_RDONLY)) == -1) | 139 | } |
| 140 | continue; | 140 | |
| 141 | 141 | if (read(ps_fd, &psinfo, sizeof(psinfo)) != sizeof(psinfo)) { | |
| 142 | if((as_fd = open(as_name, O_RDONLY)) == -1) { | 142 | int err = errno; |
| 143 | close(ps_fd); | 143 | close(ps_fd); |
| 144 | continue; | 144 | close(as_fd); |
| 145 | } | 145 | if (err == EAGAIN) { |
| 146 | 146 | goto try_again; | |
| 147 | if(read(ps_fd, &psinfo, sizeof(psinfo)) != sizeof(psinfo)) { | 147 | } |
| 148 | int err = errno; | 148 | if (err != ENOENT) { |
| 149 | close(ps_fd); | 149 | fprintf(stderr, "%s: read() on %s: %s\n", szProg, ps_name, strerror(err)); |
| 150 | close(as_fd); | 150 | } |
| 151 | if(err == EAGAIN) goto try_again; | 151 | continue; |
| 152 | if(err != ENOENT) | 152 | } |
| 153 | fprintf(stderr, "%s: read() on %s: %s\n", szProg, | 153 | close(ps_fd); |
| 154 | ps_name, strerror(err)); | 154 | |
| 155 | continue; | 155 | /* system process, ignore since the previous version did */ |
| 156 | } | 156 | if (psinfo.pr_nlwp == 0 || strcmp(psinfo.pr_lwp.pr_clname, "SYS") == 0) { |
| 157 | close(ps_fd); | 157 | continue; |
| 158 | 158 | } | |
| 159 | /* system process, ignore since the previous version did */ | 159 | |
| 160 | if( | 160 | /* get the procname to match previous versions */ |
| 161 | psinfo.pr_nlwp == 0 || | 161 | procname = strdup(psinfo.pr_psargs); |
| 162 | strcmp(psinfo.pr_lwp.pr_clname, "SYS") == 0 | 162 | if ((ptr = strchr(procname, ' ')) != NULL) { |
| 163 | ) { | 163 | *ptr = '\0'; |
| 164 | continue; | 164 | } |
| 165 | } | 165 | if ((ptr = strrchr(procname, '/')) != NULL) { |
| 166 | 166 | ptr++; | |
| 167 | /* get the procname to match previous versions */ | 167 | } else { |
| 168 | procname = strdup(psinfo.pr_psargs); | 168 | ptr = procname; |
| 169 | if((ptr = strchr(procname, ' ')) != NULL) | 169 | } |
| 170 | *ptr = '\0'; | 170 | |
| 171 | if((ptr = strrchr(procname, '/')) != NULL) | 171 | /* |
| 172 | ptr++; | 172 | * print out what we currently know |
| 173 | else | 173 | */ |
| 174 | ptr = procname; | 174 | printf("%c %5d %5d %5d %6lu %6lu %4.1f %s ", psinfo.pr_lwp.pr_sname, psinfo.pr_euid, |
| 175 | 175 | psinfo.pr_pid, psinfo.pr_ppid, psinfo.pr_size, psinfo.pr_rssize, | |
| 176 | /* | 176 | ((float)(psinfo.pr_pctcpu) / 0x8000 * 100.0), ptr); |
| 177 | * print out what we currently know | 177 | free(procname); |
| 178 | */ | 178 | |
| 179 | printf("%c %5d %5d %5d %6lu %6lu %4.1f %s ", | 179 | /* |
| 180 | psinfo.pr_lwp.pr_sname, | 180 | * and now for the command line stuff |
| 181 | psinfo.pr_euid, | 181 | */ |
| 182 | psinfo.pr_pid, | 182 | |
| 183 | psinfo.pr_ppid, | 183 | args_addr = psinfo.pr_argv; |
| 184 | psinfo.pr_size, | 184 | args_count = psinfo.pr_argc; |
| 185 | psinfo.pr_rssize, | 185 | args_vecs = malloc(args_count * sizeof(uintptr_t)); |
| 186 | ((float)(psinfo.pr_pctcpu) / 0x8000 * 100.0), | 186 | |
| 187 | ptr | 187 | if (psinfo.pr_dmodel == PR_MODEL_NATIVE) { |
| 188 | ); | 188 | /* this process matches target process */ |
| 189 | free(procname); | 189 | pread(as_fd, args_vecs, args_count * sizeof(uintptr_t), args_addr); |
| 190 | 190 | } else { | |
| 191 | /* | 191 | /* this process is 64bit, target process is 32 bit*/ |
| 192 | * and now for the command line stuff | 192 | caddr32_t *args_vecs32 = (caddr32_t *)args_vecs; |
| 193 | */ | 193 | pread(as_fd, args_vecs32, args_count * sizeof(caddr32_t), args_addr); |
| 194 | 194 | for (i = args_count - 1; i >= 0; --i) { | |
| 195 | args_addr = psinfo.pr_argv; | 195 | args_vecs[i] = args_vecs32[i]; |
| 196 | args_count = psinfo.pr_argc; | 196 | } |
| 197 | args_vecs = malloc(args_count * sizeof(uintptr_t)); | 197 | } |
| 198 | 198 | ||
| 199 | if(psinfo.pr_dmodel == PR_MODEL_NATIVE) { | 199 | /* |
| 200 | /* this process matches target process */ | 200 | * now read in the args - if what we read in fills buffer |
| 201 | pread(as_fd,args_vecs, args_count * sizeof(uintptr_t), | 201 | * resize buffer and reread that bit again |
| 202 | args_addr); | 202 | */ |
| 203 | } else { | 203 | argslen = ARGS; |
| 204 | /* this process is 64bit, target process is 32 bit*/ | 204 | args = malloc(argslen + 1); |
| 205 | caddr32_t *args_vecs32 = (caddr32_t *)args_vecs; | 205 | for (i = 0; i < args_count; i++) { |
| 206 | pread(as_fd,args_vecs32,args_count * sizeof(caddr32_t), | 206 | memset(args, '\0', argslen + 1); |
| 207 | args_addr); | 207 | if (pread(as_fd, args, argslen, args_vecs[i]) <= 0) { |
| 208 | for (i=args_count-1;i>=0;--i) | 208 | break; |
| 209 | args_vecs[i]=args_vecs32[i]; | 209 | } |
| 210 | } | 210 | args[argslen] = '\0'; |
| 211 | 211 | if (strlen(args) == argslen) { | |
| 212 | /* | 212 | argslen += ARGS; |
| 213 | * now read in the args - if what we read in fills buffer | 213 | args = realloc(args, argslen + 1); |
| 214 | * resize buffer and reread that bit again | 214 | i--; |
| 215 | */ | 215 | continue; |
| 216 | argslen=ARGS; | 216 | } |
| 217 | args=malloc(argslen+1); | 217 | printf(" %s", args); |
| 218 | for(i=0;i<args_count;i++) { | 218 | } |
| 219 | memset(args,'\0',argslen+1); | 219 | free(args_vecs); |
| 220 | if(pread(as_fd, args, argslen, args_vecs[i]) <= 0) { | 220 | free(args); |
| 221 | break; | 221 | close(as_fd); |
| 222 | } | 222 | printf("\n"); |
| 223 | args[argslen]='\0'; | 223 | } |
| 224 | if(strlen(args) == argslen){ | 224 | |
| 225 | argslen += ARGS; | 225 | (void)closedir(procdir); |
| 226 | args = realloc(args, argslen + 1); | 226 | |
| 227 | i--; | 227 | return (0); |
| 228 | continue; | ||
| 229 | } | ||
| 230 | printf(" %s", args); | ||
| 231 | } | ||
| 232 | free(args_vecs); | ||
| 233 | free(args); | ||
| 234 | close(as_fd); | ||
| 235 | printf("\n"); | ||
| 236 | } | ||
| 237 | |||
| 238 | (void) closedir(procdir); | ||
| 239 | |||
| 240 | return (0); | ||
| 241 | } | 228 | } |
| 242 | 229 | ||
| 243 | /*----------------------------------------------------------------------------*/ | 230 | /*----------------------------------------------------------------------------*/ |
| 244 | 231 | ||
| 245 | void usage() { | 232 | void usage() { |
| 246 | printf("%s: Help output\n\n", szProg); | 233 | printf("%s: Help output\n\n", szProg); |
| 247 | printf("If this program is given any arguments, this help is displayed.\n"); | 234 | printf("If this program is given any arguments, this help is displayed.\n"); |
| 248 | printf("This command is used to print out the full command line for all\n"); | 235 | printf("This command is used to print out the full command line for all\n"); |
| 249 | printf("running processes because /usr/bin/ps is limited to 80 chars and\n"); | 236 | printf("running processes because /usr/bin/ps is limited to 80 chars and\n"); |
| 250 | printf("/usr/ucb/ps can merge columns together.\n\n"); | 237 | printf("/usr/ucb/ps can merge columns together.\n\n"); |
| 251 | printf("Columns are:\n"); | 238 | printf("Columns are:\n"); |
| 252 | printf("\tS - State of process - see 'ps' man page\n"); | 239 | printf("\tS - State of process - see 'ps' man page\n"); |
| 253 | printf("\tUID - UID of the process owner\n"); | 240 | printf("\tUID - UID of the process owner\n"); |
| 254 | printf("\tPID - PID of the process\n"); | 241 | printf("\tPID - PID of the process\n"); |
| 255 | printf("\tPPID - PID of the parent process\n"); | 242 | printf("\tPPID - PID of the parent process\n"); |
| 256 | printf("\tVSZ - Virtual memory usage (kilobytes)\n"); | 243 | printf("\tVSZ - Virtual memory usage (kilobytes)\n"); |
| 257 | printf("\tRSS - Real memory usage (kilobytes)\n"); | 244 | printf("\tRSS - Real memory usage (kilobytes)\n"); |
| 258 | printf("\t%%CPU - CPU usage\n"); | 245 | printf("\t%%CPU - CPU usage\n"); |
| 259 | printf("\tCOMMAND - Command being run\n"); | 246 | printf("\tCOMMAND - Command being run\n"); |
| 260 | printf("\tARGS - Full command line with arguments\n"); | 247 | printf("\tARGS - Full command line with arguments\n"); |
| 261 | return; | 248 | return; |
| 262 | } | 249 | } |
diff --git a/plugins-root/t/check_dhcp.t b/plugins-root/t/check_dhcp.t index ce627736..70392154 100644 --- a/plugins-root/t/check_dhcp.t +++ b/plugins-root/t/check_dhcp.t | |||
| @@ -12,14 +12,14 @@ my $allow_sudo = getTestParameter( "NP_ALLOW_SUDO", | |||
| 12 | "no" ); | 12 | "no" ); |
| 13 | 13 | ||
| 14 | if ($allow_sudo eq "yes" or $> == 0) { | 14 | if ($allow_sudo eq "yes" or $> == 0) { |
| 15 | plan tests => 6; | 15 | plan tests => 7; |
| 16 | } else { | 16 | } else { |
| 17 | plan skip_all => "Need sudo to test check_dhcp"; | 17 | plan skip_all => "Need sudo to test check_dhcp"; |
| 18 | } | 18 | } |
| 19 | my $sudo = $> == 0 ? '' : 'sudo'; | 19 | my $sudo = $> == 0 ? '' : 'sudo'; |
| 20 | 20 | ||
| 21 | my $successOutput = '/OK: Received \d+ DHCPOFFER\(s\), \d+ of 1 requested servers responded, max lease time = \d+ sec\./'; | 21 | my $successOutput = '/Received \d+ DHCPOFFER(s)*, max lease time = \d+ seconds/'; |
| 22 | my $failureOutput = '/CRITICAL: (No DHCPOFFERs were received|Received \d+ DHCPOFFER\(s\), 0 of 1 requested servers responded, max lease time = \d+ sec\.)/'; | 22 | my $failureOutput = '/(No DHCPOFFERs were received|Received \d+ DHCPOFFER\(s\), 0 of 1 requested servers responded, max lease time = \d+ sec\.)/'; |
| 23 | my $invalidOutput = '/Invalid hostname/'; | 23 | my $invalidOutput = '/Invalid hostname/'; |
| 24 | 24 | ||
| 25 | my $host_responsive = getTestParameter( "NP_HOST_DHCP_RESPONSIVE", | 25 | my $host_responsive = getTestParameter( "NP_HOST_DHCP_RESPONSIVE", |
| @@ -34,6 +34,8 @@ my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID", | |||
| 34 | "An invalid (not known to DNS) hostname", | 34 | "An invalid (not known to DNS) hostname", |
| 35 | "nosuchhost" ); | 35 | "nosuchhost" ); |
| 36 | 36 | ||
| 37 | my $output_format = "--output-format mp-test-json"; | ||
| 38 | |||
| 37 | # try to determince interface | 39 | # try to determince interface |
| 38 | my $interface = ''; | 40 | my $interface = ''; |
| 39 | 41 | ||
| @@ -49,19 +51,21 @@ my $res; | |||
| 49 | SKIP: { | 51 | SKIP: { |
| 50 | skip('need responsive test host', 2) unless $host_responsive; | 52 | skip('need responsive test host', 2) unless $host_responsive; |
| 51 | $res = NPTest->testCmd( | 53 | $res = NPTest->testCmd( |
| 52 | "$sudo ./check_dhcp $interface -u -s $host_responsive" | 54 | "$sudo ./check_dhcp $interface -u -s $host_responsive $output_format" |
| 53 | ); | 55 | ); |
| 54 | is( $res->return_code, 0, "Syntax ok" ); | 56 | is( $res->return_code, 0, "with JSON test format result should always be OK" ); |
| 55 | like( $res->output, $successOutput, "Output OK" ); | 57 | like( $res->{'mp_test_result'}->{'state'}, "/OK/", "Output OK" ); |
| 58 | like( $res->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $successOutput, "Output OK" ); | ||
| 56 | }; | 59 | }; |
| 57 | 60 | ||
| 58 | SKIP: { | 61 | SKIP: { |
| 59 | skip('need nonresponsive test host', 2) unless $host_nonresponsive; | 62 | skip('need nonresponsive test host', 2) unless $host_nonresponsive; |
| 60 | $res = NPTest->testCmd( | 63 | $res = NPTest->testCmd( |
| 61 | "$sudo ./check_dhcp $interface -u -s $host_nonresponsive" | 64 | "$sudo ./check_dhcp $interface -u -s $host_nonresponsive $output_format" |
| 62 | ); | 65 | ); |
| 63 | is( $res->return_code, 2, "Exit code - host nonresponsive" ); | 66 | is( $res->return_code, 0, "with JSON test format result should always be OK" ); |
| 64 | like( $res->output, $failureOutput, "Output OK" ); | 67 | like( $res->{'mp_test_result'}->{'state'}, "/CRITICAL/", "Exit code - host nonresponsive" ); |
| 68 | like( $res->{'mp_test_result'}->{'checks'}->[0]->{'output'}, $failureOutput, "Output OK" ); | ||
| 65 | }; | 69 | }; |
| 66 | 70 | ||
| 67 | SKIP: { | 71 | SKIP: { |
| @@ -69,6 +73,6 @@ SKIP: { | |||
| 69 | $res = NPTest->testCmd( | 73 | $res = NPTest->testCmd( |
| 70 | "$sudo ./check_dhcp $interface -u -s $hostname_invalid" | 74 | "$sudo ./check_dhcp $interface -u -s $hostname_invalid" |
| 71 | ); | 75 | ); |
| 72 | is( $res->return_code, 3, "Exit code - host invalid" ); | 76 | is( $res->return_code, 3, "invalid hostname/address should return UNKNOWN" ); |
| 73 | like( $res->output, $invalidOutput, "Output OK" ); | 77 | like( $res->output, $invalidOutput, "Output OK" ); |
| 74 | }; | 78 | }; |
diff --git a/plugins-root/t/check_icmp.t b/plugins-root/t/check_icmp.t index de1d88d2..d414c3c7 100644 --- a/plugins-root/t/check_icmp.t +++ b/plugins-root/t/check_icmp.t | |||
| @@ -12,15 +12,12 @@ my $allow_sudo = getTestParameter( "NP_ALLOW_SUDO", | |||
| 12 | "no" ); | 12 | "no" ); |
| 13 | 13 | ||
| 14 | if ($allow_sudo eq "yes" or $> == 0) { | 14 | if ($allow_sudo eq "yes" or $> == 0) { |
| 15 | plan tests => 40; | 15 | plan tests => 17; |
| 16 | } else { | 16 | } else { |
| 17 | plan skip_all => "Need sudo to test check_icmp"; | 17 | plan skip_all => "Need sudo to test check_icmp"; |
| 18 | } | 18 | } |
| 19 | my $sudo = $> == 0 ? '' : 'sudo'; | 19 | my $sudo = $> == 0 ? '' : 'sudo'; |
| 20 | 20 | ||
| 21 | my $successOutput = '/OK - .*? rta (?:[\d\.]+ms)|(?:nan), lost \d+%/'; | ||
| 22 | my $failureOutput = '/(WARNING|CRITICAL) - .*? rta (?:[\d\.]+ms > [\d\.]+ms|nan)/'; | ||
| 23 | |||
| 24 | my $host_responsive = getTestParameter( "NP_HOST_RESPONSIVE", | 21 | my $host_responsive = getTestParameter( "NP_HOST_RESPONSIVE", |
| 25 | "The hostname of system responsive to network requests", | 22 | "The hostname of system responsive to network requests", |
| 26 | "localhost" ); | 23 | "localhost" ); |
| @@ -36,108 +33,85 @@ my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID", | |||
| 36 | my $res; | 33 | my $res; |
| 37 | 34 | ||
| 38 | $res = NPTest->testCmd( | 35 | $res = NPTest->testCmd( |
| 39 | "$sudo ./check_icmp -H $host_responsive -w 10000ms,100% -c 10000ms,100%" | 36 | "$sudo ./check_icmp -H $host_responsive -w 100ms,100% -c 100ms,100%" |
| 40 | ); | 37 | ); |
| 41 | is( $res->return_code, 0, "Syntax ok" ); | 38 | is( $res->return_code, 0, "Syntax ok" ); |
| 42 | like( $res->output, $successOutput, "Output OK" ); | ||
| 43 | 39 | ||
| 44 | $res = NPTest->testCmd( | 40 | $res = NPTest->testCmd( |
| 45 | "$sudo ./check_icmp -H $host_responsive -w 0ms,0% -c 10000ms,100%" | 41 | "$sudo ./check_icmp -H $host_responsive -w 0ms,0% -c 100ms,100%" |
| 46 | ); | 42 | ); |
| 47 | is( $res->return_code, 1, "Syntax ok, with forced warning" ); | 43 | is( $res->return_code, 1, "Syntax ok, with forced warning" ); |
| 48 | like( $res->output, $failureOutput, "Output OK" ); | ||
| 49 | 44 | ||
| 50 | $res = NPTest->testCmd( | 45 | $res = NPTest->testCmd( |
| 51 | "$sudo ./check_icmp -H $host_responsive -w 0,0% -c 0,0%" | 46 | "$sudo ./check_icmp -H $host_responsive -w 0,0% -c 0,0%" |
| 52 | ); | 47 | ); |
| 53 | is( $res->return_code, 2, "Syntax ok, with forced critical" ); | 48 | is( $res->return_code, 2, "Syntax ok, with forced critical" ); |
| 54 | like( $res->output, $failureOutput, "Output OK" ); | ||
| 55 | 49 | ||
| 56 | $res = NPTest->testCmd( | 50 | $res = NPTest->testCmd( |
| 57 | "$sudo ./check_icmp -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100% -t 2" | 51 | "$sudo ./check_icmp -H $host_nonresponsive -w 100ms,100% -c 100ms,100%" |
| 58 | ); | 52 | ); |
| 59 | is( $res->return_code, 2, "Timeout - host nonresponsive" ); | 53 | is( $res->return_code, 2, "Timeout - host nonresponsive" ); |
| 60 | like( $res->output, '/pl=100%/', "Error contains 'pl=100%' string (for 100% packet loss)" ); | ||
| 61 | like( $res->output, '/rta=U/', "Error contains 'rta=U' string" ); | ||
| 62 | 54 | ||
| 63 | $res = NPTest->testCmd( | 55 | $res = NPTest->testCmd( |
| 64 | "$sudo ./check_icmp -w 10000ms,100% -c 10000ms,100%" | 56 | "$sudo ./check_icmp -w 100ms,100% -c 100ms,100%" |
| 65 | ); | 57 | ); |
| 66 | is( $res->return_code, 3, "No hostname" ); | 58 | is( $res->return_code, 3, "No hostname" ); |
| 67 | like( $res->output, '/No hosts to check/', "Output with appropriate error message"); | ||
| 68 | 59 | ||
| 69 | $res = NPTest->testCmd( | 60 | $res = NPTest->testCmd( |
| 70 | "$sudo ./check_icmp -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100% -n 1 -m 0 -t 2" | 61 | "$sudo ./check_icmp -H $host_nonresponsive -w 100ms,100% -c 100ms,100% -n 1 -m 0" |
| 71 | ); | 62 | ); |
| 72 | is( $res->return_code, 0, "One host nonresponsive - zero required" ); | 63 | is( $res->return_code, 0, "One host nonresponsive - zero required" ); |
| 73 | like( $res->output, $successOutput, "Output OK" ); | ||
| 74 | 64 | ||
| 75 | $res = NPTest->testCmd( | 65 | $res = NPTest->testCmd( |
| 76 | "$sudo ./check_icmp -H $host_responsive -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100% -n 1 -m 1 -t 2" | 66 | "$sudo ./check_icmp -H $host_responsive -H $host_nonresponsive -w 100ms,100% -c 100ms,100% -n 1 -m 1" |
| 77 | ); | 67 | ); |
| 78 | is( $res->return_code, 0, "One of two host nonresponsive - one required" ); | 68 | is( $res->return_code, 0, "One of two host nonresponsive - one required" ); |
| 79 | like( $res->output, $successOutput, "Output OK" ); | ||
| 80 | 69 | ||
| 81 | $res = NPTest->testCmd( | 70 | $res = NPTest->testCmd( |
| 82 | "$sudo ./check_icmp -H $host_responsive -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100% -n 1 -m 2" | 71 | "$sudo ./check_icmp -H $host_responsive -H $host_nonresponsive -w 100ms,100% -c 100ms,100% -n 1 -m 2" |
| 83 | ); | 72 | ); |
| 84 | is( $res->return_code, 2, "One of two host nonresponsive - two required" ); | 73 | is( $res->return_code, 2, "One of two host nonresponsive - two required" ); |
| 85 | like( $res->output, $failureOutput, "Output OK" ); | ||
| 86 | 74 | ||
| 87 | $res = NPTest->testCmd( | 75 | $res = NPTest->testCmd( |
| 88 | "$sudo ./check_icmp -H $host_responsive -s 127.0.15.15 -w 10000ms,100% -c 10000ms,100% -n 1 -m 2" | 76 | "$sudo ./check_icmp -H $host_responsive -s 127.0.15.15 -w 100ms,100% -c 100ms,100% -n 1" |
| 89 | ); | 77 | ); |
| 90 | is( $res->return_code, 0, "IPv4 source_ip accepted" ); | 78 | is( $res->return_code, 0, "IPv4 source_ip accepted" ); |
| 91 | like( $res->output, $successOutput, "Output OK" ); | ||
| 92 | 79 | ||
| 93 | $res = NPTest->testCmd( | 80 | $res = NPTest->testCmd( |
| 94 | "$sudo ./check_icmp -H $host_responsive -b 65507" | 81 | "$sudo ./check_icmp -H $host_responsive -b 65507" |
| 95 | ); | 82 | ); |
| 96 | is( $res->return_code, 0, "Try max packet size" ); | 83 | is( $res->return_code, 0, "Try max packet size" ); |
| 97 | like( $res->output, $successOutput, "Output OK - Didn't overflow" ); | ||
| 98 | 84 | ||
| 99 | $res = NPTest->testCmd( | 85 | $res = NPTest->testCmd( |
| 100 | "$sudo ./check_icmp -H $host_responsive -R 100,100 -n 1 -t 2" | 86 | "$sudo ./check_icmp -H $host_responsive -R 100,100 -n 1" |
| 101 | ); | 87 | ); |
| 102 | is( $res->return_code, 0, "rta works" ); | 88 | is( $res->return_code, 0, "rta works" ); |
| 103 | like( $res->output, $successOutput, "Output OK" ); | ||
| 104 | $res = NPTest->testCmd( | 89 | $res = NPTest->testCmd( |
| 105 | "$sudo ./check_icmp -H $host_responsive -P 80,90 -n 1 -t 2" | 90 | "$sudo ./check_icmp -H $host_responsive -P 80,90 -n 1" |
| 106 | ); | 91 | ); |
| 107 | is( $res->return_code, 0, "pl works" ); | 92 | is( $res->return_code, 0, "pl works" ); |
| 108 | like( $res->output, '/lost 0%/', "Output OK" ); | ||
| 109 | 93 | ||
| 110 | $res = NPTest->testCmd( | 94 | $res = NPTest->testCmd( |
| 111 | "$sudo ./check_icmp -H $host_responsive -J 80,90 -t 2" | 95 | "$sudo ./check_icmp -H $host_responsive -J 80,90" |
| 112 | ); | 96 | ); |
| 113 | is( $res->return_code, 0, "jitter works" ); | 97 | is( $res->return_code, 0, "jitter works" ); |
| 114 | like( $res->output, '/jitter \d/', "Output OK" ); | ||
| 115 | 98 | ||
| 116 | $res = NPTest->testCmd( | 99 | $res = NPTest->testCmd( |
| 117 | "$sudo ./check_icmp -H $host_responsive -M 4,3 -t 2" | 100 | "$sudo ./check_icmp -H $host_responsive -M 4,3" |
| 118 | ); | 101 | ); |
| 119 | is( $res->return_code, 0, "mos works" ); | 102 | is( $res->return_code, 0, "mos works" ); |
| 120 | like( $res->output, '/MOS \d/', "Output OK" ); | ||
| 121 | 103 | ||
| 122 | $res = NPTest->testCmd( | 104 | $res = NPTest->testCmd( |
| 123 | "$sudo ./check_icmp -H $host_responsive -S 80,70 -t 2" | 105 | "$sudo ./check_icmp -H $host_responsive -S 80,70" |
| 124 | ); | 106 | ); |
| 125 | is( $res->return_code, 0, "score works" ); | 107 | is( $res->return_code, 0, "score works" ); |
| 126 | like( $res->output, '/Score \d/', "Output OK" ); | ||
| 127 | 108 | ||
| 128 | $res = NPTest->testCmd( | 109 | $res = NPTest->testCmd( |
| 129 | "$sudo ./check_icmp -H $host_responsive -O -t 2" | 110 | "$sudo ./check_icmp -H $host_responsive -O" |
| 130 | ); | 111 | ); |
| 131 | is( $res->return_code, 0, "order works" ); | 112 | is( $res->return_code, 0, "order works" ); |
| 132 | like( $res->output, '/Packets in order/', "Output OK" ); | ||
| 133 | 113 | ||
| 134 | $res = NPTest->testCmd( | 114 | $res = NPTest->testCmd( |
| 135 | "$sudo ./check_icmp -H $host_responsive -O -S 80,70 -M 4,3 -J 80,90 -P 80,90 -R 100,100 -t 2" | 115 | "$sudo ./check_icmp -H $host_responsive -O -S 80,70 -M 4,3 -J 80,90 -P 80,90 -R 100,100" |
| 136 | ); | 116 | ); |
| 137 | is( $res->return_code, 0, "order works" ); | 117 | is( $res->return_code, 0, "order works" ); |
| 138 | like( $res->output, '/Packets in order/', "Output OK" ); | ||
| 139 | like( $res->output, '/Score \d/', "Output OK" ); | ||
| 140 | like( $res->output, '/MOS \d/', "Output OK" ); | ||
| 141 | like( $res->output, '/jitter \d/', "Output OK" ); | ||
| 142 | like( $res->output, '/lost 0%/', "Output OK" ); | ||
| 143 | like( $res->output, $successOutput, "Output OK" ); | ||
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 6c582a15..d098fa8a 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am | |||
| @@ -13,8 +13,14 @@ AM_CFLAGS = -DNP_VERSION='"$(NP_VERSION)"' | |||
| 13 | 13 | ||
| 14 | VPATH = $(top_srcdir) $(top_srcdir)/lib $(top_srcdir)/plugins $(top_srcdir)/plugins/t | 14 | VPATH = $(top_srcdir) $(top_srcdir)/lib $(top_srcdir)/plugins $(top_srcdir)/plugins/t |
| 15 | 15 | ||
| 16 | AM_CPPFLAGS = -I.. -I$(top_srcdir)/lib -I$(top_srcdir)/gl -I$(top_srcdir)/intl \ | 16 | AM_CPPFLAGS = -I.. \ |
| 17 | @LDAPINCLUDE@ @PGINCLUDE@ @SSLINCLUDE@ | 17 | -I$(top_srcdir)/lib \ |
| 18 | -I$(top_srcdir)/gl \ | ||
| 19 | -I$(top_srcdir)/intl \ | ||
| 20 | -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ | ||
| 21 | @LDAPINCLUDE@ \ | ||
| 22 | @PGINCLUDE@ \ | ||
| 23 | @SSLINCLUDE@ | ||
| 18 | 24 | ||
| 19 | localedir = $(datadir)/locale | 25 | localedir = $(datadir)/locale |
| 20 | # gettext docs say to use AM_CPPFLAGS, but per module_CPPFLAGS override this | 26 | # gettext docs say to use AM_CPPFLAGS, but per module_CPPFLAGS override this |
| @@ -27,48 +33,68 @@ MATHLIBS = @MATHLIBS@ | |||
| 27 | #AM_CFLAGS = -Wall | 33 | #AM_CFLAGS = -Wall |
| 28 | 34 | ||
| 29 | libexec_PROGRAMS = check_apt check_cluster check_disk check_dummy check_http check_load \ | 35 | libexec_PROGRAMS = check_apt check_cluster check_disk check_dummy check_http check_load \ |
| 30 | check_mrtg check_mrtgtraf check_ntp check_ntp_peer check_nwstat check_ping \ | 36 | check_mrtg check_mrtgtraf check_ntp_peer check_ping \ |
| 31 | check_real check_smtp check_ssh check_tcp check_time check_ntp_time \ | 37 | check_real check_smtp check_ssh check_tcp check_time check_ntp_time \ |
| 32 | check_ups check_users negate \ | 38 | check_ups check_users negate \ |
| 33 | urlize @EXTRAS@ | 39 | urlize @EXTRAS@ \ |
| 40 | check_snmp | ||
| 34 | 41 | ||
| 35 | check_tcp_programs = check_ftp check_imap check_nntp check_pop \ | 42 | check_tcp_programs = check_ftp check_imap check_nntp check_pop \ |
| 36 | check_udp check_clamd @check_tcp_ssl@ | 43 | check_udp check_clamd @check_tcp_ssl@ |
| 37 | 44 | ||
| 38 | EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_snmp check_hpjd \ | 45 | EXTRA_PROGRAMS = check_mysql check_radius check_pgsql check_hpjd \ |
| 39 | check_swap check_fping check_ldap check_game check_dig \ | 46 | check_swap check_fping check_ldap check_game check_dig \ |
| 40 | check_nagios check_by_ssh check_dns check_nt check_ide_smart \ | 47 | check_nagios check_by_ssh check_dns check_ide_smart \ |
| 41 | check_procs check_mysql_query check_apt check_dbi check_curl \ | 48 | check_procs check_mysql_query check_apt check_dbi check_curl \ |
| 42 | \ | 49 | \ |
| 43 | tests/test_check_swap | 50 | tests/test_check_swap \ |
| 51 | tests/test_check_snmp \ | ||
| 52 | tests/test_check_disk | ||
| 44 | 53 | ||
| 45 | SUBDIRS = picohttpparser | 54 | SUBDIRS = picohttpparser |
| 46 | 55 | ||
| 47 | np_test_scripts = tests/test_check_swap.t | 56 | np_test_scripts = tests/test_check_swap.t \ |
| 57 | tests/test_check_snmp.t \ | ||
| 58 | tests/test_check_disk.t | ||
| 48 | 59 | ||
| 49 | EXTRA_DIST = t \ | 60 | EXTRA_DIST = t \ |
| 50 | tests \ | 61 | tests \ |
| 51 | $(np_test_scripts) \ | 62 | $(np_test_scripts) \ |
| 63 | negate.d \ | ||
| 52 | check_swap.d \ | 64 | check_swap.d \ |
| 53 | check_ldap.d \ | 65 | check_ldap.d \ |
| 54 | check_hpjd.d \ | 66 | check_hpjd.d \ |
| 55 | check_game.d \ | 67 | check_game.d \ |
| 68 | check_radius.d \ | ||
| 69 | check_curl.d \ | ||
| 70 | check_disk.d \ | ||
| 71 | check_time.d \ | ||
| 72 | check_users.d \ | ||
| 73 | check_load.d \ | ||
| 56 | check_nagios.d \ | 74 | check_nagios.d \ |
| 57 | check_dbi.d \ | 75 | check_dbi.d \ |
| 76 | check_tcp.d \ | ||
| 77 | check_real.d \ | ||
| 58 | check_ssh.d \ | 78 | check_ssh.d \ |
| 59 | check_nt.d \ | ||
| 60 | check_dns.d \ | 79 | check_dns.d \ |
| 61 | check_mrtgtraf.d \ | 80 | check_mrtgtraf.d \ |
| 62 | check_mysql_query.d \ | 81 | check_mysql_query.d \ |
| 63 | check_mrtg.d \ | 82 | check_mrtg.d \ |
| 83 | check_ntp_peer.d \ | ||
| 64 | check_apt.d \ | 84 | check_apt.d \ |
| 65 | check_pgsql.d \ | 85 | check_pgsql.d \ |
| 86 | check_procs.d \ | ||
| 87 | check_ping.d \ | ||
| 66 | check_by_ssh.d \ | 88 | check_by_ssh.d \ |
| 67 | check_smtp.d \ | 89 | check_smtp.d \ |
| 90 | check_snmp.d \ | ||
| 68 | check_mysql.d \ | 91 | check_mysql.d \ |
| 69 | check_ntp_time.d \ | 92 | check_ntp_time.d \ |
| 70 | check_dig.d \ | 93 | check_dig.d \ |
| 71 | check_cluster.d \ | 94 | check_cluster.d \ |
| 95 | check_curl.d \ | ||
| 96 | check_cluster.d \ | ||
| 97 | check_ups.d \ | ||
| 72 | check_fping.d | 98 | check_fping.d |
| 73 | 99 | ||
| 74 | PLUGINHDRS = common.h | 100 | PLUGINHDRS = common.h |
| @@ -108,9 +134,11 @@ check_cluster_LDADD = $(BASEOBJS) | |||
| 108 | check_curl_CFLAGS = $(AM_CFLAGS) $(LIBCURLCFLAGS) $(URIPARSERCFLAGS) $(LIBCURLINCLUDE) $(URIPARSERINCLUDE) -Ipicohttpparser | 134 | check_curl_CFLAGS = $(AM_CFLAGS) $(LIBCURLCFLAGS) $(URIPARSERCFLAGS) $(LIBCURLINCLUDE) $(URIPARSERINCLUDE) -Ipicohttpparser |
| 109 | check_curl_CPPFLAGS = $(AM_CPPFLAGS) $(LIBCURLCFLAGS) $(URIPARSERCFLAGS) $(LIBCURLINCLUDE) $(URIPARSERINCLUDE) -Ipicohttpparser | 135 | check_curl_CPPFLAGS = $(AM_CPPFLAGS) $(LIBCURLCFLAGS) $(URIPARSERCFLAGS) $(LIBCURLINCLUDE) $(URIPARSERINCLUDE) -Ipicohttpparser |
| 110 | check_curl_LDADD = $(NETLIBS) $(LIBCURLLIBS) $(SSLOBJS) $(URIPARSERLIBS) picohttpparser/libpicohttpparser.a | 136 | check_curl_LDADD = $(NETLIBS) $(LIBCURLLIBS) $(SSLOBJS) $(URIPARSERLIBS) picohttpparser/libpicohttpparser.a |
| 137 | check_curl_SOURCES = check_curl.c check_curl.d/check_curl_helpers.c | ||
| 111 | check_dbi_LDADD = $(NETLIBS) $(DBILIBS) | 138 | check_dbi_LDADD = $(NETLIBS) $(DBILIBS) |
| 112 | check_dig_LDADD = $(NETLIBS) | 139 | check_dig_LDADD = $(NETLIBS) |
| 113 | check_disk_LDADD = $(BASEOBJS) | 140 | check_disk_LDADD = $(BASEOBJS) |
| 141 | check_disk_SOURCES = check_disk.c check_disk.d/utils_disk.c | ||
| 114 | check_dns_LDADD = $(NETLIBS) | 142 | check_dns_LDADD = $(NETLIBS) |
| 115 | check_dummy_LDADD = $(BASEOBJS) | 143 | check_dummy_LDADD = $(BASEOBJS) |
| 116 | check_fping_LDADD = $(NETLIBS) | 144 | check_fping_LDADD = $(NETLIBS) |
| @@ -128,16 +156,16 @@ check_mysql_query_CFLAGS = $(AM_CFLAGS) $(MYSQLCFLAGS) | |||
| 128 | check_mysql_query_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) | 156 | check_mysql_query_CPPFLAGS = $(AM_CPPFLAGS) $(MYSQLINCLUDE) |
| 129 | check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) | 157 | check_mysql_query_LDADD = $(NETLIBS) $(MYSQLLIBS) |
| 130 | check_nagios_LDADD = $(BASEOBJS) | 158 | check_nagios_LDADD = $(BASEOBJS) |
| 131 | check_nt_LDADD = $(NETLIBS) | ||
| 132 | check_ntp_LDADD = $(NETLIBS) $(MATHLIBS) | ||
| 133 | check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) | 159 | check_ntp_peer_LDADD = $(NETLIBS) $(MATHLIBS) |
| 134 | check_nwstat_LDADD = $(NETLIBS) | ||
| 135 | check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) | 160 | check_pgsql_LDADD = $(NETLIBS) $(PGLIBS) |
| 136 | check_ping_LDADD = $(NETLIBS) | 161 | check_ping_LDADD = $(NETLIBS) |
| 137 | check_procs_LDADD = $(BASEOBJS) | 162 | check_procs_LDADD = $(BASEOBJS) |
| 138 | check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS) | 163 | check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS) |
| 139 | check_real_LDADD = $(NETLIBS) | 164 | check_real_LDADD = $(NETLIBS) |
| 165 | check_snmp_SOURCES = check_snmp.c check_snmp.d/check_snmp_helpers.c | ||
| 140 | check_snmp_LDADD = $(BASEOBJS) | 166 | check_snmp_LDADD = $(BASEOBJS) |
| 167 | check_snmp_LDFLAGS = $(AM_LDFLAGS) `net-snmp-config --libs` | ||
| 168 | check_snmp_CFLAGS = $(AM_CFLAGS) `net-snmp-config --cflags` | ||
| 141 | check_smtp_LDADD = $(SSLOBJS) | 169 | check_smtp_LDADD = $(SSLOBJS) |
| 142 | check_ssh_LDADD = $(NETLIBS) | 170 | check_ssh_LDADD = $(NETLIBS) |
| 143 | check_swap_SOURCES = check_swap.c check_swap.d/swap.c | 171 | check_swap_SOURCES = check_swap.c check_swap.d/swap.c |
| @@ -146,6 +174,7 @@ check_tcp_LDADD = $(SSLOBJS) | |||
| 146 | check_time_LDADD = $(NETLIBS) | 174 | check_time_LDADD = $(NETLIBS) |
| 147 | check_ntp_time_LDADD = $(NETLIBS) $(MATHLIBS) | 175 | check_ntp_time_LDADD = $(NETLIBS) $(MATHLIBS) |
| 148 | check_ups_LDADD = $(NETLIBS) | 176 | check_ups_LDADD = $(NETLIBS) |
| 177 | check_users_SOURCES = check_users.c check_users.d/users.c | ||
| 149 | check_users_LDADD = $(BASEOBJS) $(WTSAPI32LIBS) $(SYSTEMDLIBS) | 178 | check_users_LDADD = $(BASEOBJS) $(WTSAPI32LIBS) $(SYSTEMDLIBS) |
| 150 | check_by_ssh_LDADD = $(NETLIBS) | 179 | check_by_ssh_LDADD = $(NETLIBS) |
| 151 | check_ide_smart_LDADD = $(BASEOBJS) | 180 | check_ide_smart_LDADD = $(BASEOBJS) |
| @@ -158,6 +187,10 @@ endif | |||
| 158 | 187 | ||
| 159 | tests_test_check_swap_LDADD = $(BASEOBJS) $(tap_ldflags) -ltap | 188 | tests_test_check_swap_LDADD = $(BASEOBJS) $(tap_ldflags) -ltap |
| 160 | tests_test_check_swap_SOURCES = tests/test_check_swap.c check_swap.d/swap.c | 189 | tests_test_check_swap_SOURCES = tests/test_check_swap.c check_swap.d/swap.c |
| 190 | tests_test_check_snmp_LDADD = $(BASEOBJS) $(tap_ldflags) -ltap | ||
| 191 | tests_test_check_snmp_SOURCES = tests/test_check_snmp.c check_snmp.d/check_snmp_helpers.c | ||
| 192 | tests_test_check_disk_LDADD = $(BASEOBJS) $(tap_ldflags) check_disk.d/utils_disk.c -ltap | ||
| 193 | tests_test_check_disk_SOURCES = tests/test_check_disk.c | ||
| 161 | 194 | ||
| 162 | ############################################################################## | 195 | ############################################################################## |
| 163 | # secondary dependencies | 196 | # secondary dependencies |
diff --git a/plugins/check_apt.c b/plugins/check_apt.c index e840184b..9ed5b6cf 100644 --- a/plugins/check_apt.c +++ b/plugins/check_apt.c | |||
| @@ -29,31 +29,33 @@ | |||
| 29 | * | 29 | * |
| 30 | *****************************************************************************/ | 30 | *****************************************************************************/ |
| 31 | 31 | ||
| 32 | #include "states.h" | 32 | #include "perfdata.h" |
| 33 | const char *progname = "check_apt"; | 33 | const char *progname = "check_apt"; |
| 34 | const char *copyright = "2006-2024"; | 34 | const char *copyright = "2006-2024"; |
| 35 | const char *email = "devel@monitoring-plugins.org"; | 35 | const char *email = "devel@monitoring-plugins.org"; |
| 36 | 36 | ||
| 37 | #include "states.h" | ||
| 38 | #include "output.h" | ||
| 37 | #include "common.h" | 39 | #include "common.h" |
| 38 | #include "runcmd.h" | 40 | #include "runcmd.h" |
| 39 | #include "utils.h" | 41 | #include "utils.h" |
| 40 | #include "regex.h" | 42 | #include "regex.h" |
| 41 | #include "check_apt.d/config.h" | 43 | #include "check_apt.d/config.h" |
| 42 | 44 | ||
| 43 | /* Character for hidden input file option (for testing). */ | ||
| 44 | #define INPUT_FILE_OPT CHAR_MAX + 1 | ||
| 45 | /* the default opts can be overridden via the cmdline */ | 45 | /* the default opts can be overridden via the cmdline */ |
| 46 | #define UPGRADE_DEFAULT_OPTS "-o 'Debug::NoLocking=true' -s -qq" | 46 | const char *UPGRADE_DEFAULT_OPTS = "-o 'Debug::NoLocking=true' -s -qq"; |
| 47 | #define UPDATE_DEFAULT_OPTS "-q" | 47 | const char *UPDATE_DEFAULT_OPTS = "-q"; |
| 48 | |||
| 48 | /* until i commit the configure.in patch which gets this, i'll define | 49 | /* until i commit the configure.in patch which gets this, i'll define |
| 49 | * it here as well */ | 50 | * it here as well */ |
| 50 | #ifndef PATH_TO_APTGET | 51 | #ifndef PATH_TO_APTGET |
| 51 | # define PATH_TO_APTGET "/usr/bin/apt-get" | 52 | # define PATH_TO_APTGET "/usr/bin/apt-get" |
| 52 | #endif /* PATH_TO_APTGET */ | 53 | #endif /* PATH_TO_APTGET */ |
| 54 | |||
| 53 | /* String found at the beginning of the apt output lines we're interested in */ | 55 | /* String found at the beginning of the apt output lines we're interested in */ |
| 54 | #define PKGINST_PREFIX "Inst " | 56 | const char *PKGINST_PREFIX = "Inst "; |
| 55 | /* the RE that catches security updates */ | 57 | /* the RE that catches security updates */ |
| 56 | #define SECURITY_RE "^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)" | 58 | const char *SECURITY_RE = "^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)"; |
| 57 | 59 | ||
| 58 | /* some standard functions */ | 60 | /* some standard functions */ |
| 59 | typedef struct { | 61 | typedef struct { |
| @@ -66,20 +68,28 @@ void print_usage(void); | |||
| 66 | 68 | ||
| 67 | /* construct the appropriate apt-get cmdline */ | 69 | /* construct the appropriate apt-get cmdline */ |
| 68 | static char *construct_cmdline(upgrade_type /*u*/, const char * /*opts*/); | 70 | static char *construct_cmdline(upgrade_type /*u*/, const char * /*opts*/); |
| 71 | |||
| 69 | /* run an apt-get update */ | 72 | /* run an apt-get update */ |
| 70 | static int run_update(char * /*update_opts*/); | 73 | typedef struct { |
| 74 | mp_subcheck sc; | ||
| 75 | bool stderr_warning; | ||
| 76 | bool exec_warning; | ||
| 77 | } run_update_result; | ||
| 78 | static run_update_result run_update(char *update_opts); | ||
| 71 | 79 | ||
| 72 | typedef struct { | 80 | typedef struct { |
| 73 | int errorcode; | 81 | int errorcode; |
| 74 | int package_count; | 82 | size_t package_count; |
| 75 | int security_package_count; | 83 | size_t security_package_count; |
| 76 | char **packages_list; | 84 | char **packages_list; |
| 77 | char **secpackages_list; | 85 | char **secpackages_list; |
| 86 | bool exec_warning; | ||
| 78 | } run_upgrade_result; | 87 | } run_upgrade_result; |
| 79 | 88 | ||
| 80 | /* run an apt-get upgrade */ | 89 | /* run an apt-get upgrade */ |
| 81 | run_upgrade_result run_upgrade(upgrade_type upgrade, const char *do_include, const char *do_exclude, const char *do_critical, | 90 | run_upgrade_result run_upgrade(upgrade_type upgrade, const char *do_include, const char *do_exclude, |
| 82 | const char *upgrade_opts, const char *input_filename); | 91 | const char *do_critical, const char *upgrade_opts, |
| 92 | const char *input_filename); | ||
| 83 | 93 | ||
| 84 | /* add another clause to a regexp */ | 94 | /* add another clause to a regexp */ |
| 85 | static char *add_to_regexp(char * /*expr*/, const char * /*next*/); | 95 | static char *add_to_regexp(char * /*expr*/, const char * /*next*/); |
| @@ -107,6 +117,10 @@ int main(int argc, char **argv) { | |||
| 107 | 117 | ||
| 108 | const check_apt_config config = tmp_config.config; | 118 | const check_apt_config config = tmp_config.config; |
| 109 | 119 | ||
| 120 | if (config.output_format_is_set) { | ||
| 121 | mp_set_format(config.output_format); | ||
| 122 | } | ||
| 123 | |||
| 110 | /* Set signal handling and alarm timeout */ | 124 | /* Set signal handling and alarm timeout */ |
| 111 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 125 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { |
| 112 | usage_va(_("Cannot catch SIGALRM")); | 126 | usage_va(_("Cannot catch SIGALRM")); |
| @@ -115,55 +129,91 @@ int main(int argc, char **argv) { | |||
| 115 | /* handle timeouts gracefully... */ | 129 | /* handle timeouts gracefully... */ |
| 116 | alarm(timeout_interval); | 130 | alarm(timeout_interval); |
| 117 | 131 | ||
| 118 | mp_state_enum result = STATE_UNKNOWN; | 132 | mp_check overall = mp_check_init(); |
| 119 | /* if they want to run apt-get update first... */ | 133 | /* if they want to run apt-get update first... */ |
| 120 | if (config.do_update) { | 134 | if (config.do_update) { |
| 121 | result = run_update(config.update_opts); | 135 | run_update_result update_result = run_update(config.update_opts); |
| 136 | |||
| 137 | mp_add_subcheck_to_check(&overall, update_result.sc); | ||
| 122 | } | 138 | } |
| 123 | 139 | ||
| 124 | /* apt-get upgrade */ | 140 | /* apt-get upgrade */ |
| 125 | run_upgrade_result upgrad_res = | 141 | run_upgrade_result upgrad_res = |
| 126 | run_upgrade(config.upgrade, config.do_include, config.do_exclude, config.do_critical, config.upgrade_opts, config.input_filename); | 142 | run_upgrade(config.upgrade, config.do_include, config.do_exclude, config.do_critical, |
| 143 | config.upgrade_opts, config.input_filename); | ||
| 144 | |||
| 145 | mp_subcheck sc_run_upgrade = mp_subcheck_init(); | ||
| 146 | if (upgrad_res.errorcode == OK) { | ||
| 147 | sc_run_upgrade = mp_set_subcheck_state(sc_run_upgrade, STATE_OK); | ||
| 148 | } | ||
| 149 | xasprintf(&sc_run_upgrade.output, "Executed apt upgrade (dry run)"); | ||
| 127 | 150 | ||
| 128 | result = max_state(result, upgrad_res.errorcode); | 151 | mp_add_subcheck_to_check(&overall, sc_run_upgrade); |
| 129 | int packages_available = upgrad_res.package_count; | 152 | |
| 130 | int sec_count = upgrad_res.security_package_count; | 153 | size_t packages_available = upgrad_res.package_count; |
| 154 | size_t number_of_security_updates = upgrad_res.security_package_count; | ||
| 131 | char **packages_list = upgrad_res.packages_list; | 155 | char **packages_list = upgrad_res.packages_list; |
| 132 | char **secpackages_list = upgrad_res.secpackages_list; | 156 | char **secpackages_list = upgrad_res.secpackages_list; |
| 133 | 157 | ||
| 134 | if (sec_count > 0) { | 158 | mp_perfdata pd_security_updates = perfdata_init(); |
| 135 | result = max_state(result, STATE_CRITICAL); | 159 | pd_security_updates.value = mp_create_pd_value(number_of_security_updates); |
| 136 | } else if (packages_available >= config.packages_warning && !config.only_critical) { | 160 | pd_security_updates.label = "critical_updates"; |
| 137 | result = max_state(result, STATE_WARNING); | 161 | |
| 138 | } else if (result > STATE_UNKNOWN) { | 162 | mp_subcheck sc_security_updates = mp_subcheck_init(); |
| 139 | result = STATE_UNKNOWN; | 163 | xasprintf(&sc_security_updates.output, "Security updates available: %zu", |
| 164 | number_of_security_updates); | ||
| 165 | mp_add_perfdata_to_subcheck(&sc_security_updates, pd_security_updates); | ||
| 166 | |||
| 167 | if (number_of_security_updates > 0) { | ||
| 168 | sc_security_updates = mp_set_subcheck_state(sc_security_updates, STATE_CRITICAL); | ||
| 169 | } else { | ||
| 170 | sc_security_updates = mp_set_subcheck_state(sc_security_updates, STATE_OK); | ||
| 140 | } | 171 | } |
| 141 | 172 | ||
| 142 | printf(_("APT %s: %d packages available for %s (%d critical updates). %s%s%s%s|available_upgrades=%d;;;0 critical_updates=%d;;;0\n"), | 173 | mp_perfdata pd_other_updates = perfdata_init(); |
| 143 | state_text(result), packages_available, (config.upgrade == DIST_UPGRADE) ? "dist-upgrade" : "upgrade", sec_count, | 174 | pd_other_updates.value = mp_create_pd_value(packages_available); |
| 144 | (stderr_warning) ? " warnings detected" : "", (stderr_warning && exec_warning) ? "," : "", | 175 | pd_other_updates.label = "available_upgrades"; |
| 145 | (exec_warning) ? " errors detected" : "", (stderr_warning || exec_warning) ? "." : "", packages_available, sec_count); | 176 | |
| 177 | mp_subcheck sc_other_updates = mp_subcheck_init(); | ||
| 178 | |||
| 179 | xasprintf(&sc_other_updates.output, "Updates available: %zu", packages_available); | ||
| 180 | sc_other_updates = mp_set_subcheck_default_state(sc_other_updates, STATE_OK); | ||
| 181 | mp_add_perfdata_to_subcheck(&sc_other_updates, pd_other_updates); | ||
| 182 | |||
| 183 | if (packages_available >= config.packages_warning && !config.only_critical) { | ||
| 184 | sc_other_updates = mp_set_subcheck_state(sc_other_updates, STATE_WARNING); | ||
| 185 | } | ||
| 146 | 186 | ||
| 147 | if (config.list) { | 187 | if (config.list) { |
| 148 | qsort(secpackages_list, sec_count, sizeof(char *), cmpstringp); | 188 | qsort(secpackages_list, number_of_security_updates, sizeof(char *), cmpstringp); |
| 149 | qsort(packages_list, packages_available - sec_count, sizeof(char *), cmpstringp); | 189 | qsort(packages_list, packages_available - number_of_security_updates, sizeof(char *), |
| 190 | cmpstringp); | ||
| 150 | 191 | ||
| 151 | for (int i = 0; i < sec_count; i++) { | 192 | for (size_t i = 0; i < number_of_security_updates; i++) { |
| 152 | printf("%s (security)\n", secpackages_list[i]); | 193 | xasprintf(&sc_security_updates.output, "%s\n%s (security)", sc_security_updates.output, |
| 194 | secpackages_list[i]); | ||
| 153 | } | 195 | } |
| 154 | 196 | ||
| 155 | if (!config.only_critical) { | 197 | if (!config.only_critical) { |
| 156 | for (int i = 0; i < packages_available - sec_count; i++) { | 198 | for (size_t i = 0; i < packages_available - number_of_security_updates; i++) { |
| 157 | printf("%s\n", packages_list[i]); | 199 | xasprintf(&sc_other_updates.output, "%s\n%s", sc_other_updates.output, |
| 200 | packages_list[i]); | ||
| 158 | } | 201 | } |
| 159 | } | 202 | } |
| 160 | } | 203 | } |
| 204 | mp_add_subcheck_to_check(&overall, sc_security_updates); | ||
| 205 | mp_add_subcheck_to_check(&overall, sc_other_updates); | ||
| 161 | 206 | ||
| 162 | return result; | 207 | mp_exit(overall); |
| 163 | } | 208 | } |
| 164 | 209 | ||
| 165 | /* process command-line arguments */ | 210 | /* process command-line arguments */ |
| 166 | check_apt_config_wrapper process_arguments(int argc, char **argv) { | 211 | check_apt_config_wrapper process_arguments(int argc, char **argv) { |
| 212 | enum { | ||
| 213 | /* Character for hidden input file option (for testing). */ | ||
| 214 | INPUT_FILE_OPT = CHAR_MAX + 1, | ||
| 215 | output_format_index, | ||
| 216 | }; | ||
| 167 | static struct option longopts[] = {{"version", no_argument, 0, 'V'}, | 217 | static struct option longopts[] = {{"version", no_argument, 0, 'V'}, |
| 168 | {"help", no_argument, 0, 'h'}, | 218 | {"help", no_argument, 0, 'h'}, |
| 169 | {"verbose", no_argument, 0, 'v'}, | 219 | {"verbose", no_argument, 0, 'v'}, |
| @@ -179,6 +229,7 @@ check_apt_config_wrapper process_arguments(int argc, char **argv) { | |||
| 179 | {"only-critical", no_argument, 0, 'o'}, | 229 | {"only-critical", no_argument, 0, 'o'}, |
| 180 | {"input-file", required_argument, 0, INPUT_FILE_OPT}, | 230 | {"input-file", required_argument, 0, INPUT_FILE_OPT}, |
| 181 | {"packages-warning", required_argument, 0, 'w'}, | 231 | {"packages-warning", required_argument, 0, 'w'}, |
| 232 | {"output-format", required_argument, 0, output_format_index}, | ||
| 182 | {0, 0, 0, 0}}; | 233 | {0, 0, 0, 0}}; |
| 183 | 234 | ||
| 184 | check_apt_config_wrapper result = { | 235 | check_apt_config_wrapper result = { |
| @@ -257,6 +308,18 @@ check_apt_config_wrapper process_arguments(int argc, char **argv) { | |||
| 257 | case 'w': | 308 | case 'w': |
| 258 | result.config.packages_warning = atoi(optarg); | 309 | result.config.packages_warning = atoi(optarg); |
| 259 | break; | 310 | break; |
| 311 | case output_format_index: { | ||
| 312 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 313 | if (!parser.parsing_success) { | ||
| 314 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 315 | printf("Invalid output format: %s\n", optarg); | ||
| 316 | exit(STATE_UNKNOWN); | ||
| 317 | } | ||
| 318 | |||
| 319 | result.config.output_format_is_set = true; | ||
| 320 | result.config.output_format = parser.output_format; | ||
| 321 | break; | ||
| 322 | } | ||
| 260 | default: | 323 | default: |
| 261 | /* print short usage statement if args not parsable */ | 324 | /* print short usage statement if args not parsable */ |
| 262 | usage5(); | 325 | usage5(); |
| @@ -267,37 +330,38 @@ check_apt_config_wrapper process_arguments(int argc, char **argv) { | |||
| 267 | } | 330 | } |
| 268 | 331 | ||
| 269 | /* run an apt-get upgrade */ | 332 | /* run an apt-get upgrade */ |
| 270 | run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_include, const char *do_exclude, const char *do_critical, | 333 | run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_include, |
| 334 | const char *do_exclude, const char *do_critical, | ||
| 271 | const char *upgrade_opts, const char *input_filename) { | 335 | const char *upgrade_opts, const char *input_filename) { |
| 272 | regex_t ereg; | 336 | regex_t exclude_regex; |
| 273 | /* initialize ereg as it is possible it is printed while uninitialized */ | 337 | /* initialize ereg as it is possible it is printed while uninitialized */ |
| 274 | memset(&ereg, '\0', sizeof(ereg.buffer)); | 338 | memset(&exclude_regex, '\0', sizeof(exclude_regex.buffer)); |
| 275 | 339 | ||
| 276 | run_upgrade_result result = { | 340 | run_upgrade_result result = { |
| 277 | .errorcode = STATE_UNKNOWN, | 341 | .errorcode = OK, |
| 278 | }; | 342 | }; |
| 279 | 343 | ||
| 280 | if (upgrade == NO_UPGRADE) { | 344 | if (upgrade == NO_UPGRADE) { |
| 281 | result.errorcode = STATE_OK; | 345 | result.errorcode = OK; |
| 282 | return result; | 346 | return result; |
| 283 | } | 347 | } |
| 284 | 348 | ||
| 285 | int regres = 0; | 349 | int regres = 0; |
| 286 | regex_t ireg; | 350 | regex_t include_regex; |
| 287 | char rerrbuf[64]; | 351 | char rerrbuf[64]; |
| 288 | /* compile the regexps */ | 352 | /* compile the regexps */ |
| 289 | if (do_include != NULL) { | 353 | if (do_include != NULL) { |
| 290 | regres = regcomp(&ireg, do_include, REG_EXTENDED); | 354 | regres = regcomp(&include_regex, do_include, REG_EXTENDED); |
| 291 | if (regres != 0) { | 355 | if (regres != 0) { |
| 292 | regerror(regres, &ireg, rerrbuf, 64); | 356 | regerror(regres, &include_regex, rerrbuf, 64); |
| 293 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); | 357 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); |
| 294 | } | 358 | } |
| 295 | } | 359 | } |
| 296 | 360 | ||
| 297 | if (do_exclude != NULL) { | 361 | if (do_exclude != NULL) { |
| 298 | regres = regcomp(&ereg, do_exclude, REG_EXTENDED); | 362 | regres = regcomp(&exclude_regex, do_exclude, REG_EXTENDED); |
| 299 | if (regres != 0) { | 363 | if (regres != 0) { |
| 300 | regerror(regres, &ereg, rerrbuf, 64); | 364 | regerror(regres, &exclude_regex, rerrbuf, 64); |
| 301 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); | 365 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); |
| 302 | } | 366 | } |
| 303 | } | 367 | } |
| @@ -306,12 +370,12 @@ run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_includ | |||
| 306 | const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE; | 370 | const char *crit_ptr = (do_critical != NULL) ? do_critical : SECURITY_RE; |
| 307 | regres = regcomp(&sreg, crit_ptr, REG_EXTENDED); | 371 | regres = regcomp(&sreg, crit_ptr, REG_EXTENDED); |
| 308 | if (regres != 0) { | 372 | if (regres != 0) { |
| 309 | regerror(regres, &ereg, rerrbuf, 64); | 373 | regerror(regres, &exclude_regex, rerrbuf, 64); |
| 310 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); | 374 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); |
| 311 | } | 375 | } |
| 312 | 376 | ||
| 313 | struct output chld_out; | 377 | output chld_out; |
| 314 | struct output chld_err; | 378 | output chld_err; |
| 315 | char *cmdline = NULL; | 379 | char *cmdline = NULL; |
| 316 | cmdline = construct_cmdline(upgrade, upgrade_opts); | 380 | cmdline = construct_cmdline(upgrade, upgrade_opts); |
| 317 | if (input_filename != NULL) { | 381 | if (input_filename != NULL) { |
| @@ -322,13 +386,12 @@ run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_includ | |||
| 322 | result.errorcode = np_runcmd(cmdline, &chld_out, &chld_err, 0); | 386 | result.errorcode = np_runcmd(cmdline, &chld_out, &chld_err, 0); |
| 323 | } | 387 | } |
| 324 | 388 | ||
| 325 | /* apt-get upgrade only changes exit status if there is an | 389 | // apt-get upgrade only changes exit status if there is an |
| 326 | * internal error when run in dry-run mode. therefore we will | 390 | // internal error when run in dry-run mode. |
| 327 | * treat such an error as UNKNOWN */ | 391 | if (result.errorcode != 0) { |
| 328 | if (result.errorcode != STATE_OK) { | 392 | result.exec_warning = true; |
| 329 | exec_warning = 1; | 393 | result.errorcode = ERROR; |
| 330 | result.errorcode = STATE_UNKNOWN; | 394 | // fprintf(stderr, _("'%s' exited with non-zero status.\n"), cmdline); |
| 331 | fprintf(stderr, _("'%s' exited with non-zero status.\n"), cmdline); | ||
| 332 | } | 395 | } |
| 333 | 396 | ||
| 334 | char **pkglist = malloc(sizeof(char *) * chld_out.lines); | 397 | char **pkglist = malloc(sizeof(char *) * chld_out.lines); |
| @@ -349,27 +412,31 @@ run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_includ | |||
| 349 | * we may need to switch to the --print-uris output format, | 412 | * we may need to switch to the --print-uris output format, |
| 350 | * in which case the logic here will slightly change. | 413 | * in which case the logic here will slightly change. |
| 351 | */ | 414 | */ |
| 352 | int package_counter = 0; | 415 | size_t package_counter = 0; |
| 353 | int security_package_counter = 0; | 416 | size_t security_package_counter = 0; |
| 354 | for (size_t i = 0; i < chld_out.lines; i++) { | 417 | for (size_t i = 0; i < chld_out.lines; i++) { |
| 355 | if (verbose) { | 418 | if (verbose) { |
| 356 | printf("%s\n", chld_out.line[i]); | 419 | printf("%s\n", chld_out.line[i]); |
| 357 | } | 420 | } |
| 421 | |||
| 358 | /* if it is a package we care about */ | 422 | /* if it is a package we care about */ |
| 359 | if (strncmp(PKGINST_PREFIX, chld_out.line[i], strlen(PKGINST_PREFIX)) == 0 && | 423 | if (strncmp(PKGINST_PREFIX, chld_out.line[i], strlen(PKGINST_PREFIX)) == 0 && |
| 360 | (do_include == NULL || regexec(&ireg, chld_out.line[i], 0, NULL, 0) == 0)) { | 424 | (do_include == NULL || regexec(&include_regex, chld_out.line[i], 0, NULL, 0) == 0)) { |
| 361 | /* if we're not excluding, or it's not in the | 425 | /* if we're not excluding, or it's not in the |
| 362 | * list of stuff to exclude */ | 426 | * list of stuff to exclude */ |
| 363 | if (do_exclude == NULL || regexec(&ereg, chld_out.line[i], 0, NULL, 0) != 0) { | 427 | if (do_exclude == NULL || regexec(&exclude_regex, chld_out.line[i], 0, NULL, 0) != 0) { |
| 364 | package_counter++; | 428 | package_counter++; |
| 365 | if (regexec(&sreg, chld_out.line[i], 0, NULL, 0) == 0) { | 429 | if (regexec(&sreg, chld_out.line[i], 0, NULL, 0) == 0) { |
| 366 | security_package_counter++; | 430 | security_package_counter++; |
| 431 | |||
| 367 | if (verbose) { | 432 | if (verbose) { |
| 368 | printf("*"); | 433 | printf("*"); |
| 369 | } | 434 | } |
| 435 | |||
| 370 | (secpkglist)[security_package_counter - 1] = pkg_name(chld_out.line[i]); | 436 | (secpkglist)[security_package_counter - 1] = pkg_name(chld_out.line[i]); |
| 371 | } else { | 437 | } else { |
| 372 | (pkglist)[package_counter - security_package_counter - 1] = pkg_name(chld_out.line[i]); | 438 | (pkglist)[package_counter - security_package_counter - 1] = |
| 439 | pkg_name(chld_out.line[i]); | ||
| 373 | } | 440 | } |
| 374 | if (verbose) { | 441 | if (verbose) { |
| 375 | printf("*%s\n", chld_out.line[i]); | 442 | printf("*%s\n", chld_out.line[i]); |
| @@ -377,6 +444,7 @@ run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_includ | |||
| 377 | } | 444 | } |
| 378 | } | 445 | } |
| 379 | } | 446 | } |
| 447 | |||
| 380 | result.package_count = package_counter; | 448 | result.package_count = package_counter; |
| 381 | result.security_package_count = security_package_counter; | 449 | result.security_package_count = security_package_counter; |
| 382 | result.packages_list = pkglist; | 450 | result.packages_list = pkglist; |
| @@ -385,41 +453,55 @@ run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_includ | |||
| 385 | /* If we get anything on stderr, at least set warning */ | 453 | /* If we get anything on stderr, at least set warning */ |
| 386 | if (input_filename == NULL && chld_err.buflen) { | 454 | if (input_filename == NULL && chld_err.buflen) { |
| 387 | stderr_warning = true; | 455 | stderr_warning = true; |
| 388 | result.errorcode = max_state(result.errorcode, STATE_WARNING); | 456 | result.errorcode = ERROR; |
| 457 | |||
| 389 | if (verbose) { | 458 | if (verbose) { |
| 390 | for (size_t i = 0; i < chld_err.lines; i++) { | 459 | for (size_t i = 0; i < chld_err.lines; i++) { |
| 391 | fprintf(stderr, "%s\n", chld_err.line[i]); | 460 | fprintf(stderr, "%s\n", chld_err.line[i]); |
| 392 | } | 461 | } |
| 393 | } | 462 | } |
| 394 | } | 463 | } |
| 464 | |||
| 395 | if (do_include != NULL) { | 465 | if (do_include != NULL) { |
| 396 | regfree(&ireg); | 466 | regfree(&include_regex); |
| 397 | } | 467 | } |
| 468 | |||
| 398 | regfree(&sreg); | 469 | regfree(&sreg); |
| 470 | |||
| 399 | if (do_exclude != NULL) { | 471 | if (do_exclude != NULL) { |
| 400 | regfree(&ereg); | 472 | regfree(&exclude_regex); |
| 401 | } | 473 | } |
| 474 | |||
| 402 | free(cmdline); | 475 | free(cmdline); |
| 476 | |||
| 403 | return result; | 477 | return result; |
| 404 | } | 478 | } |
| 405 | 479 | ||
| 406 | /* run an apt-get update (needs root) */ | 480 | /* run an apt-get update (needs root) */ |
| 407 | int run_update(char *update_opts) { | 481 | run_update_result run_update(char *update_opts) { |
| 408 | int result = STATE_UNKNOWN; | ||
| 409 | char *cmdline; | 482 | char *cmdline; |
| 410 | /* run the update */ | 483 | /* run the update */ |
| 411 | cmdline = construct_cmdline(NO_UPGRADE, update_opts); | 484 | cmdline = construct_cmdline(NO_UPGRADE, update_opts); |
| 412 | 485 | ||
| 413 | struct output chld_out; | 486 | run_update_result result = { |
| 414 | struct output chld_err; | 487 | .exec_warning = false, |
| 415 | result = np_runcmd(cmdline, &chld_out, &chld_err, 0); | 488 | .stderr_warning = false, |
| 489 | .sc = mp_subcheck_init(), | ||
| 490 | }; | ||
| 491 | |||
| 492 | result.sc = mp_set_subcheck_default_state(result.sc, STATE_OK); | ||
| 493 | xasprintf(&result.sc.output, "executing '%s' first", cmdline); | ||
| 494 | |||
| 495 | output chld_out; | ||
| 496 | output chld_err; | ||
| 497 | int cmd_error = np_runcmd(cmdline, &chld_out, &chld_err, 0); | ||
| 416 | /* apt-get update changes exit status if it can't fetch packages. | 498 | /* apt-get update changes exit status if it can't fetch packages. |
| 417 | * since we were explicitly asked to do so, this is treated as | 499 | * since we were explicitly asked to do so, this is treated as |
| 418 | * a critical error. */ | 500 | * a critical error. */ |
| 419 | if (result != 0) { | 501 | if (cmd_error != 0) { |
| 420 | exec_warning = true; | 502 | exec_warning = true; |
| 421 | result = STATE_CRITICAL; | 503 | result.sc = mp_set_subcheck_state(result.sc, STATE_CRITICAL); |
| 422 | fprintf(stderr, _("'%s' exited with non-zero status.\n"), cmdline); | 504 | xasprintf(&result.sc.output, _("'%s' exited with non-zero status.\n"), cmdline); |
| 423 | } | 505 | } |
| 424 | 506 | ||
| 425 | if (verbose) { | 507 | if (verbose) { |
| @@ -430,15 +512,18 @@ int run_update(char *update_opts) { | |||
| 430 | 512 | ||
| 431 | /* If we get anything on stderr, at least set warning */ | 513 | /* If we get anything on stderr, at least set warning */ |
| 432 | if (chld_err.buflen) { | 514 | if (chld_err.buflen) { |
| 433 | stderr_warning = 1; | 515 | stderr_warning = true; |
| 434 | result = max_state(result, STATE_WARNING); | 516 | result.sc = mp_set_subcheck_state( |
| 517 | result.sc, max_state(mp_compute_subcheck_state(result.sc), STATE_WARNING)); | ||
| 435 | if (verbose) { | 518 | if (verbose) { |
| 436 | for (size_t i = 0; i < chld_err.lines; i++) { | 519 | for (size_t i = 0; i < chld_err.lines; i++) { |
| 437 | fprintf(stderr, "%s\n", chld_err.line[i]); | 520 | fprintf(stderr, "%s\n", chld_err.line[i]); |
| 438 | } | 521 | } |
| 439 | } | 522 | } |
| 440 | } | 523 | } |
| 524 | |||
| 441 | free(cmdline); | 525 | free(cmdline); |
| 526 | |||
| 442 | return result; | 527 | return result; |
| 443 | } | 528 | } |
| 444 | 529 | ||
| @@ -520,7 +605,7 @@ char *construct_cmdline(upgrade_type upgrade, const char *opts) { | |||
| 520 | break; | 605 | break; |
| 521 | } | 606 | } |
| 522 | 607 | ||
| 523 | int len = 0; | 608 | size_t len = 0; |
| 524 | len += strlen(PATH_TO_APTGET) + 1; /* "/usr/bin/apt-get " */ | 609 | len += strlen(PATH_TO_APTGET) + 1; /* "/usr/bin/apt-get " */ |
| 525 | len += strlen(opts_ptr) + 1; /* "opts " */ | 610 | len += strlen(opts_ptr) + 1; /* "opts " */ |
| 526 | len += strlen(aptcmd) + 1; /* "upgrade\0" */ | 611 | len += strlen(aptcmd) + 1; /* "upgrade\0" */ |
| @@ -558,7 +643,8 @@ void print_help(void) { | |||
| 558 | printf(" %s\n", _("List packages available for upgrade. Packages are printed sorted by")); | 643 | printf(" %s\n", _("List packages available for upgrade. Packages are printed sorted by")); |
| 559 | printf(" %s\n", _("name with security packages listed first.")); | 644 | printf(" %s\n", _("name with security packages listed first.")); |
| 560 | printf(" %s\n", "-i, --include=REGEXP"); | 645 | printf(" %s\n", "-i, --include=REGEXP"); |
| 561 | printf(" %s\n", _("Include only packages matching REGEXP. Can be specified multiple times")); | 646 | printf(" %s\n", |
| 647 | _("Include only packages matching REGEXP. Can be specified multiple times")); | ||
| 562 | printf(" %s\n", _("the values will be combined together. Any packages matching this list")); | 648 | printf(" %s\n", _("the values will be combined together. Any packages matching this list")); |
| 563 | printf(" %s\n", _("cause the plugin to return WARNING status. Others will be ignored.")); | 649 | printf(" %s\n", _("cause the plugin to return WARNING status. Others will be ignored.")); |
| 564 | printf(" %s\n", _("Default is to include all packages.")); | 650 | printf(" %s\n", _("Default is to include all packages.")); |
| @@ -567,7 +653,8 @@ void print_help(void) { | |||
| 567 | printf(" %s\n", _("otherwise be included. Can be specified multiple times; the values")); | 653 | printf(" %s\n", _("otherwise be included. Can be specified multiple times; the values")); |
| 568 | printf(" %s\n", _("will be combined together. Default is to exclude no packages.")); | 654 | printf(" %s\n", _("will be combined together. Default is to exclude no packages.")); |
| 569 | printf(" %s\n", "-c, --critical=REGEXP"); | 655 | printf(" %s\n", "-c, --critical=REGEXP"); |
| 570 | printf(" %s\n", _("If the full package information of any of the upgradable packages match")); | 656 | printf(" %s\n", |
| 657 | _("If the full package information of any of the upgradable packages match")); | ||
| 571 | printf(" %s\n", _("this REGEXP, the plugin will return CRITICAL status. Can be specified")); | 658 | printf(" %s\n", _("this REGEXP, the plugin will return CRITICAL status. Can be specified")); |
| 572 | printf(" %s\n", _("multiple times like above. Default is a regexp matching security")); | 659 | printf(" %s\n", _("multiple times like above. Default is a regexp matching security")); |
| 573 | printf(" %s\n", _("upgrades for Debian and Ubuntu:")); | 660 | printf(" %s\n", _("upgrades for Debian and Ubuntu:")); |
| @@ -576,15 +663,21 @@ void print_help(void) { | |||
| 576 | printf(" %s\n", _("information is compared against the critical list.")); | 663 | printf(" %s\n", _("information is compared against the critical list.")); |
| 577 | printf(" %s\n", "-o, --only-critical"); | 664 | printf(" %s\n", "-o, --only-critical"); |
| 578 | printf(" %s\n", _("Only warn about upgrades matching the critical list. The total number")); | 665 | printf(" %s\n", _("Only warn about upgrades matching the critical list. The total number")); |
| 579 | printf(" %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause")); | 666 | printf(" %s\n", |
| 667 | _("of upgrades will be printed, but any non-critical upgrades will not cause")); | ||
| 580 | printf(" %s\n", _("the plugin to return WARNING status.")); | 668 | printf(" %s\n", _("the plugin to return WARNING status.")); |
| 581 | printf(" %s\n", "-w, --packages-warning"); | 669 | printf(" %s\n", "-w, --packages-warning"); |
| 582 | printf(" %s\n", _("Minimum number of packages available for upgrade to return WARNING status.")); | 670 | printf(" %s\n", |
| 671 | _("Minimum number of packages available for upgrade to return WARNING status.")); | ||
| 583 | printf(" %s\n\n", _("Default is 1 package.")); | 672 | printf(" %s\n\n", _("Default is 1 package.")); |
| 584 | 673 | ||
| 585 | printf("%s\n\n", _("The following options require root privileges and should be used with care:")); | 674 | printf(UT_OUTPUT_FORMAT); |
| 675 | |||
| 676 | printf("%s\n\n", | ||
| 677 | _("The following options require root privileges and should be used with care:")); | ||
| 586 | printf(" %s\n", "-u, --update=OPTS"); | 678 | printf(" %s\n", "-u, --update=OPTS"); |
| 587 | printf(" %s\n", _("First perform an 'apt-get update'. An optional OPTS parameter overrides")); | 679 | printf(" %s\n", |
| 680 | _("First perform an 'apt-get update'. An optional OPTS parameter overrides")); | ||
| 588 | printf(" %s\n", _("the default options. Note: you may also need to adjust the global")); | 681 | printf(" %s\n", _("the default options. Note: you may also need to adjust the global")); |
| 589 | printf(" %s\n", _("timeout (with -t) to prevent the plugin from timing out if apt-get")); | 682 | printf(" %s\n", _("timeout (with -t) to prevent the plugin from timing out if apt-get")); |
| 590 | printf(" %s\n", _("upgrade is expected to take longer than the default timeout.")); | 683 | printf(" %s\n", _("upgrade is expected to take longer than the default timeout.")); |
| @@ -593,8 +686,10 @@ void print_help(void) { | |||
| 593 | printf(" %s\n", _("apt-get will be run with these command line options instead of the")); | 686 | printf(" %s\n", _("apt-get will be run with these command line options instead of the")); |
| 594 | printf(" %s", _("default ")); | 687 | printf(" %s", _("default ")); |
| 595 | printf("(%s).\n", UPGRADE_DEFAULT_OPTS); | 688 | printf("(%s).\n", UPGRADE_DEFAULT_OPTS); |
| 596 | printf(" %s\n", _("Note that you may be required to have root privileges if you do not use")); | 689 | printf(" %s\n", |
| 597 | printf(" %s\n", _("the default options, which will only run a simulation and NOT perform the upgrade")); | 690 | _("Note that you may be required to have root privileges if you do not use")); |
| 691 | printf(" %s\n", | ||
| 692 | _("the default options, which will only run a simulation and NOT perform the upgrade")); | ||
| 598 | printf(" %s\n", "-d, --dist-upgrade=OPTS"); | 693 | printf(" %s\n", "-d, --dist-upgrade=OPTS"); |
| 599 | printf(" %s\n", _("Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS")); | 694 | printf(" %s\n", _("Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS")); |
| 600 | printf(" %s\n", _("can be provided to override the default options.")); | 695 | printf(" %s\n", _("can be provided to override the default options.")); |
diff --git a/plugins/check_apt.d/config.h b/plugins/check_apt.d/config.h index 981f4f42..e4d622f1 100644 --- a/plugins/check_apt.d/config.h +++ b/plugins/check_apt.d/config.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include <stddef.h> | 4 | #include <stddef.h> |
| 5 | #include "../lib/output.h" | ||
| 5 | 6 | ||
| 6 | /* some constants */ | 7 | /* some constants */ |
| 7 | typedef enum { | 8 | typedef enum { |
| @@ -16,7 +17,7 @@ typedef struct { | |||
| 16 | bool only_critical; /* whether to warn about non-critical updates */ | 17 | bool only_critical; /* whether to warn about non-critical updates */ |
| 17 | bool list; /* list packages available for upgrade */ | 18 | bool list; /* list packages available for upgrade */ |
| 18 | /* number of packages available for upgrade to return WARNING status */ | 19 | /* number of packages available for upgrade to return WARNING status */ |
| 19 | int packages_warning; | 20 | size_t packages_warning; |
| 20 | 21 | ||
| 21 | char *upgrade_opts; /* options to override defaults for upgrade */ | 22 | char *upgrade_opts; /* options to override defaults for upgrade */ |
| 22 | char *update_opts; /* options to override defaults for update */ | 23 | char *update_opts; /* options to override defaults for update */ |
| @@ -24,6 +25,9 @@ typedef struct { | |||
| 24 | char *do_exclude; /* regexp to only exclude certain packages */ | 25 | char *do_exclude; /* regexp to only exclude certain packages */ |
| 25 | char *do_critical; /* regexp specifying critical packages */ | 26 | char *do_critical; /* regexp specifying critical packages */ |
| 26 | char *input_filename; /* input filename for testing */ | 27 | char *input_filename; /* input filename for testing */ |
| 28 | |||
| 29 | bool output_format_is_set; | ||
| 30 | mp_output_format output_format; | ||
| 27 | } check_apt_config; | 31 | } check_apt_config; |
| 28 | 32 | ||
| 29 | check_apt_config check_apt_config_init() { | 33 | check_apt_config check_apt_config_init() { |
| @@ -36,6 +40,7 @@ check_apt_config check_apt_config_init() { | |||
| 36 | .do_include = NULL, | 40 | .do_include = NULL, |
| 37 | .do_exclude = NULL, | 41 | .do_exclude = NULL, |
| 38 | .do_critical = NULL, | 42 | .do_critical = NULL, |
| 39 | .input_filename = NULL}; | 43 | .input_filename = NULL, |
| 44 | .output_format_is_set = false}; | ||
| 40 | return tmp; | 45 | return tmp; |
| 41 | } | 46 | } |
diff --git a/plugins/check_by_ssh.c b/plugins/check_by_ssh.c index 2bc38d49..7ffa0ded 100644 --- a/plugins/check_by_ssh.c +++ b/plugins/check_by_ssh.c | |||
| @@ -26,16 +26,17 @@ | |||
| 26 | * | 26 | * |
| 27 | *****************************************************************************/ | 27 | *****************************************************************************/ |
| 28 | 28 | ||
| 29 | const char *progname = "check_by_ssh"; | ||
| 30 | const char *copyright = "2000-2024"; | ||
| 31 | const char *email = "devel@monitoring-plugins.org"; | ||
| 32 | |||
| 33 | #include "common.h" | 29 | #include "common.h" |
| 30 | #include "output.h" | ||
| 34 | #include "utils.h" | 31 | #include "utils.h" |
| 35 | #include "utils_cmd.h" | 32 | #include "utils_cmd.h" |
| 36 | #include "check_by_ssh.d/config.h" | 33 | #include "check_by_ssh.d/config.h" |
| 37 | #include "states.h" | 34 | #include "states.h" |
| 38 | 35 | ||
| 36 | const char *progname = "check_by_ssh"; | ||
| 37 | const char *copyright = "2000-2024"; | ||
| 38 | const char *email = "devel@monitoring-plugins.org"; | ||
| 39 | |||
| 39 | #ifndef NP_MAXARGS | 40 | #ifndef NP_MAXARGS |
| 40 | # define NP_MAXARGS 1024 | 41 | # define NP_MAXARGS 1024 |
| 41 | #endif | 42 | #endif |
| @@ -45,7 +46,8 @@ typedef struct { | |||
| 45 | check_by_ssh_config config; | 46 | check_by_ssh_config config; |
| 46 | } check_by_ssh_config_wrapper; | 47 | } check_by_ssh_config_wrapper; |
| 47 | static check_by_ssh_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | 48 | static check_by_ssh_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 48 | static check_by_ssh_config_wrapper validate_arguments(check_by_ssh_config_wrapper /*config_wrapper*/); | 49 | static check_by_ssh_config_wrapper |
| 50 | validate_arguments(check_by_ssh_config_wrapper /*config_wrapper*/); | ||
| 49 | 51 | ||
| 50 | static command_construct comm_append(command_construct /*cmd*/, const char * /*str*/); | 52 | static command_construct comm_append(command_construct /*cmd*/, const char * /*str*/); |
| 51 | static void print_help(void); | 53 | static void print_help(void); |
| @@ -70,6 +72,10 @@ int main(int argc, char **argv) { | |||
| 70 | 72 | ||
| 71 | const check_by_ssh_config config = tmp_config.config; | 73 | const check_by_ssh_config config = tmp_config.config; |
| 72 | 74 | ||
| 75 | if (config.output_format_is_set) { | ||
| 76 | mp_set_format(config.output_format); | ||
| 77 | } | ||
| 78 | |||
| 73 | /* Set signal handling and alarm timeout */ | 79 | /* Set signal handling and alarm timeout */ |
| 74 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 80 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { |
| 75 | usage_va(_("Cannot catch SIGALRM")); | 81 | usage_va(_("Cannot catch SIGALRM")); |
| @@ -84,59 +90,99 @@ int main(int argc, char **argv) { | |||
| 84 | } | 90 | } |
| 85 | } | 91 | } |
| 86 | 92 | ||
| 87 | output chld_out; | 93 | cmd_run_result child_result = cmd_run_array2(config.cmd.commargv, 0); |
| 88 | output chld_err; | 94 | mp_check overall = mp_check_init(); |
| 89 | mp_state_enum result = cmd_run_array(config.cmd.commargv, &chld_out, &chld_err, 0); | ||
| 90 | 95 | ||
| 91 | /* SSH returns 255 if connection attempt fails; include the first line of error output */ | 96 | /* SSH returns 255 if connection attempt fails; include the first line of error output */ |
| 92 | if (result == 255 && config.unknown_timeout) { | 97 | // we can sadly not detect other SSH errors |
| 93 | printf(_("SSH connection failed: %s\n"), chld_err.lines > 0 ? chld_err.line[0] : "(no error output)"); | 98 | if (child_result.cmd_error_code == 255 && config.unknown_timeout) { |
| 94 | return STATE_UNKNOWN; | 99 | mp_subcheck sc_ssh_execution = mp_subcheck_init(); |
| 100 | xasprintf(&sc_ssh_execution.output, "SSH connection failed: %s", | ||
| 101 | child_result.err.lines > 0 ? child_result.err.line[0] | ||
| 102 | : "(no error output)"); | ||
| 103 | |||
| 104 | sc_ssh_execution = mp_set_subcheck_state(sc_ssh_execution, STATE_UNKNOWN); | ||
| 105 | mp_add_subcheck_to_check(&overall, sc_ssh_execution); | ||
| 106 | mp_exit(overall); | ||
| 95 | } | 107 | } |
| 96 | 108 | ||
| 97 | if (verbose) { | 109 | if (verbose) { |
| 98 | for (size_t i = 0; i < chld_out.lines; i++) { | 110 | for (size_t i = 0; i < child_result.out.lines; i++) { |
| 99 | printf("stdout: %s\n", chld_out.line[i]); | 111 | printf("stdout: %s\n", child_result.out.line[i]); |
| 100 | } | 112 | } |
| 101 | for (size_t i = 0; i < chld_err.lines; i++) { | 113 | for (size_t i = 0; i < child_result.err.lines; i++) { |
| 102 | printf("stderr: %s\n", chld_err.line[i]); | 114 | printf("stderr: %s\n", child_result.err.line[i]); |
| 103 | } | 115 | } |
| 104 | } | 116 | } |
| 105 | 117 | ||
| 106 | size_t skip_stdout = 0; | 118 | size_t skip_stdout = 0; |
| 107 | if (config.skip_stdout == -1) { /* --skip-stdout specified without argument */ | 119 | if (config.skip_stdout) { /* --skip-stdout specified without argument */ |
| 108 | skip_stdout = chld_out.lines; | 120 | skip_stdout = child_result.out.lines; |
| 109 | } else { | 121 | } else { |
| 110 | skip_stdout = config.skip_stdout; | 122 | skip_stdout = config.stdout_lines_to_ignore; |
| 111 | } | 123 | } |
| 112 | 124 | ||
| 113 | size_t skip_stderr = 0; | 125 | size_t skip_stderr = 0; |
| 114 | if (config.skip_stderr == -1) { /* --skip-stderr specified without argument */ | 126 | if (config.skip_stderr) { /* --skip-stderr specified without argument */ |
| 115 | skip_stderr = chld_err.lines; | 127 | skip_stderr = child_result.err.lines; |
| 116 | } else { | 128 | } else { |
| 117 | skip_stderr = config.skip_stderr; | 129 | skip_stderr = config.sterr_lines_to_ignore; |
| 118 | } | 130 | } |
| 119 | 131 | ||
| 120 | /* UNKNOWN or worse if (non-skipped) output found on stderr */ | 132 | /* Allow UNKNOWN or WARNING state for (non-skipped) output found on stderr */ |
| 121 | if (chld_err.lines > (size_t)skip_stderr) { | 133 | if (child_result.err.lines > skip_stderr && |
| 122 | printf(_("Remote command execution failed: %s\n"), chld_err.line[skip_stderr]); | 134 | (config.unknown_on_stderr || config.warn_on_stderr)) { |
| 135 | mp_subcheck sc_stderr = mp_subcheck_init(); | ||
| 136 | xasprintf(&sc_stderr.output, "remote command execution failed: %s", | ||
| 137 | child_result.err.line[skip_stderr]); | ||
| 138 | |||
| 139 | if (config.unknown_on_stderr) { | ||
| 140 | sc_stderr = mp_set_subcheck_state(sc_stderr, STATE_UNKNOWN); | ||
| 141 | } | ||
| 142 | |||
| 123 | if (config.warn_on_stderr) { | 143 | if (config.warn_on_stderr) { |
| 124 | return max_state_alt(result, STATE_WARNING); | 144 | sc_stderr = mp_set_subcheck_state(sc_stderr, STATE_WARNING); |
| 125 | } | 145 | } |
| 126 | return max_state_alt(result, STATE_UNKNOWN); | 146 | |
| 147 | mp_add_subcheck_to_check(&overall, sc_stderr); | ||
| 148 | // TODO still exit here? | ||
| 127 | } | 149 | } |
| 128 | 150 | ||
| 129 | /* this is simple if we're not supposed to be passive. | 151 | /* this is simple if we're not supposed to be passive. |
| 130 | * Wrap up quickly and keep the tricks below */ | 152 | * Wrap up quickly and keep the tricks below */ |
| 131 | if (!config.passive) { | 153 | if (!config.passive) { |
| 132 | if (chld_out.lines > (size_t)skip_stdout) { | 154 | mp_subcheck sc_active_check = mp_subcheck_init(); |
| 133 | for (size_t i = skip_stdout; i < chld_out.lines; i++) { | 155 | xasprintf(&sc_active_check.output, "command stdout:"); |
| 134 | puts(chld_out.line[i]); | 156 | |
| 157 | if (child_result.out.lines > skip_stdout) { | ||
| 158 | for (size_t i = skip_stdout; i < child_result.out.lines; i++) { | ||
| 159 | xasprintf(&sc_active_check.output, "%s\n%s", sc_active_check.output, | ||
| 160 | child_result.out.line[i]); | ||
| 135 | } | 161 | } |
| 136 | } else { | 162 | } else { |
| 137 | printf(_("%s - check_by_ssh: Remote command '%s' returned status %d\n"), state_text(result), config.remotecmd, result); | 163 | xasprintf(&sc_active_check.output, "remote command '%s' returned status %d", |
| 164 | config.remotecmd, child_result.cmd_error_code); | ||
| 138 | } | 165 | } |
| 139 | return result; /* return error status from remote command */ | 166 | |
| 167 | /* return error status from remote command */ | ||
| 168 | |||
| 169 | switch (child_result.cmd_error_code) { | ||
| 170 | case 0: | ||
| 171 | sc_active_check = mp_set_subcheck_state(sc_active_check, STATE_OK); | ||
| 172 | break; | ||
| 173 | case 1: | ||
| 174 | sc_active_check = mp_set_subcheck_state(sc_active_check, STATE_WARNING); | ||
| 175 | break; | ||
| 176 | case 2: | ||
| 177 | sc_active_check = mp_set_subcheck_state(sc_active_check, STATE_CRITICAL); | ||
| 178 | break; | ||
| 179 | default: | ||
| 180 | sc_active_check = mp_set_subcheck_state(sc_active_check, STATE_UNKNOWN); | ||
| 181 | break; | ||
| 182 | } | ||
| 183 | |||
| 184 | mp_add_subcheck_to_check(&overall, sc_active_check); | ||
| 185 | mp_exit(overall); | ||
| 140 | } | 186 | } |
| 141 | 187 | ||
| 142 | /* | 188 | /* |
| @@ -144,62 +190,88 @@ int main(int argc, char **argv) { | |||
| 144 | */ | 190 | */ |
| 145 | 191 | ||
| 146 | /* process output */ | 192 | /* process output */ |
| 147 | FILE *file_pointer = NULL; | 193 | mp_subcheck sc_passive_file = mp_subcheck_init(); |
| 148 | if (!(file_pointer = fopen(config.outputfile, "a"))) { | 194 | FILE *output_file = NULL; |
| 149 | printf(_("SSH WARNING: could not open %s\n"), config.outputfile); | 195 | if (!(output_file = fopen(config.outputfile, "a"))) { |
| 150 | exit(STATE_UNKNOWN); | 196 | xasprintf(&sc_passive_file.output, "could not open %s", config.outputfile); |
| 197 | sc_passive_file = mp_set_subcheck_state(sc_passive_file, STATE_UNKNOWN); | ||
| 198 | |||
| 199 | mp_add_subcheck_to_check(&overall, sc_passive_file); | ||
| 200 | mp_exit(overall); | ||
| 151 | } | 201 | } |
| 152 | 202 | ||
| 203 | xasprintf(&sc_passive_file.output, "opened output file %s", config.outputfile); | ||
| 204 | sc_passive_file = mp_set_subcheck_state(sc_passive_file, STATE_OK); | ||
| 205 | mp_add_subcheck_to_check(&overall, sc_passive_file); | ||
| 206 | |||
| 153 | time_t local_time = time(NULL); | 207 | time_t local_time = time(NULL); |
| 154 | unsigned int commands = 0; | 208 | unsigned int commands = 0; |
| 155 | char *status_text; | 209 | char *status_text; |
| 156 | int cresult; | 210 | int cresult; |
| 157 | for (size_t i = skip_stdout; i < chld_out.lines; i++) { | 211 | mp_subcheck sc_parse_passive = mp_subcheck_init(); |
| 158 | status_text = chld_out.line[i++]; | 212 | for (size_t i = skip_stdout; i < child_result.out.lines; i++) { |
| 159 | if (i == chld_out.lines || strstr(chld_out.line[i], "STATUS CODE: ") == NULL) { | 213 | status_text = child_result.out.line[i++]; |
| 160 | die(STATE_UNKNOWN, _("%s: Error parsing output\n"), progname); | 214 | if (i == child_result.out.lines || |
| 215 | strstr(child_result.out.line[i], "STATUS CODE: ") == NULL) { | ||
| 216 | |||
| 217 | sc_parse_passive = mp_set_subcheck_state(sc_parse_passive, STATE_UNKNOWN); | ||
| 218 | xasprintf(&sc_parse_passive.output, "failed to parse output"); | ||
| 219 | mp_add_subcheck_to_check(&overall, sc_parse_passive); | ||
| 220 | mp_exit(overall); | ||
| 161 | } | 221 | } |
| 162 | 222 | ||
| 163 | if (config.service[commands] && status_text && sscanf(chld_out.line[i], "STATUS CODE: %d", &cresult) == 1) { | 223 | if (config.service[commands] && status_text && |
| 164 | fprintf(file_pointer, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", (int)local_time, config.host_shortname, | 224 | sscanf(child_result.out.line[i], "STATUS CODE: %d", &cresult) == 1) { |
| 165 | config.service[commands++], cresult, status_text); | 225 | fprintf(output_file, "[%d] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n", (int)local_time, |
| 226 | config.host_shortname, config.service[commands++], cresult, status_text); | ||
| 166 | } | 227 | } |
| 167 | } | 228 | } |
| 168 | 229 | ||
| 230 | sc_parse_passive = mp_set_subcheck_state(sc_parse_passive, STATE_OK); | ||
| 231 | xasprintf(&sc_parse_passive.output, "parsed and wrote output"); | ||
| 232 | mp_add_subcheck_to_check(&overall, sc_parse_passive); | ||
| 233 | |||
| 169 | /* Multiple commands and passive checking should always return OK */ | 234 | /* Multiple commands and passive checking should always return OK */ |
| 170 | exit(result); | 235 | mp_exit(overall); |
| 171 | } | 236 | } |
| 172 | 237 | ||
| 173 | /* process command-line arguments */ | 238 | /* process command-line arguments */ |
| 174 | check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { | 239 | check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { |
| 175 | static struct option longopts[] = {{"version", no_argument, 0, 'V'}, | 240 | enum { |
| 176 | {"help", no_argument, 0, 'h'}, | 241 | output_format_index = CHAR_MAX + 1, |
| 177 | {"verbose", no_argument, 0, 'v'}, | 242 | }; |
| 178 | {"fork", no_argument, 0, 'f'}, | 243 | |
| 179 | {"timeout", required_argument, 0, 't'}, | 244 | static struct option longopts[] = { |
| 180 | {"unknown-timeout", no_argument, 0, 'U'}, | 245 | {"version", no_argument, 0, 'V'}, |
| 181 | {"host", required_argument, 0, 'H'}, /* backward compatibility */ | 246 | {"help", no_argument, 0, 'h'}, |
| 182 | {"hostname", required_argument, 0, 'H'}, | 247 | {"verbose", no_argument, 0, 'v'}, |
| 183 | {"port", required_argument, 0, 'p'}, | 248 | {"fork", no_argument, 0, 'f'}, |
| 184 | {"output", required_argument, 0, 'O'}, | 249 | {"timeout", required_argument, 0, 't'}, |
| 185 | {"name", required_argument, 0, 'n'}, | 250 | {"unknown-timeout", no_argument, 0, 'U'}, |
| 186 | {"services", required_argument, 0, 's'}, | 251 | {"host", required_argument, 0, 'H'}, /* backward compatibility */ |
| 187 | {"identity", required_argument, 0, 'i'}, | 252 | {"hostname", required_argument, 0, 'H'}, |
| 188 | {"user", required_argument, 0, 'u'}, | 253 | {"port", required_argument, 0, 'p'}, |
| 189 | {"logname", required_argument, 0, 'l'}, | 254 | {"output", required_argument, 0, 'O'}, |
| 190 | {"command", required_argument, 0, 'C'}, | 255 | {"name", required_argument, 0, 'n'}, |
| 191 | {"skip", optional_argument, 0, 'S'}, /* backwards compatibility */ | 256 | {"services", required_argument, 0, 's'}, |
| 192 | {"skip-stdout", optional_argument, 0, 'S'}, | 257 | {"identity", required_argument, 0, 'i'}, |
| 193 | {"skip-stderr", optional_argument, 0, 'E'}, | 258 | {"user", required_argument, 0, 'u'}, /* backwards compatibility */ |
| 194 | {"warn-on-stderr", no_argument, 0, 'W'}, | 259 | {"logname", required_argument, 0, 'l'}, |
| 195 | {"proto1", no_argument, 0, '1'}, | 260 | {"command", required_argument, 0, 'C'}, |
| 196 | {"proto2", no_argument, 0, '2'}, | 261 | {"skip", optional_argument, 0, 'S'}, /* backwards compatibility */ |
| 197 | {"use-ipv4", no_argument, 0, '4'}, | 262 | {"skip-stdout", optional_argument, 0, 'S'}, |
| 198 | {"use-ipv6", no_argument, 0, '6'}, | 263 | {"skip-stderr", optional_argument, 0, 'E'}, |
| 199 | {"ssh-option", required_argument, 0, 'o'}, | 264 | {"unknown-on-stderr", no_argument, 0, 'e'}, |
| 200 | {"quiet", no_argument, 0, 'q'}, | 265 | {"warn-on-stderr", no_argument, 0, 'W'}, |
| 201 | {"configfile", optional_argument, 0, 'F'}, | 266 | {"proto1", no_argument, 0, '1'}, |
| 202 | {0, 0, 0, 0}}; | 267 | {"proto2", no_argument, 0, '2'}, |
| 268 | {"use-ipv4", no_argument, 0, '4'}, | ||
| 269 | {"use-ipv6", no_argument, 0, '6'}, | ||
| 270 | {"ssh-option", required_argument, 0, 'o'}, | ||
| 271 | {"quiet", no_argument, 0, 'q'}, | ||
| 272 | {"configfile", optional_argument, 0, 'F'}, | ||
| 273 | {"output-format", required_argument, 0, output_format_index}, | ||
| 274 | {0, 0, 0, 0}}; | ||
| 203 | 275 | ||
| 204 | check_by_ssh_config_wrapper result = { | 276 | check_by_ssh_config_wrapper result = { |
| 205 | .errorcode = OK, | 277 | .errorcode = OK, |
| @@ -221,7 +293,8 @@ check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { | |||
| 221 | 293 | ||
| 222 | int option = 0; | 294 | int option = 0; |
| 223 | while (true) { | 295 | while (true) { |
| 224 | int opt_index = getopt_long(argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts, &option); | 296 | int opt_index = |
| 297 | getopt_long(argc, argv, "Vvh1246fqt:UH:O:p:i:u:l:C:S::E::n:s:o:F:", longopts, &option); | ||
| 225 | 298 | ||
| 226 | if (opt_index == -1 || opt_index == EOF) { | 299 | if (opt_index == -1 || opt_index == EOF) { |
| 227 | break; | 300 | break; |
| @@ -266,11 +339,13 @@ check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { | |||
| 266 | char *p2; | 339 | char *p2; |
| 267 | 340 | ||
| 268 | p1 = optarg; | 341 | p1 = optarg; |
| 269 | result.config.service = realloc(result.config.service, (++result.config.number_of_services) * sizeof(char *)); | 342 | result.config.service = realloc(result.config.service, |
| 343 | (++result.config.number_of_services) * sizeof(char *)); | ||
| 270 | while ((p2 = index(p1, ':'))) { | 344 | while ((p2 = index(p1, ':'))) { |
| 271 | *p2 = '\0'; | 345 | *p2 = '\0'; |
| 272 | result.config.service[result.config.number_of_services - 1] = p1; | 346 | result.config.service[result.config.number_of_services - 1] = p1; |
| 273 | result.config.service = realloc(result.config.service, (++result.config.number_of_services) * sizeof(char *)); | 347 | result.config.service = realloc( |
| 348 | result.config.service, (++result.config.number_of_services) * sizeof(char *)); | ||
| 274 | p1 = p2 + 1; | 349 | p1 = p2 + 1; |
| 275 | } | 350 | } |
| 276 | result.config.service[result.config.number_of_services - 1] = p1; | 351 | result.config.service[result.config.number_of_services - 1] = p1; |
| @@ -309,28 +384,39 @@ check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { | |||
| 309 | case 'C': /* Command for remote machine */ | 384 | case 'C': /* Command for remote machine */ |
| 310 | result.config.commands++; | 385 | result.config.commands++; |
| 311 | if (result.config.commands > 1) { | 386 | if (result.config.commands > 1) { |
| 312 | xasprintf(&result.config.remotecmd, "%s;echo STATUS CODE: $?;", result.config.remotecmd); | 387 | xasprintf(&result.config.remotecmd, "%s;echo STATUS CODE: $?;", |
| 388 | result.config.remotecmd); | ||
| 313 | } | 389 | } |
| 314 | xasprintf(&result.config.remotecmd, "%s%s", result.config.remotecmd, optarg); | 390 | xasprintf(&result.config.remotecmd, "%s%s", result.config.remotecmd, optarg); |
| 315 | break; | 391 | break; |
| 316 | case 'S': /* skip n (or all) lines on stdout */ | 392 | case 'S': /* skip n (or all) lines on stdout */ |
| 317 | if (optarg == NULL) { | 393 | if (optarg == NULL) { |
| 318 | result.config.skip_stdout = -1; /* skip all output on stdout */ | 394 | result.config.skip_stdout = true; /* skip all output on stdout */ |
| 395 | |||
| 396 | if (verbose) { | ||
| 397 | printf("Setting the skip_stdout flag\n"); | ||
| 398 | } | ||
| 319 | } else if (!is_integer(optarg)) { | 399 | } else if (!is_integer(optarg)) { |
| 320 | usage_va(_("skip-stdout argument must be an integer")); | 400 | usage_va(_("skip-stdout argument must be an integer")); |
| 321 | } else { | 401 | } else { |
| 322 | result.config.skip_stdout = atoi(optarg); | 402 | result.config.stdout_lines_to_ignore = atoi(optarg); |
| 323 | } | 403 | } |
| 324 | break; | 404 | break; |
| 325 | case 'E': /* skip n (or all) lines on stderr */ | 405 | case 'E': /* skip n (or all) lines on stderr */ |
| 326 | if (optarg == NULL) { | 406 | if (optarg == NULL) { |
| 327 | result.config.skip_stderr = -1; /* skip all output on stderr */ | 407 | result.config.skip_stderr = true; /* skip all output on stderr */ |
| 408 | if (verbose) { | ||
| 409 | printf("Setting the skip_stderr flag\n"); | ||
| 410 | } | ||
| 328 | } else if (!is_integer(optarg)) { | 411 | } else if (!is_integer(optarg)) { |
| 329 | usage_va(_("skip-stderr argument must be an integer")); | 412 | usage_va(_("skip-stderr argument must be an integer")); |
| 330 | } else { | 413 | } else { |
| 331 | result.config.skip_stderr = atoi(optarg); | 414 | result.config.sterr_lines_to_ignore = atoi(optarg); |
| 332 | } | 415 | } |
| 333 | break; | 416 | break; |
| 417 | case 'e': /* exit with unknown if there is an output on stderr */ | ||
| 418 | result.config.unknown_on_stderr = true; | ||
| 419 | break; | ||
| 334 | case 'W': /* exit with warning if there is an output on stderr */ | 420 | case 'W': /* exit with warning if there is an output on stderr */ |
| 335 | result.config.warn_on_stderr = true; | 421 | result.config.warn_on_stderr = true; |
| 336 | break; | 422 | break; |
| @@ -345,6 +431,18 @@ check_by_ssh_config_wrapper process_arguments(int argc, char **argv) { | |||
| 345 | result.config.cmd = comm_append(result.config.cmd, "-F"); | 431 | result.config.cmd = comm_append(result.config.cmd, "-F"); |
| 346 | result.config.cmd = comm_append(result.config.cmd, optarg); | 432 | result.config.cmd = comm_append(result.config.cmd, optarg); |
| 347 | break; | 433 | break; |
| 434 | case output_format_index: { | ||
| 435 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 436 | if (!parser.parsing_success) { | ||
| 437 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 438 | printf("Invalid output format: %s\n", optarg); | ||
| 439 | exit(STATE_UNKNOWN); | ||
| 440 | } | ||
| 441 | |||
| 442 | result.config.output_format_is_set = true; | ||
| 443 | result.config.output_format = parser.output_format; | ||
| 444 | break; | ||
| 445 | } | ||
| 348 | default: /* help */ | 446 | default: /* help */ |
| 349 | usage5(); | 447 | usage5(); |
| 350 | } | 448 | } |
| @@ -396,7 +494,8 @@ command_construct comm_append(command_construct cmd, const char *str) { | |||
| 396 | die(STATE_UNKNOWN, _("%s: Argument limit of %d exceeded\n"), progname, NP_MAXARGS); | 494 | die(STATE_UNKNOWN, _("%s: Argument limit of %d exceeded\n"), progname, NP_MAXARGS); |
| 397 | } | 495 | } |
| 398 | 496 | ||
| 399 | if ((cmd.commargv = (char **)realloc(cmd.commargv, (cmd.commargc + 1) * sizeof(char *))) == NULL) { | 497 | if ((cmd.commargv = (char **)realloc(cmd.commargv, (cmd.commargc + 1) * sizeof(char *))) == |
| 498 | NULL) { | ||
| 400 | die(STATE_UNKNOWN, _("Can not (re)allocate 'commargv' buffer\n")); | 499 | die(STATE_UNKNOWN, _("Can not (re)allocate 'commargv' buffer\n")); |
| 401 | } | 500 | } |
| 402 | 501 | ||
| @@ -412,12 +511,18 @@ check_by_ssh_config_wrapper validate_arguments(check_by_ssh_config_wrapper confi | |||
| 412 | return config_wrapper; | 511 | return config_wrapper; |
| 413 | } | 512 | } |
| 414 | 513 | ||
| 415 | if (config_wrapper.config.passive && config_wrapper.config.commands != config_wrapper.config.number_of_services) { | 514 | if (config_wrapper.config.passive && |
| 416 | die(STATE_UNKNOWN, _("%s: In passive mode, you must provide a service name for each command.\n"), progname); | 515 | config_wrapper.config.commands != config_wrapper.config.number_of_services) { |
| 516 | die(STATE_UNKNOWN, | ||
| 517 | _("%s: In passive mode, you must provide a service name for each command.\n"), | ||
| 518 | progname); | ||
| 417 | } | 519 | } |
| 418 | 520 | ||
| 419 | if (config_wrapper.config.passive && config_wrapper.config.host_shortname == NULL) { | 521 | if (config_wrapper.config.passive && config_wrapper.config.host_shortname == NULL) { |
| 420 | die(STATE_UNKNOWN, _("%s: In passive mode, you must provide the host short name from the monitoring configs.\n"), progname); | 522 | die(STATE_UNKNOWN, |
| 523 | _("%s: In passive mode, you must provide the host short name from the monitoring " | ||
| 524 | "configs.\n"), | ||
| 525 | progname); | ||
| 421 | } | 526 | } |
| 422 | 527 | ||
| 423 | return config_wrapper; | 528 | return config_wrapper; |
| @@ -451,10 +556,13 @@ void print_help(void) { | |||
| 451 | printf(" %s\n", _("Ignore all or (if specified) first n lines on STDOUT [optional]")); | 556 | printf(" %s\n", _("Ignore all or (if specified) first n lines on STDOUT [optional]")); |
| 452 | printf(" %s\n", "-E, --skip-stderr[=n]"); | 557 | printf(" %s\n", "-E, --skip-stderr[=n]"); |
| 453 | printf(" %s\n", _("Ignore all or (if specified) first n lines on STDERR [optional]")); | 558 | printf(" %s\n", _("Ignore all or (if specified) first n lines on STDERR [optional]")); |
| 454 | printf(" %s\n", "-W, --warn-on-stderr]"); | 559 | printf(" %s\n", "-e, --unknown-on-stderr"); |
| 455 | printf(" %s\n", _("Exit with an warning, if there is an output on STDERR")); | 560 | printf(" %s\n", _("Exit with UNKNOWN, if there is output on STDERR")); |
| 561 | printf(" %s\n", "-W, --warn-on-stderr"); | ||
| 562 | printf(" %s\n", _("Exit with WARNING, if there is output on STDERR")); | ||
| 456 | printf(" %s\n", "-f"); | 563 | printf(" %s\n", "-f"); |
| 457 | printf(" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always return OK if ssh is executed")); | 564 | printf(" %s\n", _("tells ssh to fork rather than create a tty [optional]. This will always " |
| 565 | "return OK if ssh is executed")); | ||
| 458 | printf(" %s\n", "-C, --command='COMMAND STRING'"); | 566 | printf(" %s\n", "-C, --command='COMMAND STRING'"); |
| 459 | printf(" %s\n", _("command to execute on the remote machine")); | 567 | printf(" %s\n", _("command to execute on the remote machine")); |
| 460 | printf(" %s\n", "-l, --logname=USERNAME"); | 568 | printf(" %s\n", "-l, --logname=USERNAME"); |
| @@ -477,6 +585,7 @@ void print_help(void) { | |||
| 477 | printf(" %s\n", "-U, --unknown-timeout"); | 585 | printf(" %s\n", "-U, --unknown-timeout"); |
| 478 | printf(" %s\n", _("Make connection problems return UNKNOWN instead of CRITICAL")); | 586 | printf(" %s\n", _("Make connection problems return UNKNOWN instead of CRITICAL")); |
| 479 | printf(UT_VERBOSE); | 587 | printf(UT_VERBOSE); |
| 588 | printf(UT_OUTPUT_FORMAT); | ||
| 480 | printf("\n"); | 589 | printf("\n"); |
| 481 | printf(" %s\n", _("The most common mode of use is to refer to a local identity file with")); | 590 | printf(" %s\n", _("The most common mode of use is to refer to a local identity file with")); |
| 482 | printf(" %s\n", _("the '-i' option. In this mode, the identity pair should have a null")); | 591 | printf(" %s\n", _("the '-i' option. In this mode, the identity pair should have a null")); |
| @@ -490,7 +599,8 @@ void print_help(void) { | |||
| 490 | printf(" %s\n", _("all of -O, -s, and -n options (servicelist order must match '-C'options)")); | 599 | printf(" %s\n", _("all of -O, -s, and -n options (servicelist order must match '-C'options)")); |
| 491 | printf("\n"); | 600 | printf("\n"); |
| 492 | printf("%s\n", _("Examples:")); | 601 | printf("%s\n", _("Examples:")); |
| 493 | printf(" %s\n", "$ check_by_ssh -H localhost -n lh -s c1:c2:c3 -C uptime -C uptime -C uptime -O /tmp/foo"); | 602 | printf(" %s\n", "$ check_by_ssh -H localhost -n lh -s c1:c2:c3 -C uptime -C uptime -C " |
| 603 | "uptime -O /tmp/foo"); | ||
| 494 | printf(" %s\n", "$ cat /tmp/foo"); | 604 | printf(" %s\n", "$ cat /tmp/foo"); |
| 495 | printf(" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c1;0; up 2 days"); | 605 | printf(" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c1;0; up 2 days"); |
| 496 | printf(" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c2;0; up 2 days"); | 606 | printf(" %s\n", "[1080933700] PROCESS_SERVICE_CHECK_RESULT;flint;c2;0; up 2 days"); |
| @@ -502,7 +612,7 @@ void print_help(void) { | |||
| 502 | void print_usage(void) { | 612 | void print_usage(void) { |
| 503 | printf("%s\n", _("Usage:")); | 613 | printf("%s\n", _("Usage:")); |
| 504 | printf(" %s -H <host> -C <command> [-fqvU] [-1|-2] [-4|-6]\n" | 614 | printf(" %s -H <host> -C <command> [-fqvU] [-1|-2] [-4|-6]\n" |
| 505 | " [-S [lines]] [-E [lines]] [-W] [-t timeout] [-i identity]\n" | 615 | " [-S [lines]] [-E [lines]] [-e|-W] [-t timeout] [-i identity]\n" |
| 506 | " [-l user] [-n name] [-s servicelist] [-O outputfile]\n" | 616 | " [-l user] [-n name] [-s servicelist] [-O outputfile]\n" |
| 507 | " [-p port] [-o ssh-option] [-F configfile]\n", | 617 | " [-p port] [-o ssh-option] [-F configfile]\n", |
| 508 | progname); | 618 | progname); |
diff --git a/plugins/check_by_ssh.d/config.h b/plugins/check_by_ssh.d/config.h index 05435def..b6a57964 100644 --- a/plugins/check_by_ssh.d/config.h +++ b/plugins/check_by_ssh.d/config.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "output.h" | ||
| 4 | #include <stddef.h> | 5 | #include <stddef.h> |
| 5 | 6 | ||
| 6 | typedef struct { | 7 | typedef struct { |
| @@ -21,11 +22,18 @@ typedef struct { | |||
| 21 | command_construct cmd; | 22 | command_construct cmd; |
| 22 | 23 | ||
| 23 | bool unknown_timeout; | 24 | bool unknown_timeout; |
| 25 | bool unknown_on_stderr; | ||
| 24 | bool warn_on_stderr; | 26 | bool warn_on_stderr; |
| 25 | int skip_stdout; | 27 | bool skip_stdout; |
| 26 | int skip_stderr; | 28 | size_t stdout_lines_to_ignore; |
| 29 | bool skip_stderr; | ||
| 30 | size_t sterr_lines_to_ignore; | ||
| 31 | |||
| 27 | bool passive; | 32 | bool passive; |
| 28 | char *outputfile; | 33 | char *outputfile; |
| 34 | |||
| 35 | bool output_format_is_set; | ||
| 36 | mp_output_format output_format; | ||
| 29 | } check_by_ssh_config; | 37 | } check_by_ssh_config; |
| 30 | 38 | ||
| 31 | check_by_ssh_config check_by_ssh_config_init() { | 39 | check_by_ssh_config check_by_ssh_config_init() { |
| @@ -46,11 +54,18 @@ check_by_ssh_config check_by_ssh_config_init() { | |||
| 46 | }, | 54 | }, |
| 47 | 55 | ||
| 48 | .unknown_timeout = false, | 56 | .unknown_timeout = false, |
| 57 | .unknown_on_stderr = false, | ||
| 49 | .warn_on_stderr = false, | 58 | .warn_on_stderr = false, |
| 50 | .skip_stderr = 0, | 59 | |
| 51 | .skip_stdout = 0, | 60 | .skip_stderr = false, |
| 61 | .stdout_lines_to_ignore = 0, | ||
| 62 | .skip_stdout = false, | ||
| 63 | .sterr_lines_to_ignore = 0, | ||
| 64 | |||
| 52 | .passive = false, | 65 | .passive = false, |
| 53 | .outputfile = NULL, | 66 | .outputfile = NULL, |
| 67 | |||
| 68 | .output_format_is_set = false, | ||
| 54 | }; | 69 | }; |
| 55 | return tmp; | 70 | return tmp; |
| 56 | } | 71 | } |
diff --git a/plugins/check_cluster.c b/plugins/check_cluster.c index 9b695499..1cbdcd60 100644 --- a/plugins/check_cluster.c +++ b/plugins/check_cluster.c | |||
| @@ -26,6 +26,8 @@ const char *progname = "check_cluster"; | |||
| 26 | const char *copyright = "2000-2024"; | 26 | const char *copyright = "2000-2024"; |
| 27 | const char *email = "devel@monitoring-plugins.org"; | 27 | const char *email = "devel@monitoring-plugins.org"; |
| 28 | 28 | ||
| 29 | #include "output.h" | ||
| 30 | #include "states.h" | ||
| 29 | #include "common.h" | 31 | #include "common.h" |
| 30 | #include "utils.h" | 32 | #include "utils.h" |
| 31 | #include "utils_base.h" | 33 | #include "utils_base.h" |
| @@ -57,6 +59,10 @@ int main(int argc, char **argv) { | |||
| 57 | 59 | ||
| 58 | const check_cluster_config config = tmp_config.config; | 60 | const check_cluster_config config = tmp_config.config; |
| 59 | 61 | ||
| 62 | if (config.output_format_is_set) { | ||
| 63 | mp_set_format(config.output_format); | ||
| 64 | } | ||
| 65 | |||
| 60 | /* Initialize the thresholds */ | 66 | /* Initialize the thresholds */ |
| 61 | if (verbose) { | 67 | if (verbose) { |
| 62 | print_thresholds("check_cluster", config.thresholds); | 68 | print_thresholds("check_cluster", config.thresholds); |
| @@ -72,7 +78,6 @@ int main(int argc, char **argv) { | |||
| 72 | int total_hosts_unreachable = 0; | 78 | int total_hosts_unreachable = 0; |
| 73 | /* check the data values */ | 79 | /* check the data values */ |
| 74 | for (char *ptr = strtok(config.data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) { | 80 | for (char *ptr = strtok(config.data_vals, ","); ptr != NULL; ptr = strtok(NULL, ",")) { |
| 75 | |||
| 76 | data_val = atoi(ptr); | 81 | data_val = atoi(ptr); |
| 77 | 82 | ||
| 78 | if (config.check_type == CHECK_SERVICES) { | 83 | if (config.check_type == CHECK_SERVICES) { |
| @@ -109,28 +114,49 @@ int main(int argc, char **argv) { | |||
| 109 | } | 114 | } |
| 110 | } | 115 | } |
| 111 | 116 | ||
| 112 | int return_code = STATE_OK; | 117 | mp_check overall = mp_check_init(); |
| 118 | mp_subcheck sc_real_test = mp_subcheck_init(); | ||
| 119 | sc_real_test = mp_set_subcheck_default_state(sc_real_test, STATE_OK); | ||
| 120 | |||
| 113 | /* return the status of the cluster */ | 121 | /* return the status of the cluster */ |
| 114 | if (config.check_type == CHECK_SERVICES) { | 122 | if (config.check_type == CHECK_SERVICES) { |
| 115 | return_code = get_status(total_services_warning + total_services_unknown + total_services_critical, config.thresholds); | 123 | sc_real_test = mp_set_subcheck_state( |
| 116 | printf("CLUSTER %s: %s: %d ok, %d warning, %d unknown, %d critical\n", state_text(return_code), | 124 | sc_real_test, |
| 117 | (config.label == NULL) ? "Service cluster" : config.label, total_services_ok, total_services_warning, total_services_unknown, | 125 | get_status(total_services_warning + total_services_unknown + total_services_critical, |
| 118 | total_services_critical); | 126 | config.thresholds)); |
| 127 | xasprintf(&sc_real_test.output, "%s: %d ok, %d warning, %d unknown, %d critical", | ||
| 128 | (config.label == NULL) ? "Service cluster" : config.label, total_services_ok, | ||
| 129 | total_services_warning, total_services_unknown, total_services_critical); | ||
| 119 | } else { | 130 | } else { |
| 120 | return_code = get_status(total_hosts_down + total_hosts_unreachable, config.thresholds); | 131 | sc_real_test = mp_set_subcheck_state( |
| 121 | printf("CLUSTER %s: %s: %d up, %d down, %d unreachable\n", state_text(return_code), | 132 | sc_real_test, |
| 122 | (config.label == NULL) ? "Host cluster" : config.label, total_hosts_up, total_hosts_down, total_hosts_unreachable); | 133 | get_status(total_hosts_down + total_hosts_unreachable, config.thresholds)); |
| 134 | xasprintf(&sc_real_test.output, "%s: %d up, %d down, %d unreachable\n", | ||
| 135 | (config.label == NULL) ? "Host cluster" : config.label, total_hosts_up, | ||
| 136 | total_hosts_down, total_hosts_unreachable); | ||
| 123 | } | 137 | } |
| 124 | 138 | ||
| 125 | exit(return_code); | 139 | mp_add_subcheck_to_check(&overall, sc_real_test); |
| 140 | |||
| 141 | mp_exit(overall); | ||
| 126 | } | 142 | } |
| 127 | 143 | ||
| 128 | check_cluster_config_wrapper process_arguments(int argc, char **argv) { | 144 | check_cluster_config_wrapper process_arguments(int argc, char **argv) { |
| 129 | static struct option longopts[] = {{"data", required_argument, 0, 'd'}, {"warning", required_argument, 0, 'w'}, | 145 | enum { |
| 130 | {"critical", required_argument, 0, 'c'}, {"label", required_argument, 0, 'l'}, | 146 | output_format_index = CHAR_MAX + 1, |
| 131 | {"host", no_argument, 0, 'h'}, {"service", no_argument, 0, 's'}, | 147 | }; |
| 132 | {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, | 148 | |
| 133 | {"help", no_argument, 0, 'H'}, {0, 0, 0, 0}}; | 149 | static struct option longopts[] = {{"data", required_argument, 0, 'd'}, |
| 150 | {"warning", required_argument, 0, 'w'}, | ||
| 151 | {"critical", required_argument, 0, 'c'}, | ||
| 152 | {"label", required_argument, 0, 'l'}, | ||
| 153 | {"host", no_argument, 0, 'h'}, | ||
| 154 | {"service", no_argument, 0, 's'}, | ||
| 155 | {"verbose", no_argument, 0, 'v'}, | ||
| 156 | {"version", no_argument, 0, 'V'}, | ||
| 157 | {"help", no_argument, 0, 'H'}, | ||
| 158 | {"output-format", required_argument, 0, output_format_index}, | ||
| 159 | {0, 0, 0, 0}}; | ||
| 134 | 160 | ||
| 135 | check_cluster_config_wrapper result = { | 161 | check_cluster_config_wrapper result = { |
| 136 | .errorcode = OK, | 162 | .errorcode = OK, |
| @@ -197,6 +223,18 @@ check_cluster_config_wrapper process_arguments(int argc, char **argv) { | |||
| 197 | print_help(); | 223 | print_help(); |
| 198 | exit(STATE_UNKNOWN); | 224 | exit(STATE_UNKNOWN); |
| 199 | break; | 225 | break; |
| 226 | case output_format_index: { | ||
| 227 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 228 | if (!parser.parsing_success) { | ||
| 229 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 230 | printf("Invalid output format: %s\n", optarg); | ||
| 231 | exit(STATE_UNKNOWN); | ||
| 232 | } | ||
| 233 | |||
| 234 | result.config.output_format_is_set = true; | ||
| 235 | result.config.output_format = parser.output_format; | ||
| 236 | break; | ||
| 237 | } | ||
| 200 | default: | 238 | default: |
| 201 | result.errorcode = ERROR; | 239 | result.errorcode = ERROR; |
| 202 | return result; | 240 | return result; |
| @@ -244,6 +282,8 @@ void print_help(void) { | |||
| 244 | 282 | ||
| 245 | printf(UT_VERBOSE); | 283 | printf(UT_VERBOSE); |
| 246 | 284 | ||
| 285 | printf(UT_OUTPUT_FORMAT); | ||
| 286 | |||
| 247 | printf("\n"); | 287 | printf("\n"); |
| 248 | printf("%s\n", _("Notes:")); | 288 | printf("%s\n", _("Notes:")); |
| 249 | printf(UT_THRESHOLDS_NOTES); | 289 | printf(UT_THRESHOLDS_NOTES); |
| @@ -251,7 +291,8 @@ void print_help(void) { | |||
| 251 | printf("\n"); | 291 | printf("\n"); |
| 252 | printf("%s\n", _("Examples:")); | 292 | printf("%s\n", _("Examples:")); |
| 253 | printf(" %s\n", "check_cluster -s -d 2,0,2,0 -c @3:"); | 293 | printf(" %s\n", "check_cluster -s -d 2,0,2,0 -c @3:"); |
| 254 | printf(" %s\n", _("Will alert critical if there are 3 or more service data points in a non-OK")); | 294 | printf(" %s\n", |
| 295 | _("Will alert critical if there are 3 or more service data points in a non-OK")); | ||
| 255 | printf(" %s\n", _("state.")); | 296 | printf(" %s\n", _("state.")); |
| 256 | 297 | ||
| 257 | printf(UT_SUPPORT); | 298 | printf(UT_SUPPORT); |
diff --git a/plugins/check_cluster.d/config.h b/plugins/check_cluster.d/config.h index fc386415..054657b0 100644 --- a/plugins/check_cluster.d/config.h +++ b/plugins/check_cluster.d/config.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "../../lib/thresholds.h" | 4 | #include "../../lib/thresholds.h" |
| 5 | #include "output.h" | ||
| 5 | #include <stddef.h> | 6 | #include <stddef.h> |
| 6 | 7 | ||
| 7 | enum { | 8 | enum { |
| @@ -14,6 +15,9 @@ typedef struct { | |||
| 14 | thresholds *thresholds; | 15 | thresholds *thresholds; |
| 15 | int check_type; | 16 | int check_type; |
| 16 | char *label; | 17 | char *label; |
| 18 | |||
| 19 | mp_output_format output_format; | ||
| 20 | bool output_format_is_set; | ||
| 17 | } check_cluster_config; | 21 | } check_cluster_config; |
| 18 | 22 | ||
| 19 | check_cluster_config check_cluster_config_init() { | 23 | check_cluster_config check_cluster_config_init() { |
| @@ -22,6 +26,8 @@ check_cluster_config check_cluster_config_init() { | |||
| 22 | .thresholds = NULL, | 26 | .thresholds = NULL, |
| 23 | .check_type = CHECK_SERVICES, | 27 | .check_type = CHECK_SERVICES, |
| 24 | .label = NULL, | 28 | .label = NULL, |
| 29 | |||
| 30 | .output_format_is_set = false, | ||
| 25 | }; | 31 | }; |
| 26 | return tmp; | 32 | return tmp; |
| 27 | } | 33 | } |
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 748201e8..e7737c7c 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
| @@ -32,16 +32,23 @@ | |||
| 32 | * | 32 | * |
| 33 | * | 33 | * |
| 34 | *****************************************************************************/ | 34 | *****************************************************************************/ |
| 35 | const char *progname = "check_curl"; | ||
| 36 | 35 | ||
| 36 | const char *progname = "check_curl"; | ||
| 37 | const char *copyright = "2006-2024"; | 37 | const char *copyright = "2006-2024"; |
| 38 | const char *email = "devel@monitoring-plugins.org"; | 38 | const char *email = "devel@monitoring-plugins.org"; |
| 39 | 39 | ||
| 40 | #include "check_curl.d/config.h" | ||
| 41 | #include "states.h" | ||
| 42 | #include "thresholds.h" | ||
| 40 | #include <stdbool.h> | 43 | #include <stdbool.h> |
| 41 | #include <ctype.h> | 44 | #include <ctype.h> |
| 45 | #include "output.h" | ||
| 46 | #include "perfdata.h" | ||
| 42 | 47 | ||
| 48 | #include <assert.h> | ||
| 43 | #include "common.h" | 49 | #include "common.h" |
| 44 | #include "utils.h" | 50 | #include "utils.h" |
| 51 | #include "./check_curl.d/check_curl_helpers.h" | ||
| 45 | 52 | ||
| 46 | #ifndef LIBCURL_PROTOCOL_HTTP | 53 | #ifndef LIBCURL_PROTOCOL_HTTP |
| 47 | # error libcurl compiled without HTTP support, compiling check_curl plugin does not makes a lot of sense | 54 | # error libcurl compiled without HTTP support, compiling check_curl plugin does not makes a lot of sense |
| @@ -50,8 +57,6 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 50 | #include "curl/curl.h" | 57 | #include "curl/curl.h" |
| 51 | #include "curl/easy.h" | 58 | #include "curl/easy.h" |
| 52 | 59 | ||
| 53 | #include "picohttpparser.h" | ||
| 54 | |||
| 55 | #include "uriparser/Uri.h" | 60 | #include "uriparser/Uri.h" |
| 56 | 61 | ||
| 57 | #include <arpa/inet.h> | 62 | #include <arpa/inet.h> |
| @@ -63,207 +68,58 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 63 | 68 | ||
| 64 | #include <netdb.h> | 69 | #include <netdb.h> |
| 65 | 70 | ||
| 66 | #define MAKE_LIBCURL_VERSION(major, minor, patch) ((major)*0x10000 + (minor)*0x100 + (patch)) | ||
| 67 | |||
| 68 | #define DEFAULT_BUFFER_SIZE 2048 | ||
| 69 | #define DEFAULT_SERVER_URL "/" | ||
| 70 | #define HTTP_EXPECT "HTTP/" | ||
| 71 | #define INET_ADDR_MAX_SIZE INET6_ADDRSTRLEN | ||
| 72 | enum { | 71 | enum { |
| 73 | MAX_IPV4_HOSTLENGTH = 255, | 72 | REGS = 2, |
| 74 | HTTP_PORT = 80, | ||
| 75 | HTTPS_PORT = 443, | ||
| 76 | MAX_PORT = 65535, | ||
| 77 | DEFAULT_MAX_REDIRS = 15 | ||
| 78 | }; | 73 | }; |
| 79 | 74 | ||
| 80 | enum { | 75 | #include "regex.h" |
| 81 | STICKY_NONE = 0, | ||
| 82 | STICKY_HOST = 1, | ||
| 83 | STICKY_PORT = 2 | ||
| 84 | }; | ||
| 85 | 76 | ||
| 86 | enum { | 77 | // Globals |
| 87 | FOLLOW_HTTP_CURL = 0, | 78 | int verbose = 0; |
| 88 | FOLLOW_LIBCURL = 1 | ||
| 89 | }; | ||
| 90 | 79 | ||
| 91 | /* for buffers for header and body */ | 80 | extern char errbuf[MAX_INPUT_BUFFER]; |
| 92 | typedef struct { | 81 | extern bool is_openssl_callback; |
| 93 | char *buf; | 82 | extern bool add_sslctx_verify_fun; |
| 94 | size_t buflen; | 83 | |
| 95 | size_t bufsize; | 84 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) |
| 96 | } curlhelp_write_curlbuf; | 85 | static X509 *cert = NULL; |
| 86 | #endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ | ||
| 97 | 87 | ||
| 98 | /* for buffering the data sent in PUT */ | ||
| 99 | typedef struct { | 88 | typedef struct { |
| 100 | char *buf; | 89 | int errorcode; |
| 101 | size_t buflen; | 90 | check_curl_config config; |
| 102 | off_t pos; | 91 | } check_curl_config_wrapper; |
| 103 | } curlhelp_read_curlbuf; | 92 | static check_curl_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 93 | |||
| 94 | static mp_subcheck check_http(check_curl_config /*config*/, check_curl_working_state workingState, | ||
| 95 | long redir_depth); | ||
| 104 | 96 | ||
| 105 | /* for parsing the HTTP status line */ | ||
| 106 | typedef struct { | 97 | typedef struct { |
| 107 | int http_major; /* major version of the protocol, always 1 (HTTP/0.9 | 98 | long redir_depth; |
| 108 | * never reached the big internet most likely) */ | 99 | check_curl_working_state working_state; |
| 109 | int http_minor; /* minor version of the protocol, usually 0 or 1 */ | 100 | int error_code; |
| 110 | int http_code; /* HTTP return code as in RFC 2145 */ | 101 | check_curl_global_state curl_state; |
| 111 | int http_subcode; /* Microsoft IIS extension, HTTP subcodes, see | 102 | } redir_wrapper; |
| 112 | * http://support.microsoft.com/kb/318380/en-us */ | 103 | static redir_wrapper redir(curlhelp_write_curlbuf * /*header_buf*/, check_curl_config /*config*/, |
| 113 | const char *msg; /* the human readable message */ | 104 | long redir_depth, check_curl_working_state working_state); |
| 114 | char *first_line; /* a copy of the first line */ | ||
| 115 | } curlhelp_statusline; | ||
| 116 | |||
| 117 | /* to know the underlying SSL library used by libcurl */ | ||
| 118 | typedef enum curlhelp_ssl_library { | ||
| 119 | CURLHELP_SSL_LIBRARY_UNKNOWN, | ||
| 120 | CURLHELP_SSL_LIBRARY_OPENSSL, | ||
| 121 | CURLHELP_SSL_LIBRARY_LIBRESSL, | ||
| 122 | CURLHELP_SSL_LIBRARY_GNUTLS, | ||
| 123 | CURLHELP_SSL_LIBRARY_NSS | ||
| 124 | } curlhelp_ssl_library; | ||
| 125 | 105 | ||
| 126 | enum { | ||
| 127 | REGS = 2, | ||
| 128 | MAX_RE_SIZE = 1024 | ||
| 129 | }; | ||
| 130 | #include "regex.h" | ||
| 131 | static regex_t preg; | ||
| 132 | static regmatch_t pmatch[REGS]; | ||
| 133 | static char regexp[MAX_RE_SIZE]; | ||
| 134 | static int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; | ||
| 135 | static int errcode; | ||
| 136 | static bool invert_regex = false; | ||
| 137 | static int state_regex = STATE_CRITICAL; | ||
| 138 | |||
| 139 | static char *server_address = NULL; | ||
| 140 | static char *host_name = NULL; | ||
| 141 | static char *server_url = 0; | ||
| 142 | static struct curl_slist *server_ips = NULL; | ||
| 143 | static bool specify_port = false; | ||
| 144 | static unsigned short server_port = HTTP_PORT; | ||
| 145 | static unsigned short virtual_port = 0; | ||
| 146 | static int host_name_length; | ||
| 147 | static char output_header_search[30] = ""; | ||
| 148 | static char output_string_search[30] = ""; | ||
| 149 | static char *warning_thresholds = NULL; | ||
| 150 | static char *critical_thresholds = NULL; | ||
| 151 | static int days_till_exp_warn, days_till_exp_crit; | ||
| 152 | static thresholds *thlds; | ||
| 153 | static char user_agent[DEFAULT_BUFFER_SIZE]; | ||
| 154 | static int verbose = 0; | ||
| 155 | static bool show_extended_perfdata = false; | ||
| 156 | static bool show_body = false; | ||
| 157 | static int min_page_len = 0; | ||
| 158 | static int max_page_len = 0; | ||
| 159 | static int redir_depth = 0; | ||
| 160 | static int max_depth = DEFAULT_MAX_REDIRS; | ||
| 161 | static char *http_method = NULL; | ||
| 162 | static char *http_post_data = NULL; | ||
| 163 | static char *http_content_type = NULL; | ||
| 164 | static CURL *curl; | ||
| 165 | static bool curl_global_initialized = false; | ||
| 166 | static bool curl_easy_initialized = false; | ||
| 167 | static struct curl_slist *header_list = NULL; | ||
| 168 | static bool body_buf_initialized = false; | ||
| 169 | static curlhelp_write_curlbuf body_buf; | ||
| 170 | static bool header_buf_initialized = false; | ||
| 171 | static curlhelp_write_curlbuf header_buf; | ||
| 172 | static bool status_line_initialized = false; | ||
| 173 | static curlhelp_statusline status_line; | ||
| 174 | static bool put_buf_initialized = false; | ||
| 175 | static curlhelp_read_curlbuf put_buf; | ||
| 176 | static char http_header[DEFAULT_BUFFER_SIZE]; | ||
| 177 | static long code; | ||
| 178 | static long socket_timeout = DEFAULT_SOCKET_TIMEOUT; | ||
| 179 | static double total_time; | ||
| 180 | static double time_connect; | ||
| 181 | static double time_appconnect; | ||
| 182 | static double time_headers; | ||
| 183 | static double time_firstbyte; | ||
| 184 | static char errbuf[MAX_INPUT_BUFFER]; | ||
| 185 | static CURLcode res; | ||
| 186 | static char url[DEFAULT_BUFFER_SIZE]; | ||
| 187 | static char msg[DEFAULT_BUFFER_SIZE]; | ||
| 188 | static char perfstring[DEFAULT_BUFFER_SIZE]; | ||
| 189 | static char header_expect[MAX_INPUT_BUFFER] = ""; | ||
| 190 | static char string_expect[MAX_INPUT_BUFFER] = ""; | ||
| 191 | static char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; | ||
| 192 | static int server_expect_yn = 0; | ||
| 193 | static char user_auth[MAX_INPUT_BUFFER] = ""; | ||
| 194 | static char proxy_auth[MAX_INPUT_BUFFER] = ""; | ||
| 195 | static char **http_opt_headers; | ||
| 196 | static int http_opt_headers_count = 0; | ||
| 197 | static bool display_html = false; | ||
| 198 | static int onredirect = STATE_OK; | ||
| 199 | static int followmethod = FOLLOW_HTTP_CURL; | ||
| 200 | static int followsticky = STICKY_NONE; | ||
| 201 | static bool use_ssl = false; | ||
| 202 | static bool check_cert = false; | ||
| 203 | static bool continue_after_check_cert = false; | ||
| 204 | typedef union { | ||
| 205 | struct curl_slist *to_info; | ||
| 206 | struct curl_certinfo *to_certinfo; | ||
| 207 | } cert_ptr_union; | ||
| 208 | static cert_ptr_union cert_ptr; | ||
| 209 | static int ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 210 | static char *client_cert = NULL; | ||
| 211 | static char *client_privkey = NULL; | ||
| 212 | static char *ca_cert = NULL; | ||
| 213 | static bool verify_peer_and_host = false; | ||
| 214 | static bool is_openssl_callback = false; | ||
| 215 | static bool add_sslctx_verify_fun = false; | ||
| 216 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) | ||
| 217 | static X509 *cert = NULL; | ||
| 218 | #endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ | ||
| 219 | static bool no_body = false; | ||
| 220 | static int maximum_age = -1; | ||
| 221 | static int address_family = AF_UNSPEC; | ||
| 222 | static curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN; | ||
| 223 | static int curl_http_version = CURL_HTTP_VERSION_NONE; | ||
| 224 | static bool automatic_decompression = false; | ||
| 225 | static char *cookie_jar_file = NULL; | ||
| 226 | static bool haproxy_protocol = false; | ||
| 227 | |||
| 228 | static bool process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 229 | static void handle_curl_option_return_code(CURLcode res, const char *option); | ||
| 230 | static int check_http(void); | ||
| 231 | static void redir(curlhelp_write_curlbuf * /*header_buf*/); | ||
| 232 | static char *perfd_time(double elapsed_time); | ||
| 233 | static char *perfd_time_connect(double elapsed_time_connect); | ||
| 234 | static char *perfd_time_ssl(double elapsed_time_ssl); | ||
| 235 | static char *perfd_time_firstbyte(double elapsed_time_firstbyte); | ||
| 236 | static char *perfd_time_headers(double elapsed_time_headers); | ||
| 237 | static char *perfd_time_transfer(double elapsed_time_transfer); | ||
| 238 | static char *perfd_size(int page_len); | ||
| 239 | static void print_help(void); | 106 | static void print_help(void); |
| 240 | void print_usage(void); | 107 | void print_usage(void); |
| 108 | |||
| 241 | static void print_curl_version(void); | 109 | static void print_curl_version(void); |
| 242 | static int curlhelp_initwritebuffer(curlhelp_write_curlbuf * /*buf*/); | 110 | |
| 243 | static size_t curlhelp_buffer_write_callback(void * /*buffer*/, size_t /*size*/, size_t /*nmemb*/, void * /*stream*/); | 111 | // typedef struct { |
| 244 | static void curlhelp_freewritebuffer(curlhelp_write_curlbuf * /*buf*/); | 112 | // int errorcode; |
| 245 | static int curlhelp_initreadbuffer(curlhelp_read_curlbuf * /*buf*/, const char * /*data*/, size_t /*datalen*/); | 113 | // } check_curl_evaluation_wrapper; |
| 246 | static size_t curlhelp_buffer_read_callback(void * /*buffer*/, size_t /*size*/, size_t /*nmemb*/, void * /*stream*/); | 114 | // check_curl_evaluation_wrapper check_curl_evaluate(check_curl_config config, |
| 247 | static void curlhelp_freereadbuffer(curlhelp_read_curlbuf * /*buf*/); | 115 | // mp_check overall[static 1]) {} |
| 248 | static curlhelp_ssl_library curlhelp_get_ssl_library(void); | ||
| 249 | static const char *curlhelp_get_ssl_library_string(curlhelp_ssl_library /*ssl_library*/); | ||
| 250 | int net_noopenssl_check_certificate(cert_ptr_union *, int, int); | ||
| 251 | |||
| 252 | static int curlhelp_parse_statusline(const char * /*buf*/, curlhelp_statusline * /*status_line*/); | ||
| 253 | static void curlhelp_free_statusline(curlhelp_statusline * /*status_line*/); | ||
| 254 | static char *get_header_value(const struct phr_header *headers, size_t nof_headers, const char *header); | ||
| 255 | static int check_document_dates(const curlhelp_write_curlbuf * /*header_buf*/, char (*msg)[DEFAULT_BUFFER_SIZE]); | ||
| 256 | static int get_content_length(const curlhelp_write_curlbuf *header_buf, const curlhelp_write_curlbuf *body_buf); | ||
| 257 | 116 | ||
| 258 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) | 117 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) |
| 259 | int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit); | 118 | mp_state_enum np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, |
| 119 | int days_till_exp_crit); | ||
| 260 | #endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ | 120 | #endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ |
| 261 | 121 | ||
| 262 | static void test_file(char * /*path*/); | ||
| 263 | |||
| 264 | int main(int argc, char **argv) { | 122 | int main(int argc, char **argv) { |
| 265 | int result = STATE_UNKNOWN; | ||
| 266 | |||
| 267 | setlocale(LC_ALL, ""); | 123 | setlocale(LC_ALL, ""); |
| 268 | bindtextdomain(PACKAGE, LOCALEDIR); | 124 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 269 | textdomain(PACKAGE); | 125 | textdomain(PACKAGE); |
| @@ -271,24 +127,30 @@ int main(int argc, char **argv) { | |||
| 271 | /* Parse extra opts if any */ | 127 | /* Parse extra opts if any */ |
| 272 | argv = np_extra_opts(&argc, argv, progname); | 128 | argv = np_extra_opts(&argc, argv, progname); |
| 273 | 129 | ||
| 274 | /* set defaults */ | ||
| 275 | snprintf(user_agent, DEFAULT_BUFFER_SIZE, "%s/v%s (monitoring-plugins %s, %s)", progname, NP_VERSION, VERSION, curl_version()); | ||
| 276 | |||
| 277 | /* parse arguments */ | 130 | /* parse arguments */ |
| 278 | if (process_arguments(argc, argv) == false) | 131 | check_curl_config_wrapper tmp_config = process_arguments(argc, argv); |
| 132 | if (tmp_config.errorcode == ERROR) { | ||
| 279 | usage4(_("Could not parse arguments")); | 133 | usage4(_("Could not parse arguments")); |
| 134 | } | ||
| 280 | 135 | ||
| 281 | if (display_html) | 136 | const check_curl_config config = tmp_config.config; |
| 282 | printf("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", use_ssl ? "https" : "http", host_name ? host_name : server_address, | ||
| 283 | virtual_port ? virtual_port : server_port, server_url); | ||
| 284 | 137 | ||
| 285 | result = check_http(); | 138 | if (config.output_format_is_set) { |
| 286 | return result; | 139 | mp_set_format(config.output_format); |
| 140 | } | ||
| 141 | |||
| 142 | check_curl_working_state working_state = config.initial_config; | ||
| 143 | |||
| 144 | mp_check overall = mp_check_init(); | ||
| 145 | mp_subcheck sc_test = check_http(config, working_state, 0); | ||
| 146 | |||
| 147 | mp_add_subcheck_to_check(&overall, sc_test); | ||
| 148 | |||
| 149 | mp_exit(overall); | ||
| 287 | } | 150 | } |
| 288 | 151 | ||
| 289 | #ifdef HAVE_SSL | 152 | #ifdef HAVE_SSL |
| 290 | # ifdef USE_OPENSSL | 153 | # ifdef USE_OPENSSL |
| 291 | |||
| 292 | int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { | 154 | int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { |
| 293 | (void)preverify_ok; | 155 | (void)preverify_ok; |
| 294 | /* TODO: we get all certificates of the chain, so which ones | 156 | /* TODO: we get all certificates of the chain, so which ones |
| @@ -301,19 +163,21 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { | |||
| 301 | # endif | 163 | # endif |
| 302 | if (verbose >= 2) { | 164 | if (verbose >= 2) { |
| 303 | puts("* SSL verify callback with certificate:"); | 165 | puts("* SSL verify callback with certificate:"); |
| 304 | X509_NAME *subject; | ||
| 305 | X509_NAME *issuer; | ||
| 306 | printf("* issuer:\n"); | 166 | printf("* issuer:\n"); |
| 307 | issuer = X509_get_issuer_name(cert); | 167 | X509_NAME *issuer = X509_get_issuer_name(cert); |
| 308 | X509_NAME_print_ex_fp(stdout, issuer, 5, XN_FLAG_MULTILINE); | 168 | X509_NAME_print_ex_fp(stdout, issuer, 5, XN_FLAG_MULTILINE); |
| 309 | printf("* curl verify_callback:\n* subject:\n"); | 169 | printf("* curl verify_callback:\n* subject:\n"); |
| 310 | subject = X509_get_subject_name(cert); | 170 | X509_NAME *subject = X509_get_subject_name(cert); |
| 311 | X509_NAME_print_ex_fp(stdout, subject, 5, XN_FLAG_MULTILINE); | 171 | X509_NAME_print_ex_fp(stdout, subject, 5, XN_FLAG_MULTILINE); |
| 312 | puts(""); | 172 | puts(""); |
| 313 | } | 173 | } |
| 314 | return 1; | 174 | return 1; |
| 315 | } | 175 | } |
| 176 | # endif /* USE_OPENSSL */ | ||
| 177 | #endif /* HAVE_SSL */ | ||
| 316 | 178 | ||
| 179 | #ifdef HAVE_SSL | ||
| 180 | # ifdef USE_OPENSSL | ||
| 317 | CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) { | 181 | CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) { |
| 318 | (void)curl; // ignore unused parameter | 182 | (void)curl; // ignore unused parameter |
| 319 | (void)parm; // ignore unused parameter | 183 | (void)parm; // ignore unused parameter |
| @@ -330,877 +194,508 @@ CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) { | |||
| 330 | 194 | ||
| 331 | return CURLE_OK; | 195 | return CURLE_OK; |
| 332 | } | 196 | } |
| 333 | |||
| 334 | # endif /* USE_OPENSSL */ | 197 | # endif /* USE_OPENSSL */ |
| 335 | #endif /* HAVE_SSL */ | 198 | #endif /* HAVE_SSL */ |
| 336 | 199 | ||
| 337 | /* returns a string "HTTP/1.x" or "HTTP/2" */ | 200 | mp_subcheck check_http(const check_curl_config config, check_curl_working_state workingState, |
| 338 | static char *string_statuscode(int major, int minor) { | 201 | long redir_depth) { |
| 339 | static char buf[10]; | ||
| 340 | |||
| 341 | switch (major) { | ||
| 342 | case 1: | ||
| 343 | snprintf(buf, sizeof(buf), "HTTP/%d.%d", major, minor); | ||
| 344 | break; | ||
| 345 | case 2: | ||
| 346 | case 3: | ||
| 347 | snprintf(buf, sizeof(buf), "HTTP/%d", major); | ||
| 348 | break; | ||
| 349 | default: | ||
| 350 | /* assuming here HTTP/N with N>=4 */ | ||
| 351 | snprintf(buf, sizeof(buf), "HTTP/%d", major); | ||
| 352 | break; | ||
| 353 | } | ||
| 354 | |||
| 355 | return buf; | ||
| 356 | } | ||
| 357 | |||
| 358 | /* Checks if the server 'reply' is one of the expected 'statuscodes' */ | ||
| 359 | static int expected_statuscode(const char *reply, const char *statuscodes) { | ||
| 360 | char *expected; | ||
| 361 | char *code; | ||
| 362 | int result = 0; | ||
| 363 | |||
| 364 | if ((expected = strdup(statuscodes)) == NULL) | ||
| 365 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n")); | ||
| 366 | |||
| 367 | for (code = strtok(expected, ","); code != NULL; code = strtok(NULL, ",")) | ||
| 368 | if (strstr(reply, code) != NULL) { | ||
| 369 | result = 1; | ||
| 370 | break; | ||
| 371 | } | ||
| 372 | |||
| 373 | free(expected); | ||
| 374 | return result; | ||
| 375 | } | ||
| 376 | 202 | ||
| 377 | void handle_curl_option_return_code(CURLcode res, const char *option) { | 203 | // ======================= |
| 378 | if (res != CURLE_OK) { | 204 | // Initialisation for curl |
| 379 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Error while setting cURL option '%s': cURL returned %d - %s"), option, res, | 205 | // ======================= |
| 380 | curl_easy_strerror(res)); | 206 | check_curl_configure_curl_wrapper conf_curl_struct = check_curl_configure_curl( |
| 381 | die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 207 | config.curl_config, workingState, config.check_cert, config.on_redirect_dependent, |
| 382 | } | 208 | config.followmethod, config.max_depth); |
| 383 | } | ||
| 384 | 209 | ||
| 385 | int lookup_host(const char *host, char *buf, size_t buflen) { | 210 | check_curl_global_state curl_state = conf_curl_struct.curl_state; |
| 386 | struct addrinfo hints, *res, *result; | 211 | workingState = conf_curl_struct.working_state; |
| 387 | char addrstr[100]; | ||
| 388 | size_t addrstr_len; | ||
| 389 | int errcode; | ||
| 390 | void *ptr = {0}; | ||
| 391 | size_t buflen_remaining = buflen - 1; | ||
| 392 | |||
| 393 | memset(&hints, 0, sizeof(hints)); | ||
| 394 | hints.ai_family = address_family; | ||
| 395 | hints.ai_socktype = SOCK_STREAM; | ||
| 396 | hints.ai_flags |= AI_CANONNAME; | ||
| 397 | |||
| 398 | errcode = getaddrinfo(host, NULL, &hints, &result); | ||
| 399 | if (errcode != 0) | ||
| 400 | return errcode; | ||
| 401 | |||
| 402 | strcpy(buf, ""); | ||
| 403 | res = result; | ||
| 404 | |||
| 405 | while (res) { | ||
| 406 | switch (res->ai_family) { | ||
| 407 | case AF_INET: | ||
| 408 | ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; | ||
| 409 | break; | ||
| 410 | case AF_INET6: | ||
| 411 | ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; | ||
| 412 | break; | ||
| 413 | } | ||
| 414 | 212 | ||
| 415 | inet_ntop(res->ai_family, ptr, addrstr, 100); | 213 | mp_subcheck sc_result = mp_subcheck_init(); |
| 416 | if (verbose >= 1) { | ||
| 417 | printf("* getaddrinfo IPv%d address: %s\n", res->ai_family == PF_INET6 ? 6 : 4, addrstr); | ||
| 418 | } | ||
| 419 | 214 | ||
| 420 | // Append all IPs to buf as a comma-separated string | 215 | char *url = fmt_url(workingState); |
| 421 | addrstr_len = strlen(addrstr); | 216 | xasprintf(&sc_result.output, "Testing %s", url); |
| 422 | if (buflen_remaining > addrstr_len + 1) { | 217 | // TODO add some output here URL or something |
| 423 | if (buf[0] != '\0') { | 218 | free(url); |
| 424 | strncat(buf, ",", buflen_remaining); | ||
| 425 | buflen_remaining -= 1; | ||
| 426 | } | ||
| 427 | strncat(buf, addrstr, buflen_remaining); | ||
| 428 | buflen_remaining -= addrstr_len; | ||
| 429 | } | ||
| 430 | |||
| 431 | res = res->ai_next; | ||
| 432 | } | ||
| 433 | 219 | ||
| 434 | freeaddrinfo(result); | 220 | // ============== |
| 435 | 221 | // do the request | |
| 436 | return 0; | 222 | // ============== |
| 437 | } | 223 | CURLcode res = curl_easy_perform(curl_state.curl); |
| 438 | |||
| 439 | static void cleanup(void) { | ||
| 440 | if (status_line_initialized) | ||
| 441 | curlhelp_free_statusline(&status_line); | ||
| 442 | status_line_initialized = false; | ||
| 443 | if (curl_easy_initialized) | ||
| 444 | curl_easy_cleanup(curl); | ||
| 445 | curl_easy_initialized = false; | ||
| 446 | if (curl_global_initialized) | ||
| 447 | curl_global_cleanup(); | ||
| 448 | curl_global_initialized = false; | ||
| 449 | if (body_buf_initialized) | ||
| 450 | curlhelp_freewritebuffer(&body_buf); | ||
| 451 | body_buf_initialized = false; | ||
| 452 | if (header_buf_initialized) | ||
| 453 | curlhelp_freewritebuffer(&header_buf); | ||
| 454 | header_buf_initialized = false; | ||
| 455 | if (put_buf_initialized) | ||
| 456 | curlhelp_freereadbuffer(&put_buf); | ||
| 457 | put_buf_initialized = false; | ||
| 458 | } | ||
| 459 | 224 | ||
| 460 | int check_http(void) { | 225 | if (verbose >= 2 && workingState.http_post_data) { |
| 461 | int result = STATE_OK; | 226 | printf("**** REQUEST CONTENT ****\n%s\n", workingState.http_post_data); |
| 462 | int result_ssl = STATE_OK; | ||
| 463 | int page_len = 0; | ||
| 464 | int i; | ||
| 465 | char *force_host_header = NULL; | ||
| 466 | struct curl_slist *host = NULL; | ||
| 467 | char addrstr[DEFAULT_BUFFER_SIZE / 2]; | ||
| 468 | char dnscache[DEFAULT_BUFFER_SIZE]; | ||
| 469 | |||
| 470 | /* initialize curl */ | ||
| 471 | if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) | ||
| 472 | die(STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n"); | ||
| 473 | curl_global_initialized = true; | ||
| 474 | |||
| 475 | if ((curl = curl_easy_init()) == NULL) { | ||
| 476 | die(STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n"); | ||
| 477 | } | 227 | } |
| 478 | curl_easy_initialized = true; | ||
| 479 | 228 | ||
| 480 | /* register cleanup function to shut down libcurl properly */ | 229 | mp_subcheck sc_curl = mp_subcheck_init(); |
| 481 | atexit(cleanup); | ||
| 482 | 230 | ||
| 483 | if (verbose >= 1) | 231 | /* Curl errors, result in critical Nagios state */ |
| 484 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1), "CURLOPT_VERBOSE"); | 232 | if (res != CURLE_OK) { |
| 485 | 233 | xasprintf(&sc_curl.output, _("Error while performing connection: cURL returned %d - %s"), | |
| 486 | /* print everything on stdout like check_http would do */ | 234 | res, errbuf[0] ? errbuf : curl_easy_strerror(res)); |
| 487 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_STDERR, stdout), "CURLOPT_STDERR"); | 235 | sc_curl = mp_set_subcheck_state(sc_curl, STATE_CRITICAL); |
| 488 | 236 | mp_add_subcheck_to_subcheck(&sc_result, sc_curl); | |
| 489 | if (automatic_decompression) | 237 | return sc_result; |
| 490 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) | ||
| 491 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""), "CURLOPT_ACCEPT_ENCODING"); | ||
| 492 | #else | ||
| 493 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_ENCODING, ""), "CURLOPT_ENCODING"); | ||
| 494 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) */ | ||
| 495 | |||
| 496 | /* initialize buffer for body of the answer */ | ||
| 497 | if (curlhelp_initwritebuffer(&body_buf) < 0) | ||
| 498 | die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n"); | ||
| 499 | body_buf_initialized = true; | ||
| 500 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), | ||
| 501 | "CURLOPT_WRITEFUNCTION"); | ||
| 502 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&body_buf), "CURLOPT_WRITEDATA"); | ||
| 503 | |||
| 504 | /* initialize buffer for header of the answer */ | ||
| 505 | if (curlhelp_initwritebuffer(&header_buf) < 0) | ||
| 506 | die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n"); | ||
| 507 | header_buf_initialized = true; | ||
| 508 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), | ||
| 509 | "CURLOPT_HEADERFUNCTION"); | ||
| 510 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *)&header_buf), "CURLOPT_WRITEHEADER"); | ||
| 511 | |||
| 512 | /* set the error buffer */ | ||
| 513 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf), "CURLOPT_ERRORBUFFER"); | ||
| 514 | |||
| 515 | /* set timeouts */ | ||
| 516 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, socket_timeout), "CURLOPT_CONNECTTIMEOUT"); | ||
| 517 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_TIMEOUT, socket_timeout), "CURLOPT_TIMEOUT"); | ||
| 518 | |||
| 519 | /* enable haproxy protocol */ | ||
| 520 | if (haproxy_protocol) { | ||
| 521 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HAPROXYPROTOCOL, 1L), "CURLOPT_HAPROXYPROTOCOL"); | ||
| 522 | } | ||
| 523 | |||
| 524 | // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we | ||
| 525 | // use the host_name later on to make SNI happy | ||
| 526 | if (use_ssl && host_name != NULL) { | ||
| 527 | if ((res = lookup_host(server_address, addrstr, DEFAULT_BUFFER_SIZE / 2)) != 0) { | ||
| 528 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), server_address, res, | ||
| 529 | gai_strerror(res)); | ||
| 530 | die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | ||
| 531 | } | ||
| 532 | snprintf(dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, addrstr); | ||
| 533 | host = curl_slist_append(NULL, dnscache); | ||
| 534 | curl_easy_setopt(curl, CURLOPT_RESOLVE, host); | ||
| 535 | if (verbose >= 1) | ||
| 536 | printf("* curl CURLOPT_RESOLVE: %s\n", dnscache); | ||
| 537 | } | ||
| 538 | |||
| 539 | // If server_address is an IPv6 address it must be surround by square brackets | ||
| 540 | struct in6_addr tmp_in_addr; | ||
| 541 | if (inet_pton(AF_INET6, server_address, &tmp_in_addr) == 1) { | ||
| 542 | char *new_server_address = malloc(strlen(server_address) + 3); | ||
| 543 | if (new_server_address == NULL) { | ||
| 544 | die(STATE_UNKNOWN, "HTTP UNKNOWN - Unable to allocate memory\n"); | ||
| 545 | } | ||
| 546 | snprintf(new_server_address, strlen(server_address) + 3, "[%s]", server_address); | ||
| 547 | free(server_address); | ||
| 548 | server_address = new_server_address; | ||
| 549 | } | ||
| 550 | |||
| 551 | /* compose URL: use the address we want to connect to, set Host: header later */ | ||
| 552 | snprintf(url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", use_ssl ? "https" : "http", | ||
| 553 | (use_ssl & (host_name != NULL)) ? host_name : server_address, server_port, server_url); | ||
| 554 | |||
| 555 | if (verbose >= 1) | ||
| 556 | printf("* curl CURLOPT_URL: %s\n", url); | ||
| 557 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_URL, url), "CURLOPT_URL"); | ||
| 558 | |||
| 559 | /* extract proxy information for legacy proxy https requests */ | ||
| 560 | if (!strcmp(http_method, "CONNECT") || strstr(server_url, "http") == server_url) { | ||
| 561 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_PROXY, server_address), "CURLOPT_PROXY"); | ||
| 562 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_PROXYPORT, (long)server_port), "CURLOPT_PROXYPORT"); | ||
| 563 | if (verbose >= 2) | ||
| 564 | printf("* curl CURLOPT_PROXY: %s:%d\n", server_address, server_port); | ||
| 565 | http_method = "GET"; | ||
| 566 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_URL, server_url), "CURLOPT_URL"); | ||
| 567 | } | ||
| 568 | |||
| 569 | /* disable body for HEAD request */ | ||
| 570 | if (http_method && !strcmp(http_method, "HEAD")) { | ||
| 571 | no_body = true; | ||
| 572 | } | 238 | } |
| 573 | 239 | ||
| 574 | /* set HTTP protocol version */ | 240 | /* get status line of answer, check sanity of HTTP code */ |
| 575 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, curl_http_version), "CURLOPT_HTTP_VERSION"); | 241 | if (curlhelp_parse_statusline(curl_state.header_buf->buf, curl_state.status_line) < 0) { |
| 576 | 242 | sc_result = mp_set_subcheck_state(sc_result, STATE_CRITICAL); | |
| 577 | /* set HTTP method */ | 243 | /* we cannot know the major/minor version here for sure as we cannot parse the first |
| 578 | if (http_method) { | 244 | * line */ |
| 579 | if (!strcmp(http_method, "POST")) | 245 | xasprintf(&sc_result.output, "HTTP/x.x unknown - Unparsable status line"); |
| 580 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_POST, 1), "CURLOPT_POST"); | 246 | return sc_result; |
| 581 | else if (!strcmp(http_method, "PUT")) | ||
| 582 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_UPLOAD, 1), "CURLOPT_UPLOAD"); | ||
| 583 | else | ||
| 584 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_method), "CURLOPT_CUSTOMREQUEST"); | ||
| 585 | } | 247 | } |
| 586 | 248 | ||
| 587 | /* check if Host header is explicitly set in options */ | 249 | curl_state.status_line_initialized = true; |
| 588 | if (http_opt_headers_count) { | ||
| 589 | for (i = 0; i < http_opt_headers_count; i++) { | ||
| 590 | if (strncmp(http_opt_headers[i], "Host:", 5) == 0) { | ||
| 591 | force_host_header = http_opt_headers[i]; | ||
| 592 | } | ||
| 593 | } | ||
| 594 | } | ||
| 595 | 250 | ||
| 596 | /* set hostname (virtual hosts), not needed if CURLOPT_CONNECT_TO is used, but left in anyway */ | 251 | size_t page_len = get_content_length(curl_state.header_buf, curl_state.body_buf); |
| 597 | if (host_name != NULL && force_host_header == NULL) { | ||
| 598 | if ((virtual_port != HTTP_PORT && !use_ssl) || (virtual_port != HTTPS_PORT && use_ssl)) { | ||
| 599 | snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s:%d", host_name, virtual_port); | ||
| 600 | } else { | ||
| 601 | snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s", host_name); | ||
| 602 | } | ||
| 603 | header_list = curl_slist_append(header_list, http_header); | ||
| 604 | } | ||
| 605 | 252 | ||
| 606 | /* always close connection, be nice to servers */ | 253 | double total_time; |
| 607 | snprintf(http_header, DEFAULT_BUFFER_SIZE, "Connection: close"); | 254 | handle_curl_option_return_code( |
| 608 | header_list = curl_slist_append(header_list, http_header); | 255 | curl_easy_getinfo(curl_state.curl, CURLINFO_TOTAL_TIME, &total_time), |
| 256 | "CURLINFO_TOTAL_TIME"); | ||
| 609 | 257 | ||
| 610 | /* attach additional headers supplied by the user */ | 258 | xasprintf( |
| 611 | /* optionally send any other header tag */ | 259 | &sc_curl.output, "%s %d %s - %ld bytes in %.3f second response time", |
| 612 | if (http_opt_headers_count) { | 260 | string_statuscode(curl_state.status_line->http_major, curl_state.status_line->http_minor), |
| 613 | for (i = 0; i < http_opt_headers_count; i++) { | 261 | curl_state.status_line->http_code, curl_state.status_line->msg, page_len, total_time); |
| 614 | header_list = curl_slist_append(header_list, http_opt_headers[i]); | 262 | sc_curl = mp_set_subcheck_state(sc_curl, STATE_OK); |
| 615 | } | 263 | mp_add_subcheck_to_subcheck(&sc_result, sc_curl); |
| 616 | /* This cannot be free'd here because a redirection will then try to access this and segfault */ | ||
| 617 | /* Covered in a testcase in tests/check_http.t */ | ||
| 618 | /* free(http_opt_headers); */ | ||
| 619 | } | ||
| 620 | 264 | ||
| 621 | /* set HTTP headers */ | 265 | // ========== |
| 622 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list), "CURLOPT_HTTPHEADER"); | 266 | // Evaluation |
| 267 | // ========== | ||
| 623 | 268 | ||
| 624 | #ifdef LIBCURL_FEATURE_SSL | 269 | #ifdef LIBCURL_FEATURE_SSL |
| 270 | if (workingState.use_ssl && config.check_cert) { | ||
| 271 | mp_subcheck sc_certificate = check_curl_certificate_checks( | ||
| 272 | curl_state.curl, cert, config.days_till_exp_warn, config.days_till_exp_crit); | ||
| 625 | 273 | ||
| 626 | /* set SSL version, warn about insecure or unsupported versions */ | 274 | mp_add_subcheck_to_subcheck(&sc_result, sc_certificate); |
| 627 | if (use_ssl) { | 275 | if (!config.continue_after_check_cert) { |
| 628 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSLVERSION, ssl_version), "CURLOPT_SSLVERSION"); | 276 | return sc_result; |
| 629 | } | ||
| 630 | |||
| 631 | /* client certificate and key to present to server (SSL) */ | ||
| 632 | if (client_cert) | ||
| 633 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSLCERT, client_cert), "CURLOPT_SSLCERT"); | ||
| 634 | if (client_privkey) | ||
| 635 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSLKEY, client_privkey), "CURLOPT_SSLKEY"); | ||
| 636 | if (ca_cert) { | ||
| 637 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CAINFO, ca_cert), "CURLOPT_CAINFO"); | ||
| 638 | } | ||
| 639 | if (ca_cert || verify_peer_and_host) { | ||
| 640 | /* per default if we have a CA verify both the peer and the | ||
| 641 | * hostname in the certificate, can be switched off later */ | ||
| 642 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1), "CURLOPT_SSL_VERIFYPEER"); | ||
| 643 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2), "CURLOPT_SSL_VERIFYHOST"); | ||
| 644 | } else { | ||
| 645 | /* backward-compatible behaviour, be tolerant in checks | ||
| 646 | * TODO: depending on more options have aspects we want | ||
| 647 | * to be less tolerant about ssl verfications | ||
| 648 | */ | ||
| 649 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0), "CURLOPT_SSL_VERIFYPEER"); | ||
| 650 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0), "CURLOPT_SSL_VERIFYHOST"); | ||
| 651 | } | ||
| 652 | |||
| 653 | /* detect SSL library used by libcurl */ | ||
| 654 | ssl_library = curlhelp_get_ssl_library(); | ||
| 655 | |||
| 656 | /* try hard to get a stack of certificates to verify against */ | ||
| 657 | if (check_cert) { | ||
| 658 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) | ||
| 659 | /* inform curl to report back certificates */ | ||
| 660 | switch (ssl_library) { | ||
| 661 | case CURLHELP_SSL_LIBRARY_OPENSSL: | ||
| 662 | case CURLHELP_SSL_LIBRARY_LIBRESSL: | ||
| 663 | /* set callback to extract certificate with OpenSSL context function (works with | ||
| 664 | * OpenSSL-style libraries only!) */ | ||
| 665 | # ifdef USE_OPENSSL | ||
| 666 | /* libcurl and monitoring plugins built with OpenSSL, good */ | ||
| 667 | add_sslctx_verify_fun = true; | ||
| 668 | is_openssl_callback = true; | ||
| 669 | # endif /* USE_OPENSSL */ | ||
| 670 | /* libcurl is built with OpenSSL, monitoring plugins, so falling | ||
| 671 | * back to manually extracting certificate information */ | ||
| 672 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); | ||
| 673 | break; | ||
| 674 | |||
| 675 | case CURLHELP_SSL_LIBRARY_NSS: | ||
| 676 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | ||
| 677 | /* NSS: support for CERTINFO is implemented since 7.34.0 */ | ||
| 678 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); | ||
| 679 | # else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 680 | die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library '%s' is too old)\n", | ||
| 681 | curlhelp_get_ssl_library_string(ssl_library)); | ||
| 682 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 683 | break; | ||
| 684 | |||
| 685 | case CURLHELP_SSL_LIBRARY_GNUTLS: | ||
| 686 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) | ||
| 687 | /* GnuTLS: support for CERTINFO is implemented since 7.42.0 */ | ||
| 688 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); | ||
| 689 | # else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */ | ||
| 690 | die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library '%s' is too old)\n", | ||
| 691 | curlhelp_get_ssl_library_string(ssl_library)); | ||
| 692 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */ | ||
| 693 | break; | ||
| 694 | |||
| 695 | case CURLHELP_SSL_LIBRARY_UNKNOWN: | ||
| 696 | default: | ||
| 697 | die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (unknown SSL library '%s', must implement first)\n", | ||
| 698 | curlhelp_get_ssl_library_string(ssl_library)); | ||
| 699 | break; | ||
| 700 | } | 277 | } |
| 701 | # else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ | ||
| 702 | /* old libcurl, our only hope is OpenSSL, otherwise we are out of luck */ | ||
| 703 | if (ssl_library == CURLHELP_SSL_LIBRARY_OPENSSL || ssl_library == CURLHELP_SSL_LIBRARY_LIBRESSL) | ||
| 704 | add_sslctx_verify_fun = true; | ||
| 705 | else | ||
| 706 | die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (no CURLOPT_SSL_CTX_FUNCTION, no OpenSSL library or libcurl " | ||
| 707 | "too old and has no CURLOPT_CERTINFO)\n"); | ||
| 708 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ | ||
| 709 | } | 278 | } |
| 710 | |||
| 711 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 10, 6) /* required for CURLOPT_SSL_CTX_FUNCTION */ | ||
| 712 | // ssl ctx function is not available with all ssl backends | ||
| 713 | if (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, NULL) != CURLE_UNKNOWN_OPTION) | ||
| 714 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); | ||
| 715 | # endif | ||
| 716 | |||
| 717 | #endif /* LIBCURL_FEATURE_SSL */ | ||
| 718 | |||
| 719 | /* set default or user-given user agent identification */ | ||
| 720 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent), "CURLOPT_USERAGENT"); | ||
| 721 | |||
| 722 | /* proxy-authentication */ | ||
| 723 | if (strcmp(proxy_auth, "")) | ||
| 724 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxy_auth), "CURLOPT_PROXYUSERPWD"); | ||
| 725 | |||
| 726 | /* authentication */ | ||
| 727 | if (strcmp(user_auth, "")) | ||
| 728 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_USERPWD, user_auth), "CURLOPT_USERPWD"); | ||
| 729 | |||
| 730 | /* TODO: parameter auth method, bitfield of following methods: | ||
| 731 | * CURLAUTH_BASIC (default) | ||
| 732 | * CURLAUTH_DIGEST | ||
| 733 | * CURLAUTH_DIGEST_IE | ||
| 734 | * CURLAUTH_NEGOTIATE | ||
| 735 | * CURLAUTH_NTLM | ||
| 736 | * CURLAUTH_NTLM_WB | ||
| 737 | * | ||
| 738 | * convenience tokens for typical sets of methods: | ||
| 739 | * CURLAUTH_ANYSAFE: most secure, without BASIC | ||
| 740 | * or CURLAUTH_ANY: most secure, even BASIC if necessary | ||
| 741 | * | ||
| 742 | * handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST ), "CURLOPT_HTTPAUTH"); | ||
| 743 | */ | ||
| 744 | |||
| 745 | /* handle redirections */ | ||
| 746 | if (onredirect == STATE_DEPENDENT) { | ||
| 747 | if (followmethod == FOLLOW_LIBCURL) { | ||
| 748 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1), "CURLOPT_FOLLOWLOCATION"); | ||
| 749 | |||
| 750 | /* default -1 is infinite, not good, could lead to zombie plugins! | ||
| 751 | Setting it to one bigger than maximal limit to handle errors nicely below | ||
| 752 | */ | ||
| 753 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_MAXREDIRS, max_depth + 1), "CURLOPT_MAXREDIRS"); | ||
| 754 | |||
| 755 | /* for now allow only http and https (we are a http(s) check plugin in the end) */ | ||
| 756 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 85, 0) | ||
| 757 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"), | ||
| 758 | "CURLOPT_REDIR_PROTOCOLS_STR"); | ||
| 759 | #elif LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) | ||
| 760 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), | ||
| 761 | "CURLOPT_REDIRECT_PROTOCOLS"); | ||
| 762 | #endif | 279 | #endif |
| 763 | 280 | ||
| 764 | /* TODO: handle the following aspects of redirection, make them | 281 | /* we got the data and we executed the request in a given time, so we can append |
| 765 | * command line options too later: | 282 | * performance data to the answer always |
| 766 | CURLOPT_POSTREDIR: method switch | 283 | */ |
| 767 | CURLINFO_REDIRECT_URL: custom redirect option | ||
| 768 | CURLOPT_REDIRECT_PROTOCOLS: allow people to step outside safe protocols | ||
| 769 | CURLINFO_REDIRECT_COUNT: get the number of redirects, print it, maybe a range option here is nice like for expected page size? | ||
| 770 | */ | ||
| 771 | } else { | ||
| 772 | /* old style redirection is handled below */ | ||
| 773 | } | ||
| 774 | } | ||
| 775 | |||
| 776 | /* no-body */ | ||
| 777 | if (no_body) | ||
| 778 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_NOBODY, 1), "CURLOPT_NOBODY"); | ||
| 779 | |||
| 780 | /* IPv4 or IPv6 forced DNS resolution */ | ||
| 781 | if (address_family == AF_UNSPEC) | ||
| 782 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER), | ||
| 783 | "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_WHATEVER)"); | ||
| 784 | else if (address_family == AF_INET) | ||
| 785 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4), | ||
| 786 | "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_V4)"); | ||
| 787 | #if defined(USE_IPV6) && defined(LIBCURL_FEATURE_IPV6) | ||
| 788 | else if (address_family == AF_INET6) | ||
| 789 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6), | ||
| 790 | "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_V6)"); | ||
| 791 | #endif | ||
| 792 | 284 | ||
| 793 | /* either send http POST data (any data, not only POST)*/ | 285 | // total time the query took |
| 794 | if (!strcmp(http_method, "POST") || !strcmp(http_method, "PUT")) { | 286 | mp_perfdata pd_total_time = perfdata_init(); |
| 795 | /* set content of payload for POST and PUT */ | 287 | mp_perfdata_value pd_val_total_time = mp_create_pd_value(total_time); |
| 796 | if (http_content_type) { | 288 | pd_total_time.value = pd_val_total_time; |
| 797 | snprintf(http_header, DEFAULT_BUFFER_SIZE, "Content-Type: %s", http_content_type); | 289 | pd_total_time = mp_pd_set_thresholds(pd_total_time, config.thlds); |
| 798 | header_list = curl_slist_append(header_list, http_header); | 290 | pd_total_time.label = "time"; |
| 799 | } | 291 | pd_total_time.uom = "s"; |
| 800 | /* NULL indicates "HTTP Continue" in libcurl, provide an empty string | 292 | |
| 801 | * in case of no POST/PUT data */ | 293 | mp_subcheck sc_total_time = mp_subcheck_init(); |
| 802 | if (!http_post_data) | 294 | sc_total_time = mp_set_subcheck_state(sc_total_time, mp_get_pd_status(pd_total_time)); |
| 803 | http_post_data = ""; | 295 | xasprintf(&sc_total_time.output, "Total connection time: %fs", total_time); |
| 804 | if (!strcmp(http_method, "POST")) { | 296 | mp_add_perfdata_to_subcheck(&sc_total_time, pd_total_time); |
| 805 | /* POST method, set payload with CURLOPT_POSTFIELDS */ | 297 | |
| 806 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_POSTFIELDS, http_post_data), "CURLOPT_POSTFIELDS"); | 298 | mp_add_subcheck_to_subcheck(&sc_result, sc_total_time); |
| 807 | } else if (!strcmp(http_method, "PUT")) { | 299 | |
| 808 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)curlhelp_buffer_read_callback), | 300 | if (config.show_extended_perfdata) { |
| 809 | "CURLOPT_READFUNCTION"); | 301 | // overall connection time |
| 810 | if (curlhelp_initreadbuffer(&put_buf, http_post_data, strlen(http_post_data)) < 0) | 302 | mp_perfdata pd_time_connect = perfdata_init(); |
| 811 | die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating read buffer for PUT\n"); | 303 | double time_connect; |
| 812 | put_buf_initialized = true; | 304 | handle_curl_option_return_code( |
| 813 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_READDATA, (void *)&put_buf), "CURLOPT_READDATA"); | 305 | curl_easy_getinfo(curl_state.curl, CURLINFO_CONNECT_TIME, &time_connect), |
| 814 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_INFILESIZE, (curl_off_t)strlen(http_post_data)), | 306 | "CURLINFO_CONNECT_TIME"); |
| 815 | "CURLOPT_INFILESIZE"); | 307 | |
| 308 | mp_perfdata_value pd_val_time_connect = mp_create_pd_value(time_connect); | ||
| 309 | pd_time_connect.value = pd_val_time_connect; | ||
| 310 | pd_time_connect.label = "time_connect"; | ||
| 311 | pd_time_connect.uom = "s"; | ||
| 312 | pd_time_connect = mp_set_pd_max_value( | ||
| 313 | pd_time_connect, mp_create_pd_value(config.curl_config.socket_timeout)); | ||
| 314 | |||
| 315 | pd_time_connect = mp_pd_set_thresholds(pd_time_connect, config.thlds); | ||
| 316 | mp_add_perfdata_to_subcheck(&sc_result, pd_time_connect); | ||
| 317 | |||
| 318 | // application connection time, used to compute other timings | ||
| 319 | double time_appconnect; | ||
| 320 | handle_curl_option_return_code( | ||
| 321 | curl_easy_getinfo(curl_state.curl, CURLINFO_APPCONNECT_TIME, &time_appconnect), | ||
| 322 | "CURLINFO_APPCONNECT_TIME"); | ||
| 323 | |||
| 324 | if (workingState.use_ssl) { | ||
| 325 | mp_perfdata pd_time_tls = perfdata_init(); | ||
| 326 | { | ||
| 327 | mp_perfdata_value pd_val_time_tls = | ||
| 328 | mp_create_pd_value(time_appconnect - time_connect); | ||
| 329 | |||
| 330 | pd_time_tls.value = pd_val_time_tls; | ||
| 331 | } | ||
| 332 | pd_time_tls.label = "time_tls"; | ||
| 333 | pd_time_tls.uom = "s"; | ||
| 334 | mp_add_perfdata_to_subcheck(&sc_result, pd_time_tls); | ||
| 816 | } | 335 | } |
| 817 | } | ||
| 818 | 336 | ||
| 819 | /* cookie handling */ | 337 | mp_perfdata pd_time_headers = perfdata_init(); |
| 820 | if (cookie_jar_file != NULL) { | 338 | { |
| 821 | /* enable reading cookies from a file, and if the filename is an empty string, only enable the curl cookie engine */ | 339 | double time_headers; |
| 822 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_COOKIEFILE, cookie_jar_file), "CURLOPT_COOKIEFILE"); | 340 | handle_curl_option_return_code( |
| 823 | /* now enable saving cookies to a file, but only if the filename is not an empty string, since writing it would fail */ | 341 | curl_easy_getinfo(curl_state.curl, CURLINFO_PRETRANSFER_TIME, &time_headers), |
| 824 | if (*cookie_jar_file) | 342 | "CURLINFO_PRETRANSFER_TIME"); |
| 825 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_COOKIEJAR, cookie_jar_file), "CURLOPT_COOKIEJAR"); | ||
| 826 | } | ||
| 827 | |||
| 828 | /* do the request */ | ||
| 829 | res = curl_easy_perform(curl); | ||
| 830 | |||
| 831 | if (verbose >= 2 && http_post_data) | ||
| 832 | printf("**** REQUEST CONTENT ****\n%s\n", http_post_data); | ||
| 833 | 343 | ||
| 834 | /* free header and server IP resolve lists, we don't need it anymore */ | 344 | mp_perfdata_value pd_val_time_headers = |
| 835 | curl_slist_free_all(header_list); | 345 | mp_create_pd_value(time_headers - time_appconnect); |
| 836 | header_list = NULL; | ||
| 837 | curl_slist_free_all(server_ips); | ||
| 838 | server_ips = NULL; | ||
| 839 | if (host) { | ||
| 840 | curl_slist_free_all(host); | ||
| 841 | host = NULL; | ||
| 842 | } | ||
| 843 | 346 | ||
| 844 | /* Curl errors, result in critical Nagios state */ | 347 | pd_time_headers.value = pd_val_time_headers; |
| 845 | if (res != CURLE_OK) { | 348 | } |
| 846 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"), server_port, | 349 | pd_time_headers.label = "time_headers"; |
| 847 | res, errbuf[0] ? errbuf : curl_easy_strerror(res)); | 350 | pd_time_headers.uom = "s"; |
| 848 | die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 351 | mp_add_perfdata_to_subcheck(&sc_result, pd_time_headers); |
| 849 | } | ||
| 850 | 352 | ||
| 851 | /* certificate checks */ | 353 | mp_perfdata pd_time_firstbyte = perfdata_init(); |
| 852 | #ifdef LIBCURL_FEATURE_SSL | 354 | double time_firstbyte; |
| 853 | if (use_ssl) { | 355 | handle_curl_option_return_code( |
| 854 | if (check_cert) { | 356 | curl_easy_getinfo(curl_state.curl, CURLINFO_STARTTRANSFER_TIME, &time_firstbyte), |
| 855 | if (is_openssl_callback) { | 357 | "CURLINFO_STARTTRANSFER_TIME"); |
| 856 | # ifdef USE_OPENSSL | ||
| 857 | /* check certificate with OpenSSL functions, curl has been built against OpenSSL | ||
| 858 | * and we actually have OpenSSL in the monitoring tools | ||
| 859 | */ | ||
| 860 | result_ssl = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); | ||
| 861 | if (!continue_after_check_cert) { | ||
| 862 | return result_ssl; | ||
| 863 | } | ||
| 864 | # else /* USE_OPENSSL */ | ||
| 865 | die(STATE_CRITICAL, | ||
| 866 | "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n"); | ||
| 867 | # endif /* USE_OPENSSL */ | ||
| 868 | } else { | ||
| 869 | int i; | ||
| 870 | struct curl_slist *slist; | ||
| 871 | 358 | ||
| 872 | cert_ptr.to_info = NULL; | 359 | mp_perfdata_value pd_val_time_firstbyte = mp_create_pd_value(time_firstbyte); |
| 873 | res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &cert_ptr.to_info); | 360 | pd_time_firstbyte.value = pd_val_time_firstbyte; |
| 874 | if (!res && cert_ptr.to_info) { | 361 | pd_time_firstbyte.label = "time_firstbyte"; |
| 875 | # ifdef USE_OPENSSL | 362 | pd_time_firstbyte.uom = "s"; |
| 876 | /* We have no OpenSSL in libcurl, but we can use OpenSSL for X509 cert parsing | 363 | mp_add_perfdata_to_subcheck(&sc_result, pd_time_firstbyte); |
| 877 | * We only check the first certificate and assume it's the one of the server | ||
| 878 | */ | ||
| 879 | const char *raw_cert = NULL; | ||
| 880 | for (i = 0; i < cert_ptr.to_certinfo->num_of_certs; i++) { | ||
| 881 | for (slist = cert_ptr.to_certinfo->certinfo[i]; slist; slist = slist->next) { | ||
| 882 | if (verbose >= 2) | ||
| 883 | printf("%d ** %s\n", i, slist->data); | ||
| 884 | if (strncmp(slist->data, "Cert:", 5) == 0) { | ||
| 885 | raw_cert = &slist->data[5]; | ||
| 886 | goto GOT_FIRST_CERT; | ||
| 887 | } | ||
| 888 | } | ||
| 889 | } | ||
| 890 | GOT_FIRST_CERT: | ||
| 891 | if (!raw_cert) { | ||
| 892 | snprintf(msg, DEFAULT_BUFFER_SIZE, | ||
| 893 | _("Cannot retrieve certificates from CERTINFO information - certificate data was empty")); | ||
| 894 | die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | ||
| 895 | } | ||
| 896 | BIO *cert_BIO = BIO_new(BIO_s_mem()); | ||
| 897 | BIO_write(cert_BIO, raw_cert, strlen(raw_cert)); | ||
| 898 | cert = PEM_read_bio_X509(cert_BIO, NULL, NULL, NULL); | ||
| 899 | if (!cert) { | ||
| 900 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Cannot read certificate from CERTINFO information - BIO error")); | ||
| 901 | die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | ||
| 902 | } | ||
| 903 | BIO_free(cert_BIO); | ||
| 904 | result_ssl = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); | ||
| 905 | if (!continue_after_check_cert) { | ||
| 906 | return result_ssl; | ||
| 907 | } | ||
| 908 | # else /* USE_OPENSSL */ | ||
| 909 | /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, | ||
| 910 | * so we use the libcurl CURLINFO data | ||
| 911 | */ | ||
| 912 | result_ssl = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); | ||
| 913 | if (!continue_after_check_cert) { | ||
| 914 | return result_ssl; | ||
| 915 | } | ||
| 916 | # endif /* USE_OPENSSL */ | ||
| 917 | } else { | ||
| 918 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates - cURL returned %d - %s"), res, | ||
| 919 | curl_easy_strerror(res)); | ||
| 920 | die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | ||
| 921 | } | ||
| 922 | } | ||
| 923 | } | ||
| 924 | } | ||
| 925 | #endif /* LIBCURL_FEATURE_SSL */ | ||
| 926 | 364 | ||
| 927 | /* we got the data and we executed the request in a given time, so we can append | 365 | mp_perfdata pd_time_transfer = perfdata_init(); |
| 928 | * performance data to the answer always | 366 | pd_time_transfer.value = mp_create_pd_value(total_time - time_firstbyte); |
| 929 | */ | 367 | pd_time_transfer.label = "time_transfer"; |
| 930 | handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time), "CURLINFO_TOTAL_TIME"); | 368 | pd_time_transfer.uom = "s"; |
| 931 | page_len = get_content_length(&header_buf, &body_buf); | 369 | mp_add_perfdata_to_subcheck(&sc_result, pd_time_transfer); |
| 932 | if (show_extended_perfdata) { | ||
| 933 | handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &time_connect), "CURLINFO_CONNECT_TIME"); | ||
| 934 | handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME, &time_appconnect), "CURLINFO_APPCONNECT_TIME"); | ||
| 935 | handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME, &time_headers), "CURLINFO_PRETRANSFER_TIME"); | ||
| 936 | handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME, &time_firstbyte), | ||
| 937 | "CURLINFO_STARTTRANSFER_TIME"); | ||
| 938 | snprintf(perfstring, DEFAULT_BUFFER_SIZE, "%s %s %s %s %s %s %s", perfd_time(total_time), perfd_size(page_len), | ||
| 939 | perfd_time_connect(time_connect), use_ssl ? perfd_time_ssl(time_appconnect - time_connect) : "", | ||
| 940 | perfd_time_headers(time_headers - time_appconnect), perfd_time_firstbyte(time_firstbyte - time_headers), | ||
| 941 | perfd_time_transfer(total_time - time_firstbyte)); | ||
| 942 | } else { | ||
| 943 | snprintf(perfstring, DEFAULT_BUFFER_SIZE, "%s %s", perfd_time(total_time), perfd_size(page_len)); | ||
| 944 | } | 370 | } |
| 945 | 371 | ||
| 946 | /* return a CRITICAL status if we couldn't read any data */ | 372 | /* return a CRITICAL status if we couldn't read any data */ |
| 947 | if (strlen(header_buf.buf) == 0 && strlen(body_buf.buf) == 0) | 373 | if (strlen(curl_state.header_buf->buf) == 0 && strlen(curl_state.body_buf->buf) == 0) { |
| 948 | die(STATE_CRITICAL, _("HTTP CRITICAL - No header received from host\n")); | 374 | sc_result = mp_set_subcheck_state(sc_result, STATE_CRITICAL); |
| 949 | 375 | xasprintf(&sc_result.output, "No header received from host"); | |
| 950 | /* get status line of answer, check sanity of HTTP code */ | 376 | return sc_result; |
| 951 | if (curlhelp_parse_statusline(header_buf.buf, &status_line) < 0) { | ||
| 952 | snprintf(msg, DEFAULT_BUFFER_SIZE, "Unparsable status line in %.3g seconds response time|%s\n", total_time, perfstring); | ||
| 953 | /* we cannot know the major/minor version here for sure as we cannot parse the first line */ | ||
| 954 | die(STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg); | ||
| 955 | } | 377 | } |
| 956 | status_line_initialized = true; | ||
| 957 | 378 | ||
| 958 | /* get result code from cURL */ | 379 | /* get result code from cURL */ |
| 959 | handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code), "CURLINFO_RESPONSE_CODE"); | 380 | long httpReturnCode; |
| 960 | if (verbose >= 2) | 381 | handle_curl_option_return_code( |
| 961 | printf("* curl CURLINFO_RESPONSE_CODE is %ld\n", code); | 382 | curl_easy_getinfo(curl_state.curl, CURLINFO_RESPONSE_CODE, &httpReturnCode), |
| 383 | "CURLINFO_RESPONSE_CODE"); | ||
| 384 | if (verbose >= 2) { | ||
| 385 | printf("* curl CURLINFO_RESPONSE_CODE is %ld\n", httpReturnCode); | ||
| 386 | } | ||
| 962 | 387 | ||
| 963 | /* print status line, header, body if verbose */ | 388 | /* print status line, header, body if verbose */ |
| 964 | if (verbose >= 2) { | 389 | if (verbose >= 2) { |
| 965 | printf("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header_buf.buf, (no_body ? " [[ skipped ]]" : body_buf.buf)); | 390 | printf("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", curl_state.header_buf->buf, |
| 391 | (workingState.no_body ? " [[ skipped ]]" : curl_state.body_buf->buf)); | ||
| 966 | } | 392 | } |
| 967 | 393 | ||
| 968 | /* make sure the status line matches the response we are looking for */ | 394 | /* make sure the status line matches the response we are looking for */ |
| 969 | if (!expected_statuscode(status_line.first_line, server_expect)) { | 395 | mp_subcheck sc_expect = mp_subcheck_init(); |
| 970 | if (server_port == HTTP_PORT) | 396 | sc_expect = mp_set_subcheck_default_state(sc_expect, STATE_OK); |
| 971 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"), status_line.first_line); | 397 | if (!expected_statuscode(curl_state.status_line->first_line, config.server_expect.string)) { |
| 972 | else | 398 | if (workingState.serverPort == HTTP_PORT) { |
| 973 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: %s\n"), server_port, | 399 | xasprintf(&sc_expect.output, _("Invalid HTTP response received from host: %s\n"), |
| 974 | status_line.first_line); | 400 | curl_state.status_line->first_line); |
| 975 | die(STATE_CRITICAL, "HTTP CRITICAL - %s%s%s", msg, show_body ? "\n" : "", show_body ? body_buf.buf : ""); | 401 | } else { |
| 402 | xasprintf(&sc_expect.output, | ||
| 403 | _("Invalid HTTP response received from host on port %d: %s\n"), | ||
| 404 | workingState.serverPort, curl_state.status_line->first_line); | ||
| 405 | } | ||
| 406 | sc_expect = mp_set_subcheck_default_state(sc_expect, STATE_CRITICAL); | ||
| 407 | } else { | ||
| 408 | xasprintf(&sc_expect.output, _("Status line output matched \"%s\""), | ||
| 409 | config.server_expect.string); | ||
| 976 | } | 410 | } |
| 411 | mp_add_subcheck_to_subcheck(&sc_result, sc_expect); | ||
| 977 | 412 | ||
| 978 | if (server_expect_yn) { | 413 | if (!config.server_expect.is_present) { |
| 979 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Status line output matched \"%s\" - "), server_expect); | ||
| 980 | if (verbose) | ||
| 981 | printf("%s\n", msg); | ||
| 982 | result = STATE_OK; | ||
| 983 | } else { | ||
| 984 | /* illegal return codes result in a critical state */ | 414 | /* illegal return codes result in a critical state */ |
| 985 | if (code >= 600 || code < 100) { | 415 | mp_subcheck sc_return_code = mp_subcheck_init(); |
| 986 | die(STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%d, %.40s)\n"), status_line.http_code, status_line.msg); | 416 | sc_return_code = mp_set_subcheck_default_state(sc_return_code, STATE_OK); |
| 987 | /* server errors result in a critical state */ | 417 | xasprintf(&sc_return_code.output, "HTTP return code: %d", |
| 988 | } else if (code >= 500) { | 418 | curl_state.status_line->http_code); |
| 989 | result = STATE_CRITICAL; | 419 | |
| 420 | if (httpReturnCode >= 600 || httpReturnCode < 100) { | ||
| 421 | sc_return_code = mp_set_subcheck_state(sc_return_code, STATE_CRITICAL); | ||
| 422 | xasprintf(&sc_return_code.output, _("Invalid Status (%d, %.40s)"), | ||
| 423 | curl_state.status_line->http_code, curl_state.status_line->msg); | ||
| 424 | mp_add_subcheck_to_subcheck(&sc_result, sc_return_code); | ||
| 425 | return sc_result; | ||
| 426 | } | ||
| 427 | |||
| 428 | // server errors result in a critical state | ||
| 429 | if (httpReturnCode >= 500) { | ||
| 430 | sc_return_code = mp_set_subcheck_state(sc_return_code, STATE_CRITICAL); | ||
| 990 | /* client errors result in a warning state */ | 431 | /* client errors result in a warning state */ |
| 991 | } else if (code >= 400) { | 432 | } else if (httpReturnCode >= 400) { |
| 992 | result = STATE_WARNING; | 433 | sc_return_code = mp_set_subcheck_state(sc_return_code, STATE_WARNING); |
| 993 | /* check redirected page if specified */ | 434 | /* check redirected page if specified */ |
| 994 | } else if (code >= 300) { | 435 | } else if (httpReturnCode >= 300) { |
| 995 | if (onredirect == STATE_DEPENDENT) { | 436 | if (config.on_redirect_dependent) { |
| 996 | if (followmethod == FOLLOW_LIBCURL) { | 437 | if (config.followmethod == FOLLOW_LIBCURL) { |
| 997 | code = status_line.http_code; | 438 | httpReturnCode = curl_state.status_line->http_code; |
| 439 | handle_curl_option_return_code( | ||
| 440 | curl_easy_getinfo(curl_state.curl, CURLINFO_REDIRECT_COUNT, &redir_depth), | ||
| 441 | "CURLINFO_REDIRECT_COUNT"); | ||
| 442 | |||
| 443 | if (verbose >= 2) { | ||
| 444 | printf(_("* curl LIBINFO_REDIRECT_COUNT is %ld\n"), redir_depth); | ||
| 445 | } | ||
| 446 | |||
| 447 | mp_subcheck sc_redir_depth = mp_subcheck_init(); | ||
| 448 | if (redir_depth > config.max_depth) { | ||
| 449 | xasprintf(&sc_redir_depth.output, | ||
| 450 | "maximum redirection depth %ld exceeded in libcurl", | ||
| 451 | config.max_depth); | ||
| 452 | sc_redir_depth = mp_set_subcheck_state(sc_redir_depth, STATE_CRITICAL); | ||
| 453 | mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth); | ||
| 454 | return sc_result; | ||
| 455 | } | ||
| 456 | xasprintf(&sc_redir_depth.output, "redirection depth %ld (of a maximum %ld)", | ||
| 457 | redir_depth, config.max_depth); | ||
| 458 | mp_add_subcheck_to_subcheck(&sc_result, sc_redir_depth); | ||
| 459 | |||
| 998 | } else { | 460 | } else { |
| 999 | /* old check_http style redirection, if we come | 461 | /* old check_http style redirection, if we come |
| 1000 | * back here, we are in the same status as with | 462 | * back here, we are in the same status as with |
| 1001 | * the libcurl method | 463 | * the libcurl method |
| 1002 | */ | 464 | */ |
| 1003 | redir(&header_buf); | 465 | redir_wrapper redir_result = |
| 466 | redir(curl_state.header_buf, config, redir_depth, workingState); | ||
| 467 | cleanup(curl_state); | ||
| 468 | mp_subcheck sc_redir = | ||
| 469 | check_http(config, redir_result.working_state, redir_result.redir_depth); | ||
| 470 | mp_add_subcheck_to_subcheck(&sc_result, sc_redir); | ||
| 471 | |||
| 472 | return sc_result; | ||
| 1004 | } | 473 | } |
| 1005 | } else { | 474 | } else { |
| 1006 | /* this is a specific code in the command line to | 475 | /* this is a specific code in the command line to |
| 1007 | * be returned when a redirection is encountered | 476 | * be returned when a redirection is encountered |
| 1008 | */ | 477 | */ |
| 478 | sc_return_code = | ||
| 479 | mp_set_subcheck_state(sc_return_code, config.on_redirect_result_state); | ||
| 1009 | } | 480 | } |
| 1010 | result = max_state_alt(onredirect, result); | ||
| 1011 | /* all other codes are considered ok */ | ||
| 1012 | } else { | 481 | } else { |
| 1013 | result = STATE_OK; | 482 | sc_return_code = mp_set_subcheck_state(sc_return_code, STATE_OK); |
| 1014 | } | 483 | } |
| 1015 | } | ||
| 1016 | 484 | ||
| 1017 | /* libcurl redirection internally, handle error states here */ | 485 | mp_add_subcheck_to_subcheck(&sc_result, sc_return_code); |
| 1018 | if (followmethod == FOLLOW_LIBCURL) { | ||
| 1019 | handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &redir_depth), "CURLINFO_REDIRECT_COUNT"); | ||
| 1020 | if (verbose >= 2) | ||
| 1021 | printf(_("* curl LIBINFO_REDIRECT_COUNT is %d\n"), redir_depth); | ||
| 1022 | if (redir_depth > max_depth) { | ||
| 1023 | snprintf(msg, DEFAULT_BUFFER_SIZE, "maximum redirection depth %d exceeded in libcurl", max_depth); | ||
| 1024 | die(STATE_WARNING, "HTTP WARNING - %s", msg); | ||
| 1025 | } | ||
| 1026 | } | 486 | } |
| 1027 | 487 | ||
| 1028 | /* check status codes, set exit status accordingly */ | 488 | /* check status codes, set exit status accordingly */ |
| 1029 | if (status_line.http_code != code) { | 489 | if (curl_state.status_line->http_code != httpReturnCode) { |
| 1030 | die(STATE_CRITICAL, _("HTTP CRITICAL %s %d %s - different HTTP codes (cUrl has %ld)\n"), | 490 | mp_subcheck sc_http_return_code_sanity = mp_subcheck_init(); |
| 1031 | string_statuscode(status_line.http_major, status_line.http_minor), status_line.http_code, status_line.msg, code); | 491 | sc_http_return_code_sanity = |
| 492 | mp_set_subcheck_state(sc_http_return_code_sanity, STATE_CRITICAL); | ||
| 493 | xasprintf(&sc_http_return_code_sanity.output, | ||
| 494 | _("HTTP CRITICAL %s %d %s - different HTTP codes (cUrl has %ld)\n"), | ||
| 495 | string_statuscode(curl_state.status_line->http_major, | ||
| 496 | curl_state.status_line->http_minor), | ||
| 497 | curl_state.status_line->http_code, curl_state.status_line->msg, httpReturnCode); | ||
| 498 | |||
| 499 | mp_add_subcheck_to_subcheck(&sc_result, sc_http_return_code_sanity); | ||
| 500 | return sc_result; | ||
| 1032 | } | 501 | } |
| 1033 | 502 | ||
| 1034 | if (maximum_age >= 0) { | 503 | if (config.maximum_age >= 0) { |
| 1035 | result = max_state_alt(check_document_dates(&header_buf, &msg), result); | 504 | mp_subcheck sc_max_age = check_document_dates(curl_state.header_buf, config.maximum_age); |
| 505 | mp_add_subcheck_to_subcheck(&sc_result, sc_max_age); | ||
| 1036 | } | 506 | } |
| 1037 | 507 | ||
| 1038 | /* Page and Header content checks go here */ | 508 | /* Page and Header content checks go here */ |
| 509 | if (strlen(config.header_expect)) { | ||
| 510 | mp_subcheck sc_header_expect = mp_subcheck_init(); | ||
| 511 | sc_header_expect = mp_set_subcheck_default_state(sc_header_expect, STATE_OK); | ||
| 512 | xasprintf(&sc_header_expect.output, "Expect %s in header", config.header_expect); | ||
| 1039 | 513 | ||
| 1040 | if (strlen(header_expect)) { | 514 | if (!strstr(curl_state.header_buf->buf, config.header_expect)) { |
| 1041 | if (!strstr(header_buf.buf, header_expect)) { | 515 | char output_header_search[30] = ""; |
| 1042 | 516 | strncpy(&output_header_search[0], config.header_expect, sizeof(output_header_search)); | |
| 1043 | strncpy(&output_header_search[0], header_expect, sizeof(output_header_search)); | ||
| 1044 | 517 | ||
| 1045 | if (output_header_search[sizeof(output_header_search) - 1] != '\0') { | 518 | if (output_header_search[sizeof(output_header_search) - 1] != '\0') { |
| 1046 | bcopy("...", &output_header_search[sizeof(output_header_search) - 4], 4); | 519 | bcopy("...", &output_header_search[sizeof(output_header_search) - 4], 4); |
| 1047 | } | 520 | } |
| 1048 | 521 | ||
| 1049 | char tmp[DEFAULT_BUFFER_SIZE]; | 522 | xasprintf(&sc_header_expect.output, _("header '%s' not found on '%s://%s:%d%s', "), |
| 1050 | 523 | output_header_search, workingState.use_ssl ? "https" : "http", | |
| 1051 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, output_header_search, | 524 | workingState.host_name ? workingState.host_name : workingState.server_address, |
| 1052 | use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); | 525 | workingState.serverPort, workingState.server_url); |
| 1053 | 526 | ||
| 1054 | strcpy(msg, tmp); | 527 | sc_header_expect = mp_set_subcheck_state(sc_header_expect, STATE_CRITICAL); |
| 1055 | |||
| 1056 | result = STATE_CRITICAL; | ||
| 1057 | } | 528 | } |
| 529 | |||
| 530 | mp_add_subcheck_to_subcheck(&sc_result, sc_header_expect); | ||
| 1058 | } | 531 | } |
| 1059 | 532 | ||
| 1060 | if (strlen(string_expect)) { | 533 | if (strlen(config.string_expect)) { |
| 1061 | if (!strstr(body_buf.buf, string_expect)) { | 534 | mp_subcheck sc_string_expect = mp_subcheck_init(); |
| 535 | sc_string_expect = mp_set_subcheck_default_state(sc_string_expect, STATE_OK); | ||
| 536 | xasprintf(&sc_string_expect.output, "Expect string \"%s\" in body", config.string_expect); | ||
| 1062 | 537 | ||
| 1063 | strncpy(&output_string_search[0], string_expect, sizeof(output_string_search)); | 538 | if (!strstr(curl_state.body_buf->buf, config.string_expect)) { |
| 539 | char output_string_search[30] = ""; | ||
| 540 | strncpy(&output_string_search[0], config.string_expect, sizeof(output_string_search)); | ||
| 1064 | 541 | ||
| 1065 | if (output_string_search[sizeof(output_string_search) - 1] != '\0') { | 542 | if (output_string_search[sizeof(output_string_search) - 1] != '\0') { |
| 1066 | bcopy("...", &output_string_search[sizeof(output_string_search) - 4], 4); | 543 | bcopy("...", &output_string_search[sizeof(output_string_search) - 4], 4); |
| 1067 | } | 544 | } |
| 1068 | 545 | ||
| 1069 | char tmp[DEFAULT_BUFFER_SIZE]; | 546 | xasprintf(&sc_string_expect.output, _("string '%s' not found on '%s://%s:%d%s', "), |
| 547 | output_string_search, workingState.use_ssl ? "https" : "http", | ||
| 548 | workingState.host_name ? workingState.host_name : workingState.server_address, | ||
| 549 | workingState.serverPort, workingState.server_url); | ||
| 1070 | 550 | ||
| 1071 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, | 551 | sc_string_expect = mp_set_subcheck_state(sc_string_expect, STATE_CRITICAL); |
| 1072 | use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); | ||
| 1073 | |||
| 1074 | strcpy(msg, tmp); | ||
| 1075 | |||
| 1076 | result = STATE_CRITICAL; | ||
| 1077 | } | 552 | } |
| 553 | |||
| 554 | mp_add_subcheck_to_subcheck(&sc_result, sc_string_expect); | ||
| 1078 | } | 555 | } |
| 1079 | 556 | ||
| 1080 | if (strlen(regexp)) { | 557 | if (strlen(config.regexp)) { |
| 1081 | errcode = regexec(&preg, body_buf.buf, REGS, pmatch, 0); | 558 | mp_subcheck sc_body_regex = mp_subcheck_init(); |
| 1082 | if ((errcode == 0 && !invert_regex) || (errcode == REG_NOMATCH && invert_regex)) { | 559 | xasprintf(&sc_body_regex.output, "Regex \"%s\" in body matched", config.regexp); |
| 1083 | /* OK - No-op to avoid changing the logic around it */ | 560 | regmatch_t pmatch[REGS]; |
| 1084 | result = max_state_alt(STATE_OK, result); | ||
| 1085 | } else if ((errcode == REG_NOMATCH && !invert_regex) || (errcode == 0 && invert_regex)) { | ||
| 1086 | if (!invert_regex) { | ||
| 1087 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
| 1088 | 561 | ||
| 1089 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%spattern not found, "), msg); | 562 | int errcode = regexec(&config.compiled_regex, curl_state.body_buf->buf, REGS, pmatch, 0); |
| 1090 | strcpy(msg, tmp); | ||
| 1091 | 563 | ||
| 564 | if (errcode == 0) { | ||
| 565 | // got a match | ||
| 566 | if (config.invert_regex) { | ||
| 567 | sc_body_regex = mp_set_subcheck_state(sc_body_regex, config.state_regex); | ||
| 1092 | } else { | 568 | } else { |
| 1093 | char tmp[DEFAULT_BUFFER_SIZE]; | 569 | sc_body_regex = mp_set_subcheck_state(sc_body_regex, STATE_OK); |
| 570 | } | ||
| 571 | } else if (errcode == REG_NOMATCH) { | ||
| 572 | // got no match | ||
| 573 | xasprintf(&sc_body_regex.output, "%s not", sc_body_regex.output); | ||
| 1094 | 574 | ||
| 1095 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%spattern found, "), msg); | 575 | if (config.invert_regex) { |
| 1096 | strcpy(msg, tmp); | 576 | sc_body_regex = mp_set_subcheck_state(sc_body_regex, STATE_OK); |
| 577 | } else { | ||
| 578 | sc_body_regex = mp_set_subcheck_state(sc_body_regex, config.state_regex); | ||
| 1097 | } | 579 | } |
| 1098 | result = state_regex; | ||
| 1099 | } else { | 580 | } else { |
| 1100 | regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); | 581 | // error in regexec |
| 1101 | 582 | char error_buffer[DEFAULT_BUFFER_SIZE]; | |
| 1102 | char tmp[DEFAULT_BUFFER_SIZE]; | 583 | regerror(errcode, &config.compiled_regex, &error_buffer[0], DEFAULT_BUFFER_SIZE); |
| 1103 | 584 | xasprintf(&sc_body_regex.output, "regexec error: %s", error_buffer); | |
| 1104 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sExecute Error: %s, "), msg, errbuf); | 585 | sc_body_regex = mp_set_subcheck_state(sc_body_regex, STATE_UNKNOWN); |
| 1105 | strcpy(msg, tmp); | ||
| 1106 | result = STATE_UNKNOWN; | ||
| 1107 | } | 586 | } |
| 587 | |||
| 588 | mp_add_subcheck_to_subcheck(&sc_result, sc_body_regex); | ||
| 1108 | } | 589 | } |
| 1109 | 590 | ||
| 1110 | /* make sure the page is of an appropriate size */ | 591 | // size a.k.a. page length |
| 1111 | if ((max_page_len > 0) && (page_len > max_page_len)) { | 592 | mp_perfdata pd_page_length = perfdata_init(); |
| 1112 | char tmp[DEFAULT_BUFFER_SIZE]; | 593 | mp_perfdata_value pd_val_page_length = mp_create_pd_value(page_len); |
| 594 | pd_page_length.value = pd_val_page_length; | ||
| 595 | pd_page_length.label = "size"; | ||
| 596 | pd_page_length.uom = "B"; | ||
| 597 | pd_page_length.min = mp_create_pd_value(0); | ||
| 598 | pd_page_length.warn = config.page_length_limits; | ||
| 599 | pd_page_length.warn_present = true; | ||
| 1113 | 600 | ||
| 1114 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%spage size %d too large, "), msg, page_len); | 601 | /* make sure the page is of an appropriate size */ |
| 602 | if (config.page_length_limits_is_set) { | ||
| 603 | mp_thresholds page_length_threshold = mp_thresholds_init(); | ||
| 604 | page_length_threshold.warning = config.page_length_limits; | ||
| 605 | page_length_threshold.warning_is_set = true; | ||
| 1115 | 606 | ||
| 1116 | strcpy(msg, tmp); | 607 | pd_page_length = mp_pd_set_thresholds(pd_page_length, page_length_threshold); |
| 1117 | 608 | ||
| 1118 | result = max_state_alt(STATE_WARNING, result); | 609 | mp_subcheck sc_page_length = mp_subcheck_init(); |
| 1119 | 610 | ||
| 1120 | } else if ((min_page_len > 0) && (page_len < min_page_len)) { | 611 | mp_add_perfdata_to_subcheck(&sc_page_length, pd_page_length); |
| 1121 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
| 1122 | 612 | ||
| 1123 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%spage size %d too small, "), msg, page_len); | 613 | mp_state_enum tmp_state = mp_get_pd_status(pd_page_length); |
| 1124 | strcpy(msg, tmp); | 614 | sc_page_length = mp_set_subcheck_state(sc_page_length, tmp_state); |
| 1125 | result = max_state_alt(STATE_WARNING, result); | ||
| 1126 | } | ||
| 1127 | 615 | ||
| 1128 | /* -w, -c: check warning and critical level */ | 616 | switch (tmp_state) { |
| 1129 | result = max_state_alt(get_status(total_time, thlds), result); | 617 | case STATE_CRITICAL: |
| 618 | case STATE_WARNING: | ||
| 619 | xasprintf(&sc_page_length.output, _("page size %zu violates threshold"), page_len); | ||
| 620 | break; | ||
| 621 | case STATE_OK: | ||
| 622 | xasprintf(&sc_page_length.output, _("page size %zu is OK"), page_len); | ||
| 623 | break; | ||
| 624 | default: | ||
| 625 | assert(false); | ||
| 626 | } | ||
| 1130 | 627 | ||
| 1131 | /* Cut-off trailing characters */ | 628 | mp_add_subcheck_to_subcheck(&sc_result, sc_page_length); |
| 1132 | if (strlen(msg) >= 2) { | ||
| 1133 | if (msg[strlen(msg) - 2] == ',') | ||
| 1134 | msg[strlen(msg) - 2] = '\0'; | ||
| 1135 | else | ||
| 1136 | msg[strlen(msg) - 3] = '\0'; | ||
| 1137 | } | 629 | } |
| 1138 | 630 | ||
| 1139 | /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ | 631 | return sc_result; |
| 1140 | die(max_state_alt(result, result_ssl), "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s", state_text(result), | ||
| 1141 | string_statuscode(status_line.http_major, status_line.http_minor), status_line.http_code, status_line.msg, | ||
| 1142 | strlen(msg) > 0 ? " - " : "", msg, page_len, total_time, (display_html ? "</A>" : ""), perfstring, (show_body ? body_buf.buf : ""), | ||
| 1143 | (show_body ? "\n" : "")); | ||
| 1144 | |||
| 1145 | return max_state_alt(result, result_ssl); | ||
| 1146 | } | 632 | } |
| 1147 | 633 | ||
| 1148 | int uri_strcmp(const UriTextRangeA range, const char *s) { | 634 | int uri_strcmp(const UriTextRangeA range, const char *stringToCompare) { |
| 1149 | if (!range.first) | 635 | if (!range.first) { |
| 1150 | return -1; | 636 | return -1; |
| 1151 | if ((size_t)(range.afterLast - range.first) < strlen(s)) | 637 | } |
| 638 | if ((size_t)(range.afterLast - range.first) < strlen(stringToCompare)) { | ||
| 1152 | return -1; | 639 | return -1; |
| 1153 | return strncmp(s, range.first, min((size_t)(range.afterLast - range.first), strlen(s))); | 640 | } |
| 641 | return strncmp(stringToCompare, range.first, | ||
| 642 | min((size_t)(range.afterLast - range.first), strlen(stringToCompare))); | ||
| 1154 | } | 643 | } |
| 1155 | 644 | ||
| 1156 | char *uri_string(const UriTextRangeA range, char *buf, size_t buflen) { | 645 | char *uri_string(const UriTextRangeA range, char *buf, size_t buflen) { |
| 1157 | if (!range.first) | 646 | if (!range.first) { |
| 1158 | return "(null)"; | 647 | return "(null)"; |
| 648 | } | ||
| 1159 | strncpy(buf, range.first, max(buflen - 1, (size_t)(range.afterLast - range.first))); | 649 | strncpy(buf, range.first, max(buflen - 1, (size_t)(range.afterLast - range.first))); |
| 1160 | buf[max(buflen - 1, (size_t)(range.afterLast - range.first))] = '\0'; | 650 | buf[max(buflen - 1, (size_t)(range.afterLast - range.first))] = '\0'; |
| 1161 | buf[range.afterLast - range.first] = '\0'; | 651 | buf[range.afterLast - range.first] = '\0'; |
| 1162 | return buf; | 652 | return buf; |
| 1163 | } | 653 | } |
| 1164 | 654 | ||
| 1165 | void redir(curlhelp_write_curlbuf *header_buf) { | 655 | redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config config, |
| 1166 | char *location = NULL; | 656 | long redir_depth, check_curl_working_state working_state) { |
| 1167 | curlhelp_statusline status_line; | 657 | curlhelp_statusline status_line; |
| 1168 | struct phr_header headers[255]; | 658 | struct phr_header headers[255]; |
| 1169 | size_t nof_headers = 255; | ||
| 1170 | size_t msglen; | 659 | size_t msglen; |
| 1171 | char buf[DEFAULT_BUFFER_SIZE]; | 660 | size_t nof_headers = 255; |
| 1172 | char ipstr[INET_ADDR_MAX_SIZE]; | 661 | int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major, |
| 1173 | int new_port; | 662 | &status_line.http_minor, &status_line.http_code, &status_line.msg, |
| 1174 | char *new_host; | 663 | &msglen, headers, &nof_headers, 0); |
| 1175 | char *new_url; | ||
| 1176 | |||
| 1177 | int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major, &status_line.http_minor, | ||
| 1178 | &status_line.http_code, &status_line.msg, &msglen, headers, &nof_headers, 0); | ||
| 1179 | 664 | ||
| 1180 | if (res == -1) { | 665 | if (res == -1) { |
| 1181 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); | 666 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); |
| 1182 | } | 667 | } |
| 1183 | 668 | ||
| 1184 | location = get_header_value(headers, nof_headers, "location"); | 669 | char *location = get_header_value(headers, nof_headers, "location"); |
| 1185 | 670 | ||
| 1186 | if (verbose >= 2) | 671 | if (location == NULL) { |
| 672 | // location header not found | ||
| 673 | die(STATE_UNKNOWN, "HTTP UNKNOWN - could not find \"location\" header\n"); | ||
| 674 | } | ||
| 675 | |||
| 676 | if (verbose >= 2) { | ||
| 1187 | printf(_("* Seen redirect location %s\n"), location); | 677 | printf(_("* Seen redirect location %s\n"), location); |
| 678 | } | ||
| 1188 | 679 | ||
| 1189 | if (++redir_depth > max_depth) | 680 | if (++redir_depth > config.max_depth) { |
| 1190 | die(STATE_WARNING, _("HTTP WARNING - maximum redirection depth %d exceeded - %s%s\n"), max_depth, location, | 681 | die(STATE_WARNING, _("HTTP WARNING - maximum redirection depth %ld exceeded - %s\n"), |
| 1191 | (display_html ? "</A>" : "")); | 682 | config.max_depth, location); |
| 683 | } | ||
| 1192 | 684 | ||
| 1193 | UriParserStateA state; | 685 | UriParserStateA state; |
| 1194 | UriUriA uri; | 686 | UriUriA uri; |
| 1195 | state.uri = &uri; | 687 | state.uri = &uri; |
| 1196 | if (uriParseUriA(&state, location) != URI_SUCCESS) { | 688 | if (uriParseUriA(&state, location) != URI_SUCCESS) { |
| 1197 | if (state.errorCode == URI_ERROR_SYNTAX) { | 689 | if (state.errorCode == URI_ERROR_SYNTAX) { |
| 1198 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not parse redirect location '%s'%s\n"), location, (display_html ? "</A>" : "")); | 690 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not parse redirect location '%s'\n"), |
| 691 | location); | ||
| 1199 | } else if (state.errorCode == URI_ERROR_MALLOC) { | 692 | } else if (state.errorCode == URI_ERROR_MALLOC) { |
| 1200 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n")); | 693 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n")); |
| 1201 | } | 694 | } |
| 1202 | } | 695 | } |
| 1203 | 696 | ||
| 697 | char ipstr[INET_ADDR_MAX_SIZE]; | ||
| 698 | char buf[DEFAULT_BUFFER_SIZE]; | ||
| 1204 | if (verbose >= 2) { | 699 | if (verbose >= 2) { |
| 1205 | printf(_("** scheme: %s\n"), uri_string(uri.scheme, buf, DEFAULT_BUFFER_SIZE)); | 700 | printf(_("** scheme: %s\n"), uri_string(uri.scheme, buf, DEFAULT_BUFFER_SIZE)); |
| 1206 | printf(_("** host: %s\n"), uri_string(uri.hostText, buf, DEFAULT_BUFFER_SIZE)); | 701 | printf(_("** host: %s\n"), uri_string(uri.hostText, buf, DEFAULT_BUFFER_SIZE)); |
| @@ -1215,9 +710,9 @@ void redir(curlhelp_write_curlbuf *header_buf) { | |||
| 1215 | } | 710 | } |
| 1216 | if (uri.pathHead) { | 711 | if (uri.pathHead) { |
| 1217 | printf(_("** path: ")); | 712 | printf(_("** path: ")); |
| 1218 | const UriPathSegmentA *p = uri.pathHead; | 713 | for (UriPathSegmentA *path_segment = uri.pathHead; path_segment; |
| 1219 | for (; p; p = p->next) { | 714 | path_segment = path_segment->next) { |
| 1220 | printf("/%s", uri_string(p->text, buf, DEFAULT_BUFFER_SIZE)); | 715 | printf("/%s", uri_string(path_segment->text, buf, DEFAULT_BUFFER_SIZE)); |
| 1221 | } | 716 | } |
| 1222 | puts(""); | 717 | puts(""); |
| 1223 | } | 718 | } |
| @@ -1230,99 +725,123 @@ void redir(curlhelp_write_curlbuf *header_buf) { | |||
| 1230 | } | 725 | } |
| 1231 | 726 | ||
| 1232 | if (uri.scheme.first) { | 727 | if (uri.scheme.first) { |
| 1233 | if (!uri_strcmp(uri.scheme, "https")) | 728 | working_state.use_ssl = (bool)(!uri_strcmp(uri.scheme, "https")); |
| 1234 | use_ssl = true; | ||
| 1235 | else | ||
| 1236 | use_ssl = false; | ||
| 1237 | } | 729 | } |
| 1238 | 730 | ||
| 1239 | /* we do a sloppy test here only, because uriparser would have failed | 731 | /* we do a sloppy test here only, because uriparser would have failed |
| 1240 | * above, if the port would be invalid, we just check for MAX_PORT | 732 | * above, if the port would be invalid, we just check for MAX_PORT |
| 1241 | */ | 733 | */ |
| 734 | int new_port; | ||
| 1242 | if (uri.portText.first) { | 735 | if (uri.portText.first) { |
| 1243 | new_port = atoi(uri_string(uri.portText, buf, DEFAULT_BUFFER_SIZE)); | 736 | new_port = atoi(uri_string(uri.portText, buf, DEFAULT_BUFFER_SIZE)); |
| 1244 | } else { | 737 | } else { |
| 1245 | new_port = HTTP_PORT; | 738 | new_port = HTTP_PORT; |
| 1246 | if (use_ssl) | 739 | if (working_state.use_ssl) { |
| 1247 | new_port = HTTPS_PORT; | 740 | new_port = HTTPS_PORT; |
| 741 | } | ||
| 742 | } | ||
| 743 | if (new_port > MAX_PORT) { | ||
| 744 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Redirection to port above %d - %s\n"), MAX_PORT, | ||
| 745 | location); | ||
| 1248 | } | 746 | } |
| 1249 | if (new_port > MAX_PORT) | ||
| 1250 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Redirection to port above %d - %s%s\n"), MAX_PORT, location, display_html ? "</A>" : ""); | ||
| 1251 | 747 | ||
| 1252 | /* by RFC 7231 relative URLs in Location should be taken relative to | 748 | /* by RFC 7231 relative URLs in Location should be taken relative to |
| 1253 | * the original URL, so we try to form a new absolute URL here | 749 | * the original URL, so we try to form a new absolute URL here |
| 1254 | */ | 750 | */ |
| 751 | char *new_host; | ||
| 1255 | if (!uri.scheme.first && !uri.hostText.first) { | 752 | if (!uri.scheme.first && !uri.hostText.first) { |
| 1256 | new_host = strdup(host_name ? host_name : server_address); | 753 | new_host = strdup(working_state.host_name ? working_state.host_name |
| 1257 | new_port = server_port; | 754 | : working_state.server_address); |
| 1258 | if (use_ssl) | 755 | new_port = working_state.serverPort; |
| 756 | if (working_state.use_ssl) { | ||
| 1259 | uri_string(uri.scheme, "https", DEFAULT_BUFFER_SIZE); | 757 | uri_string(uri.scheme, "https", DEFAULT_BUFFER_SIZE); |
| 758 | } | ||
| 1260 | } else { | 759 | } else { |
| 1261 | new_host = strdup(uri_string(uri.hostText, buf, DEFAULT_BUFFER_SIZE)); | 760 | new_host = strdup(uri_string(uri.hostText, buf, DEFAULT_BUFFER_SIZE)); |
| 1262 | } | 761 | } |
| 1263 | 762 | ||
| 1264 | /* compose new path */ | 763 | /* compose new path */ |
| 1265 | /* TODO: handle fragments and query part of URL */ | 764 | /* TODO: handle fragments of URL */ |
| 1266 | new_url = (char *)calloc(1, DEFAULT_BUFFER_SIZE); | 765 | char *new_url = (char *)calloc(1, DEFAULT_BUFFER_SIZE); |
| 1267 | if (uri.pathHead) { | 766 | if (uri.pathHead) { |
| 1268 | const UriPathSegmentA *p = uri.pathHead; | 767 | for (UriPathSegmentA *pathSegment = uri.pathHead; pathSegment; |
| 1269 | for (; p; p = p->next) { | 768 | pathSegment = pathSegment->next) { |
| 1270 | strncat(new_url, "/", DEFAULT_BUFFER_SIZE); | 769 | strncat(new_url, "/", DEFAULT_BUFFER_SIZE); |
| 1271 | strncat(new_url, uri_string(p->text, buf, DEFAULT_BUFFER_SIZE), DEFAULT_BUFFER_SIZE - 1); | 770 | strncat(new_url, uri_string(pathSegment->text, buf, DEFAULT_BUFFER_SIZE), |
| 771 | DEFAULT_BUFFER_SIZE - 1); | ||
| 1272 | } | 772 | } |
| 1273 | } | 773 | } |
| 1274 | 774 | ||
| 1275 | if (server_port == new_port && !strncmp(server_address, new_host, MAX_IPV4_HOSTLENGTH) && | 775 | /* missing components have null,null in their UriTextRangeA |
| 1276 | (host_name && !strncmp(host_name, new_host, MAX_IPV4_HOSTLENGTH)) && !strcmp(server_url, new_url)) | 776 | * add query parameters if they exist. |
| 1277 | die(STATE_CRITICAL, _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s%s\n"), use_ssl ? "https" : "http", | 777 | */ |
| 1278 | new_host, new_port, new_url, (display_html ? "</A>" : "")); | 778 | if (uri.query.first && uri.query.afterLast){ |
| 779 | // Ensure we have space for '?' + query_str + '\0' ahead of time, instead of calling strncat twice | ||
| 780 | size_t current_len = strlen(new_url); | ||
| 781 | size_t remaining_space = DEFAULT_BUFFER_SIZE - current_len - 1; | ||
| 782 | |||
| 783 | const char* query_str = uri_string(uri.query, buf, DEFAULT_BUFFER_SIZE); | ||
| 784 | size_t query_str_len = strlen(query_str); | ||
| 785 | |||
| 786 | if (remaining_space >= query_str_len + 1) { | ||
| 787 | strcat(new_url, "?"); | ||
| 788 | strcat(new_url, query_str); | ||
| 789 | }else{ | ||
| 790 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - No space to add query part of size %d to the buffer, buffer has remaining size %d"), query_str_len , current_len ); | ||
| 791 | } | ||
| 792 | } | ||
| 793 | |||
| 794 | if (working_state.serverPort == new_port && | ||
| 795 | !strncmp(working_state.server_address, new_host, MAX_IPV4_HOSTLENGTH) && | ||
| 796 | (working_state.host_name && | ||
| 797 | !strncmp(working_state.host_name, new_host, MAX_IPV4_HOSTLENGTH)) && | ||
| 798 | !strcmp(working_state.server_url, new_url)) { | ||
| 799 | die(STATE_CRITICAL, | ||
| 800 | _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s\n"), | ||
| 801 | working_state.use_ssl ? "https" : "http", new_host, new_port, new_url); | ||
| 802 | } | ||
| 1279 | 803 | ||
| 1280 | /* set new values for redirected request */ | 804 | /* set new values for redirected request */ |
| 1281 | 805 | ||
| 1282 | if (!(followsticky & STICKY_HOST)) { | 806 | if (!(config.followsticky & STICKY_HOST)) { |
| 1283 | free(server_address); | 807 | // free(working_state.server_address); |
| 1284 | server_address = strndup(new_host, MAX_IPV4_HOSTLENGTH); | 808 | working_state.server_address = strndup(new_host, MAX_IPV4_HOSTLENGTH); |
| 1285 | } | 809 | } |
| 1286 | if (!(followsticky & STICKY_PORT)) { | 810 | if (!(config.followsticky & STICKY_PORT)) { |
| 1287 | server_port = (unsigned short)new_port; | 811 | working_state.serverPort = (unsigned short)new_port; |
| 1288 | } | 812 | } |
| 1289 | 813 | ||
| 1290 | free(host_name); | 814 | // free(working_state.host_name); |
| 1291 | host_name = strndup(new_host, MAX_IPV4_HOSTLENGTH); | 815 | working_state.host_name = strndup(new_host, MAX_IPV4_HOSTLENGTH); |
| 1292 | 816 | ||
| 1293 | /* reset virtual port */ | 817 | /* reset virtual port */ |
| 1294 | virtual_port = server_port; | 818 | working_state.virtualPort = working_state.serverPort; |
| 1295 | 819 | ||
| 1296 | free(new_host); | 820 | free(new_host); |
| 1297 | free(server_url); | 821 | // free(working_state.server_url); |
| 1298 | server_url = new_url; | 822 | working_state.server_url = new_url; |
| 1299 | 823 | ||
| 1300 | uriFreeUriMembersA(&uri); | 824 | uriFreeUriMembersA(&uri); |
| 1301 | 825 | ||
| 1302 | if (verbose) | 826 | if (verbose) { |
| 1303 | printf(_("Redirection to %s://%s:%d%s\n"), use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, | 827 | printf(_("Redirection to %s://%s:%d%s\n"), working_state.use_ssl ? "https" : "http", |
| 1304 | server_url); | 828 | working_state.host_name ? working_state.host_name : working_state.server_address, |
| 829 | working_state.serverPort, working_state.server_url); | ||
| 830 | } | ||
| 1305 | 831 | ||
| 1306 | /* TODO: the hash component MUST be taken from the original URL and | 832 | /* TODO: the hash component MUST be taken from the original URL and |
| 1307 | * attached to the URL in Location | 833 | * attached to the URL in Location |
| 1308 | */ | 834 | */ |
| 1309 | 835 | ||
| 1310 | cleanup(); | 836 | redir_wrapper result = { |
| 1311 | check_http(); | 837 | .redir_depth = redir_depth, |
| 1312 | } | 838 | .working_state = working_state, |
| 1313 | 839 | .error_code = OK, | |
| 1314 | /* check whether a file exists */ | 840 | }; |
| 1315 | void test_file(char *path) { | 841 | return result; |
| 1316 | if (access(path, R_OK) == 0) | ||
| 1317 | return; | ||
| 1318 | usage2(_("file does not exist or is not readable"), path); | ||
| 1319 | } | 842 | } |
| 1320 | 843 | ||
| 1321 | bool process_arguments(int argc, char **argv) { | 844 | check_curl_config_wrapper process_arguments(int argc, char **argv) { |
| 1322 | char *p; | ||
| 1323 | int c = 1; | ||
| 1324 | char *temp; | ||
| 1325 | |||
| 1326 | enum { | 845 | enum { |
| 1327 | INVERT_REGEX = CHAR_MAX + 1, | 846 | INVERT_REGEX = CHAR_MAX + 1, |
| 1328 | SNI_OPTION, | 847 | SNI_OPTION, |
| @@ -1333,81 +852,101 @@ bool process_arguments(int argc, char **argv) { | |||
| 1333 | AUTOMATIC_DECOMPRESSION, | 852 | AUTOMATIC_DECOMPRESSION, |
| 1334 | COOKIE_JAR, | 853 | COOKIE_JAR, |
| 1335 | HAPROXY_PROTOCOL, | 854 | HAPROXY_PROTOCOL, |
| 1336 | STATE_REGEX | 855 | STATE_REGEX, |
| 856 | OUTPUT_FORMAT | ||
| 1337 | }; | 857 | }; |
| 1338 | 858 | ||
| 1339 | int option = 0; | 859 | static struct option longopts[] = { |
| 1340 | int got_plus = 0; | 860 | STD_LONG_OPTS, |
| 1341 | static struct option longopts[] = {STD_LONG_OPTS, | 861 | {"link", no_argument, 0, 'L'}, |
| 1342 | {"link", no_argument, 0, 'L'}, | 862 | {"nohtml", no_argument, 0, 'n'}, |
| 1343 | {"nohtml", no_argument, 0, 'n'}, | 863 | {"ssl", optional_argument, 0, 'S'}, |
| 1344 | {"ssl", optional_argument, 0, 'S'}, | 864 | {"sni", no_argument, 0, SNI_OPTION}, |
| 1345 | {"sni", no_argument, 0, SNI_OPTION}, | 865 | {"post", required_argument, 0, 'P'}, |
| 1346 | {"post", required_argument, 0, 'P'}, | 866 | {"method", required_argument, 0, 'j'}, |
| 1347 | {"method", required_argument, 0, 'j'}, | 867 | {"IP-address", required_argument, 0, 'I'}, |
| 1348 | {"IP-address", required_argument, 0, 'I'}, | 868 | {"url", required_argument, 0, 'u'}, |
| 1349 | {"url", required_argument, 0, 'u'}, | 869 | {"port", required_argument, 0, 'p'}, |
| 1350 | {"port", required_argument, 0, 'p'}, | 870 | {"authorization", required_argument, 0, 'a'}, |
| 1351 | {"authorization", required_argument, 0, 'a'}, | 871 | {"proxy-authorization", required_argument, 0, 'b'}, |
| 1352 | {"proxy-authorization", required_argument, 0, 'b'}, | 872 | {"header-string", required_argument, 0, 'd'}, |
| 1353 | {"header-string", required_argument, 0, 'd'}, | 873 | {"string", required_argument, 0, 's'}, |
| 1354 | {"string", required_argument, 0, 's'}, | 874 | {"expect", required_argument, 0, 'e'}, |
| 1355 | {"expect", required_argument, 0, 'e'}, | 875 | {"regex", required_argument, 0, 'r'}, |
| 1356 | {"regex", required_argument, 0, 'r'}, | 876 | {"ereg", required_argument, 0, 'r'}, |
| 1357 | {"ereg", required_argument, 0, 'r'}, | 877 | {"eregi", required_argument, 0, 'R'}, |
| 1358 | {"eregi", required_argument, 0, 'R'}, | 878 | {"linespan", no_argument, 0, 'l'}, |
| 1359 | {"linespan", no_argument, 0, 'l'}, | 879 | {"onredirect", required_argument, 0, 'f'}, |
| 1360 | {"onredirect", required_argument, 0, 'f'}, | 880 | {"certificate", required_argument, 0, 'C'}, |
| 1361 | {"certificate", required_argument, 0, 'C'}, | 881 | {"client-cert", required_argument, 0, 'J'}, |
| 1362 | {"client-cert", required_argument, 0, 'J'}, | 882 | {"private-key", required_argument, 0, 'K'}, |
| 1363 | {"private-key", required_argument, 0, 'K'}, | 883 | {"ca-cert", required_argument, 0, CA_CERT_OPTION}, |
| 1364 | {"ca-cert", required_argument, 0, CA_CERT_OPTION}, | 884 | {"verify-cert", no_argument, 0, 'D'}, |
| 1365 | {"verify-cert", no_argument, 0, 'D'}, | 885 | {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT}, |
| 1366 | {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT}, | 886 | {"useragent", required_argument, 0, 'A'}, |
| 1367 | {"useragent", required_argument, 0, 'A'}, | 887 | {"header", required_argument, 0, 'k'}, |
| 1368 | {"header", required_argument, 0, 'k'}, | 888 | {"no-body", no_argument, 0, 'N'}, |
| 1369 | {"no-body", no_argument, 0, 'N'}, | 889 | {"max-age", required_argument, 0, 'M'}, |
| 1370 | {"max-age", required_argument, 0, 'M'}, | 890 | {"content-type", required_argument, 0, 'T'}, |
| 1371 | {"content-type", required_argument, 0, 'T'}, | 891 | {"pagesize", required_argument, 0, 'm'}, |
| 1372 | {"pagesize", required_argument, 0, 'm'}, | 892 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, |
| 1373 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, | 893 | {"state-regex", required_argument, 0, STATE_REGEX}, |
| 1374 | {"state-regex", required_argument, 0, STATE_REGEX}, | 894 | {"use-ipv4", no_argument, 0, '4'}, |
| 1375 | {"use-ipv4", no_argument, 0, '4'}, | 895 | {"use-ipv6", no_argument, 0, '6'}, |
| 1376 | {"use-ipv6", no_argument, 0, '6'}, | 896 | {"extended-perfdata", no_argument, 0, 'E'}, |
| 1377 | {"extended-perfdata", no_argument, 0, 'E'}, | 897 | {"show-body", no_argument, 0, 'B'}, |
| 1378 | {"show-body", no_argument, 0, 'B'}, | 898 | {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION}, |
| 1379 | {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION}, | 899 | {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, |
| 1380 | {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, | 900 | {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION}, |
| 1381 | {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION}, | 901 | {"cookie-jar", required_argument, 0, COOKIE_JAR}, |
| 1382 | {"cookie-jar", required_argument, 0, COOKIE_JAR}, | 902 | {"haproxy-protocol", no_argument, 0, HAPROXY_PROTOCOL}, |
| 1383 | {"haproxy-protocol", no_argument, 0, HAPROXY_PROTOCOL}, | 903 | {"output-format", required_argument, 0, OUTPUT_FORMAT}, |
| 1384 | {0, 0, 0, 0}}; | 904 | {0, 0, 0, 0}}; |
| 1385 | 905 | ||
| 1386 | if (argc < 2) | 906 | check_curl_config_wrapper result = { |
| 1387 | return false; | 907 | .errorcode = OK, |
| 908 | .config = check_curl_config_init(), | ||
| 909 | }; | ||
| 1388 | 910 | ||
| 1389 | /* support check_http compatible arguments */ | 911 | if (argc < 2) { |
| 1390 | for (c = 1; c < argc; c++) { | 912 | result.errorcode = ERROR; |
| 1391 | if (strcmp("-to", argv[c]) == 0) | 913 | return result; |
| 1392 | strcpy(argv[c], "-t"); | ||
| 1393 | if (strcmp("-hn", argv[c]) == 0) | ||
| 1394 | strcpy(argv[c], "-H"); | ||
| 1395 | if (strcmp("-wt", argv[c]) == 0) | ||
| 1396 | strcpy(argv[c], "-w"); | ||
| 1397 | if (strcmp("-ct", argv[c]) == 0) | ||
| 1398 | strcpy(argv[c], "-c"); | ||
| 1399 | if (strcmp("-nohtml", argv[c]) == 0) | ||
| 1400 | strcpy(argv[c], "-n"); | ||
| 1401 | } | 914 | } |
| 1402 | 915 | ||
| 1403 | server_url = strdup(DEFAULT_SERVER_URL); | 916 | /* support check_http compatible arguments */ |
| 917 | for (int index = 1; index < argc; index++) { | ||
| 918 | if (strcmp("-to", argv[index]) == 0) { | ||
| 919 | strcpy(argv[index], "-t"); | ||
| 920 | } | ||
| 921 | if (strcmp("-hn", argv[index]) == 0) { | ||
| 922 | strcpy(argv[index], "-H"); | ||
| 923 | } | ||
| 924 | if (strcmp("-wt", argv[index]) == 0) { | ||
| 925 | strcpy(argv[index], "-w"); | ||
| 926 | } | ||
| 927 | if (strcmp("-ct", argv[index]) == 0) { | ||
| 928 | strcpy(argv[index], "-c"); | ||
| 929 | } | ||
| 930 | if (strcmp("-nohtml", argv[index]) == 0) { | ||
| 931 | strcpy(argv[index], "-n"); | ||
| 932 | } | ||
| 933 | } | ||
| 1404 | 934 | ||
| 1405 | while (1) { | 935 | int option = 0; |
| 1406 | c = getopt_long(argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:DnlLS::m:M:NEB", longopts, &option); | 936 | int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; |
| 1407 | if (c == -1 || c == EOF || c == 1) | 937 | bool specify_port = false; |
| 938 | bool enable_tls = false; | ||
| 939 | char *tls_option_optarg = NULL; | ||
| 940 | |||
| 941 | while (true) { | ||
| 942 | int option_index = getopt_long( | ||
| 943 | argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:DnlLS::m:M:NEB", | ||
| 944 | longopts, &option); | ||
| 945 | if (option_index == -1 || option_index == EOF || option_index == 1) { | ||
| 1408 | break; | 946 | break; |
| 947 | } | ||
| 1409 | 948 | ||
| 1410 | switch (c) { | 949 | switch (option_index) { |
| 1411 | case 'h': | 950 | case 'h': |
| 1412 | print_help(); | 951 | print_help(); |
| 1413 | exit(STATE_UNKNOWN); | 952 | exit(STATE_UNKNOWN); |
| @@ -1421,270 +960,253 @@ bool process_arguments(int argc, char **argv) { | |||
| 1421 | verbose++; | 960 | verbose++; |
| 1422 | break; | 961 | break; |
| 1423 | case 't': /* timeout period */ | 962 | case 't': /* timeout period */ |
| 1424 | if (!is_intnonneg(optarg)) | 963 | if (!is_intnonneg(optarg)) { |
| 1425 | usage2(_("Timeout interval must be a positive integer"), optarg); | 964 | usage2(_("Timeout interval must be a positive integer"), optarg); |
| 1426 | else | 965 | } else { |
| 1427 | socket_timeout = (int)strtol(optarg, NULL, 10); | 966 | result.config.curl_config.socket_timeout = (int)strtol(optarg, NULL, 10); |
| 967 | } | ||
| 1428 | break; | 968 | break; |
| 1429 | case 'c': /* critical time threshold */ | 969 | case 'c': /* critical time threshold */ |
| 1430 | critical_thresholds = optarg; | 970 | { |
| 1431 | break; | 971 | mp_range_parsed critical_range = mp_parse_range_string(optarg); |
| 972 | if (critical_range.error != MP_PARSING_SUCCES) { | ||
| 973 | die(STATE_UNKNOWN, "failed to parse critical threshold: %s", optarg); | ||
| 974 | } | ||
| 975 | result.config.thlds = mp_thresholds_set_crit(result.config.thlds, critical_range.range); | ||
| 976 | } break; | ||
| 1432 | case 'w': /* warning time threshold */ | 977 | case 'w': /* warning time threshold */ |
| 1433 | warning_thresholds = optarg; | 978 | { |
| 1434 | break; | 979 | mp_range_parsed warning_range = mp_parse_range_string(optarg); |
| 980 | |||
| 981 | if (warning_range.error != MP_PARSING_SUCCES) { | ||
| 982 | die(STATE_UNKNOWN, "failed to parse warning threshold: %s", optarg); | ||
| 983 | } | ||
| 984 | result.config.thlds = mp_thresholds_set_warn(result.config.thlds, warning_range.range); | ||
| 985 | } break; | ||
| 1435 | case 'H': /* virtual host */ | 986 | case 'H': /* virtual host */ |
| 1436 | host_name = strdup(optarg); | 987 | result.config.initial_config.host_name = strdup(optarg); |
| 1437 | if (host_name[0] == '[') { | 988 | char *tmp_string; |
| 1438 | if ((p = strstr(host_name, "]:")) != NULL) { /* [IPv6]:port */ | 989 | size_t host_name_length; |
| 1439 | virtual_port = atoi(p + 2); | 990 | if (result.config.initial_config.host_name[0] == '[') { |
| 991 | if ((tmp_string = strstr(result.config.initial_config.host_name, "]:")) != | ||
| 992 | NULL) { /* [IPv6]:port */ | ||
| 993 | result.config.initial_config.virtualPort = atoi(tmp_string + 2); | ||
| 1440 | /* cut off the port */ | 994 | /* cut off the port */ |
| 1441 | host_name_length = strlen(host_name) - strlen(p) - 1; | 995 | host_name_length = |
| 1442 | free(host_name); | 996 | strlen(result.config.initial_config.host_name) - strlen(tmp_string) - 1; |
| 1443 | host_name = strndup(optarg, host_name_length); | 997 | free(result.config.initial_config.host_name); |
| 998 | result.config.initial_config.host_name = strndup(optarg, host_name_length); | ||
| 1444 | } | 999 | } |
| 1445 | } else if ((p = strchr(host_name, ':')) != NULL && strchr(++p, ':') == NULL) { /* IPv4:port or host:port */ | 1000 | } else if ((tmp_string = strchr(result.config.initial_config.host_name, ':')) != NULL && |
| 1446 | virtual_port = atoi(p); | 1001 | strchr(++tmp_string, ':') == NULL) { /* IPv4:port or host:port */ |
| 1002 | result.config.initial_config.virtualPort = atoi(tmp_string); | ||
| 1447 | /* cut off the port */ | 1003 | /* cut off the port */ |
| 1448 | host_name_length = strlen(host_name) - strlen(p) - 1; | 1004 | host_name_length = |
| 1449 | free(host_name); | 1005 | strlen(result.config.initial_config.host_name) - strlen(tmp_string) - 1; |
| 1450 | host_name = strndup(optarg, host_name_length); | 1006 | free(result.config.initial_config.host_name); |
| 1007 | result.config.initial_config.host_name = strndup(optarg, host_name_length); | ||
| 1451 | } | 1008 | } |
| 1452 | break; | 1009 | break; |
| 1453 | case 'I': /* internet address */ | 1010 | case 'I': /* internet address */ |
| 1454 | server_address = strdup(optarg); | 1011 | result.config.initial_config.server_address = strdup(optarg); |
| 1455 | break; | 1012 | break; |
| 1456 | case 'u': /* URL path */ | 1013 | case 'u': /* URL path */ |
| 1457 | server_url = strdup(optarg); | 1014 | result.config.initial_config.server_url = strdup(optarg); |
| 1458 | break; | 1015 | break; |
| 1459 | case 'p': /* Server port */ | 1016 | case 'p': /* Server port */ |
| 1460 | if (!is_intnonneg(optarg)) | 1017 | if (!is_intnonneg(optarg)) { |
| 1461 | usage2(_("Invalid port number, expecting a non-negative number"), optarg); | 1018 | usage2(_("Invalid port number, expecting a non-negative number"), optarg); |
| 1462 | else { | 1019 | } else { |
| 1463 | if (strtol(optarg, NULL, 10) > MAX_PORT) | 1020 | if (strtol(optarg, NULL, 10) > MAX_PORT) { |
| 1464 | usage2(_("Invalid port number, supplied port number is too big"), optarg); | 1021 | usage2(_("Invalid port number, supplied port number is too big"), optarg); |
| 1465 | server_port = (unsigned short)strtol(optarg, NULL, 10); | 1022 | } |
| 1023 | result.config.initial_config.serverPort = (unsigned short)strtol(optarg, NULL, 10); | ||
| 1466 | specify_port = true; | 1024 | specify_port = true; |
| 1467 | } | 1025 | } |
| 1468 | break; | 1026 | break; |
| 1469 | case 'a': /* authorization info */ | 1027 | case 'a': /* authorization info */ |
| 1470 | strncpy(user_auth, optarg, MAX_INPUT_BUFFER - 1); | 1028 | strncpy(result.config.curl_config.user_auth, optarg, MAX_INPUT_BUFFER - 1); |
| 1471 | user_auth[MAX_INPUT_BUFFER - 1] = 0; | 1029 | result.config.curl_config.user_auth[MAX_INPUT_BUFFER - 1] = 0; |
| 1472 | break; | 1030 | break; |
| 1473 | case 'b': /* proxy-authorization info */ | 1031 | case 'b': /* proxy-authorization info */ |
| 1474 | strncpy(proxy_auth, optarg, MAX_INPUT_BUFFER - 1); | 1032 | strncpy(result.config.curl_config.proxy_auth, optarg, MAX_INPUT_BUFFER - 1); |
| 1475 | proxy_auth[MAX_INPUT_BUFFER - 1] = 0; | 1033 | result.config.curl_config.proxy_auth[MAX_INPUT_BUFFER - 1] = 0; |
| 1476 | break; | 1034 | break; |
| 1477 | case 'P': /* HTTP POST data in URL encoded format; ignored if settings already */ | 1035 | case 'P': /* HTTP POST data in URL encoded format; ignored if settings already */ |
| 1478 | if (!http_post_data) | 1036 | if (!result.config.initial_config.http_post_data) { |
| 1479 | http_post_data = strdup(optarg); | 1037 | result.config.initial_config.http_post_data = strdup(optarg); |
| 1480 | if (!http_method) | 1038 | } |
| 1481 | http_method = strdup("POST"); | 1039 | if (!result.config.initial_config.http_method) { |
| 1040 | result.config.initial_config.http_method = strdup("POST"); | ||
| 1041 | } | ||
| 1482 | break; | 1042 | break; |
| 1483 | case 'j': /* Set HTTP method */ | 1043 | case 'j': /* Set HTTP method */ |
| 1484 | if (http_method) | 1044 | if (result.config.initial_config.http_method) { |
| 1485 | free(http_method); | 1045 | free(result.config.initial_config.http_method); |
| 1486 | http_method = strdup(optarg); | 1046 | } |
| 1047 | result.config.initial_config.http_method = strdup(optarg); | ||
| 1487 | break; | 1048 | break; |
| 1488 | case 'A': /* useragent */ | 1049 | case 'A': /* useragent */ |
| 1489 | strncpy(user_agent, optarg, DEFAULT_BUFFER_SIZE); | 1050 | strncpy(result.config.curl_config.user_agent, optarg, DEFAULT_BUFFER_SIZE); |
| 1490 | user_agent[DEFAULT_BUFFER_SIZE - 1] = '\0'; | 1051 | result.config.curl_config.user_agent[DEFAULT_BUFFER_SIZE - 1] = '\0'; |
| 1491 | break; | 1052 | break; |
| 1492 | case 'k': /* Additional headers */ | 1053 | case 'k': /* Additional headers */ |
| 1493 | if (http_opt_headers_count == 0) | 1054 | if (result.config.curl_config.http_opt_headers_count == 0) { |
| 1494 | http_opt_headers = malloc(sizeof(char *) * (++http_opt_headers_count)); | 1055 | result.config.curl_config.http_opt_headers = |
| 1495 | else | 1056 | malloc(sizeof(char *) * (++result.config.curl_config.http_opt_headers_count)); |
| 1496 | http_opt_headers = realloc(http_opt_headers, sizeof(char *) * (++http_opt_headers_count)); | 1057 | } else { |
| 1497 | http_opt_headers[http_opt_headers_count - 1] = optarg; | 1058 | result.config.curl_config.http_opt_headers = |
| 1059 | realloc(result.config.curl_config.http_opt_headers, | ||
| 1060 | sizeof(char *) * (++result.config.curl_config.http_opt_headers_count)); | ||
| 1061 | } | ||
| 1062 | result.config.curl_config | ||
| 1063 | .http_opt_headers[result.config.curl_config.http_opt_headers_count - 1] = optarg; | ||
| 1498 | break; | 1064 | break; |
| 1499 | case 'L': /* show html link */ | 1065 | case 'L': /* show html link */ |
| 1500 | display_html = true; | ||
| 1501 | break; | ||
| 1502 | case 'n': /* do not show html link */ | 1066 | case 'n': /* do not show html link */ |
| 1503 | display_html = false; | 1067 | // HTML link related options are deprecated |
| 1504 | break; | 1068 | break; |
| 1505 | case 'C': /* Check SSL cert validity */ | 1069 | case 'C': /* Check SSL cert validity */ |
| 1506 | #ifdef LIBCURL_FEATURE_SSL | 1070 | #ifndef LIBCURL_FEATURE_SSL |
| 1507 | if ((temp = strchr(optarg, ',')) != NULL) { | 1071 | usage4(_("Invalid option - SSL is not available")); |
| 1508 | *temp = '\0'; | ||
| 1509 | if (!is_intnonneg(optarg)) | ||
| 1510 | usage2(_("Invalid certificate expiration period"), optarg); | ||
| 1511 | days_till_exp_warn = atoi(optarg); | ||
| 1512 | *temp = ','; | ||
| 1513 | temp++; | ||
| 1514 | if (!is_intnonneg(temp)) | ||
| 1515 | usage2(_("Invalid certificate expiration period"), temp); | ||
| 1516 | days_till_exp_crit = atoi(temp); | ||
| 1517 | } else { | ||
| 1518 | days_till_exp_crit = 0; | ||
| 1519 | if (!is_intnonneg(optarg)) | ||
| 1520 | usage2(_("Invalid certificate expiration period"), optarg); | ||
| 1521 | days_till_exp_warn = atoi(optarg); | ||
| 1522 | } | ||
| 1523 | check_cert = true; | ||
| 1524 | goto enable_ssl; | ||
| 1525 | #endif | 1072 | #endif |
| 1073 | { | ||
| 1074 | char *temp; | ||
| 1075 | if ((temp = strchr(optarg, ',')) != NULL) { | ||
| 1076 | *temp = '\0'; | ||
| 1077 | if (!is_intnonneg(optarg)) { | ||
| 1078 | usage2(_("Invalid certificate expiration period"), optarg); | ||
| 1079 | } | ||
| 1080 | result.config.days_till_exp_warn = atoi(optarg); | ||
| 1081 | *temp = ','; | ||
| 1082 | temp++; | ||
| 1083 | if (!is_intnonneg(temp)) { | ||
| 1084 | usage2(_("Invalid certificate expiration period"), temp); | ||
| 1085 | } | ||
| 1086 | result.config.days_till_exp_crit = atoi(temp); | ||
| 1087 | } else { | ||
| 1088 | result.config.days_till_exp_crit = 0; | ||
| 1089 | if (!is_intnonneg(optarg)) { | ||
| 1090 | usage2(_("Invalid certificate expiration period"), optarg); | ||
| 1091 | } | ||
| 1092 | result.config.days_till_exp_warn = atoi(optarg); | ||
| 1093 | } | ||
| 1094 | result.config.check_cert = true; | ||
| 1095 | enable_tls = true; | ||
| 1096 | } | ||
| 1097 | break; | ||
| 1526 | case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */ | 1098 | case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */ |
| 1527 | #ifdef HAVE_SSL | 1099 | #ifdef HAVE_SSL |
| 1528 | continue_after_check_cert = true; | 1100 | result.config.continue_after_check_cert = true; |
| 1529 | break; | 1101 | break; |
| 1530 | #endif | 1102 | #endif |
| 1531 | case 'J': /* use client certificate */ | 1103 | case 'J': /* use client certificate */ |
| 1532 | #ifdef LIBCURL_FEATURE_SSL | 1104 | #ifndef LIBCURL_FEATURE_SSL |
| 1533 | test_file(optarg); | 1105 | usage4(_("Invalid option - SSL is not available")); |
| 1534 | client_cert = optarg; | ||
| 1535 | goto enable_ssl; | ||
| 1536 | #endif | 1106 | #endif |
| 1537 | case 'K': /* use client private key */ | ||
| 1538 | #ifdef LIBCURL_FEATURE_SSL | ||
| 1539 | test_file(optarg); | 1107 | test_file(optarg); |
| 1540 | client_privkey = optarg; | 1108 | result.config.curl_config.client_cert = optarg; |
| 1541 | goto enable_ssl; | 1109 | enable_tls = true; |
| 1110 | break; | ||
| 1111 | case 'K': /* use client private key */ | ||
| 1112 | #ifndef LIBCURL_FEATURE_SSL | ||
| 1113 | usage4(_("Invalid option - SSL is not available")); | ||
| 1542 | #endif | 1114 | #endif |
| 1543 | #ifdef LIBCURL_FEATURE_SSL | ||
| 1544 | case CA_CERT_OPTION: /* use CA chain file */ | ||
| 1545 | test_file(optarg); | 1115 | test_file(optarg); |
| 1546 | ca_cert = optarg; | 1116 | result.config.curl_config.client_privkey = optarg; |
| 1547 | goto enable_ssl; | 1117 | enable_tls = true; |
| 1118 | break; | ||
| 1119 | case CA_CERT_OPTION: /* use CA chain file */ | ||
| 1120 | #ifndef LIBCURL_FEATURE_SSL | ||
| 1121 | usage4(_("Invalid option - SSL is not available")); | ||
| 1548 | #endif | 1122 | #endif |
| 1549 | #ifdef LIBCURL_FEATURE_SSL | 1123 | test_file(optarg); |
| 1550 | case 'D': /* verify peer certificate & host */ | 1124 | result.config.curl_config.ca_cert = optarg; |
| 1551 | verify_peer_and_host = true; | 1125 | enable_tls = true; |
| 1552 | break; | 1126 | break; |
| 1127 | case 'D': /* verify peer certificate & host */ | ||
| 1128 | #ifndef LIBCURL_FEATURE_SSL | ||
| 1129 | usage4(_("Invalid option - SSL is not available")); | ||
| 1553 | #endif | 1130 | #endif |
| 1554 | case 'S': /* use SSL */ | 1131 | result.config.curl_config.verify_peer_and_host = true; |
| 1555 | #ifdef LIBCURL_FEATURE_SSL | 1132 | enable_tls = true; |
| 1556 | enable_ssl: | ||
| 1557 | use_ssl = true; | ||
| 1558 | /* ssl_version initialized to CURL_SSLVERSION_DEFAULT as a default. | ||
| 1559 | * Only set if it's non-zero. This helps when we include multiple | ||
| 1560 | * parameters, like -S and -C combinations */ | ||
| 1561 | ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1562 | if (c == 'S' && optarg != NULL) { | ||
| 1563 | char *plus_ptr = strchr(optarg, '+'); | ||
| 1564 | if (plus_ptr) { | ||
| 1565 | got_plus = 1; | ||
| 1566 | *plus_ptr = '\0'; | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | if (optarg[0] == '2') | ||
| 1570 | ssl_version = CURL_SSLVERSION_SSLv2; | ||
| 1571 | else if (optarg[0] == '3') | ||
| 1572 | ssl_version = CURL_SSLVERSION_SSLv3; | ||
| 1573 | else if (!strcmp(optarg, "1") || !strcmp(optarg, "1.0")) | ||
| 1574 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | ||
| 1575 | ssl_version = CURL_SSLVERSION_TLSv1_0; | ||
| 1576 | # else | ||
| 1577 | ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1578 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 1579 | else if (!strcmp(optarg, "1.1")) | ||
| 1580 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | ||
| 1581 | ssl_version = CURL_SSLVERSION_TLSv1_1; | ||
| 1582 | # else | ||
| 1583 | ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1584 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 1585 | else if (!strcmp(optarg, "1.2")) | ||
| 1586 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | ||
| 1587 | ssl_version = CURL_SSLVERSION_TLSv1_2; | ||
| 1588 | # else | ||
| 1589 | ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1590 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 1591 | else if (!strcmp(optarg, "1.3")) | ||
| 1592 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) | ||
| 1593 | ssl_version = CURL_SSLVERSION_TLSv1_3; | ||
| 1594 | # else | ||
| 1595 | ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1596 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) */ | ||
| 1597 | else | ||
| 1598 | usage4(_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2, 1.3 (with optional '+' suffix)")); | ||
| 1599 | } | ||
| 1600 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) | ||
| 1601 | if (got_plus) { | ||
| 1602 | switch (ssl_version) { | ||
| 1603 | case CURL_SSLVERSION_TLSv1_3: | ||
| 1604 | ssl_version |= CURL_SSLVERSION_MAX_TLSv1_3; | ||
| 1605 | break; | ||
| 1606 | case CURL_SSLVERSION_TLSv1_2: | ||
| 1607 | case CURL_SSLVERSION_TLSv1_1: | ||
| 1608 | case CURL_SSLVERSION_TLSv1_0: | ||
| 1609 | ssl_version |= CURL_SSLVERSION_MAX_DEFAULT; | ||
| 1610 | break; | ||
| 1611 | } | ||
| 1612 | } else { | ||
| 1613 | switch (ssl_version) { | ||
| 1614 | case CURL_SSLVERSION_TLSv1_3: | ||
| 1615 | ssl_version |= CURL_SSLVERSION_MAX_TLSv1_3; | ||
| 1616 | break; | ||
| 1617 | case CURL_SSLVERSION_TLSv1_2: | ||
| 1618 | ssl_version |= CURL_SSLVERSION_MAX_TLSv1_2; | ||
| 1619 | break; | ||
| 1620 | case CURL_SSLVERSION_TLSv1_1: | ||
| 1621 | ssl_version |= CURL_SSLVERSION_MAX_TLSv1_1; | ||
| 1622 | break; | ||
| 1623 | case CURL_SSLVERSION_TLSv1_0: | ||
| 1624 | ssl_version |= CURL_SSLVERSION_MAX_TLSv1_0; | ||
| 1625 | break; | ||
| 1626 | } | ||
| 1627 | } | ||
| 1628 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */ | ||
| 1629 | if (verbose >= 2) | ||
| 1630 | printf(_("* Set SSL/TLS version to %d\n"), ssl_version); | ||
| 1631 | if (!specify_port) | ||
| 1632 | server_port = HTTPS_PORT; | ||
| 1633 | break; | 1133 | break; |
| 1634 | #else /* LIBCURL_FEATURE_SSL */ | 1134 | case 'S': /* use SSL */ |
| 1635 | /* -C -J and -K fall through to here without SSL */ | 1135 | tls_option_optarg = optarg; |
| 1136 | enable_tls = true; | ||
| 1137 | #ifndef LIBCURL_FEATURE_SSL | ||
| 1636 | usage4(_("Invalid option - SSL is not available")); | 1138 | usage4(_("Invalid option - SSL is not available")); |
| 1139 | #endif | ||
| 1637 | break; | 1140 | break; |
| 1638 | case SNI_OPTION: /* --sni is parsed, but ignored, the default is true with libcurl */ | 1141 | case SNI_OPTION: /* --sni is parsed, but ignored, the default is true with libcurl */ |
| 1639 | use_sni = true; | 1142 | #ifndef LIBCURL_FEATURE_SSL |
| 1640 | break; | 1143 | usage4(_("Invalid option - SSL is not available")); |
| 1641 | #endif /* LIBCURL_FEATURE_SSL */ | 1144 | #endif /* LIBCURL_FEATURE_SSL */ |
| 1145 | break; | ||
| 1642 | case MAX_REDIRS_OPTION: | 1146 | case MAX_REDIRS_OPTION: |
| 1643 | if (!is_intnonneg(optarg)) | 1147 | if (!is_intnonneg(optarg)) { |
| 1644 | usage2(_("Invalid max_redirs count"), optarg); | 1148 | usage2(_("Invalid max_redirs count"), optarg); |
| 1645 | else { | 1149 | } else { |
| 1646 | max_depth = atoi(optarg); | 1150 | result.config.max_depth = atoi(optarg); |
| 1647 | } | 1151 | } |
| 1648 | break; | 1152 | break; |
| 1649 | case 'f': /* onredirect */ | 1153 | case 'f': /* onredirect */ |
| 1650 | if (!strcmp(optarg, "ok")) | 1154 | if (!strcmp(optarg, "ok")) { |
| 1651 | onredirect = STATE_OK; | 1155 | result.config.on_redirect_result_state = STATE_OK; |
| 1652 | else if (!strcmp(optarg, "warning")) | 1156 | result.config.on_redirect_dependent = false; |
| 1653 | onredirect = STATE_WARNING; | 1157 | } else if (!strcmp(optarg, "warning")) { |
| 1654 | else if (!strcmp(optarg, "critical")) | 1158 | result.config.on_redirect_result_state = STATE_WARNING; |
| 1655 | onredirect = STATE_CRITICAL; | 1159 | result.config.on_redirect_dependent = false; |
| 1656 | else if (!strcmp(optarg, "unknown")) | 1160 | } else if (!strcmp(optarg, "critical")) { |
| 1657 | onredirect = STATE_UNKNOWN; | 1161 | result.config.on_redirect_result_state = STATE_CRITICAL; |
| 1658 | else if (!strcmp(optarg, "follow")) | 1162 | result.config.on_redirect_dependent = false; |
| 1659 | onredirect = STATE_DEPENDENT; | 1163 | } else if (!strcmp(optarg, "unknown")) { |
| 1660 | else if (!strcmp(optarg, "stickyport")) | 1164 | result.config.on_redirect_result_state = STATE_UNKNOWN; |
| 1661 | onredirect = STATE_DEPENDENT, followmethod = FOLLOW_HTTP_CURL, followsticky = STICKY_HOST | STICKY_PORT; | 1165 | result.config.on_redirect_dependent = false; |
| 1662 | else if (!strcmp(optarg, "sticky")) | 1166 | } else if (!strcmp(optarg, "follow")) { |
| 1663 | onredirect = STATE_DEPENDENT, followmethod = FOLLOW_HTTP_CURL, followsticky = STICKY_HOST; | 1167 | result.config.on_redirect_dependent = true; |
| 1664 | else if (!strcmp(optarg, "follow")) | 1168 | } else if (!strcmp(optarg, "stickyport")) { |
| 1665 | onredirect = STATE_DEPENDENT, followmethod = FOLLOW_HTTP_CURL, followsticky = STICKY_NONE; | 1169 | result.config.on_redirect_dependent = true; |
| 1666 | else if (!strcmp(optarg, "curl")) | 1170 | result.config.followmethod = FOLLOW_HTTP_CURL, |
| 1667 | onredirect = STATE_DEPENDENT, followmethod = FOLLOW_LIBCURL; | 1171 | result.config.followsticky = STICKY_HOST | STICKY_PORT; |
| 1668 | else | 1172 | } else if (!strcmp(optarg, "sticky")) { |
| 1173 | result.config.on_redirect_dependent = true; | ||
| 1174 | result.config.followmethod = FOLLOW_HTTP_CURL, | ||
| 1175 | result.config.followsticky = STICKY_HOST; | ||
| 1176 | } else if (!strcmp(optarg, "follow")) { | ||
| 1177 | result.config.on_redirect_dependent = true; | ||
| 1178 | result.config.followmethod = FOLLOW_HTTP_CURL, | ||
| 1179 | result.config.followsticky = STICKY_NONE; | ||
| 1180 | } else if (!strcmp(optarg, "curl")) { | ||
| 1181 | result.config.on_redirect_dependent = true; | ||
| 1182 | result.config.followmethod = FOLLOW_LIBCURL; | ||
| 1183 | } else { | ||
| 1669 | usage2(_("Invalid onredirect option"), optarg); | 1184 | usage2(_("Invalid onredirect option"), optarg); |
| 1670 | if (verbose >= 2) | 1185 | } |
| 1671 | printf(_("* Following redirects set to %s\n"), state_text(onredirect)); | 1186 | if (verbose >= 2) { |
| 1187 | if (result.config.on_redirect_dependent) { | ||
| 1188 | printf(_("* Following redirects\n")); | ||
| 1189 | } else { | ||
| 1190 | printf(_("* Following redirects set to state %s\n"), | ||
| 1191 | state_text(result.config.on_redirect_result_state)); | ||
| 1192 | } | ||
| 1193 | } | ||
| 1672 | break; | 1194 | break; |
| 1673 | case 'd': /* string or substring */ | 1195 | case 'd': /* string or substring */ |
| 1674 | strncpy(header_expect, optarg, MAX_INPUT_BUFFER - 1); | 1196 | strncpy(result.config.header_expect, optarg, MAX_INPUT_BUFFER - 1); |
| 1675 | header_expect[MAX_INPUT_BUFFER - 1] = 0; | 1197 | result.config.header_expect[MAX_INPUT_BUFFER - 1] = 0; |
| 1676 | break; | 1198 | break; |
| 1677 | case 's': /* string or substring */ | 1199 | case 's': /* string or substring */ |
| 1678 | strncpy(string_expect, optarg, MAX_INPUT_BUFFER - 1); | 1200 | strncpy(result.config.string_expect, optarg, MAX_INPUT_BUFFER - 1); |
| 1679 | string_expect[MAX_INPUT_BUFFER - 1] = 0; | 1201 | result.config.string_expect[MAX_INPUT_BUFFER - 1] = 0; |
| 1680 | break; | 1202 | break; |
| 1681 | case 'e': /* string or substring */ | 1203 | case 'e': /* string or substring */ |
| 1682 | strncpy(server_expect, optarg, MAX_INPUT_BUFFER - 1); | 1204 | strncpy(result.config.server_expect.string, optarg, MAX_INPUT_BUFFER - 1); |
| 1683 | server_expect[MAX_INPUT_BUFFER - 1] = 0; | 1205 | result.config.server_expect.string[MAX_INPUT_BUFFER - 1] = 0; |
| 1684 | server_expect_yn = 1; | 1206 | result.config.server_expect.is_present = true; |
| 1685 | break; | 1207 | break; |
| 1686 | case 'T': /* Content-type */ | 1208 | case 'T': /* Content-type */ |
| 1687 | http_content_type = strdup(optarg); | 1209 | result.config.curl_config.http_content_type = strdup(optarg); |
| 1688 | break; | 1210 | break; |
| 1689 | case 'l': /* linespan */ | 1211 | case 'l': /* linespan */ |
| 1690 | cflags &= ~REG_NEWLINE; | 1212 | cflags &= ~REG_NEWLINE; |
| @@ -1693,185 +1215,258 @@ bool process_arguments(int argc, char **argv) { | |||
| 1693 | cflags |= REG_ICASE; | 1215 | cflags |= REG_ICASE; |
| 1694 | // fall through | 1216 | // fall through |
| 1695 | case 'r': /* regex */ | 1217 | case 'r': /* regex */ |
| 1696 | strncpy(regexp, optarg, MAX_RE_SIZE - 1); | 1218 | strncpy(result.config.regexp, optarg, MAX_RE_SIZE - 1); |
| 1697 | regexp[MAX_RE_SIZE - 1] = 0; | 1219 | result.config.regexp[MAX_RE_SIZE - 1] = 0; |
| 1698 | errcode = regcomp(&preg, regexp, cflags); | 1220 | regex_t preg; |
| 1221 | int errcode = regcomp(&preg, result.config.regexp, cflags); | ||
| 1699 | if (errcode != 0) { | 1222 | if (errcode != 0) { |
| 1700 | (void)regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); | 1223 | (void)regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); |
| 1701 | printf(_("Could Not Compile Regular Expression: %s"), errbuf); | 1224 | printf(_("Could Not Compile Regular Expression: %s"), errbuf); |
| 1702 | return false; | 1225 | result.errorcode = ERROR; |
| 1226 | return result; | ||
| 1703 | } | 1227 | } |
| 1228 | |||
| 1229 | result.config.compiled_regex = preg; | ||
| 1704 | break; | 1230 | break; |
| 1705 | case INVERT_REGEX: | 1231 | case INVERT_REGEX: |
| 1706 | invert_regex = true; | 1232 | result.config.invert_regex = true; |
| 1707 | break; | 1233 | break; |
| 1708 | case STATE_REGEX: | 1234 | case STATE_REGEX: |
| 1709 | if (!strcasecmp(optarg, "critical")) | 1235 | if (!strcasecmp(optarg, "critical")) { |
| 1710 | state_regex = STATE_CRITICAL; | 1236 | result.config.state_regex = STATE_CRITICAL; |
| 1711 | else if (!strcasecmp(optarg, "warning")) | 1237 | } else if (!strcasecmp(optarg, "warning")) { |
| 1712 | state_regex = STATE_WARNING; | 1238 | result.config.state_regex = STATE_WARNING; |
| 1713 | else | 1239 | } else { |
| 1714 | usage2(_("Invalid state-regex option"), optarg); | 1240 | usage2(_("Invalid state-regex option"), optarg); |
| 1241 | } | ||
| 1715 | break; | 1242 | break; |
| 1716 | case '4': | 1243 | case '4': |
| 1717 | address_family = AF_INET; | 1244 | result.config.curl_config.sin_family = AF_INET; |
| 1718 | break; | 1245 | break; |
| 1719 | case '6': | 1246 | case '6': |
| 1720 | #if defined(USE_IPV6) && defined(LIBCURL_FEATURE_IPV6) | 1247 | #if defined(USE_IPV6) && defined(LIBCURL_FEATURE_IPV6) |
| 1721 | address_family = AF_INET6; | 1248 | result.config.curl_config.sin_family = AF_INET6; |
| 1722 | #else | 1249 | #else |
| 1723 | usage4(_("IPv6 support not available")); | 1250 | usage4(_("IPv6 support not available")); |
| 1724 | #endif | 1251 | #endif |
| 1725 | break; | 1252 | break; |
| 1726 | case 'm': /* min_page_length */ | 1253 | case 'm': /* min_page_length */ |
| 1727 | { | 1254 | { |
| 1728 | char *tmp; | 1255 | mp_range_parsed foo = mp_parse_range_string(optarg); |
| 1729 | if (strchr(optarg, ':') != (char *)NULL) { | 1256 | |
| 1730 | /* range, so get two values, min:max */ | 1257 | if (foo.error != MP_PARSING_SUCCES) { |
| 1731 | tmp = strtok(optarg, ":"); | 1258 | die(STATE_CRITICAL, "failed to parse page size limits: %s", optarg); |
| 1732 | if (tmp == NULL) { | 1259 | } |
| 1733 | printf("Bad format: try \"-m min:max\"\n"); | 1260 | |
| 1734 | exit(STATE_WARNING); | 1261 | result.config.page_length_limits = foo.range; |
| 1735 | } else | 1262 | result.config.page_length_limits_is_set = true; |
| 1736 | min_page_len = atoi(tmp); | ||
| 1737 | |||
| 1738 | tmp = strtok(NULL, ":"); | ||
| 1739 | if (tmp == NULL) { | ||
| 1740 | printf("Bad format: try \"-m min:max\"\n"); | ||
| 1741 | exit(STATE_WARNING); | ||
| 1742 | } else | ||
| 1743 | max_page_len = atoi(tmp); | ||
| 1744 | } else | ||
| 1745 | min_page_len = atoi(optarg); | ||
| 1746 | break; | 1263 | break; |
| 1747 | } | 1264 | } |
| 1748 | case 'N': /* no-body */ | 1265 | case 'N': /* no-body */ |
| 1749 | no_body = true; | 1266 | result.config.initial_config.no_body = true; |
| 1750 | break; | 1267 | break; |
| 1751 | case 'M': /* max-age */ | 1268 | case 'M': /* max-age */ |
| 1752 | { | 1269 | { |
| 1753 | int L = strlen(optarg); | 1270 | size_t option_length = strlen(optarg); |
| 1754 | if (L && optarg[L - 1] == 'm') | 1271 | if (option_length && optarg[option_length - 1] == 'm') { |
| 1755 | maximum_age = atoi(optarg) * 60; | 1272 | result.config.maximum_age = atoi(optarg) * 60; |
| 1756 | else if (L && optarg[L - 1] == 'h') | 1273 | } else if (option_length && optarg[option_length - 1] == 'h') { |
| 1757 | maximum_age = atoi(optarg) * 60 * 60; | 1274 | result.config.maximum_age = atoi(optarg) * 60 * 60; |
| 1758 | else if (L && optarg[L - 1] == 'd') | 1275 | } else if (option_length && optarg[option_length - 1] == 'd') { |
| 1759 | maximum_age = atoi(optarg) * 60 * 60 * 24; | 1276 | result.config.maximum_age = atoi(optarg) * 60 * 60 * 24; |
| 1760 | else if (L && (optarg[L - 1] == 's' || isdigit(optarg[L - 1]))) | 1277 | } else if (option_length && |
| 1761 | maximum_age = atoi(optarg); | 1278 | (optarg[option_length - 1] == 's' || isdigit(optarg[option_length - 1]))) { |
| 1762 | else { | 1279 | result.config.maximum_age = atoi(optarg); |
| 1280 | } else { | ||
| 1763 | fprintf(stderr, "unparsable max-age: %s\n", optarg); | 1281 | fprintf(stderr, "unparsable max-age: %s\n", optarg); |
| 1764 | exit(STATE_WARNING); | 1282 | exit(STATE_WARNING); |
| 1765 | } | 1283 | } |
| 1766 | if (verbose >= 2) | 1284 | if (verbose >= 2) { |
| 1767 | printf("* Maximal age of document set to %d seconds\n", maximum_age); | 1285 | printf("* Maximal age of document set to %d seconds\n", result.config.maximum_age); |
| 1286 | } | ||
| 1768 | } break; | 1287 | } break; |
| 1769 | case 'E': /* show extended perfdata */ | 1288 | case 'E': /* show extended perfdata */ |
| 1770 | show_extended_perfdata = true; | 1289 | result.config.show_extended_perfdata = true; |
| 1771 | break; | 1290 | break; |
| 1772 | case 'B': /* print body content after status line */ | 1291 | case 'B': /* print body content after status line */ |
| 1773 | show_body = true; | 1292 | result.config.show_body = true; |
| 1774 | break; | 1293 | break; |
| 1775 | case HTTP_VERSION_OPTION: | 1294 | case HTTP_VERSION_OPTION: |
| 1776 | curl_http_version = CURL_HTTP_VERSION_NONE; | 1295 | result.config.curl_config.curl_http_version = CURL_HTTP_VERSION_NONE; |
| 1777 | if (strcmp(optarg, "1.0") == 0) { | 1296 | if (strcmp(optarg, "1.0") == 0) { |
| 1778 | curl_http_version = CURL_HTTP_VERSION_1_0; | 1297 | result.config.curl_config.curl_http_version = CURL_HTTP_VERSION_1_0; |
| 1779 | } else if (strcmp(optarg, "1.1") == 0) { | 1298 | } else if (strcmp(optarg, "1.1") == 0) { |
| 1780 | curl_http_version = CURL_HTTP_VERSION_1_1; | 1299 | result.config.curl_config.curl_http_version = CURL_HTTP_VERSION_1_1; |
| 1781 | } else if ((strcmp(optarg, "2.0") == 0) || (strcmp(optarg, "2") == 0)) { | 1300 | } else if ((strcmp(optarg, "2.0") == 0) || (strcmp(optarg, "2") == 0)) { |
| 1782 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) | 1301 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) |
| 1783 | curl_http_version = CURL_HTTP_VERSION_2_0; | 1302 | result.config.curl_config.curl_http_version = CURL_HTTP_VERSION_2_0; |
| 1784 | #else | 1303 | #else |
| 1785 | curl_http_version = CURL_HTTP_VERSION_NONE; | 1304 | result.config.curl_http_version = CURL_HTTP_VERSION_NONE; |
| 1786 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) */ | 1305 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 33, 0) */ |
| 1306 | } else if ((strcmp(optarg, "3") == 0)) { | ||
| 1307 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 66, 0) | ||
| 1308 | result.config.curl_config.curl_http_version = CURL_HTTP_VERSION_3; | ||
| 1309 | #else | ||
| 1310 | result.config.curl_config.curl_http_version = CURL_HTTP_VERSION_NONE; | ||
| 1311 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 66, 0) */ | ||
| 1787 | } else { | 1312 | } else { |
| 1788 | fprintf(stderr, "unknown http-version parameter: %s\n", optarg); | 1313 | fprintf(stderr, "unknown http-version parameter: %s\n", optarg); |
| 1789 | exit(STATE_WARNING); | 1314 | exit(STATE_WARNING); |
| 1790 | } | 1315 | } |
| 1791 | break; | 1316 | break; |
| 1792 | case AUTOMATIC_DECOMPRESSION: | 1317 | case AUTOMATIC_DECOMPRESSION: |
| 1793 | automatic_decompression = true; | 1318 | result.config.curl_config.automatic_decompression = true; |
| 1794 | break; | 1319 | break; |
| 1795 | case COOKIE_JAR: | 1320 | case COOKIE_JAR: |
| 1796 | cookie_jar_file = optarg; | 1321 | result.config.curl_config.cookie_jar_file = optarg; |
| 1797 | break; | 1322 | break; |
| 1798 | case HAPROXY_PROTOCOL: | 1323 | case HAPROXY_PROTOCOL: |
| 1799 | haproxy_protocol = true; | 1324 | result.config.curl_config.haproxy_protocol = true; |
| 1800 | break; | 1325 | break; |
| 1801 | case '?': | 1326 | case '?': |
| 1802 | /* print short usage statement if args not parsable */ | 1327 | /* print short usage statement if args not parsable */ |
| 1803 | usage5(); | 1328 | usage5(); |
| 1804 | break; | 1329 | break; |
| 1330 | case OUTPUT_FORMAT: { | ||
| 1331 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 1332 | if (!parser.parsing_success) { | ||
| 1333 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 1334 | printf("Invalid output format: %s\n", optarg); | ||
| 1335 | exit(STATE_UNKNOWN); | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | result.config.output_format_is_set = true; | ||
| 1339 | result.config.output_format = parser.output_format; | ||
| 1340 | break; | ||
| 1341 | } | ||
| 1805 | } | 1342 | } |
| 1806 | } | 1343 | } |
| 1807 | 1344 | ||
| 1808 | c = optind; | 1345 | if (enable_tls) { |
| 1346 | bool got_plus = false; | ||
| 1347 | result.config.initial_config.use_ssl = true; | ||
| 1348 | /* ssl_version initialized to CURL_SSLVERSION_DEFAULT as a default. | ||
| 1349 | * Only set if it's non-zero. This helps when we include multiple | ||
| 1350 | * parameters, like -S and -C combinations */ | ||
| 1351 | result.config.curl_config.ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1352 | if (tls_option_optarg != NULL) { | ||
| 1353 | char *plus_ptr = strchr(optarg, '+'); | ||
| 1354 | if (plus_ptr) { | ||
| 1355 | got_plus = true; | ||
| 1356 | *plus_ptr = '\0'; | ||
| 1357 | } | ||
| 1809 | 1358 | ||
| 1810 | if (server_address == NULL && c < argc) | 1359 | if (optarg[0] == '2') { |
| 1811 | server_address = strdup(argv[c++]); | 1360 | result.config.curl_config.ssl_version = CURL_SSLVERSION_SSLv2; |
| 1361 | } else if (optarg[0] == '3') { | ||
| 1362 | result.config.curl_config.ssl_version = CURL_SSLVERSION_SSLv3; | ||
| 1363 | } else if (!strcmp(optarg, "1") || !strcmp(optarg, "1.0")) { | ||
| 1364 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | ||
| 1365 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_0; | ||
| 1366 | #else | ||
| 1367 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1368 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 1369 | } else if (!strcmp(optarg, "1.1")) { | ||
| 1370 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | ||
| 1371 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_1; | ||
| 1372 | #else | ||
| 1373 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1374 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 1375 | } else if (!strcmp(optarg, "1.2")) { | ||
| 1376 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | ||
| 1377 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_2; | ||
| 1378 | #else | ||
| 1379 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1380 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 1381 | } else if (!strcmp(optarg, "1.3")) { | ||
| 1382 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) | ||
| 1383 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_3; | ||
| 1384 | #else | ||
| 1385 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; | ||
| 1386 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) */ | ||
| 1387 | } else { | ||
| 1388 | usage4(_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2, 1.3 " | ||
| 1389 | "(with optional '+' suffix)")); | ||
| 1390 | } | ||
| 1391 | } | ||
| 1392 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) | ||
| 1393 | if (got_plus) { | ||
| 1394 | switch (result.config.curl_config.ssl_version) { | ||
| 1395 | case CURL_SSLVERSION_TLSv1_3: | ||
| 1396 | result.config.curl_config.ssl_version |= CURL_SSLVERSION_MAX_TLSv1_3; | ||
| 1397 | break; | ||
| 1398 | case CURL_SSLVERSION_TLSv1_2: | ||
| 1399 | case CURL_SSLVERSION_TLSv1_1: | ||
| 1400 | case CURL_SSLVERSION_TLSv1_0: | ||
| 1401 | result.config.curl_config.ssl_version |= CURL_SSLVERSION_MAX_DEFAULT; | ||
| 1402 | break; | ||
| 1403 | } | ||
| 1404 | } else { | ||
| 1405 | switch (result.config.curl_config.ssl_version) { | ||
| 1406 | case CURL_SSLVERSION_TLSv1_3: | ||
| 1407 | result.config.curl_config.ssl_version |= CURL_SSLVERSION_MAX_TLSv1_3; | ||
| 1408 | break; | ||
| 1409 | case CURL_SSLVERSION_TLSv1_2: | ||
| 1410 | result.config.curl_config.ssl_version |= CURL_SSLVERSION_MAX_TLSv1_2; | ||
| 1411 | break; | ||
| 1412 | case CURL_SSLVERSION_TLSv1_1: | ||
| 1413 | result.config.curl_config.ssl_version |= CURL_SSLVERSION_MAX_TLSv1_1; | ||
| 1414 | break; | ||
| 1415 | case CURL_SSLVERSION_TLSv1_0: | ||
| 1416 | result.config.curl_config.ssl_version |= CURL_SSLVERSION_MAX_TLSv1_0; | ||
| 1417 | break; | ||
| 1418 | } | ||
| 1419 | } | ||
| 1420 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) */ | ||
| 1421 | if (verbose >= 2) { | ||
| 1422 | printf(_("* Set SSL/TLS version to %ld\n"), result.config.curl_config.ssl_version); | ||
| 1423 | } | ||
| 1424 | if (!specify_port) { | ||
| 1425 | result.config.initial_config.serverPort = HTTPS_PORT; | ||
| 1426 | } | ||
| 1427 | } | ||
| 1812 | 1428 | ||
| 1813 | if (host_name == NULL && c < argc) | 1429 | int option_counter = optind; |
| 1814 | host_name = strdup(argv[c++]); | ||
| 1815 | 1430 | ||
| 1816 | if (server_address == NULL) { | 1431 | if (result.config.initial_config.server_address == NULL && option_counter < argc) { |
| 1817 | if (host_name == NULL) | 1432 | result.config.initial_config.server_address = strdup(argv[option_counter++]); |
| 1818 | usage4(_("You must specify a server address or host name")); | ||
| 1819 | else | ||
| 1820 | server_address = strdup(host_name); | ||
| 1821 | } | 1433 | } |
| 1822 | 1434 | ||
| 1823 | set_thresholds(&thlds, warning_thresholds, critical_thresholds); | 1435 | if (result.config.initial_config.host_name == NULL && option_counter < argc) { |
| 1436 | result.config.initial_config.host_name = strdup(argv[option_counter++]); | ||
| 1437 | } | ||
| 1824 | 1438 | ||
| 1825 | if (critical_thresholds && thlds->critical->end > (double)socket_timeout) | 1439 | if (result.config.initial_config.server_address == NULL) { |
| 1826 | socket_timeout = (int)thlds->critical->end + 1; | 1440 | if (result.config.initial_config.host_name == NULL) { |
| 1827 | if (verbose >= 2) | 1441 | usage4(_("You must specify a server address or host name")); |
| 1828 | printf("* Socket timeout set to %ld seconds\n", socket_timeout); | 1442 | } else { |
| 1443 | result.config.initial_config.server_address = | ||
| 1444 | strdup(result.config.initial_config.host_name); | ||
| 1445 | } | ||
| 1446 | } | ||
| 1829 | 1447 | ||
| 1830 | if (http_method == NULL) | 1448 | if (result.config.initial_config.http_method == NULL) { |
| 1831 | http_method = strdup("GET"); | 1449 | result.config.initial_config.http_method = strdup("GET"); |
| 1450 | } | ||
| 1832 | 1451 | ||
| 1833 | if (client_cert && !client_privkey) | 1452 | if (result.config.curl_config.client_cert && !result.config.curl_config.client_privkey) { |
| 1834 | usage4(_("If you use a client certificate you must also specify a private key file")); | 1453 | usage4(_("If you use a client certificate you must also specify a private key file")); |
| 1835 | |||
| 1836 | if (virtual_port == 0) | ||
| 1837 | virtual_port = server_port; | ||
| 1838 | else { | ||
| 1839 | if ((use_ssl && server_port == HTTPS_PORT) || (!use_ssl && server_port == HTTP_PORT)) | ||
| 1840 | if (!specify_port) | ||
| 1841 | server_port = virtual_port; | ||
| 1842 | } | 1454 | } |
| 1843 | 1455 | ||
| 1844 | return true; | 1456 | if (result.config.initial_config.virtualPort == 0) { |
| 1845 | } | 1457 | result.config.initial_config.virtualPort = result.config.initial_config.serverPort; |
| 1846 | 1458 | } else { | |
| 1847 | char *perfd_time(double elapsed_time) { | 1459 | if ((result.config.initial_config.use_ssl && |
| 1848 | return fperfdata("time", elapsed_time, "s", thlds->warning ? true : false, thlds->warning ? thlds->warning->end : 0, | 1460 | result.config.initial_config.serverPort == HTTPS_PORT) || |
| 1849 | thlds->critical ? true : false, thlds->critical ? thlds->critical->end : 0, true, 0, true, socket_timeout); | 1461 | (!result.config.initial_config.use_ssl && |
| 1850 | } | 1462 | result.config.initial_config.serverPort == HTTP_PORT)) { |
| 1851 | 1463 | if (!specify_port) { | |
| 1852 | char *perfd_time_connect(double elapsed_time_connect) { | 1464 | result.config.initial_config.serverPort = result.config.initial_config.virtualPort; |
| 1853 | return fperfdata("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, socket_timeout); | 1465 | } |
| 1854 | } | 1466 | } |
| 1855 | 1467 | } | |
| 1856 | char *perfd_time_ssl(double elapsed_time_ssl) { | ||
| 1857 | return fperfdata("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, socket_timeout); | ||
| 1858 | } | ||
| 1859 | |||
| 1860 | char *perfd_time_headers(double elapsed_time_headers) { | ||
| 1861 | return fperfdata("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, socket_timeout); | ||
| 1862 | } | ||
| 1863 | |||
| 1864 | char *perfd_time_firstbyte(double elapsed_time_firstbyte) { | ||
| 1865 | return fperfdata("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, true, socket_timeout); | ||
| 1866 | } | ||
| 1867 | |||
| 1868 | char *perfd_time_transfer(double elapsed_time_transfer) { | ||
| 1869 | return fperfdata("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, true, socket_timeout); | ||
| 1870 | } | ||
| 1871 | 1468 | ||
| 1872 | char *perfd_size(int page_len) { | 1469 | return result; |
| 1873 | return perfdata("size", page_len, "B", (min_page_len > 0 ? true : false), min_page_len, (min_page_len > 0 ? true : false), 0, true, 0, | ||
| 1874 | false, 0); | ||
| 1875 | } | 1470 | } |
| 1876 | 1471 | ||
| 1877 | void print_help(void) { | 1472 | void print_help(void) { |
| @@ -1885,7 +1480,8 @@ void print_help(void) { | |||
| 1885 | printf("%s\n", _("strings and regular expressions, check connection times, and report on")); | 1480 | printf("%s\n", _("strings and regular expressions, check connection times, and report on")); |
| 1886 | printf("%s\n", _("certificate expiration times.")); | 1481 | printf("%s\n", _("certificate expiration times.")); |
| 1887 | printf("\n"); | 1482 | printf("\n"); |
| 1888 | printf("%s\n", _("It makes use of libcurl to do so. It tries to be as compatible to check_http")); | 1483 | printf("%s\n", |
| 1484 | _("It makes use of libcurl to do so. It tries to be as compatible to check_http")); | ||
| 1889 | printf("%s\n", _("as possible.")); | 1485 | printf("%s\n", _("as possible.")); |
| 1890 | 1486 | ||
| 1891 | printf("\n\n"); | 1487 | printf("\n\n"); |
| @@ -1903,7 +1499,10 @@ void print_help(void) { | |||
| 1903 | printf(" %s\n", _("Host name argument for servers using host headers (virtual host)")); | 1499 | printf(" %s\n", _("Host name argument for servers using host headers (virtual host)")); |
| 1904 | printf(" %s\n", _("Append a port to include it in the header (eg: example.com:5000)")); | 1500 | printf(" %s\n", _("Append a port to include it in the header (eg: example.com:5000)")); |
| 1905 | printf(" %s\n", "-I, --IP-address=ADDRESS"); | 1501 | printf(" %s\n", "-I, --IP-address=ADDRESS"); |
| 1906 | printf(" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); | 1502 | printf(" %s\n", |
| 1503 | "IP address or name (use numeric address if possible to bypass DNS lookup)."); | ||
| 1504 | printf(" %s\n", | ||
| 1505 | "This overwrites the network address of the target while leaving everything else (HTTP headers) as they are"); | ||
| 1907 | printf(" %s\n", "-p, --port=INTEGER"); | 1506 | printf(" %s\n", "-p, --port=INTEGER"); |
| 1908 | printf(" %s", _("Port number (default: ")); | 1507 | printf(" %s", _("Port number (default: ")); |
| 1909 | printf("%d)\n", HTTP_PORT); | 1508 | printf("%d)\n", HTTP_PORT); |
| @@ -1912,27 +1511,36 @@ void print_help(void) { | |||
| 1912 | 1511 | ||
| 1913 | #ifdef LIBCURL_FEATURE_SSL | 1512 | #ifdef LIBCURL_FEATURE_SSL |
| 1914 | printf(" %s\n", "-S, --ssl=VERSION[+]"); | 1513 | printf(" %s\n", "-S, --ssl=VERSION[+]"); |
| 1915 | printf(" %s\n", _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents")); | 1514 | printf(" %s\n", |
| 1515 | _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents")); | ||
| 1916 | printf(" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,")); | 1516 | printf(" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,")); |
| 1917 | printf(" %s\n", _("1.2 = TLSv1.2, 1.3 = TLSv1.3). With a '+' suffix, newer versions are also accepted.")); | 1517 | printf(" %s\n", _("1.2 = TLSv1.2, 1.3 = TLSv1.3). With a '+' suffix, newer versions are " |
| 1918 | printf(" %s\n", _("Note: SSLv2, SSLv3, TLSv1.0 and TLSv1.1 are deprecated and are usually disabled in libcurl")); | 1518 | "also accepted.")); |
| 1519 | printf(" %s\n", _("Note: SSLv2, SSLv3, TLSv1.0 and TLSv1.1 are deprecated and are usually " | ||
| 1520 | "disabled in libcurl")); | ||
| 1919 | printf(" %s\n", "--sni"); | 1521 | printf(" %s\n", "--sni"); |
| 1920 | printf(" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); | 1522 | printf(" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); |
| 1921 | # if LIBCURL_VERSION_NUM >= 0x071801 | 1523 | # if LIBCURL_VERSION_NUM >= 0x071801 |
| 1922 | printf(" %s\n", _("Note: --sni is the default in libcurl as SSLv2 and SSLV3 are deprecated and")); | 1524 | printf(" %s\n", |
| 1525 | _("Note: --sni is the default in libcurl as SSLv2 and SSLV3 are deprecated and")); | ||
| 1923 | printf(" %s\n", _(" SNI only really works since TLSv1.0")); | 1526 | printf(" %s\n", _(" SNI only really works since TLSv1.0")); |
| 1924 | # else | 1527 | # else |
| 1925 | printf(" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1")); | 1528 | printf(" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1")); |
| 1926 | # endif | 1529 | # endif |
| 1927 | printf(" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); | 1530 | printf(" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); |
| 1928 | printf(" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443.")); | 1531 | printf(" %s\n", |
| 1929 | printf(" %s\n", _("A STATE_WARNING is returned if the certificate has a validity less than the")); | 1532 | _("Minimum number of days a certificate has to be valid. Port defaults to 443.")); |
| 1930 | printf(" %s\n", _("first agument's value. If there is a second argument and the certificate's")); | 1533 | printf(" %s\n", |
| 1534 | _("A STATE_WARNING is returned if the certificate has a validity less than the")); | ||
| 1535 | printf(" %s\n", | ||
| 1536 | _("first agument's value. If there is a second argument and the certificate's")); | ||
| 1931 | printf(" %s\n", _("validity is less than its value, a STATE_CRITICAL is returned.")); | 1537 | printf(" %s\n", _("validity is less than its value, a STATE_CRITICAL is returned.")); |
| 1932 | printf(" %s\n", _("(When this option is used the URL is not checked by default. You can use")); | 1538 | printf(" %s\n", |
| 1539 | _("(When this option is used the URL is not checked by default. You can use")); | ||
| 1933 | printf(" %s\n", _(" --continue-after-certificate to override this behavior)")); | 1540 | printf(" %s\n", _(" --continue-after-certificate to override this behavior)")); |
| 1934 | printf(" %s\n", "--continue-after-certificate"); | 1541 | printf(" %s\n", "--continue-after-certificate"); |
| 1935 | printf(" %s\n", _("Allows the HTTP check to continue after performing the certificate check.")); | 1542 | printf(" %s\n", |
| 1543 | _("Allows the HTTP check to continue after performing the certificate check.")); | ||
| 1936 | printf(" %s\n", _("Does nothing unless -C is used.")); | 1544 | printf(" %s\n", _("Does nothing unless -C is used.")); |
| 1937 | printf(" %s\n", "-J, --client-cert=FILE"); | 1545 | printf(" %s\n", "-J, --client-cert=FILE"); |
| 1938 | printf(" %s\n", _("Name of file that contains the client certificate (PEM format)")); | 1546 | printf(" %s\n", _("Name of file that contains the client certificate (PEM format)")); |
| @@ -1950,16 +1558,19 @@ void print_help(void) { | |||
| 1950 | printf(" %s\n", _("Comma-delimited list of strings, at least one of them is expected in")); | 1558 | printf(" %s\n", _("Comma-delimited list of strings, at least one of them is expected in")); |
| 1951 | printf(" %s", _("the first (status) line of the server response (default: ")); | 1559 | printf(" %s", _("the first (status) line of the server response (default: ")); |
| 1952 | printf("%s)\n", HTTP_EXPECT); | 1560 | printf("%s)\n", HTTP_EXPECT); |
| 1953 | printf(" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)")); | 1561 | printf(" %s\n", |
| 1562 | _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)")); | ||
| 1954 | printf(" %s\n", "-d, --header-string=STRING"); | 1563 | printf(" %s\n", "-d, --header-string=STRING"); |
| 1955 | printf(" %s\n", _("String to expect in the response headers")); | 1564 | printf(" %s\n", _("String to expect in the response headers")); |
| 1956 | printf(" %s\n", "-s, --string=STRING"); | 1565 | printf(" %s\n", "-s, --string=STRING"); |
| 1957 | printf(" %s\n", _("String to expect in the content")); | 1566 | printf(" %s\n", _("String to expect in the content")); |
| 1958 | printf(" %s\n", "-u, --url=PATH"); | 1567 | printf(" %s\n", "-u, --url=PATH"); |
| 1959 | printf(" %s\n", _("URL to GET or POST (default: /)")); | 1568 | printf(" %s\n", _("URL to GET or POST (default: /)")); |
| 1569 | printf(" %s\n", _("This is the part after the address in a URL, so for \"https://example.com/index.html\" it would be '-u /index.html'")); | ||
| 1960 | printf(" %s\n", "-P, --post=STRING"); | 1570 | printf(" %s\n", "-P, --post=STRING"); |
| 1961 | printf(" %s\n", _("URL decoded http POST data")); | 1571 | printf(" %s\n", _("URL decoded http POST data")); |
| 1962 | printf(" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"); | 1572 | printf(" %s\n", |
| 1573 | "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"); | ||
| 1963 | printf(" %s\n", _("Set HTTP method.")); | 1574 | printf(" %s\n", _("Set HTTP method.")); |
| 1964 | printf(" %s\n", "-N, --no-body"); | 1575 | printf(" %s\n", "-N, --no-body"); |
| 1965 | printf(" %s\n", _("Don't wait for document body: stop reading after headers.")); | 1576 | printf(" %s\n", _("Don't wait for document body: stop reading after headers.")); |
| @@ -1968,7 +1579,7 @@ void print_help(void) { | |||
| 1968 | printf(" %s\n", _("Warn if document is more than SECONDS old. the number can also be of")); | 1579 | printf(" %s\n", _("Warn if document is more than SECONDS old. the number can also be of")); |
| 1969 | printf(" %s\n", _("the form \"10m\" for minutes, \"10h\" for hours, or \"10d\" for days.")); | 1580 | printf(" %s\n", _("the form \"10m\" for minutes, \"10h\" for hours, or \"10d\" for days.")); |
| 1970 | printf(" %s\n", "-T, --content-type=STRING"); | 1581 | printf(" %s\n", "-T, --content-type=STRING"); |
| 1971 | printf(" %s\n", _("specify Content-Type header media type when POSTing\n")); | 1582 | printf(" %s\n", _("specify Content-Type header media type when POSTing")); |
| 1972 | printf(" %s\n", "-l, --linespan"); | 1583 | printf(" %s\n", "-l, --linespan"); |
| 1973 | printf(" %s\n", _("Allow regex to span newlines (must precede -r or -R)")); | 1584 | printf(" %s\n", _("Allow regex to span newlines (must precede -r or -R)")); |
| 1974 | printf(" %s\n", "-r, --regex, --ereg=STRING"); | 1585 | printf(" %s\n", "-r, --regex, --ereg=STRING"); |
| @@ -1979,7 +1590,8 @@ void print_help(void) { | |||
| 1979 | printf(" %s\n", _("Return STATE if found, OK if not (STATE is CRITICAL, per default)")); | 1590 | printf(" %s\n", _("Return STATE if found, OK if not (STATE is CRITICAL, per default)")); |
| 1980 | printf(" %s\n", _("can be changed with --state--regex)")); | 1591 | printf(" %s\n", _("can be changed with --state--regex)")); |
| 1981 | printf(" %s\n", "--state-regex=STATE"); | 1592 | printf(" %s\n", "--state-regex=STATE"); |
| 1982 | printf(" %s\n", _("Return STATE if regex is found, OK if not. STATE can be one of \"critical\",\"warning\"")); | 1593 | printf(" %s\n", _("Return STATE if regex is found, OK if not. STATE can be one of " |
| 1594 | "\"critical\",\"warning\"")); | ||
| 1983 | printf(" %s\n", "-a, --authorization=AUTH_PAIR"); | 1595 | printf(" %s\n", "-a, --authorization=AUTH_PAIR"); |
| 1984 | printf(" %s\n", _("Username:password on sites with basic authentication")); | 1596 | printf(" %s\n", _("Username:password on sites with basic authentication")); |
| 1985 | printf(" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); | 1597 | printf(" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); |
| @@ -1987,13 +1599,14 @@ void print_help(void) { | |||
| 1987 | printf(" %s\n", "-A, --useragent=STRING"); | 1599 | printf(" %s\n", "-A, --useragent=STRING"); |
| 1988 | printf(" %s\n", _("String to be sent in http header as \"User Agent\"")); | 1600 | printf(" %s\n", _("String to be sent in http header as \"User Agent\"")); |
| 1989 | printf(" %s\n", "-k, --header=STRING"); | 1601 | printf(" %s\n", "-k, --header=STRING"); |
| 1990 | printf(" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers")); | 1602 | printf(" %s\n", _("Any other tags to be sent in http header. Use multiple times for " |
| 1603 | "additional headers")); | ||
| 1991 | printf(" %s\n", "-E, --extended-perfdata"); | 1604 | printf(" %s\n", "-E, --extended-perfdata"); |
| 1992 | printf(" %s\n", _("Print additional performance data")); | 1605 | printf(" %s\n", _("Print additional performance data")); |
| 1993 | printf(" %s\n", "-B, --show-body"); | 1606 | printf(" %s\n", "-B, --show-body"); |
| 1994 | printf(" %s\n", _("Print body content below status line")); | 1607 | printf(" %s\n", _("Print body content below status line")); |
| 1995 | printf(" %s\n", "-L, --link"); | 1608 | // printf(" %s\n", "-L, --link"); |
| 1996 | printf(" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); | 1609 | // printf(" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); |
| 1997 | printf(" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport|curl>"); | 1610 | printf(" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport|curl>"); |
| 1998 | printf(" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the")); | 1611 | printf(" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the")); |
| 1999 | printf(" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); | 1612 | printf(" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); |
| @@ -2003,20 +1616,25 @@ void print_help(void) { | |||
| 2003 | printf(" %s", _("Maximal number of redirects (default: ")); | 1616 | printf(" %s", _("Maximal number of redirects (default: ")); |
| 2004 | printf("%d)\n", DEFAULT_MAX_REDIRS); | 1617 | printf("%d)\n", DEFAULT_MAX_REDIRS); |
| 2005 | printf(" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); | 1618 | printf(" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); |
| 2006 | printf(" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); | 1619 | printf(" %s\n", |
| 1620 | _("Minimum page size required (bytes) : Maximum page size required (bytes)")); | ||
| 2007 | printf("\n"); | 1621 | printf("\n"); |
| 2008 | printf(" %s\n", "--http-version=VERSION"); | 1622 | printf(" %s\n", "--http-version=VERSION"); |
| 2009 | printf(" %s\n", _("Connect via specific HTTP protocol.")); | 1623 | printf(" %s\n", _("Connect via specific HTTP protocol.")); |
| 2010 | printf(" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)")); | 1624 | printf(" %s\n", |
| 1625 | _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)")); | ||
| 2011 | printf(" %s\n", "--enable-automatic-decompression"); | 1626 | printf(" %s\n", "--enable-automatic-decompression"); |
| 2012 | printf(" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); | 1627 | printf(" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); |
| 2013 | printf(" %s\n", "--haproxy-protocol"); | 1628 | printf(" %s\n", "--haproxy-protocol"); |
| 2014 | printf(" %s\n", _("Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL).")); | 1629 | printf(" %s\n", _("Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL).")); |
| 2015 | printf(" %s\n", "--cookie-jar=FILE"); | 1630 | printf(" %s\n", "--cookie-jar=FILE"); |
| 2016 | printf(" %s\n", _("Store cookies in the cookie jar and send them out when requested.")); | 1631 | printf(" %s\n", _("Store cookies in the cookie jar and send them out when requested.")); |
| 2017 | printf(" %s\n", _("Specify an empty string as FILE to enable curl's cookie engine without saving")); | 1632 | printf(" %s\n", |
| 2018 | printf(" %s\n", _("the cookies to disk. Only enabling the engine without saving to disk requires")); | 1633 | _("Specify an empty string as FILE to enable curl's cookie engine without saving")); |
| 2019 | printf(" %s\n", _("handling multiple requests internally to curl, so use it with --onredirect=curl")); | 1634 | printf(" %s\n", |
| 1635 | _("the cookies to disk. Only enabling the engine without saving to disk requires")); | ||
| 1636 | printf(" %s\n", | ||
| 1637 | _("handling multiple requests internally to curl, so use it with --onredirect=curl")); | ||
| 2020 | printf("\n"); | 1638 | printf("\n"); |
| 2021 | 1639 | ||
| 2022 | printf(UT_WARN_CRIT); | 1640 | printf(UT_WARN_CRIT); |
| @@ -2025,13 +1643,18 @@ void print_help(void) { | |||
| 2025 | 1643 | ||
| 2026 | printf(UT_VERBOSE); | 1644 | printf(UT_VERBOSE); |
| 2027 | 1645 | ||
| 1646 | printf(UT_OUTPUT_FORMAT); | ||
| 1647 | |||
| 2028 | printf("\n"); | 1648 | printf("\n"); |
| 2029 | printf("%s\n", _("Notes:")); | 1649 | printf("%s\n", _("Notes:")); |
| 2030 | printf(" %s\n", _("This plugin will attempt to open an HTTP connection with the host.")); | 1650 | printf(" %s\n", _("This plugin will attempt to open an HTTP connection with the host.")); |
| 2031 | printf(" %s\n", _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL")); | 1651 | printf(" %s\n", |
| 2032 | printf(" %s\n", _("other errors return STATE_UNKNOWN. Successful connects, but incorrect response")); | 1652 | _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL")); |
| 1653 | printf(" %s\n", | ||
| 1654 | _("other errors return STATE_UNKNOWN. Successful connects, but incorrect response")); | ||
| 2033 | printf(" %s\n", _("messages from the host result in STATE_WARNING return values. If you are")); | 1655 | printf(" %s\n", _("messages from the host result in STATE_WARNING return values. If you are")); |
| 2034 | printf(" %s\n", _("checking a virtual server that uses 'host headers' you must supply the FQDN")); | 1656 | printf(" %s\n", |
| 1657 | _("checking a virtual server that uses 'host headers' you must supply the FQDN")); | ||
| 2035 | printf(" %s\n", _("(fully qualified domain name) as the [host_name] argument.")); | 1658 | printf(" %s\n", _("(fully qualified domain name) as the [host_name] argument.")); |
| 2036 | 1659 | ||
| 2037 | #ifdef LIBCURL_FEATURE_SSL | 1660 | #ifdef LIBCURL_FEATURE_SSL |
| @@ -2044,41 +1667,60 @@ void print_help(void) { | |||
| 2044 | printf(" %s\n", _("certificate matches the hostname of the server, or if the certificate")); | 1667 | printf(" %s\n", _("certificate matches the hostname of the server, or if the certificate")); |
| 2045 | printf(" %s\n", _("has a valid chain of trust to one of the locally installed CAs.")); | 1668 | printf(" %s\n", _("has a valid chain of trust to one of the locally installed CAs.")); |
| 2046 | printf("\n"); | 1669 | printf("\n"); |
| 1670 | printf(" %s\n", _("To also verify certificates, please set --verify-cert.")); | ||
| 1671 | printf("\n"); | ||
| 2047 | printf("%s\n", _("Examples:")); | 1672 | printf("%s\n", _("Examples:")); |
| 2048 | printf(" %s\n\n", "CHECK CONTENT: check_curl -w 5 -c 10 --ssl -H www.verisign.com"); | 1673 | printf(" %s\n\n", "CHECK CONTENT: check_curl -w 5 -c 10 --ssl -H www.verisign.com"); |
| 2049 | printf(" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,")); | 1674 | printf(" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,")); |
| 2050 | printf(" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); | 1675 | printf(" %s\n", |
| 2051 | printf(" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | 1676 | _("a STATE_OK will be returned. When the server returns its content but exceeds")); |
| 1677 | printf(" %s\n", | ||
| 1678 | _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | ||
| 2052 | printf(" %s\n", _("a STATE_CRITICAL will be returned.")); | 1679 | printf(" %s\n", _("a STATE_CRITICAL will be returned.")); |
| 2053 | printf("\n"); | 1680 | printf("\n"); |
| 2054 | printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 14"); | 1681 | printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 14 -D"); |
| 2055 | printf(" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); | 1682 | printf(" %s\n", |
| 2056 | printf(" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than")); | 1683 | _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); |
| 2057 | printf(" %s\n", _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); | 1684 | printf(" %s\n", |
| 2058 | printf(" %s\n\n", _("the certificate is expired.")); | 1685 | _("a STATE_OK is returned. When the certificate is still valid, but for less than")); |
| 1686 | printf(" %s\n", | ||
| 1687 | _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); | ||
| 1688 | printf(" %s\n", _("the certificate is expired.")); | ||
| 1689 | printf("\n"); | ||
| 1690 | printf(" %s\n", _("The -D flag enforces a certificate validation beyond expiration time.")); | ||
| 2059 | printf("\n"); | 1691 | printf("\n"); |
| 2060 | printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 30,14"); | 1692 | printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 30,14 -D"); |
| 2061 | printf(" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 30 days,")); | 1693 | printf(" %s\n", |
| 2062 | printf(" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than")); | 1694 | _("When the certificate of 'www.verisign.com' is valid for more than 30 days,")); |
| 1695 | printf(" %s\n", | ||
| 1696 | _("a STATE_OK is returned. When the certificate is still valid, but for less than")); | ||
| 2063 | printf(" %s\n", _("30 days, but more than 14 days, a STATE_WARNING is returned.")); | 1697 | printf(" %s\n", _("30 days, but more than 14 days, a STATE_WARNING is returned.")); |
| 2064 | printf(" %s\n", _("A STATE_CRITICAL will be returned when certificate expires in less than 14 days")); | 1698 | printf(" %s\n", |
| 1699 | _("A STATE_CRITICAL will be returned when certificate expires in less than 14 days")); | ||
| 2065 | #endif | 1700 | #endif |
| 2066 | 1701 | ||
| 2067 | printf("\n %s\n", "CHECK WEBSERVER CONTENT VIA PROXY:"); | 1702 | printf("\n %s\n", "CHECK WEBSERVER CONTENT VIA PROXY:"); |
| 2068 | printf(" %s\n", _("It is recommended to use an environment proxy like:")); | 1703 | printf(" %s\n", _("It is recommended to use an environment proxy like:")); |
| 2069 | printf(" %s\n", _("http_proxy=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org")); | 1704 | printf(" %s\n", |
| 1705 | _("http_proxy=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org")); | ||
| 2070 | printf(" %s\n", _("legacy proxy requests in check_http style still work:")); | 1706 | printf(" %s\n", _("legacy proxy requests in check_http style still work:")); |
| 2071 | printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u http://www.monitoring-plugins.org/ -H www.monitoring-plugins.org")); | 1707 | printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u http://www.monitoring-plugins.org/ " |
| 1708 | "-H www.monitoring-plugins.org")); | ||
| 2072 | 1709 | ||
| 2073 | #ifdef LIBCURL_FEATURE_SSL | 1710 | #ifdef LIBCURL_FEATURE_SSL |
| 2074 | printf("\n %s\n", "CHECK SSL WEBSERVER CONTENT VIA PROXY USING HTTP 1.1 CONNECT: "); | 1711 | printf("\n %s\n", "CHECK SSL WEBSERVER CONTENT VIA PROXY USING HTTP 1.1 CONNECT: "); |
| 2075 | printf(" %s\n", _("It is recommended to use an environment proxy like:")); | 1712 | printf(" %s\n", _("It is recommended to use an environment proxy like:")); |
| 2076 | printf(" %s\n", _("https_proxy=http://192.168.100.35:3128 ./check_curl -H www.verisign.com -S")); | 1713 | printf(" %s\n", |
| 2077 | printf(" %s\n", _("legacy proxy requests in check_http style still work:")); | 1714 | _("https_proxy=http://192.168.100.35:3128 ./check_curl -H www.verisign.com -S")); |
| 2078 | printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u https://www.verisign.com/ -S -j CONNECT -H www.verisign.com ")); | 1715 | printf(" %s\n", _("legacy proxy requests in check_http style might still work, but are frowned upon, so DONT:")); |
| 2079 | printf(" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> -S(sl) -j CONNECT -H <webserver>")); | 1716 | printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u https://www.verisign.com/ -S -j " |
| 2080 | printf(" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); | 1717 | "CONNECT -H www.verisign.com ")); |
| 2081 | printf(" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | 1718 | printf(" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> " |
| 1719 | "-S(sl) -j CONNECT -H <webserver>")); | ||
| 1720 | printf(" %s\n", | ||
| 1721 | _("a STATE_OK will be returned. When the server returns its content but exceeds")); | ||
| 1722 | printf(" %s\n", | ||
| 1723 | _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | ||
| 2082 | printf(" %s\n", _("a STATE_CRITICAL will be returned.")); | 1724 | printf(" %s\n", _("a STATE_CRITICAL will be returned.")); |
| 2083 | 1725 | ||
| 2084 | #endif | 1726 | #endif |
| @@ -2089,10 +1731,12 @@ void print_help(void) { | |||
| 2089 | void print_usage(void) { | 1731 | void print_usage(void) { |
| 2090 | printf("%s\n", _("Usage:")); | 1732 | printf("%s\n", _("Usage:")); |
| 2091 | printf(" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n", progname); | 1733 | printf(" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n", progname); |
| 2092 | printf(" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>] [-D]\n"); | 1734 | printf(" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate " |
| 1735 | "file>] [-D]\n"); | ||
| 2093 | printf(" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); | 1736 | printf(" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); |
| 2094 | printf(" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport|curl>]\n"); | 1737 | printf(" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport|curl>]\n"); |
| 2095 | printf(" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); | 1738 | printf(" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive " |
| 1739 | "regex>]\n"); | ||
| 2096 | printf(" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); | 1740 | printf(" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); |
| 2097 | printf(" [-A string] [-k string] [-S <version>] [--sni] [--haproxy-protocol]\n"); | 1741 | printf(" [-A string] [-k string] [-S <version>] [--sni] [--haproxy-protocol]\n"); |
| 2098 | printf(" [-T <content-type>] [-j method]\n"); | 1742 | printf(" [-T <content-type>] [-j method]\n"); |
| @@ -2109,435 +1753,49 @@ void print_usage(void) { | |||
| 2109 | 1753 | ||
| 2110 | void print_curl_version(void) { printf("%s\n", curl_version()); } | 1754 | void print_curl_version(void) { printf("%s\n", curl_version()); } |
| 2111 | 1755 | ||
| 2112 | int curlhelp_initwritebuffer(curlhelp_write_curlbuf *buf) { | ||
| 2113 | buf->bufsize = DEFAULT_BUFFER_SIZE; | ||
| 2114 | buf->buflen = 0; | ||
| 2115 | buf->buf = (char *)malloc((size_t)buf->bufsize); | ||
| 2116 | if (buf->buf == NULL) | ||
| 2117 | return -1; | ||
| 2118 | return 0; | ||
| 2119 | } | ||
| 2120 | |||
| 2121 | size_t curlhelp_buffer_write_callback(void *buffer, size_t size, size_t nmemb, void *stream) { | ||
| 2122 | curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream; | ||
| 2123 | |||
| 2124 | while (buf->bufsize < buf->buflen + size * nmemb + 1) { | ||
| 2125 | buf->bufsize = buf->bufsize * 2; | ||
| 2126 | buf->buf = (char *)realloc(buf->buf, buf->bufsize); | ||
| 2127 | if (buf->buf == NULL) { | ||
| 2128 | fprintf(stderr, "malloc failed (%d) %s\n", errno, strerror(errno)); | ||
| 2129 | return -1; | ||
| 2130 | } | ||
| 2131 | } | ||
| 2132 | |||
| 2133 | memcpy(buf->buf + buf->buflen, buffer, size * nmemb); | ||
| 2134 | buf->buflen += size * nmemb; | ||
| 2135 | buf->buf[buf->buflen] = '\0'; | ||
| 2136 | |||
| 2137 | return (int)(size * nmemb); | ||
| 2138 | } | ||
| 2139 | |||
| 2140 | size_t curlhelp_buffer_read_callback(void *buffer, size_t size, size_t nmemb, void *stream) { | ||
| 2141 | curlhelp_read_curlbuf *buf = (curlhelp_read_curlbuf *)stream; | ||
| 2142 | |||
| 2143 | size_t n = min(nmemb * size, buf->buflen - buf->pos); | ||
| 2144 | |||
| 2145 | memcpy(buffer, buf->buf + buf->pos, n); | ||
| 2146 | buf->pos += n; | ||
| 2147 | |||
| 2148 | return (int)n; | ||
| 2149 | } | ||
| 2150 | |||
| 2151 | void curlhelp_freewritebuffer(curlhelp_write_curlbuf *buf) { | ||
| 2152 | free(buf->buf); | ||
| 2153 | buf->buf = NULL; | ||
| 2154 | } | ||
| 2155 | |||
| 2156 | int curlhelp_initreadbuffer(curlhelp_read_curlbuf *buf, const char *data, size_t datalen) { | ||
| 2157 | buf->buflen = datalen; | ||
| 2158 | buf->buf = (char *)malloc((size_t)buf->buflen); | ||
| 2159 | if (buf->buf == NULL) | ||
| 2160 | return -1; | ||
| 2161 | memcpy(buf->buf, data, datalen); | ||
| 2162 | buf->pos = 0; | ||
| 2163 | return 0; | ||
| 2164 | } | ||
| 2165 | |||
| 2166 | void curlhelp_freereadbuffer(curlhelp_read_curlbuf *buf) { | ||
| 2167 | free(buf->buf); | ||
| 2168 | buf->buf = NULL; | ||
| 2169 | } | ||
| 2170 | |||
| 2171 | /* TODO: where to put this, it's actually part of sstrings2 (logically)? | ||
| 2172 | */ | ||
| 2173 | const char *strrstr2(const char *haystack, const char *needle) { | ||
| 2174 | int counter; | ||
| 2175 | size_t len; | ||
| 2176 | const char *prev_pos; | ||
| 2177 | const char *pos; | ||
| 2178 | |||
| 2179 | if (haystack == NULL || needle == NULL) | ||
| 2180 | return NULL; | ||
| 2181 | |||
| 2182 | if (haystack[0] == '\0' || needle[0] == '\0') | ||
| 2183 | return NULL; | ||
| 2184 | |||
| 2185 | counter = 0; | ||
| 2186 | prev_pos = NULL; | ||
| 2187 | pos = haystack; | ||
| 2188 | len = strlen(needle); | ||
| 2189 | for (;;) { | ||
| 2190 | pos = strstr(pos, needle); | ||
| 2191 | if (pos == NULL) { | ||
| 2192 | if (counter == 0) | ||
| 2193 | return NULL; | ||
| 2194 | return prev_pos; | ||
| 2195 | } | ||
| 2196 | counter++; | ||
| 2197 | prev_pos = pos; | ||
| 2198 | pos += len; | ||
| 2199 | if (*pos == '\0') | ||
| 2200 | return prev_pos; | ||
| 2201 | } | ||
| 2202 | } | ||
| 2203 | |||
| 2204 | int curlhelp_parse_statusline(const char *buf, curlhelp_statusline *status_line) { | ||
| 2205 | char *first_line_end; | ||
| 2206 | char *p; | ||
| 2207 | size_t first_line_len; | ||
| 2208 | char *pp; | ||
| 2209 | const char *start; | ||
| 2210 | char *first_line_buf; | ||
| 2211 | |||
| 2212 | /* find last start of a new header */ | ||
| 2213 | start = strrstr2(buf, "\r\nHTTP/"); | ||
| 2214 | if (start != NULL) { | ||
| 2215 | start += 2; | ||
| 2216 | buf = start; | ||
| 2217 | } | ||
| 2218 | |||
| 2219 | first_line_end = strstr(buf, "\r\n"); | ||
| 2220 | if (first_line_end == NULL) | ||
| 2221 | return -1; | ||
| 2222 | |||
| 2223 | first_line_len = (size_t)(first_line_end - buf); | ||
| 2224 | status_line->first_line = (char *)malloc(first_line_len + 1); | ||
| 2225 | if (status_line->first_line == NULL) | ||
| 2226 | return -1; | ||
| 2227 | memcpy(status_line->first_line, buf, first_line_len); | ||
| 2228 | status_line->first_line[first_line_len] = '\0'; | ||
| 2229 | first_line_buf = strdup(status_line->first_line); | ||
| 2230 | |||
| 2231 | /* protocol and version: "HTTP/x.x" SP or "HTTP/2" SP */ | ||
| 2232 | |||
| 2233 | p = strtok(first_line_buf, "/"); | ||
| 2234 | if (p == NULL) { | ||
| 2235 | free(first_line_buf); | ||
| 2236 | return -1; | ||
| 2237 | } | ||
| 2238 | if (strcmp(p, "HTTP") != 0) { | ||
| 2239 | free(first_line_buf); | ||
| 2240 | return -1; | ||
| 2241 | } | ||
| 2242 | |||
| 2243 | p = strtok(NULL, " "); | ||
| 2244 | if (p == NULL) { | ||
| 2245 | free(first_line_buf); | ||
| 2246 | return -1; | ||
| 2247 | } | ||
| 2248 | if (strchr(p, '.') != NULL) { | ||
| 2249 | |||
| 2250 | /* HTTP 1.x case */ | ||
| 2251 | strtok(p, "."); | ||
| 2252 | status_line->http_major = (int)strtol(p, &pp, 10); | ||
| 2253 | if (*pp != '\0') { | ||
| 2254 | free(first_line_buf); | ||
| 2255 | return -1; | ||
| 2256 | } | ||
| 2257 | strtok(NULL, " "); | ||
| 2258 | status_line->http_minor = (int)strtol(p, &pp, 10); | ||
| 2259 | if (*pp != '\0') { | ||
| 2260 | free(first_line_buf); | ||
| 2261 | return -1; | ||
| 2262 | } | ||
| 2263 | p += 4; /* 1.x SP */ | ||
| 2264 | } else { | ||
| 2265 | /* HTTP 2 case */ | ||
| 2266 | status_line->http_major = (int)strtol(p, &pp, 10); | ||
| 2267 | status_line->http_minor = 0; | ||
| 2268 | p += 2; /* 2 SP */ | ||
| 2269 | } | ||
| 2270 | |||
| 2271 | /* status code: "404" or "404.1", then SP */ | ||
| 2272 | |||
| 2273 | p = strtok(p, " "); | ||
| 2274 | if (p == NULL) { | ||
| 2275 | free(first_line_buf); | ||
| 2276 | return -1; | ||
| 2277 | } | ||
| 2278 | if (strchr(p, '.') != NULL) { | ||
| 2279 | char *ppp; | ||
| 2280 | ppp = strtok(p, "."); | ||
| 2281 | status_line->http_code = (int)strtol(ppp, &pp, 10); | ||
| 2282 | if (*pp != '\0') { | ||
| 2283 | free(first_line_buf); | ||
| 2284 | return -1; | ||
| 2285 | } | ||
| 2286 | ppp = strtok(NULL, ""); | ||
| 2287 | status_line->http_subcode = (int)strtol(ppp, &pp, 10); | ||
| 2288 | if (*pp != '\0') { | ||
| 2289 | free(first_line_buf); | ||
| 2290 | return -1; | ||
| 2291 | } | ||
| 2292 | p += 6; /* 400.1 SP */ | ||
| 2293 | } else { | ||
| 2294 | status_line->http_code = (int)strtol(p, &pp, 10); | ||
| 2295 | status_line->http_subcode = -1; | ||
| 2296 | if (*pp != '\0') { | ||
| 2297 | free(first_line_buf); | ||
| 2298 | return -1; | ||
| 2299 | } | ||
| 2300 | p += 4; /* 400 SP */ | ||
| 2301 | } | ||
| 2302 | |||
| 2303 | /* Human readable message: "Not Found" CRLF */ | ||
| 2304 | |||
| 2305 | p = strtok(p, ""); | ||
| 2306 | if (p == NULL) { | ||
| 2307 | status_line->msg = ""; | ||
| 2308 | return 0; | ||
| 2309 | } | ||
| 2310 | status_line->msg = status_line->first_line + (p - first_line_buf); | ||
| 2311 | free(first_line_buf); | ||
| 2312 | |||
| 2313 | return 0; | ||
| 2314 | } | ||
| 2315 | |||
| 2316 | void curlhelp_free_statusline(curlhelp_statusline *status_line) { free(status_line->first_line); } | ||
| 2317 | |||
| 2318 | char *get_header_value(const struct phr_header *headers, const size_t nof_headers, const char *header) { | ||
| 2319 | for (size_t i = 0; i < nof_headers; i++) { | ||
| 2320 | if (headers[i].name != NULL && strncasecmp(header, headers[i].name, max(headers[i].name_len, 4)) == 0) { | ||
| 2321 | return strndup(headers[i].value, headers[i].value_len); | ||
| 2322 | } | ||
| 2323 | } | ||
| 2324 | return NULL; | ||
| 2325 | } | ||
| 2326 | |||
| 2327 | int check_document_dates(const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFAULT_BUFFER_SIZE]) { | ||
| 2328 | char *server_date = NULL; | ||
| 2329 | char *document_date = NULL; | ||
| 2330 | int date_result = STATE_OK; | ||
| 2331 | curlhelp_statusline status_line; | ||
| 2332 | struct phr_header headers[255]; | ||
| 2333 | size_t nof_headers = 255; | ||
| 2334 | size_t msglen; | ||
| 2335 | |||
| 2336 | int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major, &status_line.http_minor, | ||
| 2337 | &status_line.http_code, &status_line.msg, &msglen, headers, &nof_headers, 0); | ||
| 2338 | |||
| 2339 | if (res == -1) { | ||
| 2340 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); | ||
| 2341 | } | ||
| 2342 | |||
| 2343 | server_date = get_header_value(headers, nof_headers, "date"); | ||
| 2344 | document_date = get_header_value(headers, nof_headers, "last-modified"); | ||
| 2345 | |||
| 2346 | if (!server_date || !*server_date) { | ||
| 2347 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
| 2348 | |||
| 2349 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sServer date unknown, "), *msg); | ||
| 2350 | strcpy(*msg, tmp); | ||
| 2351 | |||
| 2352 | date_result = max_state_alt(STATE_UNKNOWN, date_result); | ||
| 2353 | |||
| 2354 | } else if (!document_date || !*document_date) { | ||
| 2355 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
| 2356 | |||
| 2357 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sDocument modification date unknown, "), *msg); | ||
| 2358 | strcpy(*msg, tmp); | ||
| 2359 | |||
| 2360 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
| 2361 | |||
| 2362 | } else { | ||
| 2363 | time_t srv_data = curl_getdate(server_date, NULL); | ||
| 2364 | time_t doc_data = curl_getdate(document_date, NULL); | ||
| 2365 | if (verbose >= 2) | ||
| 2366 | printf("* server date: '%s' (%d), doc_date: '%s' (%d)\n", server_date, (int)srv_data, document_date, (int)doc_data); | ||
| 2367 | if (srv_data <= 0) { | ||
| 2368 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
| 2369 | |||
| 2370 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sServer date \"%100s\" unparsable, "), *msg, server_date); | ||
| 2371 | strcpy(*msg, tmp); | ||
| 2372 | |||
| 2373 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
| 2374 | } else if (doc_data <= 0) { | ||
| 2375 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
| 2376 | |||
| 2377 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date); | ||
| 2378 | strcpy(*msg, tmp); | ||
| 2379 | |||
| 2380 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
| 2381 | } else if (doc_data > srv_data + 30) { | ||
| 2382 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
| 2383 | |||
| 2384 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sDocument is %d seconds in the future, "), *msg, (int)doc_data - (int)srv_data); | ||
| 2385 | strcpy(*msg, tmp); | ||
| 2386 | |||
| 2387 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
| 2388 | } else if (doc_data < srv_data - maximum_age) { | ||
| 2389 | int n = (srv_data - doc_data); | ||
| 2390 | if (n > (60 * 60 * 24 * 2)) { | ||
| 2391 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
| 2392 | |||
| 2393 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %.1f days ago, "), *msg, ((float)n) / (60 * 60 * 24)); | ||
| 2394 | strcpy(*msg, tmp); | ||
| 2395 | |||
| 2396 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
| 2397 | } else { | ||
| 2398 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
| 2399 | |||
| 2400 | snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), (n / 60) % 60, n % 60); | ||
| 2401 | strcpy(*msg, tmp); | ||
| 2402 | |||
| 2403 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
| 2404 | } | ||
| 2405 | } | ||
| 2406 | } | ||
| 2407 | |||
| 2408 | if (server_date) | ||
| 2409 | free(server_date); | ||
| 2410 | if (document_date) | ||
| 2411 | free(document_date); | ||
| 2412 | |||
| 2413 | return date_result; | ||
| 2414 | } | ||
| 2415 | |||
| 2416 | int get_content_length(const curlhelp_write_curlbuf *header_buf, const curlhelp_write_curlbuf *body_buf) { | ||
| 2417 | size_t content_length = 0; | ||
| 2418 | struct phr_header headers[255]; | ||
| 2419 | size_t nof_headers = 255; | ||
| 2420 | size_t msglen; | ||
| 2421 | char *content_length_s = NULL; | ||
| 2422 | curlhelp_statusline status_line; | ||
| 2423 | |||
| 2424 | int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major, &status_line.http_minor, | ||
| 2425 | &status_line.http_code, &status_line.msg, &msglen, headers, &nof_headers, 0); | ||
| 2426 | |||
| 2427 | if (res == -1) { | ||
| 2428 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); | ||
| 2429 | } | ||
| 2430 | |||
| 2431 | content_length_s = get_header_value(headers, nof_headers, "content-length"); | ||
| 2432 | if (!content_length_s) { | ||
| 2433 | return header_buf->buflen + body_buf->buflen; | ||
| 2434 | } | ||
| 2435 | content_length_s += strspn(content_length_s, " \t"); | ||
| 2436 | content_length = atoi(content_length_s); | ||
| 2437 | if (content_length != body_buf->buflen) { | ||
| 2438 | /* TODO: should we warn if the actual and the reported body length don't match? */ | ||
| 2439 | } | ||
| 2440 | |||
| 2441 | if (content_length_s) | ||
| 2442 | free(content_length_s); | ||
| 2443 | |||
| 2444 | return header_buf->buflen + body_buf->buflen; | ||
| 2445 | } | ||
| 2446 | |||
| 2447 | /* TODO: is there a better way in libcurl to check for the SSL library? */ | ||
| 2448 | curlhelp_ssl_library curlhelp_get_ssl_library(void) { | ||
| 2449 | curl_version_info_data *version_data; | ||
| 2450 | char *ssl_version; | ||
| 2451 | char *library; | ||
| 2452 | curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN; | ||
| 2453 | |||
| 2454 | version_data = curl_version_info(CURLVERSION_NOW); | ||
| 2455 | if (version_data == NULL) | ||
| 2456 | return CURLHELP_SSL_LIBRARY_UNKNOWN; | ||
| 2457 | |||
| 2458 | ssl_version = strdup(version_data->ssl_version); | ||
| 2459 | if (ssl_version == NULL) | ||
| 2460 | return CURLHELP_SSL_LIBRARY_UNKNOWN; | ||
| 2461 | |||
| 2462 | library = strtok(ssl_version, "/"); | ||
| 2463 | if (library == NULL) | ||
| 2464 | return CURLHELP_SSL_LIBRARY_UNKNOWN; | ||
| 2465 | |||
| 2466 | if (strcmp(library, "OpenSSL") == 0) | ||
| 2467 | ssl_library = CURLHELP_SSL_LIBRARY_OPENSSL; | ||
| 2468 | else if (strcmp(library, "LibreSSL") == 0) | ||
| 2469 | ssl_library = CURLHELP_SSL_LIBRARY_LIBRESSL; | ||
| 2470 | else if (strcmp(library, "GnuTLS") == 0) | ||
| 2471 | ssl_library = CURLHELP_SSL_LIBRARY_GNUTLS; | ||
| 2472 | else if (strcmp(library, "NSS") == 0) | ||
| 2473 | ssl_library = CURLHELP_SSL_LIBRARY_NSS; | ||
| 2474 | |||
| 2475 | if (verbose >= 2) | ||
| 2476 | printf("* SSL library string is : %s %s (%d)\n", version_data->ssl_version, library, ssl_library); | ||
| 2477 | |||
| 2478 | free(ssl_version); | ||
| 2479 | |||
| 2480 | return ssl_library; | ||
| 2481 | } | ||
| 2482 | |||
| 2483 | const char *curlhelp_get_ssl_library_string(curlhelp_ssl_library ssl_library) { | ||
| 2484 | switch (ssl_library) { | ||
| 2485 | case CURLHELP_SSL_LIBRARY_OPENSSL: | ||
| 2486 | return "OpenSSL"; | ||
| 2487 | case CURLHELP_SSL_LIBRARY_LIBRESSL: | ||
| 2488 | return "LibreSSL"; | ||
| 2489 | case CURLHELP_SSL_LIBRARY_GNUTLS: | ||
| 2490 | return "GnuTLS"; | ||
| 2491 | case CURLHELP_SSL_LIBRARY_NSS: | ||
| 2492 | return "NSS"; | ||
| 2493 | case CURLHELP_SSL_LIBRARY_UNKNOWN: | ||
| 2494 | default: | ||
| 2495 | return "unknown"; | ||
| 2496 | } | ||
| 2497 | } | ||
| 2498 | |||
| 2499 | #ifdef LIBCURL_FEATURE_SSL | 1756 | #ifdef LIBCURL_FEATURE_SSL |
| 2500 | # ifndef USE_OPENSSL | 1757 | # ifndef USE_OPENSSL |
| 2501 | time_t parse_cert_date(const char *s) { | 1758 | time_t parse_cert_date(const char *s) { |
| 2502 | struct tm tm; | 1759 | if (!s) { |
| 2503 | time_t date; | ||
| 2504 | char *res; | ||
| 2505 | |||
| 2506 | if (!s) | ||
| 2507 | return -1; | 1760 | return -1; |
| 1761 | } | ||
| 2508 | 1762 | ||
| 2509 | /* Jan 17 14:25:12 2020 GMT */ | 1763 | /* Jan 17 14:25:12 2020 GMT */ |
| 2510 | res = strptime(s, "%Y-%m-%d %H:%M:%S GMT", &tm); | 1764 | struct tm tm; |
| 1765 | char *res = strptime(s, "%Y-%m-%d %H:%M:%S GMT", &tm); | ||
| 2511 | /* Sep 11 12:00:00 2020 GMT */ | 1766 | /* Sep 11 12:00:00 2020 GMT */ |
| 2512 | if (res == NULL) | 1767 | if (res == NULL) { |
| 2513 | strptime(s, "%Y %m %d %H:%M:%S GMT", &tm); | 1768 | strptime(s, "%Y %m %d %H:%M:%S GMT", &tm); |
| 2514 | date = mktime(&tm); | 1769 | } |
| 1770 | time_t date = mktime(&tm); | ||
| 2515 | 1771 | ||
| 2516 | return date; | 1772 | return date; |
| 2517 | } | 1773 | } |
| 1774 | # endif /* USE_OPENSSL */ | ||
| 1775 | #endif /* LIBCURL_FEATURE_SSL */ | ||
| 2518 | 1776 | ||
| 1777 | #ifdef LIBCURL_FEATURE_SSL | ||
| 1778 | # ifndef USE_OPENSSL | ||
| 2519 | /* TODO: this needs cleanup in the sslutils.c, maybe we the #else case to | 1779 | /* TODO: this needs cleanup in the sslutils.c, maybe we the #else case to |
| 2520 | * OpenSSL could be this function | 1780 | * OpenSSL could be this function |
| 2521 | */ | 1781 | */ |
| 2522 | int net_noopenssl_check_certificate(cert_ptr_union *cert_ptr, int days_till_exp_warn, int days_till_exp_crit) { | 1782 | int net_noopenssl_check_certificate(cert_ptr_union *cert_ptr, int days_till_exp_warn, |
| 2523 | int i; | 1783 | int days_till_exp_crit) { |
| 2524 | struct curl_slist *slist; | ||
| 2525 | int cname_found = 0; | ||
| 2526 | char *start_date_str = NULL; | ||
| 2527 | char *end_date_str = NULL; | ||
| 2528 | time_t start_date; | ||
| 2529 | time_t end_date; | ||
| 2530 | char *tz; | ||
| 2531 | float time_left; | ||
| 2532 | int days_left; | ||
| 2533 | int time_remaining; | ||
| 2534 | char timestamp[50] = ""; | ||
| 2535 | int status = STATE_UNKNOWN; | ||
| 2536 | 1784 | ||
| 2537 | if (verbose >= 2) | 1785 | if (verbose >= 2) { |
| 2538 | printf("**** REQUEST CERTIFICATES ****\n"); | 1786 | printf("**** REQUEST CERTIFICATES ****\n"); |
| 1787 | } | ||
| 1788 | |||
| 1789 | char *start_date_str = NULL; | ||
| 1790 | char *end_date_str = NULL; | ||
| 1791 | bool have_first_cert = false; | ||
| 1792 | bool cname_found = false; | ||
| 1793 | for (int i = 0; i < cert_ptr->to_certinfo->num_of_certs; i++) { | ||
| 1794 | if (have_first_cert) { | ||
| 1795 | break; | ||
| 1796 | } | ||
| 2539 | 1797 | ||
| 2540 | for (i = 0; i < cert_ptr->to_certinfo->num_of_certs; i++) { | 1798 | struct curl_slist *slist; |
| 2541 | for (slist = cert_ptr->to_certinfo->certinfo[i]; slist; slist = slist->next) { | 1799 | for (slist = cert_ptr->to_certinfo->certinfo[i]; slist; slist = slist->next) { |
| 2542 | /* find first common name in subject, | 1800 | /* find first common name in subject, |
| 2543 | * TODO: check alternative subjects for | 1801 | * TODO: check alternative subjects for |
| @@ -2553,7 +1811,7 @@ int net_noopenssl_check_certificate(cert_ptr_union *cert_ptr, int days_till_exp_ | |||
| 2553 | } | 1811 | } |
| 2554 | if (p != NULL) { | 1812 | if (p != NULL) { |
| 2555 | if (strncmp(host_name, p + d, strlen(host_name)) == 0) { | 1813 | if (strncmp(host_name, p + d, strlen(host_name)) == 0) { |
| 2556 | cname_found = 1; | 1814 | cname_found = true; |
| 2557 | } | 1815 | } |
| 2558 | } | 1816 | } |
| 2559 | } else if (strncasecmp(slist->data, "Start Date:", 11) == 0) { | 1817 | } else if (strncasecmp(slist->data, "Start Date:", 11) == 0) { |
| @@ -2561,78 +1819,93 @@ int net_noopenssl_check_certificate(cert_ptr_union *cert_ptr, int days_till_exp_ | |||
| 2561 | } else if (strncasecmp(slist->data, "Expire Date:", 12) == 0) { | 1819 | } else if (strncasecmp(slist->data, "Expire Date:", 12) == 0) { |
| 2562 | end_date_str = &slist->data[12]; | 1820 | end_date_str = &slist->data[12]; |
| 2563 | } else if (strncasecmp(slist->data, "Cert:", 5) == 0) { | 1821 | } else if (strncasecmp(slist->data, "Cert:", 5) == 0) { |
| 2564 | goto HAVE_FIRST_CERT; | 1822 | have_first_cert = true; |
| 1823 | break; | ||
| 2565 | } | 1824 | } |
| 2566 | if (verbose >= 2) | 1825 | if (verbose >= 2) { |
| 2567 | printf("%d ** %s\n", i, slist->data); | 1826 | printf("%d ** %s\n", i, slist->data); |
| 1827 | } | ||
| 2568 | } | 1828 | } |
| 2569 | } | 1829 | } |
| 2570 | HAVE_FIRST_CERT: | ||
| 2571 | 1830 | ||
| 2572 | if (verbose >= 2) | 1831 | if (verbose >= 2) { |
| 2573 | printf("**** REQUEST CERTIFICATES ****\n"); | 1832 | printf("**** REQUEST CERTIFICATES ****\n"); |
| 1833 | } | ||
| 2574 | 1834 | ||
| 2575 | if (!cname_found) { | 1835 | if (!cname_found) { |
| 2576 | printf("%s\n", _("CRITICAL - Cannot retrieve certificate subject.")); | 1836 | printf("%s\n", _("CRITICAL - Cannot retrieve certificate subject.")); |
| 2577 | return STATE_CRITICAL; | 1837 | return STATE_CRITICAL; |
| 2578 | } | 1838 | } |
| 2579 | 1839 | ||
| 2580 | start_date = parse_cert_date(start_date_str); | 1840 | time_t start_date = parse_cert_date(start_date_str); |
| 2581 | if (start_date <= 0) { | 1841 | if (start_date <= 0) { |
| 2582 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("WARNING - Unparsable 'Start Date' in certificate: '%s'"), start_date_str); | 1842 | snprintf(msg, DEFAULT_BUFFER_SIZE, |
| 1843 | _("WARNING - Unparsable 'Start Date' in certificate: '%s'"), start_date_str); | ||
| 2583 | puts(msg); | 1844 | puts(msg); |
| 2584 | return STATE_WARNING; | 1845 | return STATE_WARNING; |
| 2585 | } | 1846 | } |
| 2586 | 1847 | ||
| 2587 | end_date = parse_cert_date(end_date_str); | 1848 | time_t end_date = parse_cert_date(end_date_str); |
| 2588 | if (end_date <= 0) { | 1849 | if (end_date <= 0) { |
| 2589 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("WARNING - Unparsable 'Expire Date' in certificate: '%s'"), start_date_str); | 1850 | snprintf(msg, DEFAULT_BUFFER_SIZE, |
| 1851 | _("WARNING - Unparsable 'Expire Date' in certificate: '%s'"), start_date_str); | ||
| 2590 | puts(msg); | 1852 | puts(msg); |
| 2591 | return STATE_WARNING; | 1853 | return STATE_WARNING; |
| 2592 | } | 1854 | } |
| 2593 | 1855 | ||
| 2594 | time_left = difftime(end_date, time(NULL)); | 1856 | float time_left = difftime(end_date, time(NULL)); |
| 2595 | days_left = time_left / 86400; | 1857 | int days_left = time_left / 86400; |
| 2596 | tz = getenv("TZ"); | 1858 | char *tz = getenv("TZ"); |
| 2597 | setenv("TZ", "GMT", 1); | 1859 | setenv("TZ", "GMT", 1); |
| 2598 | tzset(); | 1860 | tzset(); |
| 1861 | |||
| 1862 | char timestamp[50] = ""; | ||
| 2599 | strftime(timestamp, 50, "%c %z", localtime(&end_date)); | 1863 | strftime(timestamp, 50, "%c %z", localtime(&end_date)); |
| 2600 | if (tz) | 1864 | if (tz) { |
| 2601 | setenv("TZ", tz, 1); | 1865 | setenv("TZ", tz, 1); |
| 2602 | else | 1866 | } else { |
| 2603 | unsetenv("TZ"); | 1867 | unsetenv("TZ"); |
| 1868 | } | ||
| 2604 | tzset(); | 1869 | tzset(); |
| 2605 | 1870 | ||
| 1871 | mp_state_enum status = STATE_UNKNOWN; | ||
| 1872 | int time_remaining; | ||
| 2606 | if (days_left > 0 && days_left <= days_till_exp_warn) { | 1873 | if (days_left > 0 && days_left <= days_till_exp_warn) { |
| 2607 | printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", | 1874 | printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), |
| 2608 | host_name, days_left, timestamp); | 1875 | (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, days_left, |
| 2609 | if (days_left > days_till_exp_crit) | 1876 | timestamp); |
| 1877 | if (days_left > days_till_exp_crit) { | ||
| 2610 | status = STATE_WARNING; | 1878 | status = STATE_WARNING; |
| 2611 | else | 1879 | } else { |
| 2612 | status = STATE_CRITICAL; | 1880 | status = STATE_CRITICAL; |
| 1881 | } | ||
| 2613 | } else if (days_left == 0 && time_left > 0) { | 1882 | } else if (days_left == 0 && time_left > 0) { |
| 2614 | if (time_left >= 3600) | 1883 | if (time_left >= 3600) { |
| 2615 | time_remaining = (int)time_left / 3600; | 1884 | time_remaining = (int)time_left / 3600; |
| 2616 | else | 1885 | } else { |
| 2617 | time_remaining = (int)time_left / 60; | 1886 | time_remaining = (int)time_left / 60; |
| 1887 | } | ||
| 2618 | 1888 | ||
| 2619 | printf(_("%s - Certificate '%s' expires in %u %s (%s)\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, | 1889 | printf(_("%s - Certificate '%s' expires in %u %s (%s)\n"), |
| 2620 | time_remaining, time_left >= 3600 ? "hours" : "minutes", timestamp); | 1890 | (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, time_remaining, |
| 1891 | time_left >= 3600 ? "hours" : "minutes", timestamp); | ||
| 2621 | 1892 | ||
| 2622 | if (days_left > days_till_exp_crit) | 1893 | if (days_left > days_till_exp_crit) { |
| 2623 | status = STATE_WARNING; | 1894 | status = STATE_WARNING; |
| 2624 | else | 1895 | } else { |
| 2625 | status = STATE_CRITICAL; | 1896 | status = STATE_CRITICAL; |
| 1897 | } | ||
| 2626 | } else if (time_left < 0) { | 1898 | } else if (time_left < 0) { |
| 2627 | printf(_("CRITICAL - Certificate '%s' expired on %s.\n"), host_name, timestamp); | 1899 | printf(_("CRITICAL - Certificate '%s' expired on %s.\n"), host_name, timestamp); |
| 2628 | status = STATE_CRITICAL; | 1900 | status = STATE_CRITICAL; |
| 2629 | } else if (days_left == 0) { | 1901 | } else if (days_left == 0) { |
| 2630 | printf(_("%s - Certificate '%s' just expired (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, | 1902 | printf(_("%s - Certificate '%s' just expired (%s).\n"), |
| 2631 | timestamp); | 1903 | (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, timestamp); |
| 2632 | if (days_left > days_till_exp_crit) | 1904 | if (days_left > days_till_exp_crit) { |
| 2633 | status = STATE_WARNING; | 1905 | status = STATE_WARNING; |
| 2634 | else | 1906 | } else { |
| 2635 | status = STATE_CRITICAL; | 1907 | status = STATE_CRITICAL; |
| 1908 | } | ||
| 2636 | } else { | 1909 | } else { |
| 2637 | printf(_("OK - Certificate '%s' will expire on %s.\n"), host_name, timestamp); | 1910 | printf(_("OK - Certificate '%s' will expire on %s.\n"), host_name, timestamp); |
| 2638 | status = STATE_OK; | 1911 | status = STATE_OK; |
diff --git a/plugins/check_curl.d/check_curl_helpers.c b/plugins/check_curl.d/check_curl_helpers.c new file mode 100644 index 00000000..7be781fc --- /dev/null +++ b/plugins/check_curl.d/check_curl_helpers.c | |||
| @@ -0,0 +1,1297 @@ | |||
| 1 | #include "./check_curl_helpers.h" | ||
| 2 | #include <stdbool.h> | ||
| 3 | #include <arpa/inet.h> | ||
| 4 | #include <netinet/in.h> | ||
| 5 | #include <netdb.h> | ||
| 6 | #include <stdlib.h> | ||
| 7 | #include <string.h> | ||
| 8 | #include "../utils.h" | ||
| 9 | #include "check_curl.d/config.h" | ||
| 10 | #include "output.h" | ||
| 11 | #include "perfdata.h" | ||
| 12 | #include "states.h" | ||
| 13 | |||
| 14 | extern int verbose; | ||
| 15 | char errbuf[MAX_INPUT_BUFFER]; | ||
| 16 | bool is_openssl_callback = false; | ||
| 17 | bool add_sslctx_verify_fun = false; | ||
| 18 | |||
| 19 | check_curl_configure_curl_wrapper | ||
| 20 | check_curl_configure_curl(const check_curl_static_curl_config config, | ||
| 21 | check_curl_working_state working_state, bool check_cert, | ||
| 22 | bool on_redirect_dependent, int follow_method, long max_depth) { | ||
| 23 | check_curl_configure_curl_wrapper result = { | ||
| 24 | .errorcode = OK, | ||
| 25 | .curl_state = | ||
| 26 | { | ||
| 27 | .curl_global_initialized = false, | ||
| 28 | .curl_easy_initialized = false, | ||
| 29 | .curl = NULL, | ||
| 30 | |||
| 31 | .body_buf_initialized = false, | ||
| 32 | .body_buf = NULL, | ||
| 33 | .header_buf_initialized = false, | ||
| 34 | .header_buf = NULL, | ||
| 35 | .status_line_initialized = false, | ||
| 36 | .status_line = NULL, | ||
| 37 | .put_buf_initialized = false, | ||
| 38 | .put_buf = NULL, | ||
| 39 | |||
| 40 | .header_list = NULL, | ||
| 41 | .host = NULL, | ||
| 42 | }, | ||
| 43 | }; | ||
| 44 | |||
| 45 | if ((result.curl_state.status_line = calloc(1, sizeof(curlhelp_statusline))) == NULL) { | ||
| 46 | die(STATE_UNKNOWN, "HTTP UNKNOWN - allocation of statusline failed\n"); | ||
| 47 | } | ||
| 48 | |||
| 49 | if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { | ||
| 50 | die(STATE_UNKNOWN, "HTTP UNKNOWN - curl_global_init failed\n"); | ||
| 51 | } | ||
| 52 | result.curl_state.curl_global_initialized = true; | ||
| 53 | |||
| 54 | if ((result.curl_state.curl = curl_easy_init()) == NULL) { | ||
| 55 | die(STATE_UNKNOWN, "HTTP UNKNOWN - curl_easy_init failed\n"); | ||
| 56 | } | ||
| 57 | result.curl_state.curl_easy_initialized = true; | ||
| 58 | |||
| 59 | if (verbose >= 1) { | ||
| 60 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_VERBOSE, 1L), | ||
| 61 | "CURLOPT_VERBOSE"); | ||
| 62 | } | ||
| 63 | |||
| 64 | /* print everything on stdout like check_http would do */ | ||
| 65 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_STDERR, stdout), | ||
| 66 | "CURLOPT_STDERR"); | ||
| 67 | |||
| 68 | if (config.automatic_decompression) { | ||
| 69 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) | ||
| 70 | handle_curl_option_return_code( | ||
| 71 | curl_easy_setopt(result.curl_state.curl, CURLOPT_ACCEPT_ENCODING, ""), | ||
| 72 | "CURLOPT_ACCEPT_ENCODING"); | ||
| 73 | #else | ||
| 74 | handle_curl_option_return_code( | ||
| 75 | curl_easy_setopt(result.curl_state.curl, CURLOPT_ENCODING, ""), "CURLOPT_ENCODING"); | ||
| 76 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) */ | ||
| 77 | } | ||
| 78 | |||
| 79 | /* initialize buffer for body of the answer */ | ||
| 80 | if (curlhelp_initwritebuffer(&result.curl_state.body_buf) < 0) { | ||
| 81 | die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n"); | ||
| 82 | } | ||
| 83 | result.curl_state.body_buf_initialized = true; | ||
| 84 | |||
| 85 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_WRITEFUNCTION, | ||
| 86 | curlhelp_buffer_write_callback), | ||
| 87 | "CURLOPT_WRITEFUNCTION"); | ||
| 88 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_WRITEDATA, | ||
| 89 | (void *)result.curl_state.body_buf), | ||
| 90 | "CURLOPT_WRITEDATA"); | ||
| 91 | |||
| 92 | /* initialize buffer for header of the answer */ | ||
| 93 | if (curlhelp_initwritebuffer(&result.curl_state.header_buf) < 0) { | ||
| 94 | die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n"); | ||
| 95 | } | ||
| 96 | result.curl_state.header_buf_initialized = true; | ||
| 97 | |||
| 98 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_HEADERFUNCTION, | ||
| 99 | curlhelp_buffer_write_callback), | ||
| 100 | "CURLOPT_HEADERFUNCTION"); | ||
| 101 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_WRITEHEADER, | ||
| 102 | (void *)result.curl_state.header_buf), | ||
| 103 | "CURLOPT_WRITEHEADER"); | ||
| 104 | |||
| 105 | /* set the error buffer */ | ||
| 106 | handle_curl_option_return_code( | ||
| 107 | curl_easy_setopt(result.curl_state.curl, CURLOPT_ERRORBUFFER, errbuf), | ||
| 108 | "CURLOPT_ERRORBUFFER"); | ||
| 109 | |||
| 110 | /* set timeouts */ | ||
| 111 | handle_curl_option_return_code( | ||
| 112 | curl_easy_setopt(result.curl_state.curl, CURLOPT_CONNECTTIMEOUT, config.socket_timeout), | ||
| 113 | "CURLOPT_CONNECTTIMEOUT"); | ||
| 114 | |||
| 115 | handle_curl_option_return_code( | ||
| 116 | curl_easy_setopt(result.curl_state.curl, CURLOPT_TIMEOUT, config.socket_timeout), | ||
| 117 | "CURLOPT_TIMEOUT"); | ||
| 118 | |||
| 119 | /* enable haproxy protocol */ | ||
| 120 | if (config.haproxy_protocol) { | ||
| 121 | handle_curl_option_return_code( | ||
| 122 | curl_easy_setopt(result.curl_state.curl, CURLOPT_HAPROXYPROTOCOL, 1L), | ||
| 123 | "CURLOPT_HAPROXYPROTOCOL"); | ||
| 124 | } | ||
| 125 | |||
| 126 | // fill dns resolve cache to make curl connect to the given server_address instead of the | ||
| 127 | // host_name, only required for ssl, because we use the host_name later on to make SNI happy | ||
| 128 | char dnscache[DEFAULT_BUFFER_SIZE]; | ||
| 129 | char addrstr[DEFAULT_BUFFER_SIZE / 2]; | ||
| 130 | if (working_state.use_ssl && working_state.host_name != NULL) { | ||
| 131 | char *tmp_mod_address; | ||
| 132 | |||
| 133 | /* lookup_host() requires an IPv6 address without the brackets. */ | ||
| 134 | if ((strnlen(working_state.server_address, MAX_IPV4_HOSTLENGTH) > 2) && | ||
| 135 | (working_state.server_address[0] == '[')) { | ||
| 136 | // Duplicate and strip the leading '[' | ||
| 137 | tmp_mod_address = | ||
| 138 | strndup(working_state.server_address + 1, strlen(working_state.server_address) - 2); | ||
| 139 | } else { | ||
| 140 | tmp_mod_address = working_state.server_address; | ||
| 141 | } | ||
| 142 | |||
| 143 | int res; | ||
| 144 | if ((res = lookup_host(tmp_mod_address, addrstr, DEFAULT_BUFFER_SIZE / 2, | ||
| 145 | config.sin_family)) != 0) { | ||
| 146 | die(STATE_CRITICAL, | ||
| 147 | _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), | ||
| 148 | working_state.server_address, res, gai_strerror(res)); | ||
| 149 | } | ||
| 150 | |||
| 151 | snprintf(dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", working_state.host_name, | ||
| 152 | working_state.serverPort, addrstr); | ||
| 153 | result.curl_state.host = curl_slist_append(NULL, dnscache); | ||
| 154 | curl_easy_setopt(result.curl_state.curl, CURLOPT_RESOLVE, result.curl_state.host); | ||
| 155 | |||
| 156 | if (verbose >= 1) { | ||
| 157 | printf("* curl CURLOPT_RESOLVE: %s\n", dnscache); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | // If server_address is an IPv6 address it must be surround by square brackets | ||
| 162 | struct in6_addr tmp_in_addr; | ||
| 163 | if (inet_pton(AF_INET6, working_state.server_address, &tmp_in_addr) == 1) { | ||
| 164 | char *new_server_address = calloc(strlen(working_state.server_address) + 3, sizeof(char)); | ||
| 165 | if (new_server_address == NULL) { | ||
| 166 | die(STATE_UNKNOWN, "HTTP UNKNOWN - Unable to allocate memory\n"); | ||
| 167 | } | ||
| 168 | snprintf(new_server_address, strlen(working_state.server_address) + 3, "[%s]", | ||
| 169 | working_state.server_address); | ||
| 170 | working_state.server_address = new_server_address; | ||
| 171 | } | ||
| 172 | |||
| 173 | /* compose URL: use the address we want to connect to, set Host: header later */ | ||
| 174 | char *url = fmt_url(working_state); | ||
| 175 | |||
| 176 | if (verbose >= 1) { | ||
| 177 | printf("* curl CURLOPT_URL: %s\n", url); | ||
| 178 | } | ||
| 179 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_URL, url), | ||
| 180 | "CURLOPT_URL"); | ||
| 181 | |||
| 182 | free(url); | ||
| 183 | |||
| 184 | /* extract proxy information for legacy proxy https requests */ | ||
| 185 | if (!strcmp(working_state.http_method, "CONNECT") || | ||
| 186 | strstr(working_state.server_url, "http") == working_state.server_url) { | ||
| 187 | handle_curl_option_return_code( | ||
| 188 | curl_easy_setopt(result.curl_state.curl, CURLOPT_PROXY, working_state.server_address), | ||
| 189 | "CURLOPT_PROXY"); | ||
| 190 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_PROXYPORT, | ||
| 191 | (long)working_state.serverPort), | ||
| 192 | "CURLOPT_PROXYPORT"); | ||
| 193 | if (verbose >= 2) { | ||
| 194 | printf("* curl CURLOPT_PROXY: %s:%d\n", working_state.server_address, | ||
| 195 | working_state.serverPort); | ||
| 196 | } | ||
| 197 | working_state.http_method = "GET"; | ||
| 198 | handle_curl_option_return_code( | ||
| 199 | curl_easy_setopt(result.curl_state.curl, CURLOPT_URL, working_state.server_url), | ||
| 200 | "CURLOPT_URL"); | ||
| 201 | } | ||
| 202 | |||
| 203 | /* disable body for HEAD request */ | ||
| 204 | if (working_state.http_method && !strcmp(working_state.http_method, "HEAD")) { | ||
| 205 | working_state.no_body = true; | ||
| 206 | } | ||
| 207 | |||
| 208 | /* set HTTP protocol version */ | ||
| 209 | handle_curl_option_return_code( | ||
| 210 | curl_easy_setopt(result.curl_state.curl, CURLOPT_HTTP_VERSION, config.curl_http_version), | ||
| 211 | "CURLOPT_HTTP_VERSION"); | ||
| 212 | |||
| 213 | /* set HTTP method */ | ||
| 214 | if (working_state.http_method) { | ||
| 215 | if (!strcmp(working_state.http_method, "POST")) { | ||
| 216 | handle_curl_option_return_code( | ||
| 217 | curl_easy_setopt(result.curl_state.curl, CURLOPT_POST, 1L), "CURLOPT_POST"); | ||
| 218 | } else if (!strcmp(working_state.http_method, "PUT")) { | ||
| 219 | handle_curl_option_return_code( | ||
| 220 | curl_easy_setopt(result.curl_state.curl, CURLOPT_UPLOAD, 1L), "CURLOPT_UPLOAD"); | ||
| 221 | } else { | ||
| 222 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, | ||
| 223 | CURLOPT_CUSTOMREQUEST, | ||
| 224 | working_state.http_method), | ||
| 225 | "CURLOPT_CUSTOMREQUEST"); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | char *force_host_header = NULL; | ||
| 230 | /* check if Host header is explicitly set in options */ | ||
| 231 | if (config.http_opt_headers_count) { | ||
| 232 | for (size_t i = 0; i < config.http_opt_headers_count; i++) { | ||
| 233 | if (strncmp(config.http_opt_headers[i], "Host:", 5) == 0) { | ||
| 234 | force_host_header = config.http_opt_headers[i]; | ||
| 235 | } | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | /* set hostname (virtual hosts), not needed if CURLOPT_CONNECT_TO is used, but left in | ||
| 240 | * anyway */ | ||
| 241 | char http_header[DEFAULT_BUFFER_SIZE]; | ||
| 242 | if (working_state.host_name != NULL && force_host_header == NULL) { | ||
| 243 | if ((working_state.virtualPort != HTTP_PORT && !working_state.use_ssl) || | ||
| 244 | (working_state.virtualPort != HTTPS_PORT && working_state.use_ssl)) { | ||
| 245 | snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s:%d", working_state.host_name, | ||
| 246 | working_state.virtualPort); | ||
| 247 | } else { | ||
| 248 | snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s", working_state.host_name); | ||
| 249 | } | ||
| 250 | result.curl_state.header_list = | ||
| 251 | curl_slist_append(result.curl_state.header_list, http_header); | ||
| 252 | } | ||
| 253 | |||
| 254 | /* always close connection, be nice to servers */ | ||
| 255 | snprintf(http_header, DEFAULT_BUFFER_SIZE, "Connection: close"); | ||
| 256 | result.curl_state.header_list = curl_slist_append(result.curl_state.header_list, http_header); | ||
| 257 | |||
| 258 | /* attach additional headers supplied by the user */ | ||
| 259 | /* optionally send any other header tag */ | ||
| 260 | if (config.http_opt_headers_count) { | ||
| 261 | for (size_t i = 0; i < config.http_opt_headers_count; i++) { | ||
| 262 | result.curl_state.header_list = | ||
| 263 | curl_slist_append(result.curl_state.header_list, config.http_opt_headers[i]); | ||
| 264 | } | ||
| 265 | } | ||
| 266 | |||
| 267 | /* set HTTP headers */ | ||
| 268 | handle_curl_option_return_code( | ||
| 269 | curl_easy_setopt(result.curl_state.curl, CURLOPT_HTTPHEADER, result.curl_state.header_list), | ||
| 270 | "CURLOPT_HTTPHEADER"); | ||
| 271 | |||
| 272 | #ifdef LIBCURL_FEATURE_SSL | ||
| 273 | /* set SSL version, warn about insecure or unsupported versions */ | ||
| 274 | if (working_state.use_ssl) { | ||
| 275 | handle_curl_option_return_code( | ||
| 276 | curl_easy_setopt(result.curl_state.curl, CURLOPT_SSLVERSION, config.ssl_version), | ||
| 277 | "CURLOPT_SSLVERSION"); | ||
| 278 | } | ||
| 279 | |||
| 280 | /* client certificate and key to present to server (SSL) */ | ||
| 281 | if (config.client_cert) { | ||
| 282 | handle_curl_option_return_code( | ||
| 283 | curl_easy_setopt(result.curl_state.curl, CURLOPT_SSLCERT, config.client_cert), | ||
| 284 | "CURLOPT_SSLCERT"); | ||
| 285 | } | ||
| 286 | |||
| 287 | if (config.client_privkey) { | ||
| 288 | handle_curl_option_return_code( | ||
| 289 | curl_easy_setopt(result.curl_state.curl, CURLOPT_SSLKEY, config.client_privkey), | ||
| 290 | "CURLOPT_SSLKEY"); | ||
| 291 | } | ||
| 292 | |||
| 293 | if (config.ca_cert) { | ||
| 294 | handle_curl_option_return_code( | ||
| 295 | curl_easy_setopt(result.curl_state.curl, CURLOPT_CAINFO, config.ca_cert), | ||
| 296 | "CURLOPT_CAINFO"); | ||
| 297 | } | ||
| 298 | |||
| 299 | if (config.ca_cert || config.verify_peer_and_host) { | ||
| 300 | /* per default if we have a CA verify both the peer and the | ||
| 301 | * hostname in the certificate, can be switched off later */ | ||
| 302 | handle_curl_option_return_code( | ||
| 303 | curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYPEER, 1L), | ||
| 304 | "CURLOPT_SSL_VERIFYPEER"); | ||
| 305 | handle_curl_option_return_code( | ||
| 306 | curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYHOST, 2L), | ||
| 307 | "CURLOPT_SSL_VERIFYHOST"); | ||
| 308 | } else { | ||
| 309 | /* backward-compatible behaviour, be tolerant in checks | ||
| 310 | * TODO: depending on more options have aspects we want | ||
| 311 | * to be less tolerant about ssl verfications | ||
| 312 | */ | ||
| 313 | handle_curl_option_return_code( | ||
| 314 | curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYPEER, 0L), | ||
| 315 | "CURLOPT_SSL_VERIFYPEER"); | ||
| 316 | handle_curl_option_return_code( | ||
| 317 | curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_VERIFYHOST, 0L), | ||
| 318 | "CURLOPT_SSL_VERIFYHOST"); | ||
| 319 | } | ||
| 320 | |||
| 321 | /* detect SSL library used by libcurl */ | ||
| 322 | curlhelp_ssl_library ssl_library = curlhelp_get_ssl_library(); | ||
| 323 | |||
| 324 | /* try hard to get a stack of certificates to verify against */ | ||
| 325 | if (check_cert) { | ||
| 326 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) | ||
| 327 | /* inform curl to report back certificates */ | ||
| 328 | switch (ssl_library) { | ||
| 329 | case CURLHELP_SSL_LIBRARY_OPENSSL: | ||
| 330 | case CURLHELP_SSL_LIBRARY_LIBRESSL: | ||
| 331 | /* set callback to extract certificate with OpenSSL context function (works with | ||
| 332 | * OpenSSL-style libraries only!) */ | ||
| 333 | # ifdef USE_OPENSSL | ||
| 334 | /* libcurl and monitoring plugins built with OpenSSL, good */ | ||
| 335 | add_sslctx_verify_fun = true; | ||
| 336 | is_openssl_callback = true; | ||
| 337 | # endif /* USE_OPENSSL */ | ||
| 338 | /* libcurl is built with OpenSSL, monitoring plugins, so falling | ||
| 339 | * back to manually extracting certificate information */ | ||
| 340 | handle_curl_option_return_code( | ||
| 341 | curl_easy_setopt(result.curl_state.curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); | ||
| 342 | break; | ||
| 343 | |||
| 344 | case CURLHELP_SSL_LIBRARY_NSS: | ||
| 345 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | ||
| 346 | /* NSS: support for CERTINFO is implemented since 7.34.0 */ | ||
| 347 | handle_curl_option_return_code( | ||
| 348 | curl_easy_setopt(result.curl_state.curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); | ||
| 349 | # else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 350 | die(STATE_CRITICAL, | ||
| 351 | "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library " | ||
| 352 | "'%s' is too old)\n", | ||
| 353 | curlhelp_get_ssl_library_string(ssl_library)); | ||
| 354 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | ||
| 355 | break; | ||
| 356 | |||
| 357 | case CURLHELP_SSL_LIBRARY_GNUTLS: | ||
| 358 | # if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) | ||
| 359 | /* GnuTLS: support for CERTINFO is implemented since 7.42.0 */ | ||
| 360 | handle_curl_option_return_code( | ||
| 361 | curl_easy_setopt(result.curl_state.curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); | ||
| 362 | # else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */ | ||
| 363 | die(STATE_CRITICAL, | ||
| 364 | "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library " | ||
| 365 | "'%s' is too old)\n", | ||
| 366 | curlhelp_get_ssl_library_string(ssl_library)); | ||
| 367 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */ | ||
| 368 | break; | ||
| 369 | |||
| 370 | case CURLHELP_SSL_LIBRARY_UNKNOWN: | ||
| 371 | default: | ||
| 372 | die(STATE_CRITICAL, | ||
| 373 | "HTTP CRITICAL - Cannot retrieve certificates (unknown SSL library '%s', must " | ||
| 374 | "implement first)\n", | ||
| 375 | curlhelp_get_ssl_library_string(ssl_library)); | ||
| 376 | break; | ||
| 377 | } | ||
| 378 | # else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ | ||
| 379 | /* old libcurl, our only hope is OpenSSL, otherwise we are out of luck */ | ||
| 380 | if (ssl_library == CURLHELP_SSL_LIBRARY_OPENSSL || | ||
| 381 | ssl_library == CURLHELP_SSL_LIBRARY_LIBRESSL) { | ||
| 382 | add_sslctx_verify_fun = true; | ||
| 383 | } else { | ||
| 384 | die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (no " | ||
| 385 | "CURLOPT_SSL_CTX_FUNCTION, no OpenSSL library or libcurl " | ||
| 386 | "too old and has no CURLOPT_CERTINFO)\n"); | ||
| 387 | } | ||
| 388 | # endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ | ||
| 389 | } | ||
| 390 | |||
| 391 | # if LIBCURL_VERSION_NUM >= \ | ||
| 392 | MAKE_LIBCURL_VERSION(7, 10, 6) /* required for CURLOPT_SSL_CTX_FUNCTION */ | ||
| 393 | // ssl ctx function is not available with all ssl backends | ||
| 394 | if (curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_CTX_FUNCTION, NULL) != | ||
| 395 | CURLE_UNKNOWN_OPTION) { | ||
| 396 | handle_curl_option_return_code( | ||
| 397 | curl_easy_setopt(result.curl_state.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), | ||
| 398 | "CURLOPT_SSL_CTX_FUNCTION"); | ||
| 399 | } | ||
| 400 | # endif | ||
| 401 | #endif /* LIBCURL_FEATURE_SSL */ | ||
| 402 | |||
| 403 | /* set default or user-given user agent identification */ | ||
| 404 | handle_curl_option_return_code( | ||
| 405 | curl_easy_setopt(result.curl_state.curl, CURLOPT_USERAGENT, config.user_agent), | ||
| 406 | "CURLOPT_USERAGENT"); | ||
| 407 | |||
| 408 | /* proxy-authentication */ | ||
| 409 | if (strcmp(config.proxy_auth, "")) { | ||
| 410 | handle_curl_option_return_code( | ||
| 411 | curl_easy_setopt(result.curl_state.curl, CURLOPT_PROXYUSERPWD, config.proxy_auth), | ||
| 412 | "CURLOPT_PROXYUSERPWD"); | ||
| 413 | } | ||
| 414 | |||
| 415 | /* authentication */ | ||
| 416 | if (strcmp(config.user_auth, "")) { | ||
| 417 | handle_curl_option_return_code( | ||
| 418 | curl_easy_setopt(result.curl_state.curl, CURLOPT_USERPWD, config.user_auth), | ||
| 419 | "CURLOPT_USERPWD"); | ||
| 420 | } | ||
| 421 | /* TODO: parameter auth method, bitfield of following methods: | ||
| 422 | * CURLAUTH_BASIC (default) | ||
| 423 | * CURLAUTH_DIGEST | ||
| 424 | * CURLAUTH_DIGEST_IE | ||
| 425 | * CURLAUTH_NEGOTIATE | ||
| 426 | * CURLAUTH_NTLM | ||
| 427 | * CURLAUTH_NTLM_WB | ||
| 428 | * | ||
| 429 | * convenience tokens for typical sets of methods: | ||
| 430 | * CURLAUTH_ANYSAFE: most secure, without BASIC | ||
| 431 | * or CURLAUTH_ANY: most secure, even BASIC if necessary | ||
| 432 | * | ||
| 433 | * handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_HTTPAUTH, | ||
| 434 | * (long)CURLAUTH_DIGEST ), "CURLOPT_HTTPAUTH"); | ||
| 435 | */ | ||
| 436 | |||
| 437 | /* handle redirections */ | ||
| 438 | if (on_redirect_dependent) { | ||
| 439 | if (follow_method == FOLLOW_LIBCURL) { | ||
| 440 | handle_curl_option_return_code( | ||
| 441 | curl_easy_setopt(result.curl_state.curl, CURLOPT_FOLLOWLOCATION, 1L), | ||
| 442 | "CURLOPT_FOLLOWLOCATION"); | ||
| 443 | |||
| 444 | /* default -1 is infinite, not good, could lead to zombie plugins! | ||
| 445 | Setting it to one bigger than maximal limit to handle errors nicely below | ||
| 446 | */ | ||
| 447 | handle_curl_option_return_code( | ||
| 448 | curl_easy_setopt(result.curl_state.curl, CURLOPT_MAXREDIRS, max_depth + 1), | ||
| 449 | "CURLOPT_MAXREDIRS"); | ||
| 450 | |||
| 451 | /* for now allow only http and https (we are a http(s) check plugin in the end) */ | ||
| 452 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 85, 0) | ||
| 453 | handle_curl_option_return_code( | ||
| 454 | curl_easy_setopt(result.curl_state.curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"), | ||
| 455 | "CURLOPT_REDIR_PROTOCOLS_STR"); | ||
| 456 | #elif LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) | ||
| 457 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, | ||
| 458 | CURLOPT_REDIR_PROTOCOLS, | ||
| 459 | CURLPROTO_HTTP | CURLPROTO_HTTPS), | ||
| 460 | "CURLOPT_REDIRECT_PROTOCOLS"); | ||
| 461 | #endif | ||
| 462 | |||
| 463 | /* TODO: handle the following aspects of redirection, make them | ||
| 464 | * command line options too later: | ||
| 465 | CURLOPT_POSTREDIR: method switch | ||
| 466 | CURLINFO_REDIRECT_URL: custom redirect option | ||
| 467 | CURLOPT_REDIRECT_PROTOCOLS: allow people to step outside safe protocols | ||
| 468 | CURLINFO_REDIRECT_COUNT: get the number of redirects, print it, maybe a range | ||
| 469 | option here is nice like for expected page size? | ||
| 470 | */ | ||
| 471 | } else { | ||
| 472 | /* old style redirection*/ | ||
| 473 | } | ||
| 474 | } | ||
| 475 | /* no-body */ | ||
| 476 | if (working_state.no_body) { | ||
| 477 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, CURLOPT_NOBODY, 1L), | ||
| 478 | "CURLOPT_NOBODY"); | ||
| 479 | } | ||
| 480 | |||
| 481 | /* IPv4 or IPv6 forced DNS resolution */ | ||
| 482 | if (config.sin_family == AF_UNSPEC) { | ||
| 483 | handle_curl_option_return_code( | ||
| 484 | curl_easy_setopt(result.curl_state.curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER), | ||
| 485 | "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_WHATEVER)"); | ||
| 486 | } else if (config.sin_family == AF_INET) { | ||
| 487 | handle_curl_option_return_code( | ||
| 488 | curl_easy_setopt(result.curl_state.curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4), | ||
| 489 | "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_V4)"); | ||
| 490 | } | ||
| 491 | #if defined(USE_IPV6) && defined(LIBCURL_FEATURE_IPV6) | ||
| 492 | else if (config.sin_family == AF_INET6) { | ||
| 493 | handle_curl_option_return_code( | ||
| 494 | curl_easy_setopt(result.curl_state.curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6), | ||
| 495 | "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_V6)"); | ||
| 496 | } | ||
| 497 | #endif | ||
| 498 | |||
| 499 | /* either send http POST data (any data, not only POST)*/ | ||
| 500 | if (!strcmp(working_state.http_method, "POST") || !strcmp(working_state.http_method, "PUT")) { | ||
| 501 | /* set content of payload for POST and PUT */ | ||
| 502 | if (config.http_content_type) { | ||
| 503 | snprintf(http_header, DEFAULT_BUFFER_SIZE, "Content-Type: %s", | ||
| 504 | config.http_content_type); | ||
| 505 | result.curl_state.header_list = | ||
| 506 | curl_slist_append(result.curl_state.header_list, http_header); | ||
| 507 | } | ||
| 508 | /* NULL indicates "HTTP Continue" in libcurl, provide an empty string | ||
| 509 | * in case of no POST/PUT data */ | ||
| 510 | if (!working_state.http_post_data) { | ||
| 511 | working_state.http_post_data = ""; | ||
| 512 | } | ||
| 513 | |||
| 514 | if (!strcmp(working_state.http_method, "POST")) { | ||
| 515 | /* POST method, set payload with CURLOPT_POSTFIELDS */ | ||
| 516 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, | ||
| 517 | CURLOPT_POSTFIELDS, | ||
| 518 | working_state.http_post_data), | ||
| 519 | "CURLOPT_POSTFIELDS"); | ||
| 520 | } else if (!strcmp(working_state.http_method, "PUT")) { | ||
| 521 | handle_curl_option_return_code( | ||
| 522 | curl_easy_setopt(result.curl_state.curl, CURLOPT_READFUNCTION, | ||
| 523 | (curl_read_callback)curlhelp_buffer_read_callback), | ||
| 524 | "CURLOPT_READFUNCTION"); | ||
| 525 | if (curlhelp_initreadbuffer(&result.curl_state.put_buf, working_state.http_post_data, | ||
| 526 | strlen(working_state.http_post_data)) < 0) { | ||
| 527 | die(STATE_UNKNOWN, | ||
| 528 | "HTTP CRITICAL - out of memory allocating read buffer for PUT\n"); | ||
| 529 | } | ||
| 530 | result.curl_state.put_buf_initialized = true; | ||
| 531 | handle_curl_option_return_code(curl_easy_setopt(result.curl_state.curl, | ||
| 532 | CURLOPT_READDATA, | ||
| 533 | (void *)result.curl_state.put_buf), | ||
| 534 | "CURLOPT_READDATA"); | ||
| 535 | handle_curl_option_return_code( | ||
| 536 | curl_easy_setopt(result.curl_state.curl, CURLOPT_INFILESIZE, | ||
| 537 | (curl_off_t)strlen(working_state.http_post_data)), | ||
| 538 | "CURLOPT_INFILESIZE"); | ||
| 539 | } | ||
| 540 | } | ||
| 541 | |||
| 542 | /* cookie handling */ | ||
| 543 | if (config.cookie_jar_file != NULL) { | ||
| 544 | /* enable reading cookies from a file, and if the filename is an empty string, only | ||
| 545 | * enable the curl cookie engine */ | ||
| 546 | handle_curl_option_return_code( | ||
| 547 | curl_easy_setopt(result.curl_state.curl, CURLOPT_COOKIEFILE, config.cookie_jar_file), | ||
| 548 | "CURLOPT_COOKIEFILE"); | ||
| 549 | /* now enable saving cookies to a file, but only if the filename is not an empty string, | ||
| 550 | * since writing it would fail */ | ||
| 551 | if (*config.cookie_jar_file) { | ||
| 552 | handle_curl_option_return_code( | ||
| 553 | curl_easy_setopt(result.curl_state.curl, CURLOPT_COOKIEJAR, config.cookie_jar_file), | ||
| 554 | "CURLOPT_COOKIEJAR"); | ||
| 555 | } | ||
| 556 | } | ||
| 557 | |||
| 558 | result.working_state = working_state; | ||
| 559 | |||
| 560 | return result; | ||
| 561 | } | ||
| 562 | |||
| 563 | void handle_curl_option_return_code(CURLcode res, const char *option) { | ||
| 564 | if (res != CURLE_OK) { | ||
| 565 | die(STATE_CRITICAL, _("Error while setting cURL option '%s': cURL returned %d - %s"), | ||
| 566 | option, res, curl_easy_strerror(res)); | ||
| 567 | } | ||
| 568 | } | ||
| 569 | |||
| 570 | char *get_header_value(const struct phr_header *headers, const size_t nof_headers, | ||
| 571 | const char *header) { | ||
| 572 | for (size_t i = 0; i < nof_headers; i++) { | ||
| 573 | if (headers[i].name != NULL && | ||
| 574 | strncasecmp(header, headers[i].name, max(headers[i].name_len, 4)) == 0) { | ||
| 575 | return strndup(headers[i].value, headers[i].value_len); | ||
| 576 | } | ||
| 577 | } | ||
| 578 | return NULL; | ||
| 579 | } | ||
| 580 | |||
| 581 | check_curl_working_state check_curl_working_state_init() { | ||
| 582 | check_curl_working_state result = { | ||
| 583 | .server_address = NULL, | ||
| 584 | .server_url = DEFAULT_SERVER_URL, | ||
| 585 | .host_name = NULL, | ||
| 586 | .http_method = NULL, | ||
| 587 | .http_post_data = NULL, | ||
| 588 | .virtualPort = 0, | ||
| 589 | .serverPort = HTTP_PORT, | ||
| 590 | .use_ssl = false, | ||
| 591 | .no_body = false, | ||
| 592 | }; | ||
| 593 | return result; | ||
| 594 | } | ||
| 595 | |||
| 596 | check_curl_config check_curl_config_init() { | ||
| 597 | check_curl_config tmp = { | ||
| 598 | .initial_config = check_curl_working_state_init(), | ||
| 599 | |||
| 600 | .curl_config = | ||
| 601 | { | ||
| 602 | .automatic_decompression = false, | ||
| 603 | .socket_timeout = DEFAULT_SOCKET_TIMEOUT, | ||
| 604 | .haproxy_protocol = false, | ||
| 605 | .sin_family = AF_UNSPEC, | ||
| 606 | .curl_http_version = CURL_HTTP_VERSION_NONE, | ||
| 607 | .http_opt_headers = NULL, | ||
| 608 | .http_opt_headers_count = 0, | ||
| 609 | .ssl_version = CURL_SSLVERSION_DEFAULT, | ||
| 610 | .client_cert = NULL, | ||
| 611 | .client_privkey = NULL, | ||
| 612 | .ca_cert = NULL, | ||
| 613 | .verify_peer_and_host = false, | ||
| 614 | .user_agent = {'\0'}, | ||
| 615 | .proxy_auth = "", | ||
| 616 | .user_auth = "", | ||
| 617 | .http_content_type = NULL, | ||
| 618 | .cookie_jar_file = NULL, | ||
| 619 | }, | ||
| 620 | .max_depth = DEFAULT_MAX_REDIRS, | ||
| 621 | .followmethod = FOLLOW_HTTP_CURL, | ||
| 622 | .followsticky = STICKY_NONE, | ||
| 623 | |||
| 624 | .maximum_age = -1, | ||
| 625 | .regexp = {}, | ||
| 626 | .compiled_regex = {}, | ||
| 627 | .state_regex = STATE_CRITICAL, | ||
| 628 | .invert_regex = false, | ||
| 629 | .check_cert = false, | ||
| 630 | .continue_after_check_cert = false, | ||
| 631 | .days_till_exp_warn = 0, | ||
| 632 | .days_till_exp_crit = 0, | ||
| 633 | .thlds = mp_thresholds_init(), | ||
| 634 | .page_length_limits = mp_range_init(), | ||
| 635 | .page_length_limits_is_set = false, | ||
| 636 | .server_expect = | ||
| 637 | { | ||
| 638 | .string = HTTP_EXPECT, | ||
| 639 | .is_present = false, | ||
| 640 | }, | ||
| 641 | .string_expect = "", | ||
| 642 | .header_expect = "", | ||
| 643 | .on_redirect_result_state = STATE_OK, | ||
| 644 | .on_redirect_dependent = false, | ||
| 645 | |||
| 646 | .show_extended_perfdata = false, | ||
| 647 | .show_body = false, | ||
| 648 | |||
| 649 | .output_format_is_set = false, | ||
| 650 | }; | ||
| 651 | |||
| 652 | snprintf(tmp.curl_config.user_agent, DEFAULT_BUFFER_SIZE, "%s/v%s (monitoring-plugins %s, %s)", | ||
| 653 | "check_curl", NP_VERSION, VERSION, curl_version()); | ||
| 654 | |||
| 655 | return tmp; | ||
| 656 | } | ||
| 657 | |||
| 658 | /* TODO: is there a better way in libcurl to check for the SSL library? */ | ||
| 659 | curlhelp_ssl_library curlhelp_get_ssl_library(void) { | ||
| 660 | curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN; | ||
| 661 | |||
| 662 | curl_version_info_data *version_data = curl_version_info(CURLVERSION_NOW); | ||
| 663 | if (version_data == NULL) { | ||
| 664 | return CURLHELP_SSL_LIBRARY_UNKNOWN; | ||
| 665 | } | ||
| 666 | |||
| 667 | char *ssl_version = strdup(version_data->ssl_version); | ||
| 668 | if (ssl_version == NULL) { | ||
| 669 | return CURLHELP_SSL_LIBRARY_UNKNOWN; | ||
| 670 | } | ||
| 671 | |||
| 672 | char *library = strtok(ssl_version, "/"); | ||
| 673 | if (library == NULL) { | ||
| 674 | return CURLHELP_SSL_LIBRARY_UNKNOWN; | ||
| 675 | } | ||
| 676 | |||
| 677 | if (strcmp(library, "OpenSSL") == 0) { | ||
| 678 | ssl_library = CURLHELP_SSL_LIBRARY_OPENSSL; | ||
| 679 | } else if (strcmp(library, "LibreSSL") == 0) { | ||
| 680 | ssl_library = CURLHELP_SSL_LIBRARY_LIBRESSL; | ||
| 681 | } else if (strcmp(library, "GnuTLS") == 0) { | ||
| 682 | ssl_library = CURLHELP_SSL_LIBRARY_GNUTLS; | ||
| 683 | } else if (strcmp(library, "NSS") == 0) { | ||
| 684 | ssl_library = CURLHELP_SSL_LIBRARY_NSS; | ||
| 685 | } | ||
| 686 | |||
| 687 | if (verbose >= 2) { | ||
| 688 | printf("* SSL library string is : %s %s (%d)\n", version_data->ssl_version, library, | ||
| 689 | ssl_library); | ||
| 690 | } | ||
| 691 | |||
| 692 | free(ssl_version); | ||
| 693 | |||
| 694 | return ssl_library; | ||
| 695 | } | ||
| 696 | |||
| 697 | const char *curlhelp_get_ssl_library_string(const curlhelp_ssl_library ssl_library) { | ||
| 698 | switch (ssl_library) { | ||
| 699 | case CURLHELP_SSL_LIBRARY_OPENSSL: | ||
| 700 | return "OpenSSL"; | ||
| 701 | case CURLHELP_SSL_LIBRARY_LIBRESSL: | ||
| 702 | return "LibreSSL"; | ||
| 703 | case CURLHELP_SSL_LIBRARY_GNUTLS: | ||
| 704 | return "GnuTLS"; | ||
| 705 | case CURLHELP_SSL_LIBRARY_NSS: | ||
| 706 | return "NSS"; | ||
| 707 | case CURLHELP_SSL_LIBRARY_UNKNOWN: | ||
| 708 | default: | ||
| 709 | return "unknown"; | ||
| 710 | } | ||
| 711 | } | ||
| 712 | |||
| 713 | size_t get_content_length(const curlhelp_write_curlbuf *header_buf, | ||
| 714 | const curlhelp_write_curlbuf *body_buf) { | ||
| 715 | struct phr_header headers[255]; | ||
| 716 | size_t nof_headers = 255; | ||
| 717 | size_t msglen; | ||
| 718 | curlhelp_statusline status_line; | ||
| 719 | int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major, | ||
| 720 | &status_line.http_minor, &status_line.http_code, &status_line.msg, | ||
| 721 | &msglen, headers, &nof_headers, 0); | ||
| 722 | |||
| 723 | if (res == -1) { | ||
| 724 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); | ||
| 725 | } | ||
| 726 | |||
| 727 | char *content_length_s = get_header_value(headers, nof_headers, "content-length"); | ||
| 728 | if (!content_length_s) { | ||
| 729 | return header_buf->buflen + body_buf->buflen; | ||
| 730 | } | ||
| 731 | |||
| 732 | content_length_s += strspn(content_length_s, " \t"); | ||
| 733 | size_t content_length = atoi(content_length_s); | ||
| 734 | if (content_length != body_buf->buflen) { | ||
| 735 | /* TODO: should we warn if the actual and the reported body length don't match? */ | ||
| 736 | } | ||
| 737 | |||
| 738 | if (content_length_s) { | ||
| 739 | free(content_length_s); | ||
| 740 | } | ||
| 741 | |||
| 742 | return header_buf->buflen + body_buf->buflen; | ||
| 743 | } | ||
| 744 | |||
| 745 | mp_subcheck check_document_dates(const curlhelp_write_curlbuf *header_buf, const int maximum_age) { | ||
| 746 | struct phr_header headers[255]; | ||
| 747 | size_t nof_headers = 255; | ||
| 748 | curlhelp_statusline status_line; | ||
| 749 | size_t msglen; | ||
| 750 | int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major, | ||
| 751 | &status_line.http_minor, &status_line.http_code, &status_line.msg, | ||
| 752 | &msglen, headers, &nof_headers, 0); | ||
| 753 | |||
| 754 | if (res == -1) { | ||
| 755 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); | ||
| 756 | } | ||
| 757 | |||
| 758 | char *server_date = get_header_value(headers, nof_headers, "date"); | ||
| 759 | char *document_date = get_header_value(headers, nof_headers, "last-modified"); | ||
| 760 | |||
| 761 | mp_subcheck sc_document_dates = mp_subcheck_init(); | ||
| 762 | if (!server_date || !*server_date) { | ||
| 763 | xasprintf(&sc_document_dates.output, _("Server date unknown")); | ||
| 764 | sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_UNKNOWN); | ||
| 765 | } else if (!document_date || !*document_date) { | ||
| 766 | xasprintf(&sc_document_dates.output, _("Document modification date unknown, ")); | ||
| 767 | sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL); | ||
| 768 | } else { | ||
| 769 | time_t srv_data = curl_getdate(server_date, NULL); | ||
| 770 | time_t doc_data = curl_getdate(document_date, NULL); | ||
| 771 | |||
| 772 | if (verbose >= 2) { | ||
| 773 | printf("* server date: '%s' (%d), doc_date: '%s' (%d)\n", server_date, (int)srv_data, | ||
| 774 | document_date, (int)doc_data); | ||
| 775 | } | ||
| 776 | |||
| 777 | if (srv_data <= 0) { | ||
| 778 | xasprintf(&sc_document_dates.output, _("Server date \"%100s\" unparsable"), | ||
| 779 | server_date); | ||
| 780 | sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL); | ||
| 781 | } else if (doc_data <= 0) { | ||
| 782 | |||
| 783 | xasprintf(&sc_document_dates.output, _("Document date \"%100s\" unparsable"), | ||
| 784 | document_date); | ||
| 785 | sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL); | ||
| 786 | } else if (doc_data > srv_data + 30) { | ||
| 787 | |||
| 788 | xasprintf(&sc_document_dates.output, _("Document is %d seconds in the future"), | ||
| 789 | (int)doc_data - (int)srv_data); | ||
| 790 | |||
| 791 | sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL); | ||
| 792 | } else if (doc_data < srv_data - maximum_age) { | ||
| 793 | time_t last_modified = (srv_data - doc_data); | ||
| 794 | if (last_modified > (60 * 60 * 24 * 2)) { // two days hardcoded? | ||
| 795 | xasprintf(&sc_document_dates.output, _("Last modified %.1f days ago"), | ||
| 796 | ((float)last_modified) / (60 * 60 * 24)); | ||
| 797 | sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL); | ||
| 798 | } else { | ||
| 799 | xasprintf(&sc_document_dates.output, _("Last modified %lld:%02d:%02d ago"), | ||
| 800 | (long long)last_modified / (60 * 60), (int)(last_modified / 60) % 60, | ||
| 801 | (int)last_modified % 60); | ||
| 802 | sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_CRITICAL); | ||
| 803 | } | ||
| 804 | } else { | ||
| 805 | // TODO is this the OK case? | ||
| 806 | time_t last_modified = (srv_data - doc_data); | ||
| 807 | xasprintf(&sc_document_dates.output, _("Last modified %lld:%02d:%02d ago"), | ||
| 808 | (long long)last_modified / (60 * 60), (int)(last_modified / 60) % 60, | ||
| 809 | (int)last_modified % 60); | ||
| 810 | sc_document_dates = mp_set_subcheck_state(sc_document_dates, STATE_OK); | ||
| 811 | } | ||
| 812 | } | ||
| 813 | |||
| 814 | if (server_date) { | ||
| 815 | free(server_date); | ||
| 816 | } | ||
| 817 | if (document_date) { | ||
| 818 | free(document_date); | ||
| 819 | } | ||
| 820 | |||
| 821 | return sc_document_dates; | ||
| 822 | } | ||
| 823 | |||
| 824 | void curlhelp_free_statusline(curlhelp_statusline *status_line) { free(status_line->first_line); } | ||
| 825 | |||
| 826 | int curlhelp_parse_statusline(const char *buf, curlhelp_statusline *status_line) { | ||
| 827 | /* find last start of a new header */ | ||
| 828 | const char *start = strrstr2(buf, "\r\nHTTP/"); | ||
| 829 | if (start != NULL) { | ||
| 830 | start += 2; | ||
| 831 | buf = start; | ||
| 832 | } | ||
| 833 | |||
| 834 | // Accept either LF or CRLF as end of line for the status line | ||
| 835 | // CRLF is the standard (RFC9112), but it is recommended to accept both | ||
| 836 | size_t length_of_first_line = strcspn(buf, "\r\n"); | ||
| 837 | const char *first_line_end = &buf[length_of_first_line]; | ||
| 838 | if (first_line_end == NULL) { | ||
| 839 | return -1; | ||
| 840 | } | ||
| 841 | |||
| 842 | size_t first_line_len = (size_t)(first_line_end - buf); | ||
| 843 | status_line->first_line = (char *)calloc(first_line_len + 1, sizeof(char)); | ||
| 844 | if (status_line->first_line == NULL) { | ||
| 845 | return -1; | ||
| 846 | } | ||
| 847 | |||
| 848 | memcpy(status_line->first_line, buf, first_line_len); | ||
| 849 | status_line->first_line[first_line_len] = '\0'; | ||
| 850 | char *first_line_buf = strdup(status_line->first_line); | ||
| 851 | |||
| 852 | /* protocol and version: "HTTP/x.x" SP or "HTTP/2" SP */ | ||
| 853 | char *temp_string = strtok(first_line_buf, "/"); | ||
| 854 | if (temp_string == NULL) { | ||
| 855 | if (verbose > 1) { | ||
| 856 | printf("%s: no / found\n", __func__); | ||
| 857 | } | ||
| 858 | free(first_line_buf); | ||
| 859 | return -1; | ||
| 860 | } | ||
| 861 | |||
| 862 | if (strcmp(temp_string, "HTTP") != 0) { | ||
| 863 | if (verbose > 1) { | ||
| 864 | printf("%s: string 'HTTP' not found\n", __func__); | ||
| 865 | } | ||
| 866 | free(first_line_buf); | ||
| 867 | return -1; | ||
| 868 | } | ||
| 869 | |||
| 870 | // try to find a space in the remaining string? | ||
| 871 | // the space after HTTP/1.1 probably | ||
| 872 | temp_string = strtok(NULL, " "); | ||
| 873 | if (temp_string == NULL) { | ||
| 874 | if (verbose > 1) { | ||
| 875 | printf("%s: no space after protocol definition\n", __func__); | ||
| 876 | } | ||
| 877 | free(first_line_buf); | ||
| 878 | return -1; | ||
| 879 | } | ||
| 880 | |||
| 881 | char *temp_string_2; | ||
| 882 | if (strchr(temp_string, '.') != NULL) { | ||
| 883 | /* HTTP 1.x case */ | ||
| 884 | strtok(temp_string, "."); | ||
| 885 | status_line->http_major = (int)strtol(temp_string, &temp_string_2, 10); | ||
| 886 | if (*temp_string_2 != '\0') { | ||
| 887 | free(first_line_buf); | ||
| 888 | return -1; | ||
| 889 | } | ||
| 890 | strtok(NULL, " "); | ||
| 891 | status_line->http_minor = (int)strtol(temp_string, &temp_string_2, 10); | ||
| 892 | if (*temp_string_2 != '\0') { | ||
| 893 | free(first_line_buf); | ||
| 894 | return -1; | ||
| 895 | } | ||
| 896 | temp_string += 4; /* 1.x SP */ | ||
| 897 | } else { | ||
| 898 | /* HTTP 2 case */ | ||
| 899 | status_line->http_major = (int)strtol(temp_string, &temp_string_2, 10); | ||
| 900 | status_line->http_minor = 0; | ||
| 901 | temp_string += 2; /* 2 SP */ | ||
| 902 | } | ||
| 903 | |||
| 904 | /* status code: "404" or "404.1", then SP */ | ||
| 905 | temp_string = strtok(temp_string, " "); | ||
| 906 | if (temp_string == NULL) { | ||
| 907 | free(first_line_buf); | ||
| 908 | return -1; | ||
| 909 | } | ||
| 910 | if (strchr(temp_string, '.') != NULL) { | ||
| 911 | char *ppp; | ||
| 912 | ppp = strtok(temp_string, "."); | ||
| 913 | status_line->http_code = (int)strtol(ppp, &temp_string_2, 10); | ||
| 914 | if (*temp_string_2 != '\0') { | ||
| 915 | free(first_line_buf); | ||
| 916 | return -1; | ||
| 917 | } | ||
| 918 | ppp = strtok(NULL, ""); | ||
| 919 | status_line->http_subcode = (int)strtol(ppp, &temp_string_2, 10); | ||
| 920 | if (*temp_string_2 != '\0') { | ||
| 921 | free(first_line_buf); | ||
| 922 | return -1; | ||
| 923 | } | ||
| 924 | temp_string += 6; /* 400.1 SP */ | ||
| 925 | } else { | ||
| 926 | status_line->http_code = (int)strtol(temp_string, &temp_string_2, 10); | ||
| 927 | status_line->http_subcode = -1; | ||
| 928 | if (*temp_string_2 != '\0') { | ||
| 929 | free(first_line_buf); | ||
| 930 | return -1; | ||
| 931 | } | ||
| 932 | temp_string += 4; /* 400 SP */ | ||
| 933 | } | ||
| 934 | |||
| 935 | /* Human readable message: "Not Found" CRLF */ | ||
| 936 | |||
| 937 | temp_string = strtok(temp_string, ""); | ||
| 938 | if (temp_string == NULL) { | ||
| 939 | status_line->msg = ""; | ||
| 940 | return 0; | ||
| 941 | } | ||
| 942 | status_line->msg = status_line->first_line + (temp_string - first_line_buf); | ||
| 943 | free(first_line_buf); | ||
| 944 | |||
| 945 | return 0; | ||
| 946 | } | ||
| 947 | |||
| 948 | /* TODO: where to put this, it's actually part of sstrings2 (logically)? | ||
| 949 | */ | ||
| 950 | const char *strrstr2(const char *haystack, const char *needle) { | ||
| 951 | if (haystack == NULL || needle == NULL) { | ||
| 952 | return NULL; | ||
| 953 | } | ||
| 954 | |||
| 955 | if (haystack[0] == '\0' || needle[0] == '\0') { | ||
| 956 | return NULL; | ||
| 957 | } | ||
| 958 | |||
| 959 | int counter = 0; | ||
| 960 | const char *prev_pos = NULL; | ||
| 961 | const char *pos = haystack; | ||
| 962 | size_t len = strlen(needle); | ||
| 963 | for (;;) { | ||
| 964 | pos = strstr(pos, needle); | ||
| 965 | if (pos == NULL) { | ||
| 966 | if (counter == 0) { | ||
| 967 | return NULL; | ||
| 968 | } | ||
| 969 | return prev_pos; | ||
| 970 | } | ||
| 971 | counter++; | ||
| 972 | prev_pos = pos; | ||
| 973 | pos += len; | ||
| 974 | if (*pos == '\0') { | ||
| 975 | return prev_pos; | ||
| 976 | } | ||
| 977 | } | ||
| 978 | } | ||
| 979 | |||
| 980 | void curlhelp_freereadbuffer(curlhelp_read_curlbuf *buf) { | ||
| 981 | free(buf->buf); | ||
| 982 | buf->buf = NULL; | ||
| 983 | } | ||
| 984 | |||
| 985 | void curlhelp_freewritebuffer(curlhelp_write_curlbuf *buf) { | ||
| 986 | free(buf->buf); | ||
| 987 | buf->buf = NULL; | ||
| 988 | } | ||
| 989 | |||
| 990 | int curlhelp_initreadbuffer(curlhelp_read_curlbuf **buf, const char *data, size_t datalen) { | ||
| 991 | if ((*buf = calloc(1, sizeof(curlhelp_read_curlbuf))) == NULL) { | ||
| 992 | return 1; | ||
| 993 | } | ||
| 994 | |||
| 995 | (*buf)->buflen = datalen; | ||
| 996 | (*buf)->buf = (char *)calloc((*buf)->buflen, sizeof(char)); | ||
| 997 | if ((*buf)->buf == NULL) { | ||
| 998 | return -1; | ||
| 999 | } | ||
| 1000 | memcpy((*buf)->buf, data, datalen); | ||
| 1001 | (*buf)->pos = 0; | ||
| 1002 | return 0; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | size_t curlhelp_buffer_read_callback(void *buffer, size_t size, size_t nmemb, void *stream) { | ||
| 1006 | curlhelp_read_curlbuf *buf = (curlhelp_read_curlbuf *)stream; | ||
| 1007 | |||
| 1008 | size_t minimalSize = min(nmemb * size, buf->buflen - buf->pos); | ||
| 1009 | |||
| 1010 | memcpy(buffer, buf->buf + buf->pos, minimalSize); | ||
| 1011 | buf->pos += minimalSize; | ||
| 1012 | |||
| 1013 | return minimalSize; | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | int curlhelp_initwritebuffer(curlhelp_write_curlbuf **buf) { | ||
| 1017 | if ((*buf = calloc(1, sizeof(curlhelp_write_curlbuf))) == NULL) { | ||
| 1018 | return 1; | ||
| 1019 | } | ||
| 1020 | (*buf)->bufsize = DEFAULT_BUFFER_SIZE * sizeof(char); | ||
| 1021 | (*buf)->buflen = 0; | ||
| 1022 | (*buf)->buf = (char *)calloc((*buf)->bufsize, sizeof(char)); | ||
| 1023 | if ((*buf)->buf == NULL) { | ||
| 1024 | return -1; | ||
| 1025 | } | ||
| 1026 | return 0; | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | size_t curlhelp_buffer_write_callback(void *buffer, size_t size, size_t nmemb, void *stream) { | ||
| 1030 | curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream; | ||
| 1031 | |||
| 1032 | while (buf->bufsize < buf->buflen + size * nmemb + 1) { | ||
| 1033 | buf->bufsize = buf->bufsize * 2; | ||
| 1034 | buf->buf = (char *)realloc(buf->buf, buf->bufsize); | ||
| 1035 | if (buf->buf == NULL) { | ||
| 1036 | fprintf(stderr, "malloc failed (%d) %s\n", errno, strerror(errno)); | ||
| 1037 | return 0; | ||
| 1038 | } | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | memcpy(buf->buf + buf->buflen, buffer, size * nmemb); | ||
| 1042 | buf->buflen += size * nmemb; | ||
| 1043 | buf->buf[buf->buflen] = '\0'; | ||
| 1044 | |||
| 1045 | return size * nmemb; | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | void cleanup(check_curl_global_state global_state) { | ||
| 1049 | if (global_state.status_line_initialized) { | ||
| 1050 | curlhelp_free_statusline(global_state.status_line); | ||
| 1051 | } | ||
| 1052 | global_state.status_line_initialized = false; | ||
| 1053 | |||
| 1054 | if (global_state.curl_easy_initialized) { | ||
| 1055 | curl_easy_cleanup(global_state.curl); | ||
| 1056 | } | ||
| 1057 | global_state.curl_easy_initialized = false; | ||
| 1058 | |||
| 1059 | if (global_state.curl_global_initialized) { | ||
| 1060 | curl_global_cleanup(); | ||
| 1061 | } | ||
| 1062 | global_state.curl_global_initialized = false; | ||
| 1063 | |||
| 1064 | if (global_state.body_buf_initialized) { | ||
| 1065 | curlhelp_freewritebuffer(global_state.body_buf); | ||
| 1066 | } | ||
| 1067 | global_state.body_buf_initialized = false; | ||
| 1068 | |||
| 1069 | if (global_state.header_buf_initialized) { | ||
| 1070 | curlhelp_freewritebuffer(global_state.header_buf); | ||
| 1071 | } | ||
| 1072 | global_state.header_buf_initialized = false; | ||
| 1073 | |||
| 1074 | if (global_state.put_buf_initialized) { | ||
| 1075 | curlhelp_freereadbuffer(global_state.put_buf); | ||
| 1076 | } | ||
| 1077 | global_state.put_buf_initialized = false; | ||
| 1078 | |||
| 1079 | if (global_state.header_list) { | ||
| 1080 | curl_slist_free_all(global_state.header_list); | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | if (global_state.host) { | ||
| 1084 | curl_slist_free_all(global_state.host); | ||
| 1085 | } | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | int lookup_host(const char *host, char *buf, size_t buflen, sa_family_t addr_family) { | ||
| 1089 | struct addrinfo hints = { | ||
| 1090 | .ai_family = addr_family, | ||
| 1091 | .ai_socktype = SOCK_STREAM, | ||
| 1092 | .ai_flags = AI_CANONNAME, | ||
| 1093 | }; | ||
| 1094 | |||
| 1095 | struct addrinfo *result; | ||
| 1096 | int errcode = getaddrinfo(host, NULL, &hints, &result); | ||
| 1097 | if (errcode != 0) { | ||
| 1098 | return errcode; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | strcpy(buf, ""); | ||
| 1102 | struct addrinfo *res = result; | ||
| 1103 | |||
| 1104 | size_t buflen_remaining = buflen - 1; | ||
| 1105 | size_t addrstr_len; | ||
| 1106 | char addrstr[100]; | ||
| 1107 | void *ptr = {0}; | ||
| 1108 | while (res) { | ||
| 1109 | switch (res->ai_family) { | ||
| 1110 | case AF_INET: | ||
| 1111 | ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; | ||
| 1112 | break; | ||
| 1113 | case AF_INET6: | ||
| 1114 | ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr; | ||
| 1115 | break; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | inet_ntop(res->ai_family, ptr, addrstr, 100); | ||
| 1119 | if (verbose >= 1) { | ||
| 1120 | printf("* getaddrinfo IPv%d address: %s\n", res->ai_family == PF_INET6 ? 6 : 4, | ||
| 1121 | addrstr); | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | // Append all IPs to buf as a comma-separated string | ||
| 1125 | addrstr_len = strlen(addrstr); | ||
| 1126 | if (buflen_remaining > addrstr_len + 1) { | ||
| 1127 | if (buf[0] != '\0') { | ||
| 1128 | strncat(buf, ",", buflen_remaining); | ||
| 1129 | buflen_remaining -= 1; | ||
| 1130 | } | ||
| 1131 | strncat(buf, addrstr, buflen_remaining); | ||
| 1132 | buflen_remaining -= addrstr_len; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | res = res->ai_next; | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | freeaddrinfo(result); | ||
| 1139 | |||
| 1140 | return 0; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | /* Checks if the server 'reply' is one of the expected 'statuscodes' */ | ||
| 1144 | bool expected_statuscode(const char *reply, const char *statuscodes) { | ||
| 1145 | char *expected; | ||
| 1146 | |||
| 1147 | if ((expected = strdup(statuscodes)) == NULL) { | ||
| 1148 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n")); | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | bool result = false; | ||
| 1152 | for (char *code = strtok(expected, ","); code != NULL; code = strtok(NULL, ",")) { | ||
| 1153 | if (strstr(reply, code) != NULL) { | ||
| 1154 | result = true; | ||
| 1155 | break; | ||
| 1156 | } | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | free(expected); | ||
| 1160 | return result; | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | /* returns a string "HTTP/1.x" or "HTTP/2" */ | ||
| 1164 | char *string_statuscode(int major, int minor) { | ||
| 1165 | static char buf[10]; | ||
| 1166 | |||
| 1167 | switch (major) { | ||
| 1168 | case 1: | ||
| 1169 | snprintf(buf, sizeof(buf), "HTTP/%d.%d", major, minor); | ||
| 1170 | break; | ||
| 1171 | case 2: | ||
| 1172 | case 3: | ||
| 1173 | snprintf(buf, sizeof(buf), "HTTP/%d", major); | ||
| 1174 | break; | ||
| 1175 | default: | ||
| 1176 | /* assuming here HTTP/N with N>=4 */ | ||
| 1177 | snprintf(buf, sizeof(buf), "HTTP/%d", major); | ||
| 1178 | break; | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | return buf; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | /* check whether a file exists */ | ||
| 1185 | void test_file(char *path) { | ||
| 1186 | if (access(path, R_OK) == 0) { | ||
| 1187 | return; | ||
| 1188 | } | ||
| 1189 | usage2(_("file does not exist or is not readable"), path); | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | mp_subcheck mp_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, | ||
| 1193 | int days_till_exp_crit); | ||
| 1194 | |||
| 1195 | mp_subcheck check_curl_certificate_checks(CURL *curl, X509 *cert, int warn_days_till_exp, | ||
| 1196 | int crit_days_till_exp) { | ||
| 1197 | mp_subcheck sc_cert_result = mp_subcheck_init(); | ||
| 1198 | sc_cert_result = mp_set_subcheck_default_state(sc_cert_result, STATE_OK); | ||
| 1199 | |||
| 1200 | #ifdef LIBCURL_FEATURE_SSL | ||
| 1201 | if (is_openssl_callback) { | ||
| 1202 | # ifdef USE_OPENSSL | ||
| 1203 | /* check certificate with OpenSSL functions, curl has been built against OpenSSL | ||
| 1204 | * and we actually have OpenSSL in the monitoring tools | ||
| 1205 | */ | ||
| 1206 | return mp_net_ssl_check_certificate(cert, warn_days_till_exp, crit_days_till_exp); | ||
| 1207 | # else /* USE_OPENSSL */ | ||
| 1208 | xasprintf(&result.output, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL " | ||
| 1209 | "callback used and not linked against OpenSSL\n"); | ||
| 1210 | mp_set_subcheck_state(result, STATE_CRITICAL); | ||
| 1211 | # endif /* USE_OPENSSL */ | ||
| 1212 | } else { | ||
| 1213 | struct curl_slist *slist; | ||
| 1214 | |||
| 1215 | cert_ptr_union cert_ptr = {0}; | ||
| 1216 | cert_ptr.to_info = NULL; | ||
| 1217 | CURLcode res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &cert_ptr.to_info); | ||
| 1218 | if (!res && cert_ptr.to_info) { | ||
| 1219 | # ifdef USE_OPENSSL | ||
| 1220 | /* We have no OpenSSL in libcurl, but we can use OpenSSL for X509 cert | ||
| 1221 | * parsing We only check the first certificate and assume it's the one of | ||
| 1222 | * the server | ||
| 1223 | */ | ||
| 1224 | char *raw_cert = NULL; | ||
| 1225 | bool got_first_cert = false; | ||
| 1226 | for (int i = 0; i < cert_ptr.to_certinfo->num_of_certs; i++) { | ||
| 1227 | if (got_first_cert) { | ||
| 1228 | break; | ||
| 1229 | } | ||
| 1230 | |||
| 1231 | for (slist = cert_ptr.to_certinfo->certinfo[i]; slist; slist = slist->next) { | ||
| 1232 | if (verbose >= 2) { | ||
| 1233 | printf("%d ** %s\n", i, slist->data); | ||
| 1234 | } | ||
| 1235 | if (strncmp(slist->data, "Cert:", 5) == 0) { | ||
| 1236 | raw_cert = &slist->data[5]; | ||
| 1237 | got_first_cert = true; | ||
| 1238 | break; | ||
| 1239 | } | ||
| 1240 | } | ||
| 1241 | } | ||
| 1242 | |||
| 1243 | if (!raw_cert) { | ||
| 1244 | |||
| 1245 | xasprintf(&sc_cert_result.output, | ||
| 1246 | _("Cannot retrieve certificates from CERTINFO information - " | ||
| 1247 | "certificate data was empty")); | ||
| 1248 | sc_cert_result = mp_set_subcheck_state(sc_cert_result, STATE_CRITICAL); | ||
| 1249 | return sc_cert_result; | ||
| 1250 | } | ||
| 1251 | |||
| 1252 | BIO *cert_BIO = BIO_new(BIO_s_mem()); | ||
| 1253 | BIO_write(cert_BIO, raw_cert, (int)strlen(raw_cert)); | ||
| 1254 | |||
| 1255 | cert = PEM_read_bio_X509(cert_BIO, NULL, NULL, NULL); | ||
| 1256 | if (!cert) { | ||
| 1257 | xasprintf(&sc_cert_result.output, | ||
| 1258 | _("Cannot read certificate from CERTINFO information - BIO error")); | ||
| 1259 | sc_cert_result = mp_set_subcheck_state(sc_cert_result, STATE_CRITICAL); | ||
| 1260 | return sc_cert_result; | ||
| 1261 | } | ||
| 1262 | |||
| 1263 | BIO_free(cert_BIO); | ||
| 1264 | return mp_net_ssl_check_certificate(cert, warn_days_till_exp, crit_days_till_exp); | ||
| 1265 | # else /* USE_OPENSSL */ | ||
| 1266 | /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our | ||
| 1267 | * disposal, so we use the libcurl CURLINFO data | ||
| 1268 | */ | ||
| 1269 | return net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, | ||
| 1270 | days_till_exp_crit); | ||
| 1271 | # endif /* USE_OPENSSL */ | ||
| 1272 | } else { | ||
| 1273 | xasprintf(&sc_cert_result.output, | ||
| 1274 | _("Cannot retrieve certificates - cURL returned %d - %s"), res, | ||
| 1275 | curl_easy_strerror(res)); | ||
| 1276 | mp_set_subcheck_state(sc_cert_result, STATE_CRITICAL); | ||
| 1277 | } | ||
| 1278 | } | ||
| 1279 | #endif /* LIBCURL_FEATURE_SSL */ | ||
| 1280 | |||
| 1281 | return sc_cert_result; | ||
| 1282 | } | ||
| 1283 | |||
| 1284 | char *fmt_url(check_curl_working_state workingState) { | ||
| 1285 | char *url = calloc(DEFAULT_BUFFER_SIZE, sizeof(char)); | ||
| 1286 | if (url == NULL) { | ||
| 1287 | die(STATE_UNKNOWN, "memory allocation failed"); | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | snprintf(url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", workingState.use_ssl ? "https" : "http", | ||
| 1291 | (workingState.use_ssl & (workingState.host_name != NULL)) | ||
| 1292 | ? workingState.host_name | ||
| 1293 | : workingState.server_address, | ||
| 1294 | workingState.serverPort, workingState.server_url); | ||
| 1295 | |||
| 1296 | return url; | ||
| 1297 | } | ||
diff --git a/plugins/check_curl.d/check_curl_helpers.h b/plugins/check_curl.d/check_curl_helpers.h new file mode 100644 index 00000000..e77b763b --- /dev/null +++ b/plugins/check_curl.d/check_curl_helpers.h | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | #include "./config.h" | ||
| 2 | #include <curl/curl.h> | ||
| 3 | #include "../picohttpparser/picohttpparser.h" | ||
| 4 | #include "output.h" | ||
| 5 | |||
| 6 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) | ||
| 7 | # include <openssl/opensslv.h> | ||
| 8 | #endif | ||
| 9 | |||
| 10 | enum { | ||
| 11 | MAX_IPV4_HOSTLENGTH = 255, | ||
| 12 | }; | ||
| 13 | |||
| 14 | /* for buffers for header and body */ | ||
| 15 | typedef struct { | ||
| 16 | size_t buflen; | ||
| 17 | size_t bufsize; | ||
| 18 | char *buf; | ||
| 19 | } curlhelp_write_curlbuf; | ||
| 20 | |||
| 21 | /* for buffering the data sent in PUT */ | ||
| 22 | typedef struct { | ||
| 23 | size_t buflen; | ||
| 24 | off_t pos; | ||
| 25 | char *buf; | ||
| 26 | } curlhelp_read_curlbuf; | ||
| 27 | |||
| 28 | /* for parsing the HTTP status line */ | ||
| 29 | typedef struct { | ||
| 30 | int http_major; /* major version of the protocol, always 1 (HTTP/0.9 | ||
| 31 | * never reached the big internet most likely) */ | ||
| 32 | int http_minor; /* minor version of the protocol, usually 0 or 1 */ | ||
| 33 | int http_code; /* HTTP return code as in RFC 2145 */ | ||
| 34 | int http_subcode; /* Microsoft IIS extension, HTTP subcodes, see | ||
| 35 | * http://support.microsoft.com/kb/318380/en-us */ | ||
| 36 | const char *msg; /* the human readable message */ | ||
| 37 | char *first_line; /* a copy of the first line */ | ||
| 38 | } curlhelp_statusline; | ||
| 39 | |||
| 40 | typedef struct { | ||
| 41 | bool curl_global_initialized; | ||
| 42 | bool curl_easy_initialized; | ||
| 43 | |||
| 44 | bool body_buf_initialized; | ||
| 45 | curlhelp_write_curlbuf *body_buf; | ||
| 46 | |||
| 47 | bool header_buf_initialized; | ||
| 48 | curlhelp_write_curlbuf *header_buf; | ||
| 49 | |||
| 50 | bool status_line_initialized; | ||
| 51 | curlhelp_statusline *status_line; | ||
| 52 | |||
| 53 | bool put_buf_initialized; | ||
| 54 | curlhelp_read_curlbuf *put_buf; | ||
| 55 | |||
| 56 | CURL *curl; | ||
| 57 | |||
| 58 | struct curl_slist *header_list; | ||
| 59 | struct curl_slist *host; | ||
| 60 | } check_curl_global_state; | ||
| 61 | |||
| 62 | /* to know the underlying SSL library used by libcurl */ | ||
| 63 | typedef enum curlhelp_ssl_library { | ||
| 64 | CURLHELP_SSL_LIBRARY_UNKNOWN, | ||
| 65 | CURLHELP_SSL_LIBRARY_OPENSSL, | ||
| 66 | CURLHELP_SSL_LIBRARY_LIBRESSL, | ||
| 67 | CURLHELP_SSL_LIBRARY_GNUTLS, | ||
| 68 | CURLHELP_SSL_LIBRARY_NSS | ||
| 69 | } curlhelp_ssl_library; | ||
| 70 | |||
| 71 | #define MAKE_LIBCURL_VERSION(major, minor, patch) ((major) * 0x10000 + (minor) * 0x100 + (patch)) | ||
| 72 | |||
| 73 | typedef struct { | ||
| 74 | int errorcode; | ||
| 75 | check_curl_global_state curl_state; | ||
| 76 | check_curl_working_state working_state; | ||
| 77 | } check_curl_configure_curl_wrapper; | ||
| 78 | |||
| 79 | check_curl_configure_curl_wrapper check_curl_configure_curl(check_curl_static_curl_config config, | ||
| 80 | check_curl_working_state working_state, | ||
| 81 | bool check_cert, | ||
| 82 | bool on_redirect_dependent, | ||
| 83 | int follow_method, long max_depth); | ||
| 84 | |||
| 85 | void handle_curl_option_return_code(CURLcode res, const char *option); | ||
| 86 | |||
| 87 | int curlhelp_initwritebuffer(curlhelp_write_curlbuf **buf); | ||
| 88 | size_t curlhelp_buffer_write_callback(void * /*buffer*/, size_t /*size*/, size_t /*nmemb*/, | ||
| 89 | void * /*stream*/); | ||
| 90 | void curlhelp_freewritebuffer(curlhelp_write_curlbuf * /*buf*/); | ||
| 91 | |||
| 92 | int curlhelp_initreadbuffer(curlhelp_read_curlbuf **buf, const char * /*data*/, size_t /*datalen*/); | ||
| 93 | size_t curlhelp_buffer_read_callback(void * /*buffer*/, size_t /*size*/, size_t /*nmemb*/, | ||
| 94 | void * /*stream*/); | ||
| 95 | void curlhelp_freereadbuffer(curlhelp_read_curlbuf * /*buf*/); | ||
| 96 | |||
| 97 | curlhelp_ssl_library curlhelp_get_ssl_library(void); | ||
| 98 | const char *curlhelp_get_ssl_library_string(curlhelp_ssl_library /*ssl_library*/); | ||
| 99 | |||
| 100 | typedef union { | ||
| 101 | struct curl_slist *to_info; | ||
| 102 | struct curl_certinfo *to_certinfo; | ||
| 103 | } cert_ptr_union; | ||
| 104 | int net_noopenssl_check_certificate(cert_ptr_union *, int, int); | ||
| 105 | |||
| 106 | int curlhelp_parse_statusline(const char * /*buf*/, curlhelp_statusline * /*status_line*/); | ||
| 107 | void curlhelp_free_statusline(curlhelp_statusline * /*status_line*/); | ||
| 108 | |||
| 109 | char *get_header_value(const struct phr_header *headers, size_t nof_headers, const char *header); | ||
| 110 | mp_subcheck check_document_dates(const curlhelp_write_curlbuf * /*header_buf*/, | ||
| 111 | int /*maximum_age*/); | ||
| 112 | size_t get_content_length(const curlhelp_write_curlbuf *header_buf, | ||
| 113 | const curlhelp_write_curlbuf *body_buf); | ||
| 114 | int lookup_host(const char *host, char *buf, size_t buflen, sa_family_t addr_family); | ||
| 115 | CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm); | ||
| 116 | |||
| 117 | #define INET_ADDR_MAX_SIZE INET6_ADDRSTRLEN | ||
| 118 | const char *strrstr2(const char *haystack, const char *needle); | ||
| 119 | |||
| 120 | void cleanup(check_curl_global_state global_state); | ||
| 121 | |||
| 122 | bool expected_statuscode(const char *reply, const char *statuscodes); | ||
| 123 | char *string_statuscode(int major, int minor); | ||
| 124 | |||
| 125 | void test_file(char *path); | ||
| 126 | mp_subcheck check_curl_certificate_checks(CURL *curl, X509 *cert, int warn_days_till_exp, | ||
| 127 | int crit_days_till_exp); | ||
| 128 | char *fmt_url(check_curl_working_state workingState); | ||
diff --git a/plugins/check_curl.d/config.h b/plugins/check_curl.d/config.h new file mode 100644 index 00000000..61067d46 --- /dev/null +++ b/plugins/check_curl.d/config.h | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include "../common.h" | ||
| 5 | #include "../../lib/states.h" | ||
| 6 | #include "../../lib/thresholds.h" | ||
| 7 | #include <stddef.h> | ||
| 8 | #include <string.h> | ||
| 9 | #include <sys/socket.h> | ||
| 10 | #include "curl/curl.h" | ||
| 11 | #include "perfdata.h" | ||
| 12 | #include "regex.h" | ||
| 13 | |||
| 14 | enum { | ||
| 15 | MAX_RE_SIZE = 1024, | ||
| 16 | HTTP_PORT = 80, | ||
| 17 | HTTPS_PORT = 443, | ||
| 18 | MAX_PORT = 65535, | ||
| 19 | DEFAULT_MAX_REDIRS = 15 | ||
| 20 | }; | ||
| 21 | |||
| 22 | enum { | ||
| 23 | FOLLOW_HTTP_CURL = 0, | ||
| 24 | FOLLOW_LIBCURL = 1 | ||
| 25 | }; | ||
| 26 | |||
| 27 | enum { | ||
| 28 | STICKY_NONE = 0, | ||
| 29 | STICKY_HOST = 1, | ||
| 30 | STICKY_PORT = 2 | ||
| 31 | }; | ||
| 32 | |||
| 33 | #define HTTP_EXPECT "HTTP/" | ||
| 34 | #define DEFAULT_BUFFER_SIZE 2048 | ||
| 35 | #define DEFAULT_SERVER_URL "/" | ||
| 36 | |||
| 37 | typedef struct { | ||
| 38 | char *server_address; | ||
| 39 | char *server_url; | ||
| 40 | char *host_name; | ||
| 41 | |||
| 42 | char *http_method; | ||
| 43 | |||
| 44 | char *http_post_data; | ||
| 45 | |||
| 46 | unsigned short virtualPort; | ||
| 47 | unsigned short serverPort; | ||
| 48 | |||
| 49 | bool use_ssl; | ||
| 50 | bool no_body; | ||
| 51 | } check_curl_working_state; | ||
| 52 | |||
| 53 | check_curl_working_state check_curl_working_state_init(); | ||
| 54 | |||
| 55 | typedef struct { | ||
| 56 | bool automatic_decompression; | ||
| 57 | bool haproxy_protocol; | ||
| 58 | long socket_timeout; | ||
| 59 | sa_family_t sin_family; | ||
| 60 | long curl_http_version; | ||
| 61 | char **http_opt_headers; | ||
| 62 | size_t http_opt_headers_count; | ||
| 63 | long ssl_version; | ||
| 64 | char *client_cert; | ||
| 65 | char *client_privkey; | ||
| 66 | char *ca_cert; | ||
| 67 | bool verify_peer_and_host; | ||
| 68 | char user_agent[DEFAULT_BUFFER_SIZE]; | ||
| 69 | char proxy_auth[MAX_INPUT_BUFFER]; | ||
| 70 | char user_auth[MAX_INPUT_BUFFER]; | ||
| 71 | char *http_content_type; | ||
| 72 | char *cookie_jar_file; | ||
| 73 | } check_curl_static_curl_config; | ||
| 74 | |||
| 75 | typedef struct { | ||
| 76 | check_curl_working_state initial_config; | ||
| 77 | |||
| 78 | check_curl_static_curl_config curl_config; | ||
| 79 | long max_depth; | ||
| 80 | int followmethod; | ||
| 81 | int followsticky; | ||
| 82 | |||
| 83 | int maximum_age; | ||
| 84 | |||
| 85 | // the original regex string from the command line | ||
| 86 | char regexp[MAX_RE_SIZE]; | ||
| 87 | |||
| 88 | // the compiled regex for usage later | ||
| 89 | regex_t compiled_regex; | ||
| 90 | |||
| 91 | mp_state_enum state_regex; | ||
| 92 | bool invert_regex; | ||
| 93 | bool check_cert; | ||
| 94 | bool continue_after_check_cert; | ||
| 95 | int days_till_exp_warn; | ||
| 96 | int days_till_exp_crit; | ||
| 97 | mp_thresholds thlds; | ||
| 98 | mp_range page_length_limits; | ||
| 99 | bool page_length_limits_is_set; | ||
| 100 | struct { | ||
| 101 | char string[MAX_INPUT_BUFFER]; | ||
| 102 | bool is_present; | ||
| 103 | } server_expect; | ||
| 104 | char string_expect[MAX_INPUT_BUFFER]; | ||
| 105 | char header_expect[MAX_INPUT_BUFFER]; | ||
| 106 | mp_state_enum on_redirect_result_state; | ||
| 107 | bool on_redirect_dependent; | ||
| 108 | |||
| 109 | bool show_extended_perfdata; | ||
| 110 | bool show_body; | ||
| 111 | |||
| 112 | bool output_format_is_set; | ||
| 113 | mp_output_format output_format; | ||
| 114 | } check_curl_config; | ||
| 115 | |||
| 116 | check_curl_config check_curl_config_init(); | ||
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index 9efcd1cb..81d92952 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c | |||
| @@ -34,6 +34,10 @@ const char *copyright = "2011-2024"; | |||
| 34 | const char *email = "devel@monitoring-plugins.org"; | 34 | const char *email = "devel@monitoring-plugins.org"; |
| 35 | 35 | ||
| 36 | #include "../lib/monitoringplug.h" | 36 | #include "../lib/monitoringplug.h" |
| 37 | #include "thresholds.h" | ||
| 38 | #include "perfdata.h" | ||
| 39 | #include "output.h" | ||
| 40 | #include "states.h" | ||
| 37 | #include "check_dbi.d/config.h" | 41 | #include "check_dbi.d/config.h" |
| 38 | #include "common.h" | 42 | #include "common.h" |
| 39 | #include "utils.h" | 43 | #include "utils.h" |
| @@ -63,7 +67,6 @@ typedef struct { | |||
| 63 | } check_dbi_config_wrapper; | 67 | } check_dbi_config_wrapper; |
| 64 | 68 | ||
| 65 | static check_dbi_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | 69 | static check_dbi_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 66 | static check_dbi_config_wrapper validate_arguments(check_dbi_config_wrapper /*config_wrapper*/); | ||
| 67 | void print_usage(void); | 70 | void print_usage(void); |
| 68 | static void print_help(void); | 71 | static void print_help(void); |
| 69 | 72 | ||
| @@ -71,25 +74,18 @@ static double timediff(struct timeval /*start*/, struct timeval /*end*/); | |||
| 71 | 74 | ||
| 72 | static void np_dbi_print_error(dbi_conn /*conn*/, char * /*fmt*/, ...); | 75 | static void np_dbi_print_error(dbi_conn /*conn*/, char * /*fmt*/, ...); |
| 73 | 76 | ||
| 74 | static mp_state_enum do_query(dbi_conn /*conn*/, const char ** /*res_val_str*/, double * /*res_val*/, double * /*res_time*/, mp_dbi_metric /*metric*/, | 77 | typedef struct { |
| 75 | mp_dbi_type /*type*/, char * /*np_dbi_query*/); | 78 | char *result_string; |
| 79 | double result_number; | ||
| 80 | double query_duration; | ||
| 81 | int error_code; | ||
| 82 | const char *error_string; | ||
| 83 | mp_state_enum query_processing_status; | ||
| 84 | } do_query_result; | ||
| 85 | static do_query_result do_query(dbi_conn conn, check_dbi_metric metric, check_dbi_type type, | ||
| 86 | char *query); | ||
| 76 | 87 | ||
| 77 | int main(int argc, char **argv) { | 88 | int main(int argc, char **argv) { |
| 78 | int status = STATE_UNKNOWN; | ||
| 79 | |||
| 80 | dbi_driver driver; | ||
| 81 | dbi_conn conn; | ||
| 82 | |||
| 83 | unsigned int server_version; | ||
| 84 | |||
| 85 | struct timeval start_timeval; | ||
| 86 | struct timeval end_timeval; | ||
| 87 | double conn_time = 0.0; | ||
| 88 | double query_time = 0.0; | ||
| 89 | |||
| 90 | const char *query_val_str = NULL; | ||
| 91 | double query_val = 0.0; | ||
| 92 | |||
| 93 | setlocale(LC_ALL, ""); | 89 | setlocale(LC_ALL, ""); |
| 94 | bindtextdomain(PACKAGE, LOCALEDIR); | 90 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 95 | textdomain(PACKAGE); | 91 | textdomain(PACKAGE); |
| @@ -105,6 +101,10 @@ int main(int argc, char **argv) { | |||
| 105 | 101 | ||
| 106 | const check_dbi_config config = tmp.config; | 102 | const check_dbi_config config = tmp.config; |
| 107 | 103 | ||
| 104 | if (config.output_format_is_set) { | ||
| 105 | mp_set_format(config.output_format); | ||
| 106 | } | ||
| 107 | |||
| 108 | /* Set signal handling and alarm */ | 108 | /* Set signal handling and alarm */ |
| 109 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 109 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { |
| 110 | usage4(_("Cannot catch SIGALRM")); | 110 | usage4(_("Cannot catch SIGALRM")); |
| @@ -115,63 +115,71 @@ int main(int argc, char **argv) { | |||
| 115 | printf("Initializing DBI\n"); | 115 | printf("Initializing DBI\n"); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | dbi_inst *instance_p = {0}; | 118 | dbi_inst instance_p = NULL; |
| 119 | 119 | if (dbi_initialize_r(NULL, &instance_p) < 0) { | |
| 120 | if (dbi_initialize_r(NULL, instance_p) < 0) { | 120 | printf("failed to initialize DBI; possibly you don't have any drivers installed.\n"); |
| 121 | printf("UNKNOWN - failed to initialize DBI; possibly you don't have any drivers installed.\n"); | 121 | exit(STATE_UNKNOWN); |
| 122 | return STATE_UNKNOWN; | ||
| 123 | } | 122 | } |
| 124 | 123 | ||
| 124 | // Try to prevent libdbi from printing stuff on stderr | ||
| 125 | // Who thought that would be a good idea anyway? | ||
| 126 | dbi_set_verbosity_r(0, instance_p); | ||
| 127 | |||
| 125 | if (instance_p == NULL) { | 128 | if (instance_p == NULL) { |
| 126 | printf("UNKNOWN - failed to initialize DBI.\n"); | 129 | printf("failed to initialize DBI.\n"); |
| 127 | return STATE_UNKNOWN; | 130 | exit(STATE_UNKNOWN); |
| 128 | } | 131 | } |
| 129 | 132 | ||
| 130 | if (verbose) { | 133 | if (verbose) { |
| 131 | printf("Opening DBI driver '%s'\n", config.dbi_driver); | 134 | printf("Opening DBI driver '%s'\n", config.dbi_driver); |
| 132 | } | 135 | } |
| 133 | 136 | ||
| 134 | driver = dbi_driver_open_r(config.dbi_driver, instance_p); | 137 | dbi_driver driver = dbi_driver_open_r(config.dbi_driver, instance_p); |
| 135 | if (!driver) { | 138 | if (!driver) { |
| 136 | printf("UNKNOWN - failed to open DBI driver '%s'; possibly it's not installed.\n", config.dbi_driver); | 139 | printf("failed to open DBI driver '%s'; possibly it's not installed.\n", config.dbi_driver); |
| 137 | 140 | ||
| 138 | printf("Known drivers:\n"); | 141 | printf("Known drivers:\n"); |
| 139 | for (driver = dbi_driver_list_r(NULL, instance_p); driver; driver = dbi_driver_list_r(driver, instance_p)) { | 142 | for (driver = dbi_driver_list_r(NULL, instance_p); driver; |
| 143 | driver = dbi_driver_list_r(driver, instance_p)) { | ||
| 140 | printf(" - %s\n", dbi_driver_get_name(driver)); | 144 | printf(" - %s\n", dbi_driver_get_name(driver)); |
| 141 | } | 145 | } |
| 142 | return STATE_UNKNOWN; | 146 | exit(STATE_UNKNOWN); |
| 143 | } | 147 | } |
| 144 | 148 | ||
| 145 | /* make a connection to the database */ | 149 | /* make a connection to the database */ |
| 150 | struct timeval start_timeval; | ||
| 146 | gettimeofday(&start_timeval, NULL); | 151 | gettimeofday(&start_timeval, NULL); |
| 147 | 152 | ||
| 148 | conn = dbi_conn_open(driver); | 153 | dbi_conn conn = dbi_conn_open(driver); |
| 149 | if (!conn) { | 154 | if (!conn) { |
| 150 | printf("UNKNOWN - failed top open connection object.\n"); | 155 | printf("UNKNOWN - failed top open connection object.\n"); |
| 151 | dbi_conn_close(conn); | 156 | dbi_conn_close(conn); |
| 152 | return STATE_UNKNOWN; | 157 | exit(STATE_UNKNOWN); |
| 153 | } | 158 | } |
| 154 | 159 | ||
| 155 | for (size_t i = 0; i < config.dbi_options_num; ++i) { | 160 | for (size_t i = 0; i < config.dbi_options_num; ++i) { |
| 156 | const char *opt; | 161 | const char *opt; |
| 157 | 162 | ||
| 158 | if (verbose > 1) { | 163 | if (verbose > 1) { |
| 159 | printf("Setting DBI driver option '%s' to '%s'\n", config.dbi_options[i].key, config.dbi_options[i].value); | 164 | printf("Setting DBI driver option '%s' to '%s'\n", config.dbi_options[i].key, |
| 165 | config.dbi_options[i].value); | ||
| 160 | } | 166 | } |
| 161 | 167 | ||
| 162 | if (!dbi_conn_set_option(conn, config.dbi_options[i].key, config.dbi_options[i].value)) { | 168 | if (!dbi_conn_set_option(conn, config.dbi_options[i].key, config.dbi_options[i].value)) { |
| 163 | continue; | 169 | continue; |
| 164 | } | 170 | } |
| 165 | /* else: status != 0 */ | ||
| 166 | 171 | ||
| 167 | np_dbi_print_error(conn, "UNKNOWN - failed to set option '%s' to '%s'", config.dbi_options[i].key, config.dbi_options[i].value); | 172 | // Failing to set option |
| 173 | np_dbi_print_error(conn, "failed to set option '%s' to '%s'", config.dbi_options[i].key, | ||
| 174 | config.dbi_options[i].value); | ||
| 168 | printf("Known driver options:\n"); | 175 | printf("Known driver options:\n"); |
| 169 | 176 | ||
| 170 | for (opt = dbi_conn_get_option_list(conn, NULL); opt; opt = dbi_conn_get_option_list(conn, opt)) { | 177 | for (opt = dbi_conn_get_option_list(conn, NULL); opt; |
| 178 | opt = dbi_conn_get_option_list(conn, opt)) { | ||
| 171 | printf(" - %s\n", opt); | 179 | printf(" - %s\n", opt); |
| 172 | } | 180 | } |
| 173 | dbi_conn_close(conn); | 181 | dbi_conn_close(conn); |
| 174 | return STATE_UNKNOWN; | 182 | exit(STATE_UNKNOWN); |
| 175 | } | 183 | } |
| 176 | 184 | ||
| 177 | if (config.host) { | 185 | if (config.host) { |
| @@ -199,78 +207,216 @@ int main(int argc, char **argv) { | |||
| 199 | } | 207 | } |
| 200 | 208 | ||
| 201 | if (dbi_conn_connect(conn) < 0) { | 209 | if (dbi_conn_connect(conn) < 0) { |
| 202 | np_dbi_print_error(conn, "UNKNOWN - failed to connect to database"); | 210 | np_dbi_print_error(conn, "failed to connect to database"); |
| 203 | return STATE_UNKNOWN; | 211 | exit(STATE_UNKNOWN); |
| 204 | } | 212 | } |
| 205 | 213 | ||
| 214 | struct timeval end_timeval; | ||
| 206 | gettimeofday(&end_timeval, NULL); | 215 | gettimeofday(&end_timeval, NULL); |
| 207 | conn_time = timediff(start_timeval, end_timeval); | 216 | double conn_time = timediff(start_timeval, end_timeval); |
| 208 | |||
| 209 | server_version = dbi_conn_get_engine_version(conn); | ||
| 210 | if (verbose) { | 217 | if (verbose) { |
| 211 | printf("Connected to server version %u\n", server_version); | 218 | printf("Time elapsed: %f\n", conn_time); |
| 212 | } | 219 | } |
| 213 | 220 | ||
| 214 | if (config.metric == METRIC_SERVER_VERSION) { | 221 | mp_check overall = mp_check_init(); |
| 215 | status = get_status(server_version, config.dbi_thresholds); | 222 | |
| 223 | mp_subcheck sc_connection_time = mp_subcheck_init(); | ||
| 224 | sc_connection_time = mp_set_subcheck_default_state(sc_connection_time, STATE_OK); | ||
| 225 | xasprintf(&sc_connection_time.output, "Connection time: %f", conn_time); | ||
| 226 | |||
| 227 | mp_perfdata pd_conn_duration = perfdata_init(); | ||
| 228 | pd_conn_duration.label = "conntime"; | ||
| 229 | pd_conn_duration = mp_set_pd_value(pd_conn_duration, conn_time); | ||
| 230 | |||
| 231 | if (config.metric == METRIC_CONN_TIME) { | ||
| 232 | pd_conn_duration = mp_pd_set_thresholds(pd_conn_duration, config.thresholds); | ||
| 233 | mp_state_enum status = mp_get_pd_status(pd_conn_duration); | ||
| 234 | sc_connection_time = mp_set_subcheck_state(sc_connection_time, status); | ||
| 235 | if (status != STATE_OK) { | ||
| 236 | xasprintf(&sc_connection_time.output, "%s violates thresholds", | ||
| 237 | sc_connection_time.output); | ||
| 238 | } | ||
| 216 | } | 239 | } |
| 217 | 240 | ||
| 241 | mp_add_perfdata_to_subcheck(&sc_connection_time, pd_conn_duration); | ||
| 242 | mp_add_subcheck_to_check(&overall, sc_connection_time); | ||
| 243 | |||
| 244 | unsigned int server_version = dbi_conn_get_engine_version(conn); | ||
| 218 | if (verbose) { | 245 | if (verbose) { |
| 219 | printf("Time elapsed: %f\n", conn_time); | 246 | printf("Connected to server version %u\n", server_version); |
| 220 | } | 247 | } |
| 221 | 248 | ||
| 222 | if (config.metric == METRIC_CONN_TIME) { | 249 | mp_subcheck sc_server_version = mp_subcheck_init(); |
| 223 | status = get_status(conn_time, config.dbi_thresholds); | 250 | sc_server_version = mp_set_subcheck_default_state(sc_server_version, STATE_OK); |
| 224 | } | 251 | xasprintf(&sc_server_version.output, "Connected to server version %u", server_version); |
| 252 | |||
| 253 | if (config.metric == METRIC_SERVER_VERSION) { | ||
| 254 | mp_perfdata pd_server_version = perfdata_init(); | ||
| 255 | pd_server_version = mp_set_pd_value(pd_server_version, server_version); | ||
| 256 | pd_server_version = mp_pd_set_thresholds(pd_server_version, config.thresholds); | ||
| 257 | mp_state_enum status = mp_get_pd_status(pd_server_version); | ||
| 258 | mp_add_perfdata_to_subcheck(&sc_server_version, pd_server_version); | ||
| 259 | |||
| 260 | sc_server_version = mp_set_subcheck_state(sc_server_version, status); | ||
| 261 | |||
| 262 | if (status != STATE_OK) { | ||
| 263 | xasprintf(&sc_server_version.output, "%s violates thresholds", | ||
| 264 | sc_server_version.output); | ||
| 265 | } | ||
| 266 | }; | ||
| 267 | mp_add_subcheck_to_check(&overall, sc_server_version); | ||
| 225 | 268 | ||
| 226 | /* select a database */ | 269 | /* select a database */ |
| 227 | if (config.dbi_database) { | 270 | if (config.database) { |
| 228 | if (verbose > 1) { | 271 | if (verbose > 1) { |
| 229 | printf("Selecting database '%s'\n", config.dbi_database); | 272 | printf("Selecting database '%s'\n", config.database); |
| 230 | } | 273 | } |
| 231 | 274 | ||
| 232 | if (dbi_conn_select_db(conn, config.dbi_database)) { | 275 | mp_subcheck sc_select_db = mp_subcheck_init(); |
| 233 | np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", config.dbi_database); | 276 | sc_select_db = mp_set_subcheck_default_state(sc_select_db, STATE_OK); |
| 234 | return STATE_UNKNOWN; | 277 | |
| 278 | if (dbi_conn_select_db(conn, config.database)) { | ||
| 279 | np_dbi_print_error(conn, "UNKNOWN - failed to select database '%s'", config.database); | ||
| 280 | exit(STATE_UNKNOWN); | ||
| 281 | } else { | ||
| 282 | mp_add_subcheck_to_check(&overall, sc_select_db); | ||
| 235 | } | 283 | } |
| 236 | } | 284 | } |
| 237 | 285 | ||
| 238 | if (config.dbi_query) { | 286 | // Do a query (if configured) |
| 287 | if (config.query) { | ||
| 288 | mp_subcheck sc_query = mp_subcheck_init(); | ||
| 289 | sc_query = mp_set_subcheck_default_state(sc_query, STATE_UNKNOWN); | ||
| 290 | |||
| 239 | /* execute query */ | 291 | /* execute query */ |
| 240 | status = do_query(conn, &query_val_str, &query_val, &query_time, config.metric, config.type, config.dbi_query); | 292 | do_query_result query_res = do_query(conn, config.metric, config.type, config.query); |
| 241 | if (status != STATE_OK) { | 293 | |
| 242 | /* do_query prints an error message in this case */ | 294 | if (query_res.error_code != 0) { |
| 243 | return status; | 295 | xasprintf(&sc_query.output, "Query failed: %s", query_res.error_string); |
| 244 | } | 296 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); |
| 297 | } else if (query_res.query_processing_status != STATE_OK) { | ||
| 298 | if (query_res.error_string) { | ||
| 299 | xasprintf(&sc_query.output, "Failed to process query: %s", query_res.error_string); | ||
| 300 | } else { | ||
| 301 | xasprintf(&sc_query.output, "Failed to process query"); | ||
| 302 | } | ||
| 303 | sc_query = mp_set_subcheck_state(sc_query, query_res.query_processing_status); | ||
| 304 | } else { | ||
| 305 | // query succeeded in general | ||
| 306 | xasprintf(&sc_query.output, "Query '%s' succeeded", config.query); | ||
| 307 | |||
| 308 | // that's a OK by default now | ||
| 309 | sc_query = mp_set_subcheck_default_state(sc_query, STATE_OK); | ||
| 310 | |||
| 311 | // query duration first | ||
| 312 | mp_perfdata pd_query_duration = perfdata_init(); | ||
| 313 | pd_query_duration = mp_set_pd_value(pd_query_duration, query_res.query_duration); | ||
| 314 | pd_query_duration.label = "querytime"; | ||
| 315 | if (config.metric == METRIC_QUERY_TIME) { | ||
| 316 | pd_query_duration = mp_pd_set_thresholds(pd_query_duration, config.thresholds); | ||
| 317 | } | ||
| 318 | |||
| 319 | mp_add_perfdata_to_subcheck(&sc_query, pd_query_duration); | ||
| 245 | 320 | ||
| 246 | if (config.metric == METRIC_QUERY_RESULT) { | 321 | if (config.metric == METRIC_QUERY_RESULT) { |
| 247 | if (config.expect) { | 322 | if (config.expect) { |
| 248 | if ((!query_val_str) || strcmp(query_val_str, config.expect)) { | 323 | if ((!query_res.result_string) || |
| 249 | status = STATE_CRITICAL; | 324 | strcmp(query_res.result_string, config.expect)) { |
| 325 | xasprintf(&sc_query.output, "Found string '%s' in query result", | ||
| 326 | config.expect); | ||
| 327 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | ||
| 328 | } else { | ||
| 329 | xasprintf(&sc_query.output, "Did not find string '%s' in query result", | ||
| 330 | config.expect); | ||
| 331 | sc_query = mp_set_subcheck_state(sc_query, STATE_OK); | ||
| 332 | } | ||
| 333 | } else if (config.expect_re_str) { | ||
| 334 | int comp_err; | ||
| 335 | regex_t expect_re = {}; | ||
| 336 | comp_err = regcomp(&expect_re, config.expect_re_str, config.expect_re_cflags); | ||
| 337 | if (comp_err != 0) { | ||
| 338 | // TODO error, failed to compile regex | ||
| 339 | // TODO move this to config sanitatisation | ||
| 340 | printf("Failed to compile regex from string '%s'", config.expect_re_str); | ||
| 341 | exit(STATE_UNKNOWN); | ||
| 342 | } | ||
| 343 | |||
| 344 | int err = | ||
| 345 | regexec(&expect_re, query_res.result_string, 0, NULL, /* flags = */ 0); | ||
| 346 | if (!err) { | ||
| 347 | sc_query = mp_set_subcheck_state(sc_query, STATE_OK); | ||
| 348 | xasprintf(&sc_query.output, "Found regular expression '%s' in query result", | ||
| 349 | config.expect_re_str); | ||
| 350 | } else if (err == REG_NOMATCH) { | ||
| 351 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | ||
| 352 | xasprintf(&sc_query.output, | ||
| 353 | "Did not find regular expression '%s' in query result", | ||
| 354 | config.expect_re_str); | ||
| 355 | } else { | ||
| 356 | char errmsg[1024]; | ||
| 357 | regerror(err, &expect_re, errmsg, sizeof(errmsg)); | ||
| 358 | xasprintf(&sc_query.output, | ||
| 359 | "ERROR - failed to execute regular expression: %s\n", errmsg); | ||
| 360 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | ||
| 361 | } | ||
| 250 | } else { | 362 | } else { |
| 251 | status = STATE_OK; | 363 | // no string matching |
| 364 | if (isnan(query_res.result_number)) { | ||
| 365 | // The query result is not a number, but no string checking was configured | ||
| 366 | // so we expected a number | ||
| 367 | // this is a CRITICAL | ||
| 368 | xasprintf(&sc_query.output, "Query '%s' result is not numeric", | ||
| 369 | config.query); | ||
| 370 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | ||
| 371 | |||
| 372 | } else { | ||
| 373 | |||
| 374 | mp_perfdata pd_query_val = perfdata_init(); | ||
| 375 | pd_query_val = mp_set_pd_value(pd_query_val, query_res.result_number); | ||
| 376 | pd_query_val.label = "query"; | ||
| 377 | pd_query_val = mp_pd_set_thresholds(pd_query_val, config.thresholds); | ||
| 378 | |||
| 379 | mp_add_perfdata_to_subcheck(&sc_query, pd_query_val); | ||
| 380 | mp_state_enum query_numerical_result = mp_get_pd_status(pd_query_val); | ||
| 381 | |||
| 382 | sc_query = mp_set_subcheck_state(sc_query, query_numerical_result); | ||
| 383 | // TODO set pd thresholds | ||
| 384 | // if (config.dbi_thresholds->warning) { | ||
| 385 | // pd_query_val.warn= config.dbi_thresholds->warning | ||
| 386 | // } else { | ||
| 387 | // } | ||
| 388 | |||
| 389 | if (query_numerical_result == STATE_OK) { | ||
| 390 | xasprintf(&sc_query.output, | ||
| 391 | "Query result '%f' is within given thresholds", | ||
| 392 | query_res.result_number); | ||
| 393 | } else { | ||
| 394 | xasprintf(&sc_query.output, | ||
| 395 | "Query result '%f' violates the given thresholds", | ||
| 396 | query_res.result_number); | ||
| 397 | } | ||
| 398 | } | ||
| 252 | } | 399 | } |
| 253 | } else if (config.expect_re_str) { | 400 | } else if (config.metric == METRIC_QUERY_TIME) { |
| 254 | int err; | 401 | mp_state_enum query_time_status = mp_get_pd_status(pd_query_duration); |
| 255 | 402 | mp_set_subcheck_state(sc_query, query_time_status); | |
| 256 | regex_t expect_re = {}; | 403 | |
| 257 | err = regexec(&expect_re, query_val_str, 0, NULL, /* flags = */ 0); | 404 | if (query_time_status == STATE_OK) { |
| 258 | if (!err) { | 405 | xasprintf(&sc_query.output, "Query duration '%f' is within given thresholds", |
| 259 | status = STATE_OK; | 406 | query_res.query_duration); |
| 260 | } else if (err == REG_NOMATCH) { | ||
| 261 | status = STATE_CRITICAL; | ||
| 262 | } else { | 407 | } else { |
| 263 | char errmsg[1024]; | 408 | xasprintf(&sc_query.output, "Query duration '%f' violates the given thresholds", |
| 264 | regerror(err, &expect_re, errmsg, sizeof(errmsg)); | 409 | query_res.query_duration); |
| 265 | printf("ERROR - failed to execute regular expression: %s\n", errmsg); | ||
| 266 | status = STATE_CRITICAL; | ||
| 267 | } | 410 | } |
| 268 | } else { | 411 | } else { |
| 269 | status = get_status(query_val, config.dbi_thresholds); | 412 | /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error |
| 413 | * which should have been reported and handled (abort) before | ||
| 414 | * ... unless we expected a string to be returned */ | ||
| 415 | assert((!isnan(query_res.result_number)) || (config.type == TYPE_STRING)); | ||
| 270 | } | 416 | } |
| 271 | } else if (config.metric == METRIC_QUERY_TIME) { | ||
| 272 | status = get_status(query_time, config.dbi_thresholds); | ||
| 273 | } | 417 | } |
| 418 | |||
| 419 | mp_add_subcheck_to_check(&overall, sc_query); | ||
| 274 | } | 420 | } |
| 275 | 421 | ||
| 276 | if (verbose) { | 422 | if (verbose) { |
| @@ -278,55 +424,17 @@ int main(int argc, char **argv) { | |||
| 278 | } | 424 | } |
| 279 | dbi_conn_close(conn); | 425 | dbi_conn_close(conn); |
| 280 | 426 | ||
| 281 | /* In case of METRIC_QUERY_RESULT, isnan(query_val) indicates an error | 427 | mp_exit(overall); |
| 282 | * which should have been reported and handled (abort) before | ||
| 283 | * ... unless we expected a string to be returned */ | ||
| 284 | assert((config.metric != METRIC_QUERY_RESULT) || (!isnan(query_val)) || (config.type == TYPE_STRING)); | ||
| 285 | |||
| 286 | assert((config.type != TYPE_STRING) || (config.expect || config.expect_re_str)); | ||
| 287 | |||
| 288 | printf("%s - connection time: %fs", state_text(status), conn_time); | ||
| 289 | if (config.dbi_query) { | ||
| 290 | if (config.type == TYPE_STRING) { | ||
| 291 | assert(config.expect || config.expect_re_str); | ||
| 292 | printf(", '%s' returned '%s' in %fs", config.dbi_query, query_val_str ? query_val_str : "<nothing>", query_time); | ||
| 293 | if (status != STATE_OK) { | ||
| 294 | if (config.expect) { | ||
| 295 | printf(" (expected '%s')", config.expect); | ||
| 296 | } else if (config.expect_re_str) { | ||
| 297 | printf(" (expected regex /%s/%s)", config.expect_re_str, ((config.expect_re_cflags & REG_ICASE) ? "i" : "")); | ||
| 298 | } | ||
| 299 | } | ||
| 300 | } else if (isnan(query_val)) { | ||
| 301 | printf(", '%s' query execution time: %fs", config.dbi_query, query_time); | ||
| 302 | } else { | ||
| 303 | printf(", '%s' returned %f in %fs", config.dbi_query, query_val, query_time); | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | printf(" | conntime=%fs;%s;%s;0; server_version=%u;%s;%s;0;", conn_time, | ||
| 308 | ((config.metric == METRIC_CONN_TIME) && config.warning_range) ? config.warning_range : "", | ||
| 309 | ((config.metric == METRIC_CONN_TIME) && config.critical_range) ? config.critical_range : "", server_version, | ||
| 310 | ((config.metric == METRIC_SERVER_VERSION) && config.warning_range) ? config.warning_range : "", | ||
| 311 | ((config.metric == METRIC_SERVER_VERSION) && config.critical_range) ? config.critical_range : ""); | ||
| 312 | if (config.dbi_query) { | ||
| 313 | if (!isnan(query_val)) { /* this is also true when -e is used */ | ||
| 314 | printf(" query=%f;%s;%s;;", query_val, ((config.metric == METRIC_QUERY_RESULT) && config.warning_range) ? config.warning_range : "", | ||
| 315 | ((config.metric == METRIC_QUERY_RESULT) && config.critical_range) ? config.critical_range : ""); | ||
| 316 | } | ||
| 317 | printf(" querytime=%fs;%s;%s;0;", query_time, ((config.metric == METRIC_QUERY_TIME) && config.warning_range) ? config.warning_range : "", | ||
| 318 | ((config.metric == METRIC_QUERY_TIME) && config.critical_range) ? config.critical_range : ""); | ||
| 319 | } | ||
| 320 | printf("\n"); | ||
| 321 | return status; | ||
| 322 | } | 428 | } |
| 323 | 429 | ||
| 324 | /* process command-line arguments */ | 430 | /* process command-line arguments */ |
| 325 | check_dbi_config_wrapper process_arguments(int argc, char **argv) { | 431 | check_dbi_config_wrapper process_arguments(int argc, char **argv) { |
| 432 | enum { | ||
| 433 | output_format_index = CHAR_MAX + 1, | ||
| 434 | }; | ||
| 326 | 435 | ||
| 327 | int option = 0; | 436 | int option = 0; |
| 328 | static struct option longopts[] = {STD_LONG_OPTS, | 437 | static struct option longopts[] = {STD_LONG_OPTS, |
| 329 | |||
| 330 | {"expect", required_argument, 0, 'e'}, | 438 | {"expect", required_argument, 0, 'e'}, |
| 331 | {"regex", required_argument, 0, 'r'}, | 439 | {"regex", required_argument, 0, 'r'}, |
| 332 | {"regexi", required_argument, 0, 'R'}, | 440 | {"regexi", required_argument, 0, 'R'}, |
| @@ -335,6 +443,7 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 335 | {"option", required_argument, 0, 'o'}, | 443 | {"option", required_argument, 0, 'o'}, |
| 336 | {"query", required_argument, 0, 'q'}, | 444 | {"query", required_argument, 0, 'q'}, |
| 337 | {"database", required_argument, 0, 'D'}, | 445 | {"database", required_argument, 0, 'D'}, |
| 446 | {"output-format", required_argument, 0, output_format_index}, | ||
| 338 | {0, 0, 0, 0}}; | 447 | {0, 0, 0, 0}}; |
| 339 | 448 | ||
| 340 | check_dbi_config_wrapper result = { | 449 | check_dbi_config_wrapper result = { |
| @@ -359,14 +468,22 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 359 | print_revision(progname, NP_VERSION); | 468 | print_revision(progname, NP_VERSION); |
| 360 | exit(STATE_UNKNOWN); | 469 | exit(STATE_UNKNOWN); |
| 361 | 470 | ||
| 362 | case 'c': /* critical range */ | 471 | case 'c': /* critical range */ { |
| 363 | result.config.critical_range = optarg; | 472 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 473 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 474 | die(STATE_UNKNOWN, "failed to parse critical threshold"); | ||
| 475 | } | ||
| 476 | result.config.thresholds = mp_thresholds_set_crit(result.config.thresholds, tmp.range); | ||
| 364 | result.config.type = TYPE_NUMERIC; | 477 | result.config.type = TYPE_NUMERIC; |
| 365 | break; | 478 | } break; |
| 366 | case 'w': /* warning range */ | 479 | case 'w': /* warning range */ { |
| 367 | result.config.warning_range = optarg; | 480 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 481 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 482 | die(STATE_UNKNOWN, "failed to parse warning threshold"); | ||
| 483 | } | ||
| 484 | result.config.thresholds = mp_thresholds_set_warn(result.config.thresholds, tmp.range); | ||
| 368 | result.config.type = TYPE_NUMERIC; | 485 | result.config.type = TYPE_NUMERIC; |
| 369 | break; | 486 | } break; |
| 370 | case 'e': | 487 | case 'e': |
| 371 | result.config.expect = optarg; | 488 | result.config.expect = optarg; |
| 372 | result.config.type = TYPE_STRING; | 489 | result.config.type = TYPE_STRING; |
| @@ -393,7 +510,6 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 393 | } | 510 | } |
| 394 | break; | 511 | break; |
| 395 | } | 512 | } |
| 396 | |||
| 397 | case 'm': | 513 | case 'm': |
| 398 | if (!strcasecmp(optarg, "CONN_TIME")) { | 514 | if (!strcasecmp(optarg, "CONN_TIME")) { |
| 399 | result.config.metric = METRIC_CONN_TIME; | 515 | result.config.metric = METRIC_CONN_TIME; |
| @@ -413,7 +529,6 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 413 | } else { | 529 | } else { |
| 414 | timeout_interval = atoi(optarg); | 530 | timeout_interval = atoi(optarg); |
| 415 | } | 531 | } |
| 416 | |||
| 417 | break; | 532 | break; |
| 418 | case 'H': /* host */ | 533 | case 'H': /* host */ |
| 419 | if (!is_host(optarg)) { | 534 | if (!is_host(optarg)) { |
| @@ -425,7 +540,6 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 425 | case 'v': | 540 | case 'v': |
| 426 | verbose++; | 541 | verbose++; |
| 427 | break; | 542 | break; |
| 428 | |||
| 429 | case 'd': | 543 | case 'd': |
| 430 | result.config.dbi_driver = optarg; | 544 | result.config.dbi_driver = optarg; |
| 431 | break; | 545 | break; |
| @@ -442,7 +556,8 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 442 | *value = '\0'; | 556 | *value = '\0'; |
| 443 | ++value; | 557 | ++value; |
| 444 | 558 | ||
| 445 | new = realloc(result.config.dbi_options, (result.config.dbi_options_num + 1) * sizeof(*new)); | 559 | new = realloc(result.config.dbi_options, |
| 560 | (result.config.dbi_options_num + 1) * sizeof(*new)); | ||
| 446 | if (!new) { | 561 | if (!new) { |
| 447 | printf("UNKNOWN - failed to reallocate memory\n"); | 562 | printf("UNKNOWN - failed to reallocate memory\n"); |
| 448 | exit(STATE_UNKNOWN); | 563 | exit(STATE_UNKNOWN); |
| @@ -456,52 +571,68 @@ check_dbi_config_wrapper process_arguments(int argc, char **argv) { | |||
| 456 | new->value = value; | 571 | new->value = value; |
| 457 | } break; | 572 | } break; |
| 458 | case 'q': | 573 | case 'q': |
| 459 | result.config.dbi_query = optarg; | 574 | result.config.query = optarg; |
| 460 | break; | 575 | break; |
| 461 | case 'D': | 576 | case 'D': |
| 462 | result.config.dbi_database = optarg; | 577 | result.config.database = optarg; |
| 578 | break; | ||
| 579 | case output_format_index: { | ||
| 580 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 581 | if (!parser.parsing_success) { | ||
| 582 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 583 | printf("Invalid output format: %s\n", optarg); | ||
| 584 | exit(STATE_UNKNOWN); | ||
| 585 | } | ||
| 586 | |||
| 587 | result.config.output_format_is_set = true; | ||
| 588 | result.config.output_format = parser.output_format; | ||
| 463 | break; | 589 | break; |
| 464 | } | 590 | } |
| 591 | } | ||
| 465 | } | 592 | } |
| 466 | 593 | ||
| 467 | set_thresholds(&result.config.dbi_thresholds, result.config.warning_range, result.config.critical_range); | 594 | if (!result.config.dbi_driver) { |
| 468 | |||
| 469 | return validate_arguments(result); | ||
| 470 | } | ||
| 471 | |||
| 472 | check_dbi_config_wrapper validate_arguments(check_dbi_config_wrapper config_wrapper) { | ||
| 473 | if (!config_wrapper.config.dbi_driver) { | ||
| 474 | usage("Must specify a DBI driver"); | 595 | usage("Must specify a DBI driver"); |
| 475 | } | 596 | } |
| 476 | 597 | ||
| 477 | if (((config_wrapper.config.metric == METRIC_QUERY_RESULT) || (config_wrapper.config.metric == METRIC_QUERY_TIME)) && | 598 | if (((result.config.metric == METRIC_QUERY_RESULT) || |
| 478 | (!config_wrapper.config.dbi_query)) { | 599 | (result.config.metric == METRIC_QUERY_TIME)) && |
| 600 | (!result.config.query)) { | ||
| 479 | usage("Must specify a query to execute (metric == QUERY_RESULT)"); | 601 | usage("Must specify a query to execute (metric == QUERY_RESULT)"); |
| 480 | } | 602 | } |
| 481 | 603 | ||
| 482 | if ((config_wrapper.config.metric != METRIC_CONN_TIME) && (config_wrapper.config.metric != METRIC_SERVER_VERSION) && | 604 | if ((result.config.metric != METRIC_CONN_TIME) && |
| 483 | (config_wrapper.config.metric != METRIC_QUERY_RESULT) && (config_wrapper.config.metric != METRIC_QUERY_TIME)) { | 605 | (result.config.metric != METRIC_SERVER_VERSION) && |
| 606 | (result.config.metric != METRIC_QUERY_RESULT) && | ||
| 607 | (result.config.metric != METRIC_QUERY_TIME)) { | ||
| 484 | usage("Invalid metric specified"); | 608 | usage("Invalid metric specified"); |
| 485 | } | 609 | } |
| 486 | 610 | ||
| 487 | if (config_wrapper.config.expect && (config_wrapper.config.warning_range || config_wrapper.config.critical_range || config_wrapper.config.expect_re_str)) { | 611 | if (result.config.expect && |
| 612 | (result.config.thresholds.warning_is_set || result.config.thresholds.critical_is_set || | ||
| 613 | result.config.expect_re_str)) { | ||
| 488 | usage("Do not mix -e and -w/-c/-r/-R"); | 614 | usage("Do not mix -e and -w/-c/-r/-R"); |
| 489 | } | 615 | } |
| 490 | 616 | ||
| 491 | if (config_wrapper.config.expect_re_str && (config_wrapper.config.warning_range || config_wrapper.config.critical_range || config_wrapper.config.expect)) { | 617 | if (result.config.expect_re_str && |
| 618 | (result.config.thresholds.warning_is_set || result.config.thresholds.critical_is_set || | ||
| 619 | result.config.expect)) { | ||
| 492 | usage("Do not mix -r/-R and -w/-c/-e"); | 620 | usage("Do not mix -r/-R and -w/-c/-e"); |
| 493 | } | 621 | } |
| 494 | 622 | ||
| 495 | if (config_wrapper.config.expect && (config_wrapper.config.metric != METRIC_QUERY_RESULT)) { | 623 | if (result.config.expect && (result.config.metric != METRIC_QUERY_RESULT)) { |
| 496 | usage("Option -e requires metric QUERY_RESULT"); | 624 | usage("Option -e requires metric QUERY_RESULT"); |
| 497 | } | 625 | } |
| 498 | 626 | ||
| 499 | if (config_wrapper.config.expect_re_str && (config_wrapper.config.metric != METRIC_QUERY_RESULT)) { | 627 | if (result.config.expect_re_str && (result.config.metric != METRIC_QUERY_RESULT)) { |
| 500 | usage("Options -r/-R require metric QUERY_RESULT"); | 628 | usage("Options -r/-R require metric QUERY_RESULT"); |
| 501 | } | 629 | } |
| 502 | 630 | ||
| 503 | config_wrapper.errorcode = OK; | 631 | if (result.config.type == TYPE_STRING) { |
| 504 | return config_wrapper; | 632 | assert(result.config.expect || result.config.expect_re_str); |
| 633 | } | ||
| 634 | |||
| 635 | return result; | ||
| 505 | } | 636 | } |
| 506 | 637 | ||
| 507 | void print_help(void) { | 638 | void print_help(void) { |
| @@ -557,6 +688,8 @@ void print_help(void) { | |||
| 557 | 688 | ||
| 558 | printf(UT_VERBOSE); | 689 | printf(UT_VERBOSE); |
| 559 | 690 | ||
| 691 | printf(UT_OUTPUT_FORMAT); | ||
| 692 | |||
| 560 | printf("\n"); | 693 | printf("\n"); |
| 561 | printf(" %s\n", _("A DBI driver (-d option) is required. If the specified metric operates")); | 694 | printf(" %s\n", _("A DBI driver (-d option) is required. If the specified metric operates")); |
| 562 | printf(" %s\n\n", _("on a query, one has to be specified (-q option).")); | 695 | printf(" %s\n\n", _("on a query, one has to be specified (-q option).")); |
| @@ -607,20 +740,12 @@ void print_usage(void) { | |||
| 607 | printf(" [-e <string>] [-r|-R <regex>]\n"); | 740 | printf(" [-e <string>] [-r|-R <regex>]\n"); |
| 608 | } | 741 | } |
| 609 | 742 | ||
| 610 | const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_type, mp_dbi_metric metric, mp_dbi_type type) { | 743 | const char *get_field_str(dbi_result res, check_dbi_metric metric, check_dbi_type type) { |
| 611 | const char *str; | 744 | const char *str = dbi_result_get_string_idx(res, 1); |
| 612 | |||
| 613 | if (field_type != DBI_TYPE_STRING) { | ||
| 614 | printf("CRITICAL - result value is not a string\n"); | ||
| 615 | return NULL; | ||
| 616 | } | ||
| 617 | |||
| 618 | str = dbi_result_get_string_idx(res, 1); | ||
| 619 | if ((!str) || (strcmp(str, "ERROR") == 0)) { | 745 | if ((!str) || (strcmp(str, "ERROR") == 0)) { |
| 620 | if (metric != METRIC_QUERY_RESULT) { | 746 | if (metric != METRIC_QUERY_RESULT) { |
| 621 | return NULL; | 747 | return NULL; |
| 622 | } | 748 | } |
| 623 | np_dbi_print_error(conn, "CRITICAL - failed to fetch string value"); | ||
| 624 | return NULL; | 749 | return NULL; |
| 625 | } | 750 | } |
| 626 | 751 | ||
| @@ -630,35 +755,50 @@ const char *get_field_str(dbi_conn conn, dbi_result res, unsigned short field_ty | |||
| 630 | return str; | 755 | return str; |
| 631 | } | 756 | } |
| 632 | 757 | ||
| 633 | double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type, mp_dbi_metric metric, mp_dbi_type type) { | 758 | typedef struct { |
| 634 | double val = NAN; | 759 | double value; |
| 760 | int error_code; | ||
| 761 | int dbi_error_code; // not sure if useful | ||
| 762 | } get_field_wrapper; | ||
| 763 | get_field_wrapper get_field(dbi_result res, check_dbi_metric metric, check_dbi_type type) { | ||
| 764 | |||
| 765 | unsigned short field_type = dbi_result_get_field_type_idx(res, 1); | ||
| 766 | get_field_wrapper result = { | ||
| 767 | .value = NAN, | ||
| 768 | .error_code = OK, | ||
| 769 | }; | ||
| 635 | 770 | ||
| 636 | if (*field_type == DBI_TYPE_INTEGER) { | 771 | if (field_type == DBI_TYPE_INTEGER) { |
| 637 | val = (double)dbi_result_get_longlong_idx(res, 1); | 772 | result.value = (double)dbi_result_get_longlong_idx(res, 1); |
| 638 | } else if (*field_type == DBI_TYPE_DECIMAL) { | 773 | } else if (field_type == DBI_TYPE_DECIMAL) { |
| 639 | val = dbi_result_get_double_idx(res, 1); | 774 | result.value = dbi_result_get_double_idx(res, 1); |
| 640 | } else if (*field_type == DBI_TYPE_STRING) { | 775 | } else if (field_type == DBI_TYPE_STRING) { |
| 641 | const char *val_str; | 776 | const char *val_str; |
| 642 | char *endptr = NULL; | 777 | char *endptr = NULL; |
| 643 | 778 | ||
| 644 | val_str = get_field_str(conn, res, *field_type, metric, type); | 779 | val_str = get_field_str(res, metric, type); |
| 645 | if (!val_str) { | 780 | if (!val_str) { |
| 646 | if (metric != METRIC_QUERY_RESULT) { | 781 | result.error_code = ERROR; |
| 647 | return NAN; | 782 | field_type = DBI_TYPE_ERROR; |
| 648 | } | 783 | return result; |
| 649 | *field_type = DBI_TYPE_ERROR; | ||
| 650 | return NAN; | ||
| 651 | } | 784 | } |
| 652 | 785 | ||
| 653 | val = strtod(val_str, &endptr); | 786 | result.value = strtod(val_str, &endptr); |
| 654 | if (endptr == val_str) { | 787 | if (endptr == val_str) { |
| 655 | if (metric != METRIC_QUERY_RESULT) { | 788 | if (metric != METRIC_QUERY_RESULT) { |
| 656 | return NAN; | 789 | result.error_code = ERROR; |
| 790 | return result; | ||
| 657 | } | 791 | } |
| 658 | printf("CRITICAL - result value is not a numeric: %s\n", val_str); | 792 | |
| 659 | *field_type = DBI_TYPE_ERROR; | 793 | if (verbose) { |
| 660 | return NAN; | 794 | printf("CRITICAL - result value is not a numeric: %s\n", val_str); |
| 795 | } | ||
| 796 | |||
| 797 | field_type = DBI_TYPE_ERROR; | ||
| 798 | result.error_code = ERROR; | ||
| 799 | return result; | ||
| 661 | } | 800 | } |
| 801 | |||
| 662 | if ((endptr != NULL) && (*endptr != '\0')) { | 802 | if ((endptr != NULL) && (*endptr != '\0')) { |
| 663 | if (verbose) { | 803 | if (verbose) { |
| 664 | printf("Garbage after value: %s\n", endptr); | 804 | printf("Garbage after value: %s\n", endptr); |
| @@ -666,122 +806,127 @@ double get_field(dbi_conn conn, dbi_result res, unsigned short *field_type, mp_d | |||
| 666 | } | 806 | } |
| 667 | } else { | 807 | } else { |
| 668 | if (metric != METRIC_QUERY_RESULT) { | 808 | if (metric != METRIC_QUERY_RESULT) { |
| 669 | return NAN; | 809 | result.error_code = ERROR; |
| 810 | return result; | ||
| 670 | } | 811 | } |
| 671 | printf("CRITICAL - cannot parse value of type %s (%i)\n", | 812 | // printf("CRITICAL - cannot parse value of type %s (%i)\n", |
| 672 | (*field_type == DBI_TYPE_BINARY) ? "BINARY" | 813 | // (*field_type == DBI_TYPE_BINARY) ? "BINARY" |
| 673 | : (*field_type == DBI_TYPE_DATETIME) ? "DATETIME" | 814 | // : (*field_type == DBI_TYPE_DATETIME) ? "DATETIME" |
| 674 | : "<unknown>", | 815 | // : "<unknown>", |
| 675 | *field_type); | 816 | // *field_type); |
| 676 | *field_type = DBI_TYPE_ERROR; | 817 | field_type = DBI_TYPE_ERROR; |
| 677 | return NAN; | 818 | result.error_code = ERROR; |
| 678 | } | 819 | } |
| 679 | return val; | 820 | return result; |
| 680 | } | 821 | } |
| 681 | 822 | ||
| 682 | mp_state_enum get_query_result(dbi_conn conn, dbi_result res, const char **res_val_str, double *res_val, mp_dbi_metric metric, mp_dbi_type type) { | 823 | static do_query_result do_query(dbi_conn conn, check_dbi_metric metric, check_dbi_type type, |
| 683 | unsigned short field_type; | 824 | char *query) { |
| 684 | double val = NAN; | 825 | assert(query); |
| 685 | |||
| 686 | if (dbi_result_get_numrows(res) == DBI_ROW_ERROR) { | ||
| 687 | if (metric != METRIC_QUERY_RESULT) { | ||
| 688 | return STATE_OK; | ||
| 689 | } | ||
| 690 | np_dbi_print_error(conn, "CRITICAL - failed to fetch rows"); | ||
| 691 | return STATE_CRITICAL; | ||
| 692 | } | ||
| 693 | |||
| 694 | if (dbi_result_get_numrows(res) < 1) { | ||
| 695 | if (metric != METRIC_QUERY_RESULT) { | ||
| 696 | return STATE_OK; | ||
| 697 | } | ||
| 698 | printf("WARNING - no rows returned\n"); | ||
| 699 | return STATE_WARNING; | ||
| 700 | } | ||
| 701 | 826 | ||
| 702 | if (dbi_result_get_numfields(res) == DBI_FIELD_ERROR) { | 827 | if (verbose) { |
| 703 | if (metric != METRIC_QUERY_RESULT) { | 828 | printf("Executing query '%s'\n", query); |
| 704 | return STATE_OK; | ||
| 705 | } | ||
| 706 | np_dbi_print_error(conn, "CRITICAL - failed to fetch fields"); | ||
| 707 | return STATE_CRITICAL; | ||
| 708 | } | ||
| 709 | |||
| 710 | if (dbi_result_get_numfields(res) < 1) { | ||
| 711 | if (metric != METRIC_QUERY_RESULT) { | ||
| 712 | return STATE_OK; | ||
| 713 | } | ||
| 714 | printf("WARNING - no fields returned\n"); | ||
| 715 | return STATE_WARNING; | ||
| 716 | } | ||
| 717 | |||
| 718 | if (dbi_result_first_row(res) != 1) { | ||
| 719 | if (metric != METRIC_QUERY_RESULT) { | ||
| 720 | return STATE_OK; | ||
| 721 | } | ||
| 722 | np_dbi_print_error(conn, "CRITICAL - failed to fetch first row"); | ||
| 723 | return STATE_CRITICAL; | ||
| 724 | } | 829 | } |
| 725 | 830 | ||
| 726 | field_type = dbi_result_get_field_type_idx(res, 1); | 831 | do_query_result result = { |
| 727 | if (field_type != DBI_TYPE_ERROR) { | 832 | .query_duration = 0, |
| 728 | if (type == TYPE_STRING) { | 833 | .result_string = NULL, |
| 729 | /* the value will be freed in dbi_result_free */ | 834 | .result_number = 0, |
| 730 | *res_val_str = strdup(get_field_str(conn, res, field_type, metric, type)); | 835 | .error_code = 0, |
| 731 | } else { | 836 | .query_processing_status = STATE_UNKNOWN, |
| 732 | val = get_field(conn, res, &field_type, metric, type); | 837 | }; |
| 733 | } | ||
| 734 | } | ||
| 735 | 838 | ||
| 736 | *res_val = val; | 839 | struct timeval timeval_start; |
| 840 | gettimeofday(&timeval_start, NULL); | ||
| 737 | 841 | ||
| 738 | if (field_type == DBI_TYPE_ERROR) { | 842 | dbi_result res = dbi_conn_query(conn, query); |
| 739 | if (metric != METRIC_QUERY_RESULT) { | 843 | if (!res) { |
| 740 | return STATE_OK; | 844 | dbi_conn_error(conn, &result.error_string); |
| 741 | } | 845 | result.error_code = 1; |
| 742 | np_dbi_print_error(conn, "CRITICAL - failed to fetch data"); | 846 | return result; |
| 743 | return STATE_CRITICAL; | ||
| 744 | } | 847 | } |
| 745 | 848 | ||
| 746 | dbi_result_free(res); | ||
| 747 | return STATE_OK; | ||
| 748 | } | ||
| 749 | |||
| 750 | mp_state_enum do_query(dbi_conn conn, const char **res_val_str, double *res_val, double *res_time, mp_dbi_metric metric, mp_dbi_type type, | ||
| 751 | char *np_dbi_query) { | ||
| 752 | dbi_result res; | ||
| 753 | |||
| 754 | struct timeval timeval_start; | ||
| 755 | struct timeval timeval_end; | 849 | struct timeval timeval_end; |
| 756 | mp_state_enum status = STATE_OK; | 850 | gettimeofday(&timeval_end, NULL); |
| 757 | 851 | result.query_duration = timediff(timeval_start, timeval_end); | |
| 758 | assert(np_dbi_query); | ||
| 759 | 852 | ||
| 760 | if (verbose) { | 853 | if (verbose) { |
| 761 | printf("Executing query '%s'\n", np_dbi_query); | 854 | printf("Query duration: %f\n", result.query_duration); |
| 762 | } | 855 | } |
| 763 | 856 | ||
| 764 | gettimeofday(&timeval_start, NULL); | 857 | // Default state is OK, all error will be set explicitly |
| 858 | mp_state_enum query_processing_state = STATE_OK; | ||
| 859 | { | ||
| 765 | 860 | ||
| 766 | res = dbi_conn_query(conn, np_dbi_query); | 861 | if (dbi_result_get_numrows(res) == DBI_ROW_ERROR) { |
| 767 | if (!res) { | 862 | if (metric != METRIC_QUERY_RESULT) { |
| 768 | np_dbi_print_error(conn, "CRITICAL - failed to execute query '%s'", np_dbi_query); | 863 | query_processing_state = STATE_OK; |
| 769 | return STATE_CRITICAL; | 864 | } else { |
| 865 | dbi_conn_error(conn, &result.error_string); | ||
| 866 | query_processing_state = STATE_CRITICAL; | ||
| 867 | } | ||
| 868 | } else if (dbi_result_get_numrows(res) < 1) { | ||
| 869 | if (metric != METRIC_QUERY_RESULT) { | ||
| 870 | query_processing_state = STATE_OK; | ||
| 871 | } else { | ||
| 872 | result.error_string = "no rows returned"; | ||
| 873 | // printf("WARNING - no rows returned\n"); | ||
| 874 | query_processing_state = STATE_WARNING; | ||
| 875 | } | ||
| 876 | } else if (dbi_result_get_numfields(res) == DBI_FIELD_ERROR) { | ||
| 877 | if (metric != METRIC_QUERY_RESULT) { | ||
| 878 | query_processing_state = STATE_OK; | ||
| 879 | } else { | ||
| 880 | dbi_conn_error(conn, &result.error_string); | ||
| 881 | // np_dbi_print_error(conn, "CRITICAL - failed to fetch fields"); | ||
| 882 | query_processing_state = STATE_CRITICAL; | ||
| 883 | } | ||
| 884 | } else if (dbi_result_get_numfields(res) < 1) { | ||
| 885 | if (metric != METRIC_QUERY_RESULT) { | ||
| 886 | query_processing_state = STATE_OK; | ||
| 887 | } else { | ||
| 888 | result.error_string = "no fields returned"; | ||
| 889 | // printf("WARNING - no fields returned\n"); | ||
| 890 | query_processing_state = STATE_WARNING; | ||
| 891 | } | ||
| 892 | } else if (dbi_result_first_row(res) != 1) { | ||
| 893 | if (metric != METRIC_QUERY_RESULT) { | ||
| 894 | query_processing_state = STATE_OK; | ||
| 895 | } else { | ||
| 896 | dbi_conn_error(conn, &result.error_string); | ||
| 897 | // np_dbi_print_error(conn, "CRITICAL - failed to fetch first row"); | ||
| 898 | query_processing_state = STATE_CRITICAL; | ||
| 899 | } | ||
| 900 | } else { | ||
| 901 | unsigned short field_type = dbi_result_get_field_type_idx(res, 1); | ||
| 902 | if (field_type != DBI_TYPE_ERROR) { | ||
| 903 | if (type == TYPE_STRING) { | ||
| 904 | result.result_string = strdup(get_field_str(res, metric, type)); | ||
| 905 | } else { | ||
| 906 | get_field_wrapper gfw = get_field(res, metric, type); | ||
| 907 | result.result_number = gfw.value; | ||
| 908 | } | ||
| 909 | } else { | ||
| 910 | // Error when retrieving the field, that is OK if the Query result is not of | ||
| 911 | // interest | ||
| 912 | if (metric != METRIC_QUERY_RESULT) { | ||
| 913 | query_processing_state = STATE_OK; | ||
| 914 | } else { | ||
| 915 | dbi_conn_error(conn, &result.error_string); | ||
| 916 | // np_dbi_print_error(conn, "CRITICAL - failed to fetch data"); | ||
| 917 | query_processing_state = STATE_CRITICAL; | ||
| 918 | } | ||
| 919 | } | ||
| 920 | } | ||
| 770 | } | 921 | } |
| 922 | dbi_result_free(res); | ||
| 771 | 923 | ||
| 772 | status = get_query_result(conn, res, res_val_str, res_val, metric, type); | 924 | result.query_processing_status = query_processing_state; |
| 773 | |||
| 774 | gettimeofday(&timeval_end, NULL); | ||
| 775 | *res_time = timediff(timeval_start, timeval_end); | ||
| 776 | |||
| 777 | if (verbose) { | ||
| 778 | printf("Time elapsed: %f\n", *res_time); | ||
| 779 | } | ||
| 780 | 925 | ||
| 781 | return status; | 926 | return result; |
| 782 | } | 927 | } |
| 783 | 928 | ||
| 784 | double timediff(struct timeval start, struct timeval end) { | 929 | static double timediff(struct timeval start, struct timeval end) { |
| 785 | double diff; | 930 | double diff; |
| 786 | 931 | ||
| 787 | while (start.tv_usec > end.tv_usec) { | 932 | while (start.tv_usec > end.tv_usec) { |
| @@ -792,7 +937,7 @@ double timediff(struct timeval start, struct timeval end) { | |||
| 792 | return diff; | 937 | return diff; |
| 793 | } | 938 | } |
| 794 | 939 | ||
| 795 | void np_dbi_print_error(dbi_conn conn, char *fmt, ...) { | 940 | static void np_dbi_print_error(dbi_conn conn, char *fmt, ...) { |
| 796 | const char *errmsg = NULL; | 941 | const char *errmsg = NULL; |
| 797 | va_list ap; | 942 | va_list ap; |
| 798 | 943 | ||
diff --git a/plugins/check_dbi.d/config.h b/plugins/check_dbi.d/config.h index f6f0d7b3..25d74a12 100644 --- a/plugins/check_dbi.d/config.h +++ b/plugins/check_dbi.d/config.h | |||
| @@ -3,18 +3,19 @@ | |||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include <stddef.h> | 4 | #include <stddef.h> |
| 5 | #include "../../lib/monitoringplug.h" | 5 | #include "../../lib/monitoringplug.h" |
| 6 | #include "thresholds.h" | ||
| 6 | 7 | ||
| 7 | typedef enum { | 8 | typedef enum { |
| 8 | METRIC_CONN_TIME, | 9 | METRIC_CONN_TIME, |
| 9 | METRIC_SERVER_VERSION, | 10 | METRIC_SERVER_VERSION, |
| 10 | METRIC_QUERY_RESULT, | 11 | METRIC_QUERY_RESULT, |
| 11 | METRIC_QUERY_TIME, | 12 | METRIC_QUERY_TIME, |
| 12 | } mp_dbi_metric; | 13 | } check_dbi_metric; |
| 13 | 14 | ||
| 14 | typedef enum { | 15 | typedef enum { |
| 15 | TYPE_NUMERIC, | 16 | TYPE_NUMERIC, |
| 16 | TYPE_STRING, | 17 | TYPE_STRING, |
| 17 | } mp_dbi_type; | 18 | } check_dbi_type; |
| 18 | 19 | ||
| 19 | typedef struct { | 20 | typedef struct { |
| 20 | char *key; | 21 | char *key; |
| @@ -24,20 +25,22 @@ typedef struct { | |||
| 24 | typedef struct { | 25 | typedef struct { |
| 25 | char *dbi_driver; | 26 | char *dbi_driver; |
| 26 | char *host; | 27 | char *host; |
| 28 | |||
| 27 | driver_option_t *dbi_options; | 29 | driver_option_t *dbi_options; |
| 28 | size_t dbi_options_num; | 30 | size_t dbi_options_num; |
| 29 | char *dbi_database; | 31 | |
| 30 | char *dbi_query; | 32 | char *database; |
| 33 | char *query; | ||
| 31 | 34 | ||
| 32 | char *expect; | 35 | char *expect; |
| 33 | char *expect_re_str; | 36 | char *expect_re_str; |
| 34 | int expect_re_cflags; | 37 | int expect_re_cflags; |
| 35 | mp_dbi_metric metric; | 38 | check_dbi_metric metric; |
| 36 | mp_dbi_type type; | 39 | check_dbi_type type; |
| 37 | char *warning_range; | 40 | mp_thresholds thresholds; |
| 38 | char *critical_range; | ||
| 39 | thresholds *dbi_thresholds; | ||
| 40 | 41 | ||
| 42 | bool output_format_is_set; | ||
| 43 | mp_output_format output_format; | ||
| 41 | } check_dbi_config; | 44 | } check_dbi_config; |
| 42 | 45 | ||
| 43 | check_dbi_config check_dbi_config_init() { | 46 | check_dbi_config check_dbi_config_init() { |
| @@ -46,8 +49,8 @@ check_dbi_config check_dbi_config_init() { | |||
| 46 | .host = NULL, | 49 | .host = NULL, |
| 47 | .dbi_options = NULL, | 50 | .dbi_options = NULL, |
| 48 | .dbi_options_num = 0, | 51 | .dbi_options_num = 0, |
| 49 | .dbi_database = NULL, | 52 | .database = NULL, |
| 50 | .dbi_query = NULL, | 53 | .query = NULL, |
| 51 | 54 | ||
| 52 | .expect = NULL, | 55 | .expect = NULL, |
| 53 | .expect_re_str = NULL, | 56 | .expect_re_str = NULL, |
| @@ -55,9 +58,9 @@ check_dbi_config check_dbi_config_init() { | |||
| 55 | .metric = METRIC_QUERY_RESULT, | 58 | .metric = METRIC_QUERY_RESULT, |
| 56 | .type = TYPE_NUMERIC, | 59 | .type = TYPE_NUMERIC, |
| 57 | 60 | ||
| 58 | .warning_range = NULL, | 61 | .thresholds = mp_thresholds_init(), |
| 59 | .critical_range = NULL, | 62 | |
| 60 | .dbi_thresholds = NULL, | 63 | .output_format_is_set = false, |
| 61 | }; | 64 | }; |
| 62 | return tmp; | 65 | return tmp; |
| 63 | } | 66 | } |
diff --git a/plugins/check_dig.c b/plugins/check_dig.c index d0903be2..9ea19e6a 100644 --- a/plugins/check_dig.c +++ b/plugins/check_dig.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * Monitoring check_dig plugin | 3 | * Monitoring check_dig plugin |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 2002-2024 Monitoring Plugins Development Team | 6 | * Copyright (c) 2002-2025 Monitoring Plugins Development Team |
| 7 | * | 7 | * |
| 8 | * Description: | 8 | * Description: |
| 9 | * | 9 | * |
| @@ -33,9 +33,10 @@ | |||
| 33 | * because on some architectures those strings are in non-writable memory */ | 33 | * because on some architectures those strings are in non-writable memory */ |
| 34 | 34 | ||
| 35 | const char *progname = "check_dig"; | 35 | const char *progname = "check_dig"; |
| 36 | const char *copyright = "2002-2024"; | 36 | const char *copyright = "2002-2025"; |
| 37 | const char *email = "devel@monitoring-plugins.org"; | 37 | const char *email = "devel@monitoring-plugins.org"; |
| 38 | 38 | ||
| 39 | #include <ctype.h> | ||
| 39 | #include "common.h" | 40 | #include "common.h" |
| 40 | #include "netutils.h" | 41 | #include "netutils.h" |
| 41 | #include "utils.h" | 42 | #include "utils.h" |
| @@ -56,6 +57,12 @@ void print_usage(void); | |||
| 56 | 57 | ||
| 57 | static int verbose = 0; | 58 | static int verbose = 0; |
| 58 | 59 | ||
| 60 | /* helpers for flag parsing */ | ||
| 61 | static flag_list parse_flags_line(const char *line); | ||
| 62 | static flag_list split_csv_trim(const char *csv); | ||
| 63 | static bool flag_list_contains(const flag_list *list, const char *needle); | ||
| 64 | static void free_flag_list(flag_list *list); | ||
| 65 | |||
| 59 | int main(int argc, char **argv) { | 66 | int main(int argc, char **argv) { |
| 60 | setlocale(LC_ALL, ""); | 67 | setlocale(LC_ALL, ""); |
| 61 | bindtextdomain(PACKAGE, LOCALEDIR); | 68 | bindtextdomain(PACKAGE, LOCALEDIR); |
| @@ -81,8 +88,9 @@ int main(int argc, char **argv) { | |||
| 81 | 88 | ||
| 82 | char *command_line; | 89 | char *command_line; |
| 83 | /* get the command to run */ | 90 | /* get the command to run */ |
| 84 | xasprintf(&command_line, "%s %s %s -p %d @%s %s %s +retry=%d +time=%d", PATH_TO_DIG, config.dig_args, config.query_transport, | 91 | xasprintf(&command_line, "%s %s %s -p %d @%s %s %s +retry=%d +time=%d", PATH_TO_DIG, |
| 85 | config.server_port, config.dns_server, config.query_address, config.record_type, config.number_tries, timeout_interval_dig); | 92 | config.dig_args, config.query_transport, config.server_port, config.dns_server, |
| 93 | config.query_address, config.record_type, config.number_tries, timeout_interval_dig); | ||
| 86 | 94 | ||
| 87 | alarm(timeout_interval); | 95 | alarm(timeout_interval); |
| 88 | struct timeval start_time; | 96 | struct timeval start_time; |
| @@ -100,13 +108,35 @@ int main(int argc, char **argv) { | |||
| 100 | output chld_out; | 108 | output chld_out; |
| 101 | output chld_err; | 109 | output chld_err; |
| 102 | char *msg = NULL; | 110 | char *msg = NULL; |
| 111 | flag_list dig_flags = {.items = NULL, .count = 0}; | ||
| 103 | mp_state_enum result = STATE_UNKNOWN; | 112 | mp_state_enum result = STATE_UNKNOWN; |
| 113 | |||
| 104 | /* run the command */ | 114 | /* run the command */ |
| 105 | if (np_runcmd(command_line, &chld_out, &chld_err, 0) != 0) { | 115 | if (np_runcmd(command_line, &chld_out, &chld_err, 0) != 0) { |
| 106 | result = STATE_WARNING; | 116 | result = STATE_WARNING; |
| 107 | msg = (char *)_("dig returned an error status"); | 117 | msg = (char *)_("dig returned an error status"); |
| 108 | } | 118 | } |
| 109 | 119 | ||
| 120 | /* extract ';; flags: ...' from stdout (first occurrence) */ | ||
| 121 | for (size_t i = 0; i < chld_out.lines; i++) { | ||
| 122 | if (strstr(chld_out.line[i], "flags:")) { | ||
| 123 | if (verbose) { | ||
| 124 | printf("Raw flags line: %s\n", chld_out.line[i]); | ||
| 125 | } | ||
| 126 | |||
| 127 | dig_flags = parse_flags_line(chld_out.line[i]); | ||
| 128 | |||
| 129 | if (verbose && dig_flags.count > 0) { | ||
| 130 | printf(_("Parsed flags:")); | ||
| 131 | for (size_t k = 0; k < dig_flags.count; k++) { | ||
| 132 | printf(" %s", dig_flags.items[k]); | ||
| 133 | } | ||
| 134 | printf("\n"); | ||
| 135 | } | ||
| 136 | break; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 110 | for (size_t i = 0; i < chld_out.lines; i++) { | 140 | for (size_t i = 0; i < chld_out.lines; i++) { |
| 111 | /* the server is responding, we just got the host name... */ | 141 | /* the server is responding, we just got the host name... */ |
| 112 | if (strstr(chld_out.line[i], ";; ANSWER SECTION:")) { | 142 | if (strstr(chld_out.line[i], ";; ANSWER SECTION:")) { |
| @@ -118,8 +148,9 @@ int main(int argc, char **argv) { | |||
| 118 | printf("%s\n", chld_out.line[i]); | 148 | printf("%s\n", chld_out.line[i]); |
| 119 | } | 149 | } |
| 120 | 150 | ||
| 121 | if (strcasestr(chld_out.line[i], (config.expected_address == NULL ? config.query_address : config.expected_address)) != | 151 | if (strcasestr(chld_out.line[i], (config.expected_address == NULL |
| 122 | NULL) { | 152 | ? config.query_address |
| 153 | : config.expected_address)) != NULL) { | ||
| 123 | msg = chld_out.line[i]; | 154 | msg = chld_out.line[i]; |
| 124 | result = STATE_OK; | 155 | result = STATE_OK; |
| 125 | 156 | ||
| @@ -172,10 +203,49 @@ int main(int argc, char **argv) { | |||
| 172 | result = STATE_WARNING; | 203 | result = STATE_WARNING; |
| 173 | } | 204 | } |
| 174 | 205 | ||
| 206 | /* Optional: evaluate dig flags only if -E/-X were provided */ | ||
| 207 | if ((config.require_flags.count > 0) || (config.forbid_flags.count > 0)) { | ||
| 208 | if (dig_flags.count > 0) { | ||
| 209 | for (size_t r = 0; r < config.require_flags.count; r++) { | ||
| 210 | if (!flag_list_contains(&dig_flags, config.require_flags.items[r])) { | ||
| 211 | result = STATE_CRITICAL; | ||
| 212 | if (!msg) { | ||
| 213 | xasprintf(&msg, _("Missing required DNS flag: %s"), | ||
| 214 | config.require_flags.items[r]); | ||
| 215 | } else { | ||
| 216 | char *newmsg = NULL; | ||
| 217 | xasprintf(&newmsg, _("%s; missing required DNS flag: %s"), msg, | ||
| 218 | config.require_flags.items[r]); | ||
| 219 | msg = newmsg; | ||
| 220 | } | ||
| 221 | } | ||
| 222 | } | ||
| 223 | |||
| 224 | for (size_t r = 0; r < config.forbid_flags.count; r++) { | ||
| 225 | if (flag_list_contains(&dig_flags, config.forbid_flags.items[r])) { | ||
| 226 | result = STATE_CRITICAL; | ||
| 227 | if (!msg) { | ||
| 228 | xasprintf(&msg, _("Forbidden DNS flag present: %s"), | ||
| 229 | config.forbid_flags.items[r]); | ||
| 230 | } else { | ||
| 231 | char *newmsg = NULL; | ||
| 232 | xasprintf(&newmsg, _("%s; forbidden DNS flag present: %s"), msg, | ||
| 233 | config.forbid_flags.items[r]); | ||
| 234 | msg = newmsg; | ||
| 235 | } | ||
| 236 | } | ||
| 237 | } | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | /* cleanup flags buffer */ | ||
| 242 | free_flag_list(&dig_flags); | ||
| 243 | |||
| 175 | printf("DNS %s - %.3f seconds response time (%s)|%s\n", state_text(result), elapsed_time, | 244 | printf("DNS %s - %.3f seconds response time (%s)|%s\n", state_text(result), elapsed_time, |
| 176 | msg ? msg : _("Probably a non-existent host/domain"), | 245 | msg ? msg : _("Probably a non-existent host/domain"), |
| 177 | fperfdata("time", elapsed_time, "s", (config.warning_interval > UNDEFINED), config.warning_interval, | 246 | fperfdata("time", elapsed_time, "s", (config.warning_interval > UNDEFINED), |
| 178 | (config.critical_interval > UNDEFINED), config.critical_interval, true, 0, false, 0)); | 247 | config.warning_interval, (config.critical_interval > UNDEFINED), |
| 248 | config.critical_interval, true, 0, false, 0)); | ||
| 179 | exit(result); | 249 | exit(result); |
| 180 | } | 250 | } |
| 181 | 251 | ||
| @@ -187,6 +257,8 @@ check_dig_config_wrapper process_arguments(int argc, char **argv) { | |||
| 187 | {"critical", required_argument, 0, 'c'}, | 257 | {"critical", required_argument, 0, 'c'}, |
| 188 | {"timeout", required_argument, 0, 't'}, | 258 | {"timeout", required_argument, 0, 't'}, |
| 189 | {"dig-arguments", required_argument, 0, 'A'}, | 259 | {"dig-arguments", required_argument, 0, 'A'}, |
| 260 | {"require-flags", required_argument, 0, 'E'}, | ||
| 261 | {"forbid-flags", required_argument, 0, 'X'}, | ||
| 190 | {"verbose", no_argument, 0, 'v'}, | 262 | {"verbose", no_argument, 0, 'v'}, |
| 191 | {"version", no_argument, 0, 'V'}, | 263 | {"version", no_argument, 0, 'V'}, |
| 192 | {"help", no_argument, 0, 'h'}, | 264 | {"help", no_argument, 0, 'h'}, |
| @@ -209,7 +281,8 @@ check_dig_config_wrapper process_arguments(int argc, char **argv) { | |||
| 209 | 281 | ||
| 210 | int option = 0; | 282 | int option = 0; |
| 211 | while (true) { | 283 | while (true) { |
| 212 | int option_index = getopt_long(argc, argv, "hVvt:l:H:w:c:T:p:a:A:46", longopts, &option); | 284 | int option_index = |
| 285 | getopt_long(argc, argv, "hVvt:l:H:w:c:T:p:a:A:E:X:46", longopts, &option); | ||
| 213 | 286 | ||
| 214 | if (option_index == -1 || option_index == EOF) { | 287 | if (option_index == -1 || option_index == EOF) { |
| 215 | break; | 288 | break; |
| @@ -260,6 +333,12 @@ check_dig_config_wrapper process_arguments(int argc, char **argv) { | |||
| 260 | case 'A': /* dig arguments */ | 333 | case 'A': /* dig arguments */ |
| 261 | result.config.dig_args = strdup(optarg); | 334 | result.config.dig_args = strdup(optarg); |
| 262 | break; | 335 | break; |
| 336 | case 'E': /* require flags */ | ||
| 337 | result.config.require_flags = split_csv_trim(optarg); | ||
| 338 | break; | ||
| 339 | case 'X': /* forbid flags */ | ||
| 340 | result.config.forbid_flags = split_csv_trim(optarg); | ||
| 341 | break; | ||
| 263 | case 'v': /* verbose */ | 342 | case 'v': /* verbose */ |
| 264 | verbose++; | 343 | verbose++; |
| 265 | break; | 344 | break; |
| @@ -335,10 +414,15 @@ void print_help(void) { | |||
| 335 | printf(" %s\n", "-T, --record_type=STRING"); | 414 | printf(" %s\n", "-T, --record_type=STRING"); |
| 336 | printf(" %s\n", _("Record type to lookup (default: A)")); | 415 | printf(" %s\n", _("Record type to lookup (default: A)")); |
| 337 | printf(" %s\n", "-a, --expected_address=STRING"); | 416 | printf(" %s\n", "-a, --expected_address=STRING"); |
| 338 | printf(" %s\n", _("An address expected to be in the answer section. If not set, uses whatever")); | 417 | printf(" %s\n", |
| 418 | _("An address expected to be in the answer section. If not set, uses whatever")); | ||
| 339 | printf(" %s\n", _("was in -l")); | 419 | printf(" %s\n", _("was in -l")); |
| 340 | printf(" %s\n", "-A, --dig-arguments=STRING"); | 420 | printf(" %s\n", "-A, --dig-arguments=STRING"); |
| 341 | printf(" %s\n", _("Pass STRING as argument(s) to dig")); | 421 | printf(" %s\n", _("Pass STRING as argument(s) to dig")); |
| 422 | printf(" %s\n", "-E, --require-flags=LIST"); | ||
| 423 | printf(" %s\n", _("Comma-separated dig flags that must be present (e.g. 'aa,qr')")); | ||
| 424 | printf(" %s\n", "-X, --forbid-flags=LIST"); | ||
| 425 | printf(" %s\n", _("Comma-separated dig flags that must NOT be present")); | ||
| 342 | printf(UT_WARN_CRIT); | 426 | printf(UT_WARN_CRIT); |
| 343 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 427 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 344 | printf(UT_VERBOSE); | 428 | printf(UT_VERBOSE); |
| @@ -355,5 +439,185 @@ void print_usage(void) { | |||
| 355 | printf("%s\n", _("Usage:")); | 439 | printf("%s\n", _("Usage:")); |
| 356 | printf("%s -l <query_address> [-H <host>] [-p <server port>]\n", progname); | 440 | printf("%s -l <query_address> [-H <host>] [-p <server port>]\n", progname); |
| 357 | printf(" [-T <query type>] [-w <warning interval>] [-c <critical interval>]\n"); | 441 | printf(" [-T <query type>] [-w <warning interval>] [-c <critical interval>]\n"); |
| 358 | printf(" [-t <timeout>] [-a <expected answer address>] [-v]\n"); | 442 | printf(" [-t <timeout>] [-a <expected answer address>] [-E <flags>] [-X <flags>] [-v]\n"); |
| 443 | } | ||
| 444 | |||
| 445 | /* helpers */ | ||
| 446 | |||
| 447 | /** | ||
| 448 | * parse_flags_line - Parse a dig output line and extract DNS header flags. | ||
| 449 | * | ||
| 450 | * Input: | ||
| 451 | * line - NUL terminated dig output line, e.g. ";; flags: qr rd ra; ..." | ||
| 452 | * | ||
| 453 | * Returns: | ||
| 454 | * flag_list where: | ||
| 455 | * - items: array of NUL terminated flag strings (heap allocated) | ||
| 456 | * - count: number of entries in items | ||
| 457 | * On parse failure or if no flags were found, count is 0 and items is NULL. | ||
| 458 | */ | ||
| 459 | static flag_list parse_flags_line(const char *line) { | ||
| 460 | flag_list result = {.items = NULL, .count = 0}; | ||
| 461 | |||
| 462 | if (!line) { | ||
| 463 | return result; | ||
| 464 | } | ||
| 465 | |||
| 466 | /* Locate start of DNS header flags in dig output */ | ||
| 467 | const char *p = strstr(line, "flags:"); | ||
| 468 | if (!p) { | ||
| 469 | return result; | ||
| 470 | } | ||
| 471 | p += 6; /* skip literal "flags:" */ | ||
| 472 | |||
| 473 | /* Skip whitespace after "flags:" */ | ||
| 474 | while (*p && isspace((unsigned char)*p)) { | ||
| 475 | p++; | ||
| 476 | } | ||
| 477 | |||
| 478 | /* Flags are terminated by the next semicolon e.g. "qr rd ra;" */ | ||
| 479 | const char *q = strchr(p, ';'); | ||
| 480 | if (!q) { | ||
| 481 | return result; | ||
| 482 | } | ||
| 483 | |||
| 484 | /* Extract substring containing the flag block */ | ||
| 485 | size_t len = (size_t)(q - p); | ||
| 486 | if (len == 0) { | ||
| 487 | return result; | ||
| 488 | } | ||
| 489 | |||
| 490 | char *buf = (char *)malloc(len + 1); | ||
| 491 | if (!buf) { | ||
| 492 | return result; | ||
| 493 | } | ||
| 494 | memcpy(buf, p, len); | ||
| 495 | buf[len] = '\0'; | ||
| 496 | |||
| 497 | /* Tokenize flags separated by whitespace */ | ||
| 498 | char **arr = NULL; | ||
| 499 | size_t cnt = 0; | ||
| 500 | char *saveptr = NULL; | ||
| 501 | char *tok = strtok_r(buf, " \t", &saveptr); | ||
| 502 | |||
| 503 | while (tok) { | ||
| 504 | /* Expand array for the next flag token */ | ||
| 505 | char **tmp = (char **)realloc(arr, (cnt + 1) * sizeof(char *)); | ||
| 506 | if (!tmp) { | ||
| 507 | /* On allocation failure keep what we have and return it */ | ||
| 508 | break; | ||
| 509 | } | ||
| 510 | arr = tmp; | ||
| 511 | arr[cnt++] = strdup(tok); | ||
| 512 | tok = strtok_r(NULL, " \t", &saveptr); | ||
| 513 | } | ||
| 514 | |||
| 515 | free(buf); | ||
| 516 | |||
| 517 | result.items = arr; | ||
| 518 | result.count = cnt; | ||
| 519 | return result; | ||
| 520 | } | ||
| 521 | |||
| 522 | /** | ||
| 523 | * split_csv_trim - Split a comma separated string into trimmed tokens. | ||
| 524 | * | ||
| 525 | * Input: | ||
| 526 | * csv - NUL terminated string, e.g. "aa, qr , rd" | ||
| 527 | * | ||
| 528 | * Returns: | ||
| 529 | * flag_list where: | ||
| 530 | * - items: array of NUL terminated tokens (heap allocated, whitespace trimmed) | ||
| 531 | * - count: number of tokens | ||
| 532 | * On empty input, count is 0 and items is NULL | ||
| 533 | */ | ||
| 534 | static flag_list split_csv_trim(const char *csv) { | ||
| 535 | flag_list result = {.items = NULL, .count = 0}; | ||
| 536 | |||
| 537 | if (!csv || !*csv) { | ||
| 538 | return result; | ||
| 539 | } | ||
| 540 | |||
| 541 | char *tmp = strdup(csv); | ||
| 542 | if (!tmp) { | ||
| 543 | return result; | ||
| 544 | } | ||
| 545 | |||
| 546 | char *s = tmp; | ||
| 547 | char *token = NULL; | ||
| 548 | |||
| 549 | /* Split CSV by commas, trimming whitespace on each token */ | ||
| 550 | while ((token = strsep(&s, ",")) != NULL) { | ||
| 551 | /* trim leading whitespace */ | ||
| 552 | while (*token && isspace((unsigned char)*token)) { | ||
| 553 | token++; | ||
| 554 | } | ||
| 555 | |||
| 556 | /* trim trailing whitespace */ | ||
| 557 | char *end = token + strlen(token); | ||
| 558 | while (end > token && isspace((unsigned char)end[-1])) { | ||
| 559 | *--end = '\0'; | ||
| 560 | } | ||
| 561 | |||
| 562 | if (*token) { | ||
| 563 | /* Expand the items array and append the token */ | ||
| 564 | char **arr = (char **)realloc(result.items, (result.count + 1) * sizeof(char *)); | ||
| 565 | if (!arr) { | ||
| 566 | /* Allocation failed, stop and return what we have */ | ||
| 567 | break; | ||
| 568 | } | ||
| 569 | result.items = arr; | ||
| 570 | result.items[result.count++] = strdup(token); | ||
| 571 | } | ||
| 572 | } | ||
| 573 | |||
| 574 | free(tmp); | ||
| 575 | return result; | ||
| 576 | } | ||
| 577 | |||
| 578 | /** | ||
| 579 | * flag_list_contains - Case-insensitive membership test in a flag_list. | ||
| 580 | * | ||
| 581 | * Input: | ||
| 582 | * list - pointer to a flag_list | ||
| 583 | * needle - NUL terminated string to search for | ||
| 584 | * | ||
| 585 | * Returns: | ||
| 586 | * true if needle is contained in list (strcasecmp) | ||
| 587 | * false otherwise | ||
| 588 | */ | ||
| 589 | static bool flag_list_contains(const flag_list *list, const char *needle) { | ||
| 590 | if (!list || !needle || !*needle) { | ||
| 591 | return false; | ||
| 592 | } | ||
| 593 | |||
| 594 | for (size_t i = 0; i < list->count; i++) { | ||
| 595 | if (strcasecmp(list->items[i], needle) == 0) { | ||
| 596 | return true; | ||
| 597 | } | ||
| 598 | } | ||
| 599 | return false; | ||
| 600 | } | ||
| 601 | |||
| 602 | /** | ||
| 603 | * free_flag_list - Release all heap allocations held by a flag_list. | ||
| 604 | * | ||
| 605 | * Input: | ||
| 606 | * list - pointer to a flag_list whose items were allocated by | ||
| 607 | * parse_flags_line() or split_csv_trim(). | ||
| 608 | * | ||
| 609 | * After this call list->items is NULL and list->count is 0. | ||
| 610 | */ | ||
| 611 | static void free_flag_list(flag_list *list) { | ||
| 612 | if (!list || !list->items) { | ||
| 613 | return; | ||
| 614 | } | ||
| 615 | |||
| 616 | for (size_t i = 0; i < list->count; i++) { | ||
| 617 | free(list->items[i]); | ||
| 618 | } | ||
| 619 | free(list->items); | ||
| 620 | |||
| 621 | list->items = NULL; | ||
| 622 | list->count = 0; | ||
| 359 | } | 623 | } |
diff --git a/plugins/check_dig.d/config.h b/plugins/check_dig.d/config.h index a570b633..dd1f58b5 100644 --- a/plugins/check_dig.d/config.h +++ b/plugins/check_dig.d/config.h | |||
| @@ -8,6 +8,11 @@ | |||
| 8 | #define DEFAULT_TRIES 2 | 8 | #define DEFAULT_TRIES 2 |
| 9 | 9 | ||
| 10 | typedef struct { | 10 | typedef struct { |
| 11 | char **items; | ||
| 12 | size_t count; | ||
| 13 | } flag_list; | ||
| 14 | |||
| 15 | typedef struct { | ||
| 11 | char *query_address; | 16 | char *query_address; |
| 12 | char *record_type; | 17 | char *record_type; |
| 13 | char *expected_address; | 18 | char *expected_address; |
| @@ -19,6 +24,8 @@ typedef struct { | |||
| 19 | 24 | ||
| 20 | double warning_interval; | 25 | double warning_interval; |
| 21 | double critical_interval; | 26 | double critical_interval; |
| 27 | flag_list require_flags; | ||
| 28 | flag_list forbid_flags; | ||
| 22 | } check_dig_config; | 29 | } check_dig_config; |
| 23 | 30 | ||
| 24 | check_dig_config check_dig_config_init() { | 31 | check_dig_config check_dig_config_init() { |
| @@ -34,7 +41,8 @@ check_dig_config check_dig_config_init() { | |||
| 34 | 41 | ||
| 35 | .warning_interval = UNDEFINED, | 42 | .warning_interval = UNDEFINED, |
| 36 | .critical_interval = UNDEFINED, | 43 | .critical_interval = UNDEFINED, |
| 37 | 44 | .require_flags = {.count = 0, .items = NULL}, | |
| 45 | .forbid_flags = {.count = 0, .items = NULL}, | ||
| 38 | }; | 46 | }; |
| 39 | return tmp; | 47 | return tmp; |
| 40 | } | 48 | } |
diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 037a6f7a..d42b5486 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c | |||
| @@ -31,24 +31,35 @@ const char *program_name = "check_disk"; /* Required for coreutils libs */ | |||
| 31 | const char *copyright = "1999-2024"; | 31 | const char *copyright = "1999-2024"; |
| 32 | const char *email = "devel@monitoring-plugins.org"; | 32 | const char *email = "devel@monitoring-plugins.org"; |
| 33 | 33 | ||
| 34 | #include "states.h" | ||
| 34 | #include "common.h" | 35 | #include "common.h" |
| 36 | #include "output.h" | ||
| 37 | #include "perfdata.h" | ||
| 38 | #include "utils_base.h" | ||
| 39 | #include "lib/thresholds.h" | ||
| 40 | |||
| 35 | #ifdef HAVE_SYS_STAT_H | 41 | #ifdef HAVE_SYS_STAT_H |
| 36 | # include <sys/stat.h> | 42 | # include <sys/stat.h> |
| 37 | #endif | 43 | #endif |
| 44 | |||
| 38 | #if HAVE_INTTYPES_H | 45 | #if HAVE_INTTYPES_H |
| 39 | # include <inttypes.h> | 46 | # include <inttypes.h> |
| 40 | #endif | 47 | #endif |
| 48 | |||
| 41 | #include <assert.h> | 49 | #include <assert.h> |
| 42 | #include "popen.h" | ||
| 43 | #include "utils.h" | ||
| 44 | #include "utils_disk.h" | ||
| 45 | #include <stdarg.h> | 50 | #include <stdarg.h> |
| 46 | #include "fsusage.h" | 51 | #include <stdint.h> |
| 47 | #include "mountlist.h" | ||
| 48 | #include <float.h> | 52 | #include <float.h> |
| 53 | #include "./popen.h" | ||
| 54 | #include "./utils.h" | ||
| 55 | #include "../gl/fsusage.h" | ||
| 56 | #include "../gl/mountlist.h" | ||
| 57 | #include "./check_disk.d/utils_disk.h" | ||
| 58 | |||
| 49 | #if HAVE_LIMITS_H | 59 | #if HAVE_LIMITS_H |
| 50 | # include <limits.h> | 60 | # include <limits.h> |
| 51 | #endif | 61 | #endif |
| 62 | |||
| 52 | #include "regex.h" | 63 | #include "regex.h" |
| 53 | 64 | ||
| 54 | #ifdef __CYGWIN__ | 65 | #ifdef __CYGWIN__ |
| @@ -57,424 +68,322 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 57 | # define ERROR -1 | 68 | # define ERROR -1 |
| 58 | #endif | 69 | #endif |
| 59 | 70 | ||
| 60 | /* If nonzero, show even filesystems with zero size or | ||
| 61 | uninteresting types. */ | ||
| 62 | static int show_all_fs = 1; | ||
| 63 | |||
| 64 | /* If nonzero, show only local filesystems. */ | ||
| 65 | static int show_local_fs = 0; | ||
| 66 | |||
| 67 | /* If nonzero, show only local filesystems but call stat() on remote ones. */ | ||
| 68 | static int stat_remote_fs = 0; | ||
| 69 | |||
| 70 | /* If positive, the units to use when printing sizes; | ||
| 71 | if negative, the human-readable base. */ | ||
| 72 | /* static int output_block_size; */ | ||
| 73 | |||
| 74 | /* If nonzero, invoke the `sync' system call before getting any usage data. | ||
| 75 | Using this option can make df very slow, especially with many or very | ||
| 76 | busy disks. Note that this may make a difference on some systems -- | ||
| 77 | SunOs4.1.3, for one. It is *not* necessary on Linux. */ | ||
| 78 | /* static int require_sync = 0; */ | ||
| 79 | |||
| 80 | /* Linked list of filesystem types to display. | ||
| 81 | If `fs_select_list' is NULL, list all types. | ||
| 82 | This table is generated dynamically from command-line options, | ||
| 83 | rather than hardcoding into the program what it thinks are the | ||
| 84 | valid filesystem types; let the user specify any filesystem type | ||
| 85 | they want to, and if there are any filesystems of that type, they | ||
| 86 | will be shown. | ||
| 87 | |||
| 88 | Some filesystem types: | ||
| 89 | 4.2 4.3 ufs nfs swap ignore io vm efs dbg */ | ||
| 90 | |||
| 91 | /* static struct parameter_list *fs_select_list; */ | ||
| 92 | |||
| 93 | /* Linked list of filesystem types to omit. | ||
| 94 | If the list is empty, don't exclude any types. */ | ||
| 95 | static struct regex_list *fs_exclude_list = NULL; | ||
| 96 | |||
| 97 | /* Linked list of filesystem types to check. | ||
| 98 | If the list is empty, include all types. */ | ||
| 99 | static struct regex_list *fs_include_list; | ||
| 100 | |||
| 101 | static struct name_list *dp_exclude_list; | ||
| 102 | |||
| 103 | static struct parameter_list *path_select_list = NULL; | ||
| 104 | |||
| 105 | /* Linked list of mounted filesystems. */ | ||
| 106 | static struct mount_entry *mount_list; | ||
| 107 | |||
| 108 | /* For long options that have no equivalent short option, use a | ||
| 109 | non-character as a pseudo short option, starting with CHAR_MAX + 1. */ | ||
| 110 | enum { | ||
| 111 | SYNC_OPTION = CHAR_MAX + 1, | ||
| 112 | NO_SYNC_OPTION, | ||
| 113 | BLOCK_SIZE_OPTION | ||
| 114 | }; | ||
| 115 | |||
| 116 | #ifdef _AIX | 71 | #ifdef _AIX |
| 117 | # pragma alloca | 72 | # pragma alloca |
| 118 | #endif | 73 | #endif |
| 119 | 74 | ||
| 120 | static int process_arguments(int /*argc*/, char ** /*argv*/); | 75 | typedef struct { |
| 121 | static void set_all_thresholds(struct parameter_list *path); | 76 | int errorcode; |
| 122 | static void print_help(void); | 77 | check_disk_config config; |
| 78 | } check_disk_config_wrapper; | ||
| 79 | static check_disk_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 80 | |||
| 81 | static void set_all_thresholds(parameter_list_elem *path, char *warn_freespace_units, | ||
| 82 | char *crit_freespace_units, char *warn_freespace_percent, | ||
| 83 | char *crit_freespace_percent, char *warn_freeinodes_percent, | ||
| 84 | char *crit_freeinodes_percent); | ||
| 85 | static double calculate_percent(uintmax_t /*value*/, uintmax_t /*total*/); | ||
| 86 | static bool stat_path(parameter_list_elem * /*parameters*/, bool /*ignore_missing*/); | ||
| 87 | |||
| 88 | /* | ||
| 89 | * Puts the values from a struct fs_usage into a parameter_list with an additional flag to control | ||
| 90 | * how reserved and inodes should be judged (ignored or not) | ||
| 91 | */ | ||
| 92 | static parameter_list_elem get_path_stats(parameter_list_elem parameters, struct fs_usage fsp, | ||
| 93 | bool freespace_ignore_reserved); | ||
| 94 | static mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, | ||
| 95 | bool display_inodes_perfdata, byte_unit unit); | ||
| 96 | |||
| 123 | void print_usage(void); | 97 | void print_usage(void); |
| 124 | static double calculate_percent(uintmax_t, uintmax_t); | 98 | static void print_help(void); |
| 125 | static bool stat_path(struct parameter_list *p); | ||
| 126 | static void get_stats(struct parameter_list *p, struct fs_usage *fsp); | ||
| 127 | static void get_path_stats(struct parameter_list *p, struct fs_usage *fsp); | ||
| 128 | 99 | ||
| 129 | static char *units; | ||
| 130 | static uintmax_t mult = 1024 * 1024; | ||
| 131 | static int verbose = 0; | 100 | static int verbose = 0; |
| 132 | static bool erronly = false; | ||
| 133 | static bool display_mntp = false; | ||
| 134 | static bool exact_match = false; | ||
| 135 | static bool ignore_missing = false; | ||
| 136 | static bool freespace_ignore_reserved = false; | ||
| 137 | static bool display_inodes_perfdata = false; | ||
| 138 | static char *warn_freespace_units = NULL; | ||
| 139 | static char *crit_freespace_units = NULL; | ||
| 140 | static char *warn_freespace_percent = NULL; | ||
| 141 | static char *crit_freespace_percent = NULL; | ||
| 142 | static char *warn_usedspace_units = NULL; | ||
| 143 | static char *crit_usedspace_units = NULL; | ||
| 144 | static char *warn_usedspace_percent = NULL; | ||
| 145 | static char *crit_usedspace_percent = NULL; | ||
| 146 | static char *warn_usedinodes_percent = NULL; | ||
| 147 | static char *crit_usedinodes_percent = NULL; | ||
| 148 | static char *warn_freeinodes_percent = NULL; | ||
| 149 | static char *crit_freeinodes_percent = NULL; | ||
| 150 | static bool path_selected = false; | ||
| 151 | static bool path_ignored = false; | ||
| 152 | static char *group = NULL; | ||
| 153 | static struct stat *stat_buf; | ||
| 154 | static struct name_list *seen = NULL; | ||
| 155 | 101 | ||
| 156 | int main(int argc, char **argv) { | 102 | // This would not be necessary in C23!! |
| 157 | int result = STATE_UNKNOWN; | 103 | const byte_unit Bytes_Factor = 1; |
| 158 | int disk_result = STATE_UNKNOWN; | 104 | const byte_unit KibiBytes_factor = 1024; |
| 159 | char *output = NULL; | 105 | const byte_unit MebiBytes_factor = 1048576; |
| 160 | char *ignored = NULL; | 106 | const byte_unit GibiBytes_factor = 1073741824; |
| 161 | char *details = NULL; | 107 | const byte_unit TebiBytes_factor = 1099511627776; |
| 162 | char *perf = NULL; | 108 | const byte_unit PebiBytes_factor = 1125899906842624; |
| 163 | char *perf_ilabel = NULL; | 109 | const byte_unit ExbiBytes_factor = 1152921504606846976; |
| 164 | char *preamble = " - free space:"; | 110 | const byte_unit KiloBytes_factor = 1000; |
| 165 | char *ignored_preamble = " - ignored paths:"; | 111 | const byte_unit MegaBytes_factor = 1000000; |
| 166 | char *flag_header = NULL; | 112 | const byte_unit GigaBytes_factor = 1000000000; |
| 167 | int temp_result = STATE_UNKNOWN; | 113 | const byte_unit TeraBytes_factor = 1000000000000; |
| 168 | 114 | const byte_unit PetaBytes_factor = 1000000000000000; | |
| 169 | struct mount_entry *me = NULL; | 115 | const byte_unit ExaBytes_factor = 1000000000000000000; |
| 170 | struct fs_usage fsp = {0}; | ||
| 171 | struct parameter_list *temp_list = NULL; | ||
| 172 | struct parameter_list *path = NULL; | ||
| 173 | |||
| 174 | #ifdef __CYGWIN__ | ||
| 175 | char mountdir[32]; | ||
| 176 | #endif | ||
| 177 | |||
| 178 | output = strdup(""); | ||
| 179 | ignored = strdup(""); | ||
| 180 | details = strdup(""); | ||
| 181 | perf = strdup(""); | ||
| 182 | perf_ilabel = strdup(""); | ||
| 183 | stat_buf = malloc(sizeof *stat_buf); | ||
| 184 | 116 | ||
| 117 | int main(int argc, char **argv) { | ||
| 185 | setlocale(LC_ALL, ""); | 118 | setlocale(LC_ALL, ""); |
| 186 | bindtextdomain(PACKAGE, LOCALEDIR); | 119 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 187 | textdomain(PACKAGE); | 120 | textdomain(PACKAGE); |
| 188 | 121 | ||
| 189 | mount_list = read_file_system_list(0); | 122 | #ifdef __CYGWIN__ |
| 123 | char mountdir[32]; | ||
| 124 | #endif | ||
| 190 | 125 | ||
| 191 | /* Parse extra opts if any */ | 126 | // Parse extra opts if any |
| 192 | argv = np_extra_opts(&argc, argv, progname); | 127 | argv = np_extra_opts(&argc, argv, progname); |
| 193 | 128 | ||
| 194 | if (process_arguments(argc, argv) == ERROR) | 129 | check_disk_config_wrapper tmp_config = process_arguments(argc, argv); |
| 130 | if (tmp_config.errorcode == ERROR) { | ||
| 195 | usage4(_("Could not parse arguments")); | 131 | usage4(_("Could not parse arguments")); |
| 132 | } | ||
| 196 | 133 | ||
| 197 | /* If a list of paths has not been selected, find entire | 134 | check_disk_config config = tmp_config.config; |
| 198 | mount list and create list of paths | 135 | |
| 199 | */ | 136 | if (config.output_format_is_set) { |
| 200 | if (path_selected == false && path_ignored == false) { | 137 | mp_set_format(config.output_format); |
| 201 | for (me = mount_list; me; me = me->me_next) { | ||
| 202 | if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) { | ||
| 203 | path = np_add_parameter(&path_select_list, me->me_mountdir); | ||
| 204 | } | ||
| 205 | path->best_match = me; | ||
| 206 | path->group = group; | ||
| 207 | set_all_thresholds(path); | ||
| 208 | } | ||
| 209 | } | 138 | } |
| 210 | 139 | ||
| 211 | if (path_ignored == false) { | 140 | if (config.erronly) { |
| 212 | np_set_best_match(path_select_list, mount_list, exact_match); | 141 | mp_set_level_of_detail(MP_DETAIL_NON_OK_ONLY); |
| 213 | } | 142 | } |
| 214 | 143 | ||
| 215 | /* Error if no match found for specified paths */ | 144 | if (!config.path_ignored) { |
| 216 | temp_list = path_select_list; | 145 | mp_int_fs_list_set_best_match(config.path_select_list, config.mount_list, |
| 146 | config.exact_match); | ||
| 147 | } | ||
| 217 | 148 | ||
| 218 | while (path_select_list) { | 149 | // Error if no match found for specified paths |
| 219 | if (!path_select_list->best_match && ignore_missing == true) { | 150 | for (parameter_list_elem *elem = config.path_select_list.first; elem;) { |
| 220 | /* If the first element will be deleted, the temp_list must be updated with the new start address as well */ | 151 | if (!elem->best_match && config.ignore_missing) { |
| 221 | if (path_select_list == temp_list) { | ||
| 222 | temp_list = path_select_list->name_next; | ||
| 223 | } | ||
| 224 | /* Add path argument to list of ignored paths to inform about missing paths being ignored and not alerted */ | ||
| 225 | xasprintf(&ignored, "%s %s;", ignored, path_select_list->name); | ||
| 226 | /* Delete the path from the list so that it is not stat-checked later in the code. */ | 152 | /* Delete the path from the list so that it is not stat-checked later in the code. */ |
| 227 | path_select_list = np_del_parameter(path_select_list, path_select_list->name_prev); | 153 | elem = mp_int_fs_list_del(&config.path_select_list, elem); |
| 228 | } else if (!path_select_list->best_match) { | 154 | continue; |
| 155 | } | ||
| 156 | if (!elem->best_match) { | ||
| 229 | /* Without --ignore-missing option, exit with Critical state. */ | 157 | /* Without --ignore-missing option, exit with Critical state. */ |
| 230 | die(STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), path_select_list->name); | 158 | die(STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), elem->name); |
| 231 | } else { | ||
| 232 | /* Continue jumping through the list */ | ||
| 233 | path_select_list = path_select_list->name_next; | ||
| 234 | } | 159 | } |
| 235 | } | ||
| 236 | 160 | ||
| 237 | path_select_list = temp_list; | 161 | elem = mp_int_fs_list_get_next(elem); |
| 162 | } | ||
| 238 | 163 | ||
| 239 | if (!path_select_list && ignore_missing == true) { | 164 | mp_check overall = mp_check_init(); |
| 240 | result = STATE_OK; | 165 | if (config.path_select_list.length == 0) { |
| 241 | if (verbose >= 2) { | 166 | mp_subcheck none_sc = mp_subcheck_init(); |
| 242 | printf("None of the provided paths were found\n"); | 167 | xasprintf(&none_sc.output, "No filesystems were found for the provided parameters"); |
| 168 | if (config.ignore_missing) { | ||
| 169 | none_sc = mp_set_subcheck_state(none_sc, STATE_OK); | ||
| 170 | } else { | ||
| 171 | none_sc = mp_set_subcheck_state(none_sc, STATE_UNKNOWN); | ||
| 172 | if (verbose >= 2) { | ||
| 173 | printf("None of the provided paths were found\n"); | ||
| 174 | } | ||
| 243 | } | 175 | } |
| 176 | mp_add_subcheck_to_check(&overall, none_sc); | ||
| 177 | mp_exit(overall); | ||
| 244 | } | 178 | } |
| 245 | 179 | ||
| 246 | /* Process for every path in list */ | 180 | // Filter list first |
| 247 | for (path = path_select_list; path; path = path->name_next) { | 181 | for (parameter_list_elem *path = config.path_select_list.first; path;) { |
| 248 | if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) | 182 | if (!path->best_match) { |
| 249 | printf("Thresholds(pct) for %s warn: %f crit %f\n", path->name, path->freespace_percent->warning->end, | 183 | path = mp_int_fs_list_del(&config.path_select_list, path); |
| 250 | path->freespace_percent->critical->end); | ||
| 251 | |||
| 252 | if (verbose >= 3 && path->group != NULL) | ||
| 253 | printf("Group of %s: %s\n", path->name, path->group); | ||
| 254 | |||
| 255 | /* reset disk result */ | ||
| 256 | disk_result = STATE_UNKNOWN; | ||
| 257 | |||
| 258 | me = path->best_match; | ||
| 259 | |||
| 260 | if (!me) { | ||
| 261 | continue; | 184 | continue; |
| 262 | } | 185 | } |
| 263 | 186 | ||
| 187 | struct mount_entry *mount_entry = path->best_match; | ||
| 188 | |||
| 264 | #ifdef __CYGWIN__ | 189 | #ifdef __CYGWIN__ |
| 265 | if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) | 190 | if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) { |
| 191 | path = mp_int_fs_list_del(&config.path_select_list, path); | ||
| 266 | continue; | 192 | continue; |
| 193 | } | ||
| 194 | |||
| 195 | char *mountdir = NULL; | ||
| 267 | snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10); | 196 | snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10); |
| 268 | if (GetDriveType(mountdir) != DRIVE_FIXED) | 197 | if (GetDriveType(mountdir) != DRIVE_FIXED) { |
| 269 | me->me_remote = 1; | 198 | mount_entry->me_remote = 1; |
| 199 | } | ||
| 270 | #endif | 200 | #endif |
| 271 | /* Filters */ | ||
| 272 | 201 | ||
| 273 | /* Remove filesystems already seen */ | 202 | /* Remove filesystems already seen */ |
| 274 | if (np_seen_name(seen, me->me_mountdir)) { | 203 | if (np_seen_name(config.seen, mount_entry->me_mountdir)) { |
| 204 | path = mp_int_fs_list_del(&config.path_select_list, path); | ||
| 275 | continue; | 205 | continue; |
| 276 | } | 206 | } |
| 277 | np_add_name(&seen, me->me_mountdir); | ||
| 278 | 207 | ||
| 279 | if (path->group == NULL) { | 208 | if (path->group == NULL) { |
| 280 | /* Skip remote filesystems if we're not interested in them */ | 209 | if (config.fs_exclude_list && |
| 281 | if (me->me_remote && show_local_fs) { | 210 | np_find_regmatch(config.fs_exclude_list, mount_entry->me_type)) { |
| 282 | if (stat_remote_fs) { | 211 | // Skip excluded fs's |
| 283 | if (!stat_path(path) && ignore_missing == true) { | 212 | path = mp_int_fs_list_del(&config.path_select_list, path); |
| 284 | result = STATE_OK; | ||
| 285 | xasprintf(&ignored, "%s %s;", ignored, path->name); | ||
| 286 | } | ||
| 287 | } | ||
| 288 | continue; | 213 | continue; |
| 289 | /* Skip pseudo fs's if we haven't asked for all fs's */ | ||
| 290 | } | 214 | } |
| 291 | if (me->me_dummy && !show_all_fs) { | 215 | |
| 292 | continue; | 216 | if (config.device_path_exclude_list && |
| 293 | /* Skip excluded fstypes */ | 217 | (np_find_name(config.device_path_exclude_list, mount_entry->me_devname) || |
| 294 | } | 218 | np_find_name(config.device_path_exclude_list, mount_entry->me_mountdir))) { |
| 295 | if (fs_exclude_list && np_find_regmatch(fs_exclude_list, me->me_type)) { | 219 | // Skip excluded device or mount paths |
| 220 | path = mp_int_fs_list_del(&config.path_select_list, path); | ||
| 296 | continue; | 221 | continue; |
| 297 | /* Skip excluded fs's */ | ||
| 298 | } | 222 | } |
| 299 | if (dp_exclude_list && (np_find_name(dp_exclude_list, me->me_devname) || np_find_name(dp_exclude_list, me->me_mountdir))) { | 223 | |
| 224 | if (config.fs_include_list && | ||
| 225 | !np_find_regmatch(config.fs_include_list, mount_entry->me_type)) { | ||
| 226 | // Skip not included fstypes | ||
| 227 | path = mp_int_fs_list_del(&config.path_select_list, path); | ||
| 300 | continue; | 228 | continue; |
| 301 | /* Skip not included fstypes */ | ||
| 302 | } | 229 | } |
| 303 | if (fs_include_list && !np_find_regmatch(fs_include_list, me->me_type)) { | 230 | |
| 231 | /* Skip remote filesystems if we're not interested in them */ | ||
| 232 | if (mount_entry->me_remote && config.show_local_fs) { | ||
| 233 | if (config.stat_remote_fs) { | ||
| 234 | // TODO Stat here | ||
| 235 | if (!stat_path(path, config.ignore_missing) && config.ignore_missing) { | ||
| 236 | } | ||
| 237 | } | ||
| 304 | continue; | 238 | continue; |
| 305 | } | 239 | } |
| 306 | } | ||
| 307 | 240 | ||
| 308 | if (!stat_path(path)) { | 241 | // TODO why stat here? remove unstatable fs? |
| 309 | if (ignore_missing == true) { | 242 | if (!stat_path(path, config.ignore_missing)) { |
| 310 | result = STATE_OK; | 243 | // if (config.ignore_missing) { |
| 311 | xasprintf(&ignored, "%s %s;", ignored, path->name); | 244 | // xasprintf(&ignored, "%s %s;", ignored, path->name); |
| 245 | // } | ||
| 246 | // not accessible, remove from list | ||
| 247 | path = mp_int_fs_list_del(&config.path_select_list, path); | ||
| 248 | continue; | ||
| 312 | } | 249 | } |
| 313 | continue; | ||
| 314 | } | 250 | } |
| 315 | get_fs_usage(me->me_mountdir, me->me_devname, &fsp); | ||
| 316 | |||
| 317 | if (fsp.fsu_blocks && strcmp("none", me->me_mountdir)) { | ||
| 318 | get_stats(path, &fsp); | ||
| 319 | |||
| 320 | if (verbose >= 3) { | ||
| 321 | printf("For %s, used_pct=%f free_pct=%f used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%f " | ||
| 322 | "free_inodes_pct=%f fsp.fsu_blocksize=%lu mult=%lu\n", | ||
| 323 | me->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, | ||
| 324 | path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, mult); | ||
| 325 | } | ||
| 326 | |||
| 327 | /* Threshold comparisons */ | ||
| 328 | |||
| 329 | temp_result = get_status(path->dfree_units, path->freespace_units); | ||
| 330 | if (verbose >= 3) | ||
| 331 | printf("Freespace_units result=%d\n", temp_result); | ||
| 332 | disk_result = max_state(disk_result, temp_result); | ||
| 333 | |||
| 334 | temp_result = get_status(path->dfree_pct, path->freespace_percent); | ||
| 335 | if (verbose >= 3) | ||
| 336 | printf("Freespace%% result=%d\n", temp_result); | ||
| 337 | disk_result = max_state(disk_result, temp_result); | ||
| 338 | 251 | ||
| 339 | temp_result = get_status(path->dused_units, path->usedspace_units); | 252 | path = mp_int_fs_list_get_next(path); |
| 340 | if (verbose >= 3) | 253 | } |
| 341 | printf("Usedspace_units result=%d\n", temp_result); | ||
| 342 | disk_result = max_state(disk_result, temp_result); | ||
| 343 | |||
| 344 | temp_result = get_status(path->dused_pct, path->usedspace_percent); | ||
| 345 | if (verbose >= 3) | ||
| 346 | printf("Usedspace_percent result=%d\n", temp_result); | ||
| 347 | disk_result = max_state(disk_result, temp_result); | ||
| 348 | |||
| 349 | temp_result = get_status(path->dused_inodes_percent, path->usedinodes_percent); | ||
| 350 | if (verbose >= 3) | ||
| 351 | printf("Usedinodes_percent result=%d\n", temp_result); | ||
| 352 | disk_result = max_state(disk_result, temp_result); | ||
| 353 | |||
| 354 | temp_result = get_status(path->dfree_inodes_percent, path->freeinodes_percent); | ||
| 355 | if (verbose >= 3) | ||
| 356 | printf("Freeinodes_percent result=%d\n", temp_result); | ||
| 357 | disk_result = max_state(disk_result, temp_result); | ||
| 358 | |||
| 359 | result = max_state(result, disk_result); | ||
| 360 | |||
| 361 | /* What a mess of units. The output shows free space, the perf data shows used space. Yikes! | ||
| 362 | Hack here. Trying to get warn/crit levels from freespace_(units|percent) for perf | ||
| 363 | data. Assumption that start=0. Roll on new syntax... | ||
| 364 | */ | ||
| 365 | |||
| 366 | /* *_high_tide must be reinitialized at each run */ | ||
| 367 | uint64_t warning_high_tide = UINT64_MAX; | ||
| 368 | 254 | ||
| 369 | if (path->freespace_units->warning != NULL) { | 255 | // now get the actual measurements |
| 370 | warning_high_tide = (path->dtotal_units - path->freespace_units->warning->end) * mult; | 256 | for (parameter_list_elem *filesystem = config.path_select_list.first; filesystem;) { |
| 371 | } | 257 | // Get actual metrics here |
| 372 | if (path->freespace_percent->warning != NULL) { | 258 | struct mount_entry *mount_entry = filesystem->best_match; |
| 373 | warning_high_tide = | 259 | struct fs_usage fsp = {0}; |
| 374 | min(warning_high_tide, (uint64_t)((1.0 - path->freespace_percent->warning->end / 100) * (path->dtotal_units * mult))); | 260 | get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp); |
| 375 | } | ||
| 376 | 261 | ||
| 377 | uint64_t critical_high_tide = UINT64_MAX; | 262 | if (fsp.fsu_blocks != 0 && strcmp("none", mount_entry->me_mountdir) != 0) { |
| 263 | *filesystem = get_path_stats(*filesystem, fsp, config.freespace_ignore_reserved); | ||
| 378 | 264 | ||
| 379 | if (path->freespace_units->critical != NULL) { | 265 | if (verbose >= 3) { |
| 380 | critical_high_tide = (path->dtotal_units - path->freespace_units->critical->end) * mult; | 266 | printf("For %s, used_units=%lu free_units=%lu total_units=%lu " |
| 381 | } | 267 | "fsp.fsu_blocksize=%lu\n", |
| 382 | if (path->freespace_percent->critical != NULL) { | 268 | mount_entry->me_mountdir, filesystem->used_bytes, filesystem->free_bytes, |
| 383 | critical_high_tide = | 269 | filesystem->total_bytes, fsp.fsu_blocksize); |
| 384 | min(critical_high_tide, (uint64_t)((1.0 - path->freespace_percent->critical->end / 100) * (path->dtotal_units * mult))); | ||
| 385 | } | 270 | } |
| 271 | } else { | ||
| 272 | // failed to retrieve file system data or not mounted? | ||
| 273 | filesystem = mp_int_fs_list_del(&config.path_select_list, filesystem); | ||
| 274 | continue; | ||
| 275 | } | ||
| 276 | filesystem = mp_int_fs_list_get_next(filesystem); | ||
| 277 | } | ||
| 386 | 278 | ||
| 387 | /* Nb: *_high_tide are unset when == UINT64_MAX */ | 279 | if (verbose > 2) { |
| 388 | xasprintf(&perf, "%s %s", perf, | 280 | for (parameter_list_elem *filesystem = config.path_select_list.first; filesystem; |
| 389 | perfdata_uint64((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, | 281 | filesystem = mp_int_fs_list_get_next(filesystem)) { |
| 390 | path->dused_units * mult, "B", (warning_high_tide == UINT64_MAX ? false : true), warning_high_tide, | 282 | assert(filesystem->best_match != NULL); |
| 391 | (critical_high_tide == UINT64_MAX ? false : true), critical_high_tide, true, 0, true, | 283 | if (filesystem->best_match == NULL) { |
| 392 | path->dtotal_units * mult)); | 284 | printf("Filesystem path %s has no mount_entry!\n", filesystem->name); |
| 393 | 285 | } else { | |
| 394 | if (display_inodes_perfdata) { | 286 | // printf("Filesystem path %s has a mount_entry!\n", filesystem->name); |
| 395 | /* *_high_tide must be reinitialized at each run */ | ||
| 396 | warning_high_tide = UINT64_MAX; | ||
| 397 | critical_high_tide = UINT64_MAX; | ||
| 398 | |||
| 399 | if (path->freeinodes_percent->warning != NULL) { | ||
| 400 | warning_high_tide = (uint64_t)fabs( | ||
| 401 | min((double)warning_high_tide, (double)(1.0 - path->freeinodes_percent->warning->end / 100) * path->inodes_total)); | ||
| 402 | } | ||
| 403 | if (path->freeinodes_percent->critical != NULL) { | ||
| 404 | critical_high_tide = (uint64_t)fabs(min( | ||
| 405 | (double)critical_high_tide, (double)(1.0 - path->freeinodes_percent->critical->end / 100) * path->inodes_total)); | ||
| 406 | } | ||
| 407 | |||
| 408 | xasprintf(&perf_ilabel, "%s (inodes)", | ||
| 409 | (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir); | ||
| 410 | /* Nb: *_high_tide are unset when == UINT64_MAX */ | ||
| 411 | xasprintf(&perf, "%s %s", perf, | ||
| 412 | perfdata_uint64(perf_ilabel, path->inodes_used, "", (warning_high_tide != UINT64_MAX ? true : false), | ||
| 413 | warning_high_tide, (critical_high_tide != UINT64_MAX ? true : false), critical_high_tide, true, 0, | ||
| 414 | true, path->inodes_total)); | ||
| 415 | } | 287 | } |
| 288 | } | ||
| 289 | } | ||
| 416 | 290 | ||
| 417 | if (disk_result == STATE_OK && erronly && !verbose) | 291 | measurement_unit_list *measurements = NULL; |
| 418 | continue; | 292 | measurement_unit_list *current = NULL; |
| 419 | 293 | // create measuring units, because of groups | |
| 420 | if (disk_result && verbose >= 1) { | 294 | for (parameter_list_elem *filesystem = config.path_select_list.first; filesystem; |
| 421 | xasprintf(&flag_header, " %s [", state_text(disk_result)); | 295 | filesystem = mp_int_fs_list_get_next(filesystem)) { |
| 296 | assert(filesystem->best_match != NULL); | ||
| 297 | |||
| 298 | if (filesystem->group == NULL) { | ||
| 299 | // create a measurement unit for the fs | ||
| 300 | measurement_unit unit = | ||
| 301 | create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); | ||
| 302 | if (measurements == NULL) { | ||
| 303 | measurements = current = add_measurement_list(NULL, unit); | ||
| 422 | } else { | 304 | } else { |
| 423 | xasprintf(&flag_header, ""); | 305 | current = add_measurement_list(measurements, unit); |
| 424 | } | 306 | } |
| 425 | xasprintf(&output, "%s%s %s %llu%s (%.1f%%", output, flag_header, | 307 | } else { |
| 426 | (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, path->dfree_units, units, | 308 | // Grouped elements are consecutive |
| 427 | path->dfree_pct); | 309 | if (measurements == NULL) { |
| 428 | if (path->dused_inodes_percent < 0) { | 310 | // first entry |
| 429 | xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : "")); | 311 | measurement_unit unit = |
| 312 | create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); | ||
| 313 | unit.name = strdup(filesystem->group); | ||
| 314 | measurements = current = add_measurement_list(NULL, unit); | ||
| 430 | } else { | 315 | } else { |
| 431 | xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : "")); | 316 | // if this is the first element of a group, the name of the previous entry is |
| 317 | // different | ||
| 318 | if (strcmp(filesystem->group, current->unit.name) != 0) { | ||
| 319 | // so, this must be the first element of a group | ||
| 320 | measurement_unit unit = | ||
| 321 | create_measurement_unit_from_filesystem(*filesystem, config.display_mntp); | ||
| 322 | unit.name = filesystem->group; | ||
| 323 | current = add_measurement_list(measurements, unit); | ||
| 324 | |||
| 325 | } else { | ||
| 326 | // NOT the first entry of a group, add info to the other one | ||
| 327 | current->unit = add_filesystem_to_measurement_unit(current->unit, *filesystem); | ||
| 328 | } | ||
| 432 | } | 329 | } |
| 433 | free(flag_header); | ||
| 434 | } | 330 | } |
| 435 | } | 331 | } |
| 436 | 332 | ||
| 437 | if (verbose >= 2) | 333 | /* Process for every path in list */ |
| 438 | xasprintf(&output, "%s%s", output, details); | 334 | if (measurements != NULL) { |
| 335 | for (measurement_unit_list *unit = measurements; unit; unit = unit->next) { | ||
| 336 | mp_subcheck unit_sc = evaluate_filesystem(unit->unit, config.display_inodes_perfdata, | ||
| 337 | config.display_unit); | ||
| 338 | mp_add_subcheck_to_check(&overall, unit_sc); | ||
| 339 | } | ||
| 340 | } else { | ||
| 341 | // Apparently no machting fs found | ||
| 342 | mp_subcheck none_sc = mp_subcheck_init(); | ||
| 343 | xasprintf(&none_sc.output, "No filesystems were found for the provided parameters"); | ||
| 439 | 344 | ||
| 440 | if (strcmp(output, "") == 0 && !erronly) { | 345 | if (config.ignore_missing) { |
| 441 | preamble = ""; | 346 | none_sc = mp_set_subcheck_state(none_sc, STATE_OK); |
| 442 | xasprintf(&output, " - No disks were found for provided parameters"); | 347 | } else { |
| 348 | none_sc = mp_set_subcheck_state(none_sc, STATE_UNKNOWN); | ||
| 349 | } | ||
| 350 | mp_add_subcheck_to_check(&overall, none_sc); | ||
| 443 | } | 351 | } |
| 444 | 352 | ||
| 445 | printf("DISK %s%s%s%s%s|%s\n", state_text(result), ((erronly && result == STATE_OK)) ? "" : preamble, output, | 353 | mp_exit(overall); |
| 446 | (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf); | ||
| 447 | return result; | ||
| 448 | } | 354 | } |
| 449 | 355 | ||
| 450 | double calculate_percent(uintmax_t value, uintmax_t total) { | 356 | double calculate_percent(uintmax_t value, uintmax_t total) { |
| 451 | double pct = -1; | 357 | double pct = -1; |
| 452 | if (value <= DBL_MAX && total != 0) { | 358 | if (value <= DBL_MAX && total != 0) { |
| 453 | pct = (double)value / total * 100.0; | 359 | pct = (double)value / (double)total * 100.0; |
| 454 | } | 360 | } |
| 361 | |||
| 455 | return pct; | 362 | return pct; |
| 456 | } | 363 | } |
| 457 | 364 | ||
| 458 | /* process command-line arguments */ | 365 | /* process command-line arguments */ |
| 459 | int process_arguments(int argc, char **argv) { | 366 | check_disk_config_wrapper process_arguments(int argc, char **argv) { |
| 460 | int c; | 367 | |
| 461 | int err; | 368 | check_disk_config_wrapper result = { |
| 462 | struct parameter_list *se; | 369 | .errorcode = OK, |
| 463 | struct parameter_list *temp_list = NULL; | 370 | .config = check_disk_config_init(), |
| 464 | struct parameter_list *previous = NULL; | 371 | }; |
| 465 | struct mount_entry *me; | 372 | |
| 466 | regex_t re; | 373 | if (argc < 2) { |
| 467 | int cflags = REG_NOSUB | REG_EXTENDED; | 374 | result.errorcode = ERROR; |
| 468 | int default_cflags = cflags; | 375 | return result; |
| 469 | char errbuf[MAX_INPUT_BUFFER]; | 376 | } |
| 470 | int fnd = 0; | 377 | |
| 378 | enum { | ||
| 379 | output_format_index = CHAR_MAX + 1, | ||
| 380 | display_unit_index, | ||
| 381 | }; | ||
| 471 | 382 | ||
| 472 | int option = 0; | ||
| 473 | static struct option longopts[] = {{"timeout", required_argument, 0, 't'}, | 383 | static struct option longopts[] = {{"timeout", required_argument, 0, 't'}, |
| 474 | {"warning", required_argument, 0, 'w'}, | 384 | {"warning", required_argument, 0, 'w'}, |
| 475 | {"critical", required_argument, 0, 'c'}, | 385 | {"critical", required_argument, 0, 'c'}, |
| 476 | {"iwarning", required_argument, 0, 'W'}, | 386 | {"iwarning", required_argument, 0, 'W'}, |
| 477 | /* Dang, -C is taken. We might want to reshuffle this. */ | ||
| 478 | {"icritical", required_argument, 0, 'K'}, | 387 | {"icritical", required_argument, 0, 'K'}, |
| 479 | {"kilobytes", no_argument, 0, 'k'}, | 388 | {"kilobytes", no_argument, 0, 'k'}, |
| 480 | {"megabytes", no_argument, 0, 'm'}, | 389 | {"megabytes", no_argument, 0, 'm'}, |
| @@ -507,24 +416,43 @@ int process_arguments(int argc, char **argv) { | |||
| 507 | {"clear", no_argument, 0, 'C'}, | 416 | {"clear", no_argument, 0, 'C'}, |
| 508 | {"version", no_argument, 0, 'V'}, | 417 | {"version", no_argument, 0, 'V'}, |
| 509 | {"help", no_argument, 0, 'h'}, | 418 | {"help", no_argument, 0, 'h'}, |
| 419 | {"output-format", required_argument, 0, output_format_index}, | ||
| 420 | {"display-unit", required_argument, 0, display_unit_index}, | ||
| 510 | {0, 0, 0, 0}}; | 421 | {0, 0, 0, 0}}; |
| 511 | 422 | ||
| 512 | if (argc < 2) | 423 | for (int index = 1; index < argc; index++) { |
| 513 | return ERROR; | 424 | if (strcmp("-to", argv[index]) == 0) { |
| 425 | strcpy(argv[index], "-t"); | ||
| 426 | } | ||
| 427 | } | ||
| 428 | |||
| 429 | int cflags = REG_NOSUB | REG_EXTENDED; | ||
| 430 | int default_cflags = cflags; | ||
| 431 | char *warn_freespace_units = NULL; | ||
| 432 | char *crit_freespace_units = NULL; | ||
| 433 | char *warn_freespace_percent = NULL; | ||
| 434 | char *crit_freespace_percent = NULL; | ||
| 435 | char *warn_freeinodes_percent = NULL; | ||
| 436 | char *crit_freeinodes_percent = NULL; | ||
| 514 | 437 | ||
| 515 | np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED); | 438 | bool path_selected = false; |
| 439 | char *group = NULL; | ||
| 440 | byte_unit unit = MebiBytes_factor; | ||
| 516 | 441 | ||
| 517 | for (c = 1; c < argc; c++) | 442 | result.config.mount_list = read_file_system_list(false); |
| 518 | if (strcmp("-to", argv[c]) == 0) | ||
| 519 | strcpy(argv[c], "-t"); | ||
| 520 | 443 | ||
| 521 | while (1) { | 444 | np_add_regex(&result.config.fs_exclude_list, "iso9660", REG_EXTENDED); |
| 522 | c = getopt_long(argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEAn", longopts, &option); | ||
| 523 | 445 | ||
| 524 | if (c == -1 || c == EOF) | 446 | while (true) { |
| 447 | int option = 0; | ||
| 448 | int option_index = getopt_long( | ||
| 449 | argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEAn", longopts, &option); | ||
| 450 | |||
| 451 | if (option_index == -1 || option_index == EOF) { | ||
| 525 | break; | 452 | break; |
| 453 | } | ||
| 526 | 454 | ||
| 527 | switch (c) { | 455 | switch (option_index) { |
| 528 | case 't': /* timeout period */ | 456 | case 't': /* timeout period */ |
| 529 | if (is_integer(optarg)) { | 457 | if (is_integer(optarg)) { |
| 530 | timeout_interval = atoi(optarg); | 458 | timeout_interval = atoi(optarg); |
| @@ -555,10 +483,10 @@ int process_arguments(int argc, char **argv) { | |||
| 555 | break; | 483 | break; |
| 556 | 484 | ||
| 557 | /* Awful mistake where the range values do not make sense. Normally, | 485 | /* Awful mistake where the range values do not make sense. Normally, |
| 558 | you alert if the value is within the range, but since we are using | 486 | * you alert if the value is within the range, but since we are using |
| 559 | freespace, we have to alert if outside the range. Thus we artificially | 487 | * freespace, we have to alert if outside the range. Thus we artificially |
| 560 | force @ at the beginning of the range, so that it is backwards compatible | 488 | * force @ at the beginning of the range, so that it is backwards compatible |
| 561 | */ | 489 | */ |
| 562 | case 'c': /* critical threshold */ | 490 | case 'c': /* critical threshold */ |
| 563 | if (!is_percentage_expression(optarg) && !is_numeric(optarg)) { | 491 | if (!is_percentage_expression(optarg) && !is_numeric(optarg)) { |
| 564 | die(STATE_UNKNOWN, "Argument for --critical invalid or missing: %s\n", optarg); | 492 | die(STATE_UNKNOWN, "Argument for --critical invalid or missing: %s\n", optarg); |
| @@ -594,181 +522,193 @@ int process_arguments(int argc, char **argv) { | |||
| 594 | } | 522 | } |
| 595 | break; | 523 | break; |
| 596 | case 'u': | 524 | case 'u': |
| 597 | if (units) | ||
| 598 | free(units); | ||
| 599 | if (!strcasecmp(optarg, "bytes")) { | 525 | if (!strcasecmp(optarg, "bytes")) { |
| 600 | mult = (uintmax_t)1; | 526 | unit = Bytes_Factor; |
| 601 | units = strdup("B"); | ||
| 602 | } else if (!strcmp(optarg, "KiB")) { | 527 | } else if (!strcmp(optarg, "KiB")) { |
| 603 | mult = (uintmax_t)1024; | 528 | unit = KibiBytes_factor; |
| 604 | units = strdup("KiB"); | ||
| 605 | } else if (!strcmp(optarg, "kB")) { | 529 | } else if (!strcmp(optarg, "kB")) { |
| 606 | mult = (uintmax_t)1000; | 530 | unit = KiloBytes_factor; |
| 607 | units = strdup("kB"); | ||
| 608 | } else if (!strcmp(optarg, "MiB")) { | 531 | } else if (!strcmp(optarg, "MiB")) { |
| 609 | mult = (uintmax_t)1024 * 1024; | 532 | unit = MebiBytes_factor; |
| 610 | units = strdup("MiB"); | ||
| 611 | } else if (!strcmp(optarg, "MB")) { | 533 | } else if (!strcmp(optarg, "MB")) { |
| 612 | mult = (uintmax_t)1000 * 1000; | 534 | unit = MegaBytes_factor; |
| 613 | units = strdup("MB"); | ||
| 614 | } else if (!strcmp(optarg, "GiB")) { | 535 | } else if (!strcmp(optarg, "GiB")) { |
| 615 | mult = (uintmax_t)1024 * 1024 * 1024; | 536 | unit = GibiBytes_factor; |
| 616 | units = strdup("GiB"); | ||
| 617 | } else if (!strcmp(optarg, "GB")) { | 537 | } else if (!strcmp(optarg, "GB")) { |
| 618 | mult = (uintmax_t)1000 * 1000 * 1000; | 538 | unit = GigaBytes_factor; |
| 619 | units = strdup("GB"); | ||
| 620 | } else if (!strcmp(optarg, "TiB")) { | 539 | } else if (!strcmp(optarg, "TiB")) { |
| 621 | mult = (uintmax_t)1024 * 1024 * 1024 * 1024; | 540 | unit = TebiBytes_factor; |
| 622 | units = strdup("TiB"); | ||
| 623 | } else if (!strcmp(optarg, "TB")) { | 541 | } else if (!strcmp(optarg, "TB")) { |
| 624 | mult = (uintmax_t)1000 * 1000 * 1000 * 1000; | 542 | unit = TeraBytes_factor; |
| 625 | units = strdup("TB"); | ||
| 626 | } else if (!strcmp(optarg, "PiB")) { | 543 | } else if (!strcmp(optarg, "PiB")) { |
| 627 | mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024; | 544 | unit = PebiBytes_factor; |
| 628 | units = strdup("PiB"); | ||
| 629 | } else if (!strcmp(optarg, "PB")) { | 545 | } else if (!strcmp(optarg, "PB")) { |
| 630 | mult = (uintmax_t)1000 * 1000 * 1000 * 1000 * 1000; | 546 | unit = PetaBytes_factor; |
| 631 | units = strdup("PB"); | ||
| 632 | } else { | 547 | } else { |
| 633 | die(STATE_UNKNOWN, _("unit type %s not known\n"), optarg); | 548 | die(STATE_UNKNOWN, _("unit type %s not known\n"), optarg); |
| 634 | } | 549 | } |
| 635 | if (units == NULL) | ||
| 636 | die(STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units"); | ||
| 637 | break; | 550 | break; |
| 638 | case 'k': /* display mountpoint */ | 551 | case 'k': |
| 639 | mult = 1024; | 552 | unit = KibiBytes_factor; |
| 640 | if (units) | ||
| 641 | free(units); | ||
| 642 | units = strdup("kiB"); | ||
| 643 | break; | 553 | break; |
| 644 | case 'm': /* display mountpoint */ | 554 | case 'm': |
| 645 | mult = 1024 * 1024; | 555 | unit = MebiBytes_factor; |
| 646 | if (units) | 556 | break; |
| 647 | free(units); | 557 | case display_unit_index: |
| 648 | units = strdup("MiB"); | 558 | if (!strcasecmp(optarg, "bytes")) { |
| 559 | result.config.display_unit = Bytes; | ||
| 560 | } else if (!strcmp(optarg, "KiB")) { | ||
| 561 | result.config.display_unit = KibiBytes; | ||
| 562 | } else if (!strcmp(optarg, "kB")) { | ||
| 563 | result.config.display_unit = KiloBytes; | ||
| 564 | } else if (!strcmp(optarg, "MiB")) { | ||
| 565 | result.config.display_unit = MebiBytes; | ||
| 566 | } else if (!strcmp(optarg, "MB")) { | ||
| 567 | result.config.display_unit = MegaBytes; | ||
| 568 | } else if (!strcmp(optarg, "GiB")) { | ||
| 569 | result.config.display_unit = GibiBytes; | ||
| 570 | } else if (!strcmp(optarg, "GB")) { | ||
| 571 | result.config.display_unit = GigaBytes; | ||
| 572 | } else if (!strcmp(optarg, "TiB")) { | ||
| 573 | result.config.display_unit = TebiBytes; | ||
| 574 | } else if (!strcmp(optarg, "TB")) { | ||
| 575 | result.config.display_unit = TeraBytes; | ||
| 576 | } else if (!strcmp(optarg, "PiB")) { | ||
| 577 | result.config.display_unit = PebiBytes; | ||
| 578 | } else if (!strcmp(optarg, "PB")) { | ||
| 579 | result.config.display_unit = PetaBytes; | ||
| 580 | } else { | ||
| 581 | die(STATE_UNKNOWN, _("unit type %s not known\n"), optarg); | ||
| 582 | } | ||
| 649 | break; | 583 | break; |
| 650 | case 'L': | 584 | case 'L': |
| 651 | stat_remote_fs = 1; | 585 | result.config.stat_remote_fs = true; |
| 652 | /* fallthrough */ | 586 | /* fallthrough */ |
| 653 | case 'l': | 587 | case 'l': |
| 654 | show_local_fs = 1; | 588 | result.config.show_local_fs = true; |
| 655 | break; | 589 | break; |
| 656 | case 'P': | 590 | case 'P': |
| 657 | display_inodes_perfdata = 1; | 591 | result.config.display_inodes_perfdata = true; |
| 658 | break; | 592 | break; |
| 659 | case 'p': /* select path */ | 593 | case 'p': /* select path */ { |
| 660 | if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || | 594 | if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || |
| 661 | warn_usedspace_units || crit_usedspace_units || warn_usedspace_percent || crit_usedspace_percent || | 595 | crit_freespace_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { |
| 662 | warn_usedinodes_percent || crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { | 596 | die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), |
| 663 | die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n")); | 597 | _("Must set a threshold value before using -p\n")); |
| 664 | } | 598 | } |
| 665 | 599 | ||
| 666 | /* add parameter if not found. overwrite thresholds if path has already been added */ | 600 | /* add parameter if not found. overwrite thresholds if path has already been added */ |
| 667 | if (!(se = np_find_parameter(path_select_list, optarg))) { | 601 | parameter_list_elem *search_entry; |
| 668 | se = np_add_parameter(&path_select_list, optarg); | 602 | if (!(search_entry = mp_int_fs_list_find(result.config.path_select_list, optarg))) { |
| 669 | 603 | search_entry = mp_int_fs_list_append(&result.config.path_select_list, optarg); | |
| 670 | if (stat(optarg, &stat_buf[0]) && ignore_missing == true) { | 604 | |
| 671 | path_ignored = true; | 605 | // struct stat stat_buf = {}; |
| 672 | break; | 606 | // if (stat(optarg, &stat_buf) && result.config.ignore_missing) { |
| 673 | } | 607 | // result.config.path_ignored = true; |
| 608 | // break; | ||
| 609 | // } | ||
| 674 | } | 610 | } |
| 675 | se->group = group; | 611 | search_entry->group = group; |
| 676 | set_all_thresholds(se); | 612 | set_all_thresholds(search_entry, warn_freespace_units, crit_freespace_units, |
| 613 | warn_freespace_percent, crit_freespace_percent, | ||
| 614 | |||
| 615 | warn_freeinodes_percent, crit_freeinodes_percent); | ||
| 677 | 616 | ||
| 678 | /* With autofs, it is required to stat() the path before re-populating the mount_list */ | 617 | /* With autofs, it is required to stat() the path before re-populating the mount_list */ |
| 679 | if (!stat_path(se)) { | 618 | // if (!stat_path(se, result.config.ignore_missing)) { |
| 680 | break; | 619 | // break; |
| 681 | } | 620 | // } |
| 682 | /* NB: We can't free the old mount_list "just like that": both list pointers and struct | 621 | mp_int_fs_list_set_best_match(result.config.path_select_list, result.config.mount_list, |
| 683 | * pointers are copied around. One of the reason it wasn't done yet is that other parts | 622 | result.config.exact_match); |
| 684 | * of check_disk need the same kind of cleanup so it'd better be done as a whole */ | ||
| 685 | mount_list = read_file_system_list(0); | ||
| 686 | np_set_best_match(se, mount_list, exact_match); | ||
| 687 | 623 | ||
| 688 | path_selected = true; | 624 | path_selected = true; |
| 689 | break; | 625 | } break; |
| 690 | case 'x': /* exclude path or partition */ | 626 | case 'x': /* exclude path or partition */ |
| 691 | np_add_name(&dp_exclude_list, optarg); | 627 | np_add_name(&result.config.device_path_exclude_list, optarg); |
| 692 | break; | 628 | break; |
| 693 | case 'X': /* exclude file system type */ | 629 | case 'X': /* exclude file system type */ { |
| 694 | err = np_add_regex(&fs_exclude_list, optarg, REG_EXTENDED); | 630 | int err = np_add_regex(&result.config.fs_exclude_list, optarg, REG_EXTENDED); |
| 695 | if (err != 0) { | 631 | if (err != 0) { |
| 696 | regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); | 632 | char errbuf[MAX_INPUT_BUFFER]; |
| 697 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | 633 | regerror(err, &result.config.fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); |
| 634 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), | ||
| 635 | _("Could not compile regular expression"), errbuf); | ||
| 698 | } | 636 | } |
| 699 | break; | 637 | break; |
| 700 | case 'N': /* include file system type */ | 638 | case 'N': /* include file system type */ |
| 701 | err = np_add_regex(&fs_include_list, optarg, REG_EXTENDED); | 639 | err = np_add_regex(&result.config.fs_include_list, optarg, REG_EXTENDED); |
| 702 | if (err != 0) { | 640 | if (err != 0) { |
| 703 | regerror(err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); | 641 | char errbuf[MAX_INPUT_BUFFER]; |
| 704 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | 642 | regerror(err, &result.config.fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER); |
| 643 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), | ||
| 644 | _("Could not compile regular expression"), errbuf); | ||
| 705 | } | 645 | } |
| 706 | break; | 646 | } break; |
| 707 | case 'v': /* verbose */ | 647 | case 'v': /* verbose */ |
| 708 | verbose++; | 648 | verbose++; |
| 709 | break; | 649 | break; |
| 710 | case 'q': /* TODO: this function should eventually go away (removed 2007-09-20) */ | 650 | case 'q': /* TODO: this function should eventually go away (removed 2007-09-20) */ |
| 711 | /* verbose--; **replaced by line below**. -q was only a broken way of implementing -e */ | 651 | /* verbose--; **replaced by line below**. -q was only a broken way of implementing -e */ |
| 712 | erronly = true; | 652 | result.config.erronly = true; |
| 713 | break; | 653 | break; |
| 714 | case 'e': | 654 | case 'e': |
| 715 | erronly = true; | 655 | result.config.erronly = true; |
| 716 | break; | 656 | break; |
| 717 | case 'E': | 657 | case 'E': |
| 718 | if (path_selected) | 658 | if (path_selected) { |
| 719 | die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set -E before selecting paths\n")); | 659 | die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), |
| 720 | exact_match = true; | 660 | _("Must set -E before selecting paths\n")); |
| 661 | } | ||
| 662 | result.config.exact_match = true; | ||
| 721 | break; | 663 | break; |
| 722 | case 'f': | 664 | case 'f': |
| 723 | freespace_ignore_reserved = true; | 665 | result.config.freespace_ignore_reserved = true; |
| 724 | break; | 666 | break; |
| 725 | case 'g': | 667 | case 'g': |
| 726 | if (path_selected) | 668 | if (path_selected) { |
| 727 | die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before selecting paths\n")); | 669 | die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), |
| 670 | _("Must set group value before selecting paths\n")); | ||
| 671 | } | ||
| 728 | group = optarg; | 672 | group = optarg; |
| 729 | break; | 673 | break; |
| 730 | case 'I': | 674 | case 'I': |
| 731 | cflags |= REG_ICASE; | 675 | cflags |= REG_ICASE; |
| 732 | // Intentional fallthrough | 676 | // Intentional fallthrough |
| 733 | case 'i': | 677 | case 'i': { |
| 734 | if (!path_selected) | 678 | if (!path_selected) { |
| 735 | die(STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), | 679 | die(STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), |
| 736 | _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); | 680 | _("Paths need to be selected before using -i/-I. Use -A to select all paths " |
| 737 | err = regcomp(&re, optarg, cflags); | 681 | "explicitly")); |
| 682 | } | ||
| 683 | regex_t regex; | ||
| 684 | int err = regcomp(®ex, optarg, cflags); | ||
| 738 | if (err != 0) { | 685 | if (err != 0) { |
| 739 | regerror(err, &re, errbuf, MAX_INPUT_BUFFER); | 686 | char errbuf[MAX_INPUT_BUFFER]; |
| 740 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | 687 | regerror(err, ®ex, errbuf, MAX_INPUT_BUFFER); |
| 688 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), | ||
| 689 | _("Could not compile regular expression"), errbuf); | ||
| 741 | } | 690 | } |
| 742 | 691 | ||
| 743 | temp_list = path_select_list; | 692 | for (parameter_list_elem *elem = result.config.path_select_list.first; elem;) { |
| 693 | if (elem->best_match) { | ||
| 694 | if (np_regex_match_mount_entry(elem->best_match, ®ex)) { | ||
| 744 | 695 | ||
| 745 | previous = NULL; | 696 | if (verbose >= 3) { |
| 746 | while (temp_list) { | 697 | printf("ignoring %s matching regex\n", elem->name); |
| 747 | if (temp_list->best_match) { | 698 | } |
| 748 | if (np_regex_match_mount_entry(temp_list->best_match, &re)) { | ||
| 749 | 699 | ||
| 750 | if (verbose >= 3) | 700 | elem = mp_int_fs_list_del(&result.config.path_select_list, elem); |
| 751 | printf("ignoring %s matching regex\n", temp_list->name); | 701 | continue; |
| 752 | |||
| 753 | temp_list = np_del_parameter(temp_list, previous); | ||
| 754 | /* pointer to first element needs to be updated if first item gets deleted */ | ||
| 755 | if (previous == NULL) | ||
| 756 | path_select_list = temp_list; | ||
| 757 | } else { | ||
| 758 | previous = temp_list; | ||
| 759 | temp_list = temp_list->name_next; | ||
| 760 | } | 702 | } |
| 761 | } else { | ||
| 762 | previous = temp_list; | ||
| 763 | temp_list = temp_list->name_next; | ||
| 764 | } | 703 | } |
| 704 | |||
| 705 | elem = mp_int_fs_list_get_next(elem); | ||
| 765 | } | 706 | } |
| 766 | 707 | ||
| 767 | cflags = default_cflags; | 708 | cflags = default_cflags; |
| 768 | break; | 709 | } break; |
| 769 | |||
| 770 | case 'n': | 710 | case 'n': |
| 771 | ignore_missing = true; | 711 | result.config.ignore_missing = true; |
| 772 | break; | 712 | break; |
| 773 | case 'A': | 713 | case 'A': |
| 774 | optarg = strdup(".*"); | 714 | optarg = strdup(".*"); |
| @@ -776,80 +716,96 @@ int process_arguments(int argc, char **argv) { | |||
| 776 | case 'R': | 716 | case 'R': |
| 777 | cflags |= REG_ICASE; | 717 | cflags |= REG_ICASE; |
| 778 | // Intentional fallthrough | 718 | // Intentional fallthrough |
| 779 | case 'r': | 719 | case 'r': { |
| 780 | if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || crit_freespace_percent || | 720 | if (!(warn_freespace_units || crit_freespace_units || warn_freespace_percent || |
| 781 | warn_usedspace_units || crit_usedspace_units || warn_usedspace_percent || crit_usedspace_percent || | 721 | crit_freespace_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { |
| 782 | warn_usedinodes_percent || crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent)) { | ||
| 783 | die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), | 722 | die(STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), |
| 784 | _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n")); | 723 | _("Must set a threshold value before using -r/-R/-A " |
| 724 | "(--ereg-path/--eregi-path/--all)\n")); | ||
| 785 | } | 725 | } |
| 786 | 726 | ||
| 787 | err = regcomp(&re, optarg, cflags); | 727 | regex_t regex; |
| 728 | int err = regcomp(®ex, optarg, cflags); | ||
| 788 | if (err != 0) { | 729 | if (err != 0) { |
| 789 | regerror(err, &re, errbuf, MAX_INPUT_BUFFER); | 730 | char errbuf[MAX_INPUT_BUFFER]; |
| 790 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | 731 | regerror(err, ®ex, errbuf, MAX_INPUT_BUFFER); |
| 732 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), | ||
| 733 | _("Could not compile regular expression"), errbuf); | ||
| 791 | } | 734 | } |
| 792 | 735 | ||
| 793 | for (me = mount_list; me; me = me->me_next) { | 736 | bool found = false; |
| 794 | if (np_regex_match_mount_entry(me, &re)) { | 737 | for (struct mount_entry *me = result.config.mount_list; me; me = me->me_next) { |
| 795 | fnd = true; | 738 | if (np_regex_match_mount_entry(me, ®ex)) { |
| 796 | if (verbose >= 3) | 739 | found = true; |
| 797 | printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, optarg); | 740 | if (verbose >= 3) { |
| 741 | printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, | ||
| 742 | optarg); | ||
| 743 | } | ||
| 798 | 744 | ||
| 799 | /* add parameter if not found. overwrite thresholds if path has already been added */ | 745 | /* add parameter if not found. overwrite thresholds if path has already been |
| 800 | if (!(se = np_find_parameter(path_select_list, me->me_mountdir))) { | 746 | * added */ |
| 801 | se = np_add_parameter(&path_select_list, me->me_mountdir); | 747 | parameter_list_elem *se = NULL; |
| 748 | if (!(se = mp_int_fs_list_find(result.config.path_select_list, | ||
| 749 | me->me_mountdir))) { | ||
| 750 | se = | ||
| 751 | mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); | ||
| 802 | } | 752 | } |
| 803 | se->group = group; | 753 | se->group = group; |
| 804 | set_all_thresholds(se); | 754 | set_all_thresholds(se, warn_freespace_units, crit_freespace_units, |
| 755 | warn_freespace_percent, crit_freespace_percent, | ||
| 756 | warn_freeinodes_percent, crit_freeinodes_percent); | ||
| 805 | } | 757 | } |
| 806 | } | 758 | } |
| 807 | 759 | ||
| 808 | if (!fnd && ignore_missing == true) { | 760 | if (!found) { |
| 809 | path_ignored = true; | 761 | if (result.config.ignore_missing) { |
| 810 | path_selected = true; | 762 | result.config.path_ignored = true; |
| 811 | break; | 763 | path_selected = true; |
| 764 | break; | ||
| 765 | } | ||
| 766 | |||
| 767 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), | ||
| 768 | _("Regular expression did not match any path or disk"), optarg); | ||
| 812 | } | 769 | } |
| 813 | if (!fnd) | ||
| 814 | die(STATE_UNKNOWN, "DISK %s: %s - %s\n", _("UNKNOWN"), _("Regular expression did not match any path or disk"), optarg); | ||
| 815 | 770 | ||
| 816 | fnd = false; | ||
| 817 | path_selected = true; | 771 | path_selected = true; |
| 818 | np_set_best_match(path_select_list, mount_list, exact_match); | 772 | mp_int_fs_list_set_best_match(result.config.path_select_list, result.config.mount_list, |
| 773 | result.config.exact_match); | ||
| 819 | cflags = default_cflags; | 774 | cflags = default_cflags; |
| 820 | 775 | ||
| 821 | break; | 776 | } break; |
| 822 | case 'M': /* display mountpoint */ | 777 | case 'M': /* display mountpoint */ |
| 823 | display_mntp = true; | 778 | result.config.display_mntp = true; |
| 824 | break; | 779 | break; |
| 825 | case 'C': | 780 | case 'C': { |
| 826 | /* add all mount entries to path_select list if no partitions have been explicitly defined using -p */ | 781 | /* add all mount entries to path_select list if no partitions have been explicitly |
| 827 | if (path_selected == false) { | 782 | * defined using -p */ |
| 828 | struct parameter_list *path; | 783 | if (!path_selected) { |
| 829 | for (me = mount_list; me; me = me->me_next) { | 784 | parameter_list_elem *path; |
| 830 | if (!(path = np_find_parameter(path_select_list, me->me_mountdir))) | 785 | for (struct mount_entry *me = result.config.mount_list; me; me = me->me_next) { |
| 831 | path = np_add_parameter(&path_select_list, me->me_mountdir); | 786 | if (!(path = mp_int_fs_list_find(result.config.path_select_list, |
| 787 | me->me_mountdir))) { | ||
| 788 | path = | ||
| 789 | mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); | ||
| 790 | } | ||
| 832 | path->best_match = me; | 791 | path->best_match = me; |
| 833 | path->group = group; | 792 | path->group = group; |
| 834 | set_all_thresholds(path); | 793 | set_all_thresholds(path, warn_freespace_units, crit_freespace_units, |
| 794 | warn_freespace_percent, crit_freespace_percent, | ||
| 795 | warn_freeinodes_percent, crit_freeinodes_percent); | ||
| 835 | } | 796 | } |
| 836 | } | 797 | } |
| 798 | |||
| 837 | warn_freespace_units = NULL; | 799 | warn_freespace_units = NULL; |
| 838 | crit_freespace_units = NULL; | 800 | crit_freespace_units = NULL; |
| 839 | warn_usedspace_units = NULL; | ||
| 840 | crit_usedspace_units = NULL; | ||
| 841 | warn_freespace_percent = NULL; | 801 | warn_freespace_percent = NULL; |
| 842 | crit_freespace_percent = NULL; | 802 | crit_freespace_percent = NULL; |
| 843 | warn_usedspace_percent = NULL; | ||
| 844 | crit_usedspace_percent = NULL; | ||
| 845 | warn_usedinodes_percent = NULL; | ||
| 846 | crit_usedinodes_percent = NULL; | ||
| 847 | warn_freeinodes_percent = NULL; | 803 | warn_freeinodes_percent = NULL; |
| 848 | crit_freeinodes_percent = NULL; | 804 | crit_freeinodes_percent = NULL; |
| 849 | 805 | ||
| 850 | path_selected = false; | 806 | path_selected = false; |
| 851 | group = NULL; | 807 | group = NULL; |
| 852 | break; | 808 | } break; |
| 853 | case 'V': /* version */ | 809 | case 'V': /* version */ |
| 854 | print_revision(progname, NP_VERSION); | 810 | print_revision(progname, NP_VERSION); |
| 855 | exit(STATE_UNKNOWN); | 811 | exit(STATE_UNKNOWN); |
| @@ -858,50 +814,152 @@ int process_arguments(int argc, char **argv) { | |||
| 858 | exit(STATE_UNKNOWN); | 814 | exit(STATE_UNKNOWN); |
| 859 | case '?': /* help */ | 815 | case '?': /* help */ |
| 860 | usage(_("Unknown argument")); | 816 | usage(_("Unknown argument")); |
| 817 | case output_format_index: { | ||
| 818 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 819 | if (!parser.parsing_success) { | ||
| 820 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 821 | printf("Invalid output format: %s\n", optarg); | ||
| 822 | exit(STATE_UNKNOWN); | ||
| 823 | } | ||
| 824 | |||
| 825 | result.config.output_format_is_set = true; | ||
| 826 | result.config.output_format = parser.output_format; | ||
| 827 | break; | ||
| 828 | } | ||
| 861 | } | 829 | } |
| 862 | } | 830 | } |
| 863 | 831 | ||
| 864 | /* Support for "check_disk warn crit [fs]" with thresholds at used% level */ | 832 | /* Support for "check_disk warn crit [fs]" with thresholds at used% level */ |
| 865 | c = optind; | 833 | int index = optind; |
| 866 | if (warn_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) | 834 | |
| 867 | warn_usedspace_percent = argv[c++]; | 835 | if (argc > index && is_intnonneg(argv[index])) { |
| 836 | if (verbose > 0) { | ||
| 837 | printf("Got an positional warn threshold: %s\n", argv[index]); | ||
| 838 | } | ||
| 839 | char *range = argv[index++]; | ||
| 840 | mp_range_parsed tmp = mp_parse_range_string(range); | ||
| 841 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 842 | die(STATE_UNKNOWN, "failed to parse warning threshold"); | ||
| 843 | } | ||
| 844 | |||
| 845 | mp_range tmp_range = tmp.range; | ||
| 846 | // Invert range to use it for free instead of used | ||
| 847 | // tmp_range.alert_on_inside_range = !tmp_range.alert_on_inside_range; | ||
| 868 | 848 | ||
| 869 | if (crit_usedspace_percent == NULL && argc > c && is_intnonneg(argv[c])) | 849 | warn_freespace_percent = mp_range_to_string(tmp_range); |
| 870 | crit_usedspace_percent = argv[c++]; | ||
| 871 | 850 | ||
| 872 | if (argc > c) { | 851 | if (verbose > 0) { |
| 873 | se = np_add_parameter(&path_select_list, strdup(argv[c++])); | 852 | printf("Positional warning threshold transformed to: %s\n", warn_freespace_percent); |
| 853 | } | ||
| 854 | } | ||
| 855 | |||
| 856 | if (argc > index && is_intnonneg(argv[index])) { | ||
| 857 | if (verbose > 0) { | ||
| 858 | printf("Got an positional crit threshold: %s\n", argv[index]); | ||
| 859 | } | ||
| 860 | char *range = argv[index++]; | ||
| 861 | mp_range_parsed tmp = mp_parse_range_string(range); | ||
| 862 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 863 | die(STATE_UNKNOWN, "failed to parse warning threshold"); | ||
| 864 | } | ||
| 865 | |||
| 866 | mp_range tmp_range = tmp.range; | ||
| 867 | // Invert range to use it for free instead of used | ||
| 868 | // tmp_range.alert_on_inside_range = !tmp_range.alert_on_inside_range; | ||
| 869 | |||
| 870 | crit_freespace_percent = mp_range_to_string(tmp_range); | ||
| 871 | |||
| 872 | if (verbose > 0) { | ||
| 873 | printf("Positional critical threshold transformed to: %s\n", crit_freespace_percent); | ||
| 874 | } | ||
| 875 | } | ||
| 876 | |||
| 877 | if (argc > index) { | ||
| 878 | if (verbose > 0) { | ||
| 879 | printf("Got an positional filesystem: %s\n", argv[index]); | ||
| 880 | } | ||
| 881 | struct parameter_list *se = | ||
| 882 | mp_int_fs_list_append(&result.config.path_select_list, strdup(argv[index++])); | ||
| 874 | path_selected = true; | 883 | path_selected = true; |
| 875 | set_all_thresholds(se); | 884 | set_all_thresholds(se, warn_freespace_units, crit_freespace_units, warn_freespace_percent, |
| 885 | crit_freespace_percent, warn_freeinodes_percent, | ||
| 886 | crit_freeinodes_percent); | ||
| 876 | } | 887 | } |
| 877 | 888 | ||
| 878 | if (units == NULL) { | 889 | // If a list of paths has not been explicitly selected, find entire |
| 879 | units = strdup("MiB"); | 890 | // mount list and create list of paths |
| 880 | mult = (uintmax_t)1024 * 1024; | 891 | if (!path_selected && !result.config.path_ignored) { |
| 892 | for (struct mount_entry *me = result.config.mount_list; me; me = me->me_next) { | ||
| 893 | if (me->me_dummy != 0) { | ||
| 894 | // just do not add dummy filesystems | ||
| 895 | continue; | ||
| 896 | } | ||
| 897 | |||
| 898 | parameter_list_elem *path = NULL; | ||
| 899 | if (!(path = mp_int_fs_list_find(result.config.path_select_list, me->me_mountdir))) { | ||
| 900 | path = mp_int_fs_list_append(&result.config.path_select_list, me->me_mountdir); | ||
| 901 | } | ||
| 902 | path->best_match = me; | ||
| 903 | path->group = group; | ||
| 904 | set_all_thresholds(path, warn_freespace_units, crit_freespace_units, | ||
| 905 | warn_freespace_percent, crit_freespace_percent, | ||
| 906 | warn_freeinodes_percent, crit_freeinodes_percent); | ||
| 907 | } | ||
| 881 | } | 908 | } |
| 882 | 909 | ||
| 883 | return true; | 910 | // Set thresholds to the appropriate unit |
| 911 | for (parameter_list_elem *tmp = result.config.path_select_list.first; tmp; | ||
| 912 | tmp = mp_int_fs_list_get_next(tmp)) { | ||
| 913 | |||
| 914 | mp_perfdata_value factor = mp_create_pd_value(unit); | ||
| 915 | |||
| 916 | if (tmp->freespace_units.critical_is_set) { | ||
| 917 | tmp->freespace_units.critical = | ||
| 918 | mp_range_multiply(tmp->freespace_units.critical, factor); | ||
| 919 | } | ||
| 920 | if (tmp->freespace_units.warning_is_set) { | ||
| 921 | tmp->freespace_units.warning = mp_range_multiply(tmp->freespace_units.warning, factor); | ||
| 922 | } | ||
| 923 | } | ||
| 924 | |||
| 925 | return result; | ||
| 884 | } | 926 | } |
| 885 | 927 | ||
| 886 | void set_all_thresholds(struct parameter_list *path) { | 928 | void set_all_thresholds(parameter_list_elem *path, char *warn_freespace_units, |
| 887 | if (path->freespace_units != NULL) | 929 | char *crit_freespace_units, char *warn_freespace_percent, |
| 888 | free(path->freespace_units); | 930 | char *crit_freespace_percent, char *warn_freeinodes_percent, |
| 889 | set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units); | 931 | char *crit_freeinodes_percent) { |
| 890 | if (path->freespace_percent != NULL) | 932 | mp_range_parsed tmp; |
| 891 | free(path->freespace_percent); | 933 | |
| 892 | set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent); | 934 | if (warn_freespace_units) { |
| 893 | if (path->usedspace_units != NULL) | 935 | tmp = mp_parse_range_string(warn_freespace_units); |
| 894 | free(path->usedspace_units); | 936 | path->freespace_units = mp_thresholds_set_warn(path->freespace_units, tmp.range); |
| 895 | set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units); | 937 | } |
| 896 | if (path->usedspace_percent != NULL) | 938 | |
| 897 | free(path->usedspace_percent); | 939 | if (crit_freespace_units) { |
| 898 | set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent); | 940 | tmp = mp_parse_range_string(crit_freespace_units); |
| 899 | if (path->usedinodes_percent != NULL) | 941 | path->freespace_units = mp_thresholds_set_crit(path->freespace_units, tmp.range); |
| 900 | free(path->usedinodes_percent); | 942 | } |
| 901 | set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent); | 943 | |
| 902 | if (path->freeinodes_percent != NULL) | 944 | if (warn_freespace_percent) { |
| 903 | free(path->freeinodes_percent); | 945 | tmp = mp_parse_range_string(warn_freespace_percent); |
| 904 | set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); | 946 | path->freespace_percent = mp_thresholds_set_warn(path->freespace_percent, tmp.range); |
| 947 | } | ||
| 948 | |||
| 949 | if (crit_freespace_percent) { | ||
| 950 | tmp = mp_parse_range_string(crit_freespace_percent); | ||
| 951 | path->freespace_percent = mp_thresholds_set_crit(path->freespace_percent, tmp.range); | ||
| 952 | } | ||
| 953 | |||
| 954 | if (warn_freeinodes_percent) { | ||
| 955 | tmp = mp_parse_range_string(warn_freeinodes_percent); | ||
| 956 | path->freeinodes_percent = mp_thresholds_set_warn(path->freeinodes_percent, tmp.range); | ||
| 957 | } | ||
| 958 | |||
| 959 | if (crit_freeinodes_percent) { | ||
| 960 | tmp = mp_parse_range_string(crit_freeinodes_percent); | ||
| 961 | path->freeinodes_percent = mp_thresholds_set_crit(path->freeinodes_percent, tmp.range); | ||
| 962 | } | ||
| 905 | } | 963 | } |
| 906 | 964 | ||
| 907 | void print_help(void) { | 965 | void print_help(void) { |
| @@ -911,7 +969,8 @@ void print_help(void) { | |||
| 911 | printf(COPYRIGHT, copyright, email); | 969 | printf(COPYRIGHT, copyright, email); |
| 912 | 970 | ||
| 913 | printf("%s\n", _("This plugin checks the amount of used disk space on a mounted file system")); | 971 | printf("%s\n", _("This plugin checks the amount of used disk space on a mounted file system")); |
| 914 | printf("%s\n", _("and generates an alert if free space is less than one of the threshold values")); | 972 | printf("%s\n", |
| 973 | _("and generates an alert if free space is less than one of the threshold values")); | ||
| 915 | 974 | ||
| 916 | printf("\n\n"); | 975 | printf("\n\n"); |
| 917 | 976 | ||
| @@ -933,7 +992,8 @@ void print_help(void) { | |||
| 933 | printf(" %s\n", "-K, --icritical=PERCENT%"); | 992 | printf(" %s\n", "-K, --icritical=PERCENT%"); |
| 934 | printf(" %s\n", _("Exit with CRITICAL status if less than PERCENT of inode space is free")); | 993 | printf(" %s\n", _("Exit with CRITICAL status if less than PERCENT of inode space is free")); |
| 935 | printf(" %s\n", "-p, --path=PATH, --partition=PARTITION"); | 994 | printf(" %s\n", "-p, --path=PATH, --partition=PARTITION"); |
| 936 | printf(" %s\n", _("Mount point or block device as emitted by the mount(8) command (may be repeated)")); | 995 | printf(" %s\n", |
| 996 | _("Mount point or block device as emitted by the mount(8) command (may be repeated)")); | ||
| 937 | printf(" %s\n", "-x, --exclude_device=PATH <STRING>"); | 997 | printf(" %s\n", "-x, --exclude_device=PATH <STRING>"); |
| 938 | printf(" %s\n", _("Ignore device (only works if -p unspecified)")); | 998 | printf(" %s\n", _("Ignore device (only works if -p unspecified)")); |
| 939 | printf(" %s\n", "-C, --clear"); | 999 | printf(" %s\n", "-C, --clear"); |
| @@ -947,167 +1007,298 @@ void print_help(void) { | |||
| 947 | printf(" %s\n", "-P, --iperfdata"); | 1007 | printf(" %s\n", "-P, --iperfdata"); |
| 948 | printf(" %s\n", _("Display inode usage in perfdata")); | 1008 | printf(" %s\n", _("Display inode usage in perfdata")); |
| 949 | printf(" %s\n", "-g, --group=NAME"); | 1009 | printf(" %s\n", "-g, --group=NAME"); |
| 950 | printf(" %s\n", _("Group paths. Thresholds apply to (free-)space of all partitions together")); | 1010 | printf(" %s\n", |
| 951 | printf(" %s\n", "-k, --kilobytes"); | 1011 | _("Group paths. Thresholds apply to (free-)space of all partitions together")); |
| 952 | printf(" %s\n", _("Same as '--units kB'")); | ||
| 953 | printf(" %s\n", "-l, --local"); | 1012 | printf(" %s\n", "-l, --local"); |
| 954 | printf(" %s\n", _("Only check local filesystems")); | 1013 | printf(" %s\n", _("Only check local filesystems")); |
| 955 | printf(" %s\n", "-L, --stat-remote-fs"); | 1014 | printf(" %s\n", "-L, --stat-remote-fs"); |
| 956 | printf(" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems")); | 1015 | printf( |
| 1016 | " %s\n", | ||
| 1017 | _("Only check local filesystems against thresholds. Yet call stat on remote filesystems")); | ||
| 957 | printf(" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)")); | 1018 | printf(" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)")); |
| 958 | printf(" %s\n", "-M, --mountpoint"); | 1019 | printf(" %s\n", "-M, --mountpoint"); |
| 959 | printf(" %s\n", _("Display the (block) device instead of the mount point")); | 1020 | printf(" %s\n", _("Display the (block) device instead of the mount point")); |
| 960 | printf(" %s\n", "-m, --megabytes"); | ||
| 961 | printf(" %s\n", _("Same as '--units MB'")); | ||
| 962 | printf(" %s\n", "-A, --all"); | 1021 | printf(" %s\n", "-A, --all"); |
| 963 | printf(" %s\n", _("Explicitly select all paths. This is equivalent to -R '.*'")); | 1022 | printf(" %s\n", _("Explicitly select all paths. This is equivalent to -R '.*'")); |
| 964 | printf(" %s\n", "-R, --eregi-path=PATH, --eregi-partition=PARTITION"); | 1023 | printf(" %s\n", "-R, --eregi-path=PATH, --eregi-partition=PARTITION"); |
| 965 | printf(" %s\n", _("Case insensitive regular expression for path/partition (may be repeated)")); | 1024 | printf(" %s\n", |
| 1025 | _("Case insensitive regular expression for path/partition (may be repeated)")); | ||
| 966 | printf(" %s\n", "-r, --ereg-path=PATH, --ereg-partition=PARTITION"); | 1026 | printf(" %s\n", "-r, --ereg-path=PATH, --ereg-partition=PARTITION"); |
| 967 | printf(" %s\n", _("Regular expression for path or partition (may be repeated)")); | 1027 | printf(" %s\n", _("Regular expression for path or partition (may be repeated)")); |
| 968 | printf(" %s\n", "-I, --ignore-eregi-path=PATH, --ignore-eregi-partition=PARTITION"); | 1028 | printf(" %s\n", "-I, --ignore-eregi-path=PATH, --ignore-eregi-partition=PARTITION"); |
| 969 | printf(" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)")); | 1029 | printf(" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) " |
| 1030 | "(may be repeated)")); | ||
| 970 | printf(" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION"); | 1031 | printf(" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION"); |
| 971 | printf(" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)")); | 1032 | printf(" %s\n", |
| 1033 | _("Regular expression to ignore selected path or partition (may be repeated)")); | ||
| 972 | printf(" %s\n", "-n, --ignore-missing"); | 1034 | printf(" %s\n", "-n, --ignore-missing"); |
| 973 | printf(" %s\n", _("Return OK if no filesystem matches, filesystem does not exist or is inaccessible.")); | 1035 | printf(" %s\n", |
| 1036 | _("Return OK if no filesystem matches, filesystem does not exist or is inaccessible.")); | ||
| 974 | printf(" %s\n", _("(Provide this option before -p / -r / --ereg-path if used)")); | 1037 | printf(" %s\n", _("(Provide this option before -p / -r / --ereg-path if used)")); |
| 975 | printf(UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 1038 | printf(UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 976 | printf(" %s\n", "-u, --units=STRING"); | 1039 | printf(" %s\n", "-u, --units=STRING"); |
| 977 | printf(" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); | 1040 | printf(" %s\n", _("Select the unit used for the absolute value thresholds")); |
| 1041 | printf(" %s\n", _("Choose one of \"bytes\", \"KiB\", \"kB\", \"MiB\", \"MB\", \"GiB\", " | ||
| 1042 | "\"GB\", \"TiB\", \"TB\", \"PiB\", \"PB\" (default: MiB)")); | ||
| 1043 | printf(" %s\n", "-k, --kilobytes"); | ||
| 1044 | printf(" %s\n", _("Same as '--units kB'")); | ||
| 1045 | printf(" %s\n", "--display-unit"); | ||
| 1046 | printf(" %s\n", _("Select the unit used for in the output")); | ||
| 1047 | printf(" %s\n", _("Choose one of \"bytes\", \"KiB\", \"kB\", \"MiB\", \"MB\", \"GiB\", " | ||
| 1048 | "\"GB\", \"TiB\", \"TB\", \"PiB\", \"PB\" (default: MiB)")); | ||
| 1049 | printf(" %s\n", "-m, --megabytes"); | ||
| 1050 | printf(" %s\n", _("Same as '--units MB'")); | ||
| 978 | printf(UT_VERBOSE); | 1051 | printf(UT_VERBOSE); |
| 979 | printf(" %s\n", "-X, --exclude-type=TYPE_REGEX"); | 1052 | printf(" %s\n", "-X, --exclude-type=TYPE_REGEX"); |
| 980 | printf(" %s\n", _("Ignore all filesystems of types matching given regex(7) (may be repeated)")); | 1053 | printf(" %s\n", |
| 1054 | _("Ignore all filesystems of types matching given regex(7) (may be repeated)")); | ||
| 981 | printf(" %s\n", "-N, --include-type=TYPE_REGEX"); | 1055 | printf(" %s\n", "-N, --include-type=TYPE_REGEX"); |
| 982 | printf(" %s\n", _("Check only filesystems where the type matches this given regex(7) (may be repeated)")); | 1056 | printf( |
| 1057 | " %s\n", | ||
| 1058 | _("Check only filesystems where the type matches this given regex(7) (may be repeated)")); | ||
| 1059 | printf(UT_OUTPUT_FORMAT); | ||
| 983 | 1060 | ||
| 984 | printf("\n"); | 1061 | printf("\n"); |
| 985 | printf("%s\n", _("General usage hints:")); | 1062 | printf("%s\n", _("General usage hints:")); |
| 986 | printf(" %s\n", _("- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the same as")); | 1063 | printf( |
| 1064 | " %s\n", | ||
| 1065 | _("- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the same as")); | ||
| 987 | printf(" %s\n", _("\"-w 5 -c 1 -p /bar w6 -c2 -p /foo\".")); | 1066 | printf(" %s\n", _("\"-w 5 -c 1 -p /bar w6 -c2 -p /foo\".")); |
| 988 | printf(" %s\n", _("- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} {thresholds b} ...\"")); | 1067 | printf(" %s\n", _("- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} " |
| 1068 | "{thresholds b} ...\"")); | ||
| 989 | 1069 | ||
| 990 | printf("\n"); | 1070 | printf("\n"); |
| 991 | printf("%s\n", _("Examples:")); | 1071 | printf("%s\n", _("Examples:")); |
| 992 | printf(" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /"); | 1072 | printf(" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /"); |
| 993 | printf(" %s\n\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB")); | 1073 | printf(" %s\n\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB")); |
| 994 | printf(" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -g sidDATA -r '^/oracle/SID/data.*$'"); | 1074 | printf(" %s\n", |
| 995 | printf(" %s\n", _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex")); | 1075 | "check_disk -w 100 -c 50 -C -w 1000 -c 500 -g sidDATA -r '^/oracle/SID/data.*$'"); |
| 996 | printf(" %s\n\n", _("are grouped which means the freespace thresholds are applied to all disks together")); | 1076 | printf( |
| 1077 | " %s\n", | ||
| 1078 | _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex")); | ||
| 1079 | printf(" %s\n\n", | ||
| 1080 | _("are grouped which means the freespace thresholds are applied to all disks together")); | ||
| 997 | printf(" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar"); | 1081 | printf(" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar"); |
| 998 | printf(" %s\n", _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M")); | 1082 | printf(" %s\n", |
| 1083 | _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M")); | ||
| 999 | 1084 | ||
| 1000 | printf(UT_SUPPORT); | 1085 | printf(UT_SUPPORT); |
| 1001 | } | 1086 | } |
| 1002 | 1087 | ||
| 1003 | void print_usage(void) { | 1088 | void print_usage(void) { |
| 1004 | printf("%s\n", _("Usage:")); | 1089 | printf("%s\n", _("Usage:")); |
| 1005 | printf(" %s {-w absolute_limit |-w percentage_limit%% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit%% | -K " | 1090 | printf(" %s {-w absolute_limit |-w percentage_limit%% | -W inode_percentage_limit } {-c " |
| 1091 | "absolute_limit|-c percentage_limit%% | -K " | ||
| 1006 | "inode_percentage_limit } {-p path | -x device}\n", | 1092 | "inode_percentage_limit } {-p path | -x device}\n", |
| 1007 | progname); | 1093 | progname); |
| 1008 | printf("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); | 1094 | printf("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); |
| 1009 | printf("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n"); | 1095 | printf("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n"); |
| 1010 | } | 1096 | } |
| 1011 | 1097 | ||
| 1012 | bool stat_path(struct parameter_list *p) { | 1098 | bool stat_path(parameter_list_elem *parameters, bool ignore_missing) { |
| 1013 | /* Stat entry to check that dir exists and is accessible */ | 1099 | /* Stat entry to check that dir exists and is accessible */ |
| 1014 | if (verbose >= 3) | 1100 | if (verbose >= 3) { |
| 1015 | printf("calling stat on %s\n", p->name); | 1101 | printf("calling stat on %s\n", parameters->name); |
| 1016 | if (stat(p->name, &stat_buf[0])) { | 1102 | } |
| 1017 | if (verbose >= 3) | 1103 | |
| 1018 | printf("stat failed on %s\n", p->name); | 1104 | struct stat stat_buf = {0}; |
| 1019 | if (ignore_missing == true) { | 1105 | if (stat(parameters->name, &stat_buf)) { |
| 1106 | if (verbose >= 3) { | ||
| 1107 | printf("stat failed on %s\n", parameters->name); | ||
| 1108 | } | ||
| 1109 | if (ignore_missing) { | ||
| 1020 | return false; | 1110 | return false; |
| 1021 | } | 1111 | } |
| 1022 | printf("DISK %s - ", _("CRITICAL")); | 1112 | printf("DISK %s - ", _("CRITICAL")); |
| 1023 | die(STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno)); | 1113 | die(STATE_CRITICAL, _("%s %s: %s\n"), parameters->name, _("is not accessible"), |
| 1114 | strerror(errno)); | ||
| 1024 | } | 1115 | } |
| 1116 | |||
| 1025 | return true; | 1117 | return true; |
| 1026 | } | 1118 | } |
| 1027 | 1119 | ||
| 1028 | void get_stats(struct parameter_list *p, struct fs_usage *fsp) { | 1120 | static parameter_list_elem get_path_stats(parameter_list_elem parameters, const struct fs_usage fsp, |
| 1029 | struct parameter_list *p_list; | 1121 | bool freespace_ignore_reserved) { |
| 1030 | struct fs_usage tmpfsp; | 1122 | uintmax_t available = fsp.fsu_bavail; |
| 1031 | int first = 1; | 1123 | uintmax_t available_to_root = fsp.fsu_bfree; |
| 1124 | uintmax_t used = fsp.fsu_blocks - fsp.fsu_bfree; | ||
| 1125 | uintmax_t total; | ||
| 1032 | 1126 | ||
| 1033 | if (p->group == NULL) { | ||
| 1034 | get_path_stats(p, fsp); | ||
| 1035 | } else { | ||
| 1036 | /* find all group members */ | ||
| 1037 | for (p_list = path_select_list; p_list; p_list = p_list->name_next) { | ||
| 1038 | #ifdef __CYGWIN__ | ||
| 1039 | if (strncmp(p_list->name, "/cygdrive/", 10) != 0) | ||
| 1040 | continue; | ||
| 1041 | #endif | ||
| 1042 | if (p_list->group && !(strcmp(p_list->group, p->group))) { | ||
| 1043 | if (!stat_path(p_list)) | ||
| 1044 | continue; | ||
| 1045 | get_fs_usage(p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); | ||
| 1046 | get_path_stats(p_list, &tmpfsp); | ||
| 1047 | if (verbose >= 3) | ||
| 1048 | printf("Group %s: adding %lu blocks sized %lu, (%s) used_units=%lu free_units=%lu total_units=%lu mult=%lu\n", | ||
| 1049 | p_list->group, tmpfsp.fsu_blocks, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, | ||
| 1050 | p_list->dfree_units, p_list->dtotal_units, mult); | ||
| 1051 | |||
| 1052 | /* prevent counting the first FS of a group twice since its parameter_list entry | ||
| 1053 | * is used to carry the information of all file systems of the entire group */ | ||
| 1054 | if (!first) { | ||
| 1055 | p->total += p_list->total; | ||
| 1056 | p->available += p_list->available; | ||
| 1057 | p->available_to_root += p_list->available_to_root; | ||
| 1058 | p->used += p_list->used; | ||
| 1059 | |||
| 1060 | p->dused_units += p_list->dused_units; | ||
| 1061 | p->dfree_units += p_list->dfree_units; | ||
| 1062 | p->dtotal_units += p_list->dtotal_units; | ||
| 1063 | p->inodes_total += p_list->inodes_total; | ||
| 1064 | p->inodes_free += p_list->inodes_free; | ||
| 1065 | p->inodes_free_to_root += p_list->inodes_free_to_root; | ||
| 1066 | p->inodes_used += p_list->inodes_used; | ||
| 1067 | } | ||
| 1068 | first = 0; | ||
| 1069 | } | ||
| 1070 | if (verbose >= 3) | ||
| 1071 | printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n", p->group, | ||
| 1072 | p->dused_units, p->dfree_units, p->dtotal_units, tmpfsp.fsu_blocksize, mult); | ||
| 1073 | } | ||
| 1074 | /* modify devname and mountdir for output */ | ||
| 1075 | p->best_match->me_mountdir = p->best_match->me_devname = p->group; | ||
| 1076 | } | ||
| 1077 | /* finally calculate percentages for either plain FS or summed up group */ | ||
| 1078 | p->dused_pct = calculate_percent(p->used, p->used + p->available); /* used + available can never be > uintmax */ | ||
| 1079 | p->dfree_pct = 100.0 - p->dused_pct; | ||
| 1080 | p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total); | ||
| 1081 | p->dfree_inodes_percent = 100 - p->dused_inodes_percent; | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | void get_path_stats(struct parameter_list *p, struct fs_usage *fsp) { | ||
| 1085 | p->available = fsp->fsu_bavail; | ||
| 1086 | p->available_to_root = fsp->fsu_bfree; | ||
| 1087 | p->used = fsp->fsu_blocks - fsp->fsu_bfree; | ||
| 1088 | if (freespace_ignore_reserved) { | 1127 | if (freespace_ignore_reserved) { |
| 1089 | /* option activated : we subtract the root-reserved space from the total */ | 1128 | /* option activated : we subtract the root-reserved space from the total */ |
| 1090 | p->total = fsp->fsu_blocks - p->available_to_root + p->available; | 1129 | total = fsp.fsu_blocks - available_to_root + available; |
| 1091 | } else { | 1130 | } else { |
| 1092 | /* default behaviour : take all the blocks into account */ | 1131 | /* default behaviour : take all the blocks into account */ |
| 1093 | p->total = fsp->fsu_blocks; | 1132 | total = fsp.fsu_blocks; |
| 1094 | } | 1133 | } |
| 1095 | 1134 | ||
| 1096 | p->dused_units = p->used * fsp->fsu_blocksize / mult; | 1135 | parameters.used_bytes = used * fsp.fsu_blocksize; |
| 1097 | p->dfree_units = p->available * fsp->fsu_blocksize / mult; | 1136 | parameters.free_bytes = available * fsp.fsu_blocksize; |
| 1098 | p->dtotal_units = p->total * fsp->fsu_blocksize / mult; | 1137 | parameters.total_bytes = total * fsp.fsu_blocksize; |
| 1138 | |||
| 1099 | /* Free file nodes. Not sure the workaround is required, but in case...*/ | 1139 | /* Free file nodes. Not sure the workaround is required, but in case...*/ |
| 1100 | p->inodes_free = fsp->fsu_ffree; | 1140 | parameters.inodes_free = fsp.fsu_ffree; |
| 1101 | p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ | 1141 | parameters.inodes_free_to_root = fsp.fsu_ffree; /* Free file nodes for root. */ |
| 1102 | p->inodes_used = fsp->fsu_files - fsp->fsu_ffree; | 1142 | parameters.inodes_used = fsp.fsu_files - fsp.fsu_ffree; |
| 1143 | |||
| 1103 | if (freespace_ignore_reserved) { | 1144 | if (freespace_ignore_reserved) { |
| 1104 | /* option activated : we subtract the root-reserved inodes from the total */ | 1145 | /* option activated : we subtract the root-reserved inodes from the total */ |
| 1105 | /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */ | 1146 | /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */ |
| 1106 | /* for others, fsp->fsu_ffree == fsp->fsu_favail */ | 1147 | /* for others, fsp->fsu_ffree == fsp->fsu_favail */ |
| 1107 | p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free; | 1148 | parameters.inodes_total = |
| 1149 | fsp.fsu_files - parameters.inodes_free_to_root + parameters.inodes_free; | ||
| 1108 | } else { | 1150 | } else { |
| 1109 | /* default behaviour : take all the inodes into account */ | 1151 | /* default behaviour : take all the inodes into account */ |
| 1110 | p->inodes_total = fsp->fsu_files; | 1152 | parameters.inodes_total = fsp.fsu_files; |
| 1111 | } | 1153 | } |
| 1112 | np_add_name(&seen, p->best_match->me_mountdir); | 1154 | |
| 1155 | return parameters; | ||
| 1156 | } | ||
| 1157 | |||
| 1158 | mp_subcheck evaluate_filesystem(measurement_unit measurement_unit, bool display_inodes_perfdata, | ||
| 1159 | byte_unit unit) { | ||
| 1160 | mp_subcheck result = mp_subcheck_init(); | ||
| 1161 | result = mp_set_subcheck_default_state(result, STATE_UNKNOWN); | ||
| 1162 | xasprintf(&result.output, "%s", measurement_unit.name); | ||
| 1163 | |||
| 1164 | if (!measurement_unit.is_group && measurement_unit.filesystem_type) { | ||
| 1165 | xasprintf(&result.output, "%s (%s)", result.output, measurement_unit.filesystem_type); | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | /* Threshold comparisons */ | ||
| 1169 | |||
| 1170 | // =============================== | ||
| 1171 | // Free space absolute values test | ||
| 1172 | mp_subcheck freespace_bytes_sc = mp_subcheck_init(); | ||
| 1173 | freespace_bytes_sc = mp_set_subcheck_default_state(freespace_bytes_sc, STATE_OK); | ||
| 1174 | |||
| 1175 | if (unit != Humanized) { | ||
| 1176 | xasprintf(&freespace_bytes_sc.output, "Free space absolute: %ju%s (of %ju%s)", | ||
| 1177 | (uintmax_t)(measurement_unit.free_bytes / unit), get_unit_string(unit), | ||
| 1178 | (uintmax_t)(measurement_unit.total_bytes / unit), get_unit_string(unit)); | ||
| 1179 | } else { | ||
| 1180 | xasprintf(&freespace_bytes_sc.output, "Free space absolute: %s (of %s)", | ||
| 1181 | humanize_byte_value(measurement_unit.free_bytes, false), | ||
| 1182 | humanize_byte_value((unsigned long long)measurement_unit.total_bytes, false)); | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | mp_perfdata used_space = perfdata_init(); | ||
| 1186 | used_space.label = measurement_unit.name; | ||
| 1187 | used_space.value = mp_create_pd_value(measurement_unit.free_bytes); | ||
| 1188 | used_space = mp_set_pd_max_value(used_space, mp_create_pd_value(measurement_unit.total_bytes)); | ||
| 1189 | used_space = mp_set_pd_min_value(used_space, mp_create_pd_value(0)); | ||
| 1190 | used_space.uom = "B"; | ||
| 1191 | used_space = mp_pd_set_thresholds(used_space, measurement_unit.freespace_bytes_thresholds); | ||
| 1192 | freespace_bytes_sc = mp_set_subcheck_state(freespace_bytes_sc, mp_get_pd_status(used_space)); | ||
| 1193 | |||
| 1194 | // special case for absolute space thresholds here: | ||
| 1195 | // if absolute values are not set, compute the thresholds from percentage thresholds | ||
| 1196 | mp_thresholds temp_thlds = measurement_unit.freespace_bytes_thresholds; | ||
| 1197 | if (!temp_thlds.critical_is_set && | ||
| 1198 | measurement_unit.freespace_percent_thresholds.critical_is_set) { | ||
| 1199 | mp_range tmp_range = measurement_unit.freespace_percent_thresholds.critical; | ||
| 1200 | |||
| 1201 | if (!tmp_range.end_infinity) { | ||
| 1202 | tmp_range.end = mp_create_pd_value(mp_get_pd_value(tmp_range.end) / 100 * | ||
| 1203 | measurement_unit.total_bytes); | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | if (!tmp_range.start_infinity) { | ||
| 1207 | tmp_range.start = mp_create_pd_value(mp_get_pd_value(tmp_range.start) / 100 * | ||
| 1208 | measurement_unit.total_bytes); | ||
| 1209 | } | ||
| 1210 | measurement_unit.freespace_bytes_thresholds = | ||
| 1211 | mp_thresholds_set_crit(measurement_unit.freespace_bytes_thresholds, tmp_range); | ||
| 1212 | used_space = mp_pd_set_thresholds(used_space, measurement_unit.freespace_bytes_thresholds); | ||
| 1213 | } | ||
| 1214 | |||
| 1215 | if (!temp_thlds.warning_is_set && | ||
| 1216 | measurement_unit.freespace_percent_thresholds.warning_is_set) { | ||
| 1217 | mp_range tmp_range = measurement_unit.freespace_percent_thresholds.warning; | ||
| 1218 | if (!tmp_range.end_infinity) { | ||
| 1219 | tmp_range.end = mp_create_pd_value(mp_get_pd_value(tmp_range.end) / 100 * | ||
| 1220 | measurement_unit.total_bytes); | ||
| 1221 | } | ||
| 1222 | if (!tmp_range.start_infinity) { | ||
| 1223 | tmp_range.start = mp_create_pd_value(mp_get_pd_value(tmp_range.start) / 100 * | ||
| 1224 | measurement_unit.total_bytes); | ||
| 1225 | } | ||
| 1226 | measurement_unit.freespace_bytes_thresholds = | ||
| 1227 | mp_thresholds_set_warn(measurement_unit.freespace_bytes_thresholds, tmp_range); | ||
| 1228 | used_space = mp_pd_set_thresholds(used_space, measurement_unit.freespace_bytes_thresholds); | ||
| 1229 | } | ||
| 1230 | |||
| 1231 | mp_add_perfdata_to_subcheck(&freespace_bytes_sc, used_space); | ||
| 1232 | mp_add_subcheck_to_subcheck(&result, freespace_bytes_sc); | ||
| 1233 | |||
| 1234 | // ========================== | ||
| 1235 | // Free space percentage test | ||
| 1236 | mp_subcheck freespace_percent_sc = mp_subcheck_init(); | ||
| 1237 | freespace_percent_sc = mp_set_subcheck_default_state(freespace_percent_sc, STATE_OK); | ||
| 1238 | |||
| 1239 | double free_percentage = | ||
| 1240 | calculate_percent(measurement_unit.free_bytes, measurement_unit.total_bytes); | ||
| 1241 | xasprintf(&freespace_percent_sc.output, "Free space percentage: %g%%", free_percentage); | ||
| 1242 | |||
| 1243 | // Using perfdata here just to get to the test result | ||
| 1244 | mp_perfdata free_space_percent_pd = perfdata_init(); | ||
| 1245 | free_space_percent_pd.value = mp_create_pd_value(free_percentage); | ||
| 1246 | free_space_percent_pd = | ||
| 1247 | mp_pd_set_thresholds(free_space_percent_pd, measurement_unit.freespace_percent_thresholds); | ||
| 1248 | |||
| 1249 | freespace_percent_sc = | ||
| 1250 | mp_set_subcheck_state(freespace_percent_sc, mp_get_pd_status(free_space_percent_pd)); | ||
| 1251 | mp_add_subcheck_to_subcheck(&result, freespace_percent_sc); | ||
| 1252 | |||
| 1253 | // ================ | ||
| 1254 | // Free inodes test | ||
| 1255 | // Only ever useful if the number of inodes is static (e.g. ext4), | ||
| 1256 | // not when it is dynamic (e.g btrfs) | ||
| 1257 | // Assumption: if the total number of inodes == 0, we have such a case and just skip the test | ||
| 1258 | if (measurement_unit.inodes_total > 0) { | ||
| 1259 | mp_subcheck freeindodes_percent_sc = mp_subcheck_init(); | ||
| 1260 | freeindodes_percent_sc = mp_set_subcheck_default_state(freeindodes_percent_sc, STATE_OK); | ||
| 1261 | |||
| 1262 | double free_inode_percentage = | ||
| 1263 | calculate_percent(measurement_unit.inodes_free, measurement_unit.inodes_total); | ||
| 1264 | |||
| 1265 | if (verbose > 0) { | ||
| 1266 | printf("free inode percentage computed: %g\n", free_inode_percentage); | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | xasprintf(&freeindodes_percent_sc.output, "Inodes free: %g%% (%ju of %ju)", | ||
| 1270 | free_inode_percentage, measurement_unit.inodes_free, | ||
| 1271 | measurement_unit.inodes_total); | ||
| 1272 | |||
| 1273 | mp_perfdata inodes_pd = perfdata_init(); | ||
| 1274 | xasprintf(&inodes_pd.label, "%s (inodes)", measurement_unit.name); | ||
| 1275 | inodes_pd = mp_set_pd_value(inodes_pd, measurement_unit.inodes_used); | ||
| 1276 | inodes_pd = | ||
| 1277 | mp_set_pd_max_value(inodes_pd, mp_create_pd_value(measurement_unit.inodes_total)); | ||
| 1278 | inodes_pd = mp_set_pd_min_value(inodes_pd, mp_create_pd_value(0)); | ||
| 1279 | |||
| 1280 | mp_thresholds absolut_inode_thresholds = measurement_unit.freeinodes_percent_thresholds; | ||
| 1281 | |||
| 1282 | if (absolut_inode_thresholds.critical_is_set) { | ||
| 1283 | absolut_inode_thresholds.critical = | ||
| 1284 | mp_range_multiply(absolut_inode_thresholds.critical, | ||
| 1285 | mp_create_pd_value(measurement_unit.inodes_total / 100)); | ||
| 1286 | } | ||
| 1287 | if (absolut_inode_thresholds.warning_is_set) { | ||
| 1288 | absolut_inode_thresholds.warning = | ||
| 1289 | mp_range_multiply(absolut_inode_thresholds.warning, | ||
| 1290 | mp_create_pd_value(measurement_unit.inodes_total / 100)); | ||
| 1291 | } | ||
| 1292 | |||
| 1293 | inodes_pd = mp_pd_set_thresholds(inodes_pd, absolut_inode_thresholds); | ||
| 1294 | |||
| 1295 | freeindodes_percent_sc = | ||
| 1296 | mp_set_subcheck_state(freeindodes_percent_sc, mp_get_pd_status(inodes_pd)); | ||
| 1297 | if (display_inodes_perfdata) { | ||
| 1298 | mp_add_perfdata_to_subcheck(&freeindodes_percent_sc, inodes_pd); | ||
| 1299 | } | ||
| 1300 | mp_add_subcheck_to_subcheck(&result, freeindodes_percent_sc); | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | return result; | ||
| 1113 | } | 1304 | } |
diff --git a/plugins/check_disk.d/utils_disk.c b/plugins/check_disk.d/utils_disk.c new file mode 100644 index 00000000..0b89018d --- /dev/null +++ b/plugins/check_disk.d/utils_disk.c | |||
| @@ -0,0 +1,528 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Library for check_disk | ||
| 4 | * | ||
| 5 | * License: GPL | ||
| 6 | * Copyright (c) 1999-2024 Monitoring Plugins Development Team | ||
| 7 | * | ||
| 8 | * Description: | ||
| 9 | * | ||
| 10 | * This file contains utilities for check_disk. These are tested by libtap | ||
| 11 | * | ||
| 12 | * | ||
| 13 | * This program is free software: you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation, either version 3 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 25 | * | ||
| 26 | * | ||
| 27 | *****************************************************************************/ | ||
| 28 | |||
| 29 | #include "../common.h" | ||
| 30 | #include "utils_disk.h" | ||
| 31 | #include "../../gl/fsusage.h" | ||
| 32 | #include "../../lib/thresholds.h" | ||
| 33 | #include "../../lib/states.h" | ||
| 34 | #include <stdint.h> | ||
| 35 | #include <stdio.h> | ||
| 36 | #include <string.h> | ||
| 37 | #include <assert.h> | ||
| 38 | |||
| 39 | void np_add_name(struct name_list **list, const char *name) { | ||
| 40 | struct name_list *new_entry; | ||
| 41 | new_entry = (struct name_list *)malloc(sizeof *new_entry); | ||
| 42 | new_entry->name = (char *)name; | ||
| 43 | new_entry->next = *list; | ||
| 44 | *list = new_entry; | ||
| 45 | } | ||
| 46 | |||
| 47 | /* @brief Initialises a new regex at the begin of list via regcomp(3) | ||
| 48 | * | ||
| 49 | * @details if the regex fails to compile the error code of regcomp(3) is returned | ||
| 50 | * and list is not modified, otherwise list is modified to point to the new | ||
| 51 | * element | ||
| 52 | * @param list Pointer to a linked list of regex_list elements | ||
| 53 | * @param regex the string containing the regex which should be inserted into the list | ||
| 54 | * @param clags the cflags parameter for regcomp(3) | ||
| 55 | */ | ||
| 56 | int np_add_regex(struct regex_list **list, const char *regex, int cflags) { | ||
| 57 | struct regex_list *new_entry = (struct regex_list *)malloc(sizeof *new_entry); | ||
| 58 | |||
| 59 | if (new_entry == NULL) { | ||
| 60 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 61 | } | ||
| 62 | |||
| 63 | int regcomp_result = regcomp(&new_entry->regex, regex, cflags); | ||
| 64 | |||
| 65 | if (!regcomp_result) { | ||
| 66 | // regcomp succeeded | ||
| 67 | new_entry->next = *list; | ||
| 68 | *list = new_entry; | ||
| 69 | |||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | // regcomp failed | ||
| 73 | free(new_entry); | ||
| 74 | |||
| 75 | return regcomp_result; | ||
| 76 | } | ||
| 77 | |||
| 78 | parameter_list_elem parameter_list_init(const char *name) { | ||
| 79 | parameter_list_elem result = { | ||
| 80 | .name = strdup(name), | ||
| 81 | .best_match = NULL, | ||
| 82 | |||
| 83 | .freespace_units = mp_thresholds_init(), | ||
| 84 | .freespace_percent = mp_thresholds_init(), | ||
| 85 | .freeinodes_percent = mp_thresholds_init(), | ||
| 86 | |||
| 87 | .group = NULL, | ||
| 88 | |||
| 89 | .inodes_total = 0, | ||
| 90 | .inodes_free = 0, | ||
| 91 | .inodes_free_to_root = 0, | ||
| 92 | .inodes_used = 0, | ||
| 93 | |||
| 94 | .used_bytes = 0, | ||
| 95 | .free_bytes = 0, | ||
| 96 | .total_bytes = 0, | ||
| 97 | |||
| 98 | .next = NULL, | ||
| 99 | .prev = NULL, | ||
| 100 | }; | ||
| 101 | return result; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* Returns true if name is in list */ | ||
| 105 | bool np_find_name(struct name_list *list, const char *name) { | ||
| 106 | if (list == NULL || name == NULL) { | ||
| 107 | return false; | ||
| 108 | } | ||
| 109 | for (struct name_list *iterator = list; iterator; iterator = iterator->next) { | ||
| 110 | if (!strcmp(name, iterator->name)) { | ||
| 111 | return true; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | return false; | ||
| 115 | } | ||
| 116 | |||
| 117 | /* Returns true if name is in list */ | ||
| 118 | bool np_find_regmatch(struct regex_list *list, const char *name) { | ||
| 119 | if (name == NULL) { | ||
| 120 | return false; | ||
| 121 | } | ||
| 122 | |||
| 123 | size_t len = strlen(name); | ||
| 124 | |||
| 125 | for (; list; list = list->next) { | ||
| 126 | /* Emulate a full match as if surrounded with ^( )$ | ||
| 127 | by checking whether the match spans the whole name */ | ||
| 128 | regmatch_t dummy_match; | ||
| 129 | if (!regexec(&list->regex, name, 1, &dummy_match, 0) && dummy_match.rm_so == 0 && | ||
| 130 | dummy_match.rm_eo == len) { | ||
| 131 | return true; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | return false; | ||
| 136 | } | ||
| 137 | |||
| 138 | bool np_seen_name(struct name_list *list, const char *name) { | ||
| 139 | for (struct name_list *iterator = list; iterator; iterator = iterator->next) { | ||
| 140 | if (!strcmp(iterator->name, name)) { | ||
| 141 | return true; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | return false; | ||
| 145 | } | ||
| 146 | |||
| 147 | bool np_regex_match_mount_entry(struct mount_entry *me, regex_t *re) { | ||
| 148 | return ((regexec(re, me->me_devname, (size_t)0, NULL, 0) == 0) || | ||
| 149 | (regexec(re, me->me_mountdir, (size_t)0, NULL, 0) == 0)); | ||
| 150 | } | ||
| 151 | |||
| 152 | check_disk_config check_disk_config_init() { | ||
| 153 | check_disk_config tmp = { | ||
| 154 | .erronly = false, | ||
| 155 | .display_mntp = false, | ||
| 156 | .show_local_fs = false, | ||
| 157 | .stat_remote_fs = false, | ||
| 158 | .display_inodes_perfdata = false, | ||
| 159 | |||
| 160 | .exact_match = false, | ||
| 161 | .freespace_ignore_reserved = false, | ||
| 162 | |||
| 163 | .ignore_missing = false, | ||
| 164 | .path_ignored = false, | ||
| 165 | |||
| 166 | // FS Filters | ||
| 167 | .fs_exclude_list = NULL, | ||
| 168 | .fs_include_list = NULL, | ||
| 169 | .device_path_exclude_list = NULL, | ||
| 170 | |||
| 171 | // Actual filesystems paths to investigate | ||
| 172 | .path_select_list = filesystem_list_init(), | ||
| 173 | |||
| 174 | .mount_list = NULL, | ||
| 175 | .seen = NULL, | ||
| 176 | |||
| 177 | .display_unit = Humanized, | ||
| 178 | // .unit = MebiBytes, | ||
| 179 | |||
| 180 | .output_format_is_set = false, | ||
| 181 | }; | ||
| 182 | return tmp; | ||
| 183 | } | ||
| 184 | |||
| 185 | char *get_unit_string(byte_unit_enum unit) { | ||
| 186 | switch (unit) { | ||
| 187 | case Bytes: | ||
| 188 | return "Bytes"; | ||
| 189 | case KibiBytes: | ||
| 190 | return "KiB"; | ||
| 191 | case MebiBytes: | ||
| 192 | return "MiB"; | ||
| 193 | case GibiBytes: | ||
| 194 | return "GiB"; | ||
| 195 | case TebiBytes: | ||
| 196 | return "TiB"; | ||
| 197 | case PebiBytes: | ||
| 198 | return "PiB"; | ||
| 199 | case ExbiBytes: | ||
| 200 | return "EiB"; | ||
| 201 | case KiloBytes: | ||
| 202 | return "KB"; | ||
| 203 | case MegaBytes: | ||
| 204 | return "MB"; | ||
| 205 | case GigaBytes: | ||
| 206 | return "GB"; | ||
| 207 | case TeraBytes: | ||
| 208 | return "TB"; | ||
| 209 | case PetaBytes: | ||
| 210 | return "PB"; | ||
| 211 | case ExaBytes: | ||
| 212 | return "EB"; | ||
| 213 | default: | ||
| 214 | assert(false); | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | measurement_unit measurement_unit_init() { | ||
| 219 | measurement_unit tmp = { | ||
| 220 | .name = NULL, | ||
| 221 | .filesystem_type = NULL, | ||
| 222 | .is_group = false, | ||
| 223 | |||
| 224 | .freeinodes_percent_thresholds = mp_thresholds_init(), | ||
| 225 | .freespace_percent_thresholds = mp_thresholds_init(), | ||
| 226 | .freespace_bytes_thresholds = mp_thresholds_init(), | ||
| 227 | |||
| 228 | .free_bytes = 0, | ||
| 229 | .used_bytes = 0, | ||
| 230 | .total_bytes = 0, | ||
| 231 | |||
| 232 | .inodes_total = 0, | ||
| 233 | .inodes_free = 0, | ||
| 234 | .inodes_free_to_root = 0, | ||
| 235 | .inodes_used = 0, | ||
| 236 | }; | ||
| 237 | return tmp; | ||
| 238 | } | ||
| 239 | |||
| 240 | // Add a given element to the list, memory for the new element is freshly allocated | ||
| 241 | // Returns a pointer to new element | ||
| 242 | measurement_unit_list *add_measurement_list(measurement_unit_list *list, measurement_unit elem) { | ||
| 243 | // find last element | ||
| 244 | measurement_unit_list *new = NULL; | ||
| 245 | if (list == NULL) { | ||
| 246 | new = calloc(1, sizeof(measurement_unit_list)); | ||
| 247 | if (new == NULL) { | ||
| 248 | die(STATE_UNKNOWN, _("allocation failed")); | ||
| 249 | } | ||
| 250 | } else { | ||
| 251 | measurement_unit_list *list_elem = list; | ||
| 252 | while (list_elem->next != NULL) { | ||
| 253 | list_elem = list_elem->next; | ||
| 254 | } | ||
| 255 | |||
| 256 | new = calloc(1, sizeof(measurement_unit_list)); | ||
| 257 | if (new == NULL) { | ||
| 258 | die(STATE_UNKNOWN, _("allocation failed")); | ||
| 259 | } | ||
| 260 | |||
| 261 | list_elem->next = new; | ||
| 262 | } | ||
| 263 | |||
| 264 | new->unit = elem; | ||
| 265 | new->next = NULL; | ||
| 266 | return new; | ||
| 267 | } | ||
| 268 | |||
| 269 | measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, | ||
| 270 | parameter_list_elem filesystem) { | ||
| 271 | |||
| 272 | unit.free_bytes += filesystem.free_bytes; | ||
| 273 | unit.used_bytes += filesystem.used_bytes; | ||
| 274 | unit.total_bytes += filesystem.total_bytes; | ||
| 275 | |||
| 276 | unit.inodes_total += filesystem.inodes_total; | ||
| 277 | unit.inodes_free += filesystem.inodes_free; | ||
| 278 | unit.inodes_free_to_root += filesystem.inodes_free_to_root; | ||
| 279 | unit.inodes_used += filesystem.inodes_used; | ||
| 280 | return unit; | ||
| 281 | } | ||
| 282 | |||
| 283 | measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, | ||
| 284 | bool display_mntp) { | ||
| 285 | measurement_unit result = measurement_unit_init(); | ||
| 286 | if (!display_mntp) { | ||
| 287 | result.name = strdup(filesystem.best_match->me_mountdir); | ||
| 288 | } else { | ||
| 289 | result.name = strdup(filesystem.best_match->me_devname); | ||
| 290 | } | ||
| 291 | |||
| 292 | if (filesystem.group) { | ||
| 293 | result.is_group = true; | ||
| 294 | } else { | ||
| 295 | result.is_group = false; | ||
| 296 | if (filesystem.best_match) { | ||
| 297 | result.filesystem_type = filesystem.best_match->me_type; | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | result.freeinodes_percent_thresholds = filesystem.freeinodes_percent; | ||
| 302 | result.freespace_percent_thresholds = filesystem.freespace_percent; | ||
| 303 | result.freespace_bytes_thresholds = filesystem.freespace_units; | ||
| 304 | result.free_bytes = filesystem.free_bytes; | ||
| 305 | result.total_bytes = filesystem.total_bytes; | ||
| 306 | result.used_bytes = filesystem.used_bytes; | ||
| 307 | result.inodes_total = filesystem.inodes_total; | ||
| 308 | result.inodes_used = filesystem.inodes_used; | ||
| 309 | result.inodes_free = filesystem.inodes_free; | ||
| 310 | result.inodes_free_to_root = filesystem.inodes_free_to_root; | ||
| 311 | return result; | ||
| 312 | } | ||
| 313 | |||
| 314 | #define RANDOM_STRING_LENGTH 64 | ||
| 315 | |||
| 316 | char *humanize_byte_value(unsigned long long value, bool use_si_units) { | ||
| 317 | // Idea: A reasonable output should have at most 3 orders of magnitude | ||
| 318 | // before the decimal separator | ||
| 319 | // 353GiB is ok, 2444 GiB should be 2.386 TiB | ||
| 320 | char *result = calloc(RANDOM_STRING_LENGTH, sizeof(char)); | ||
| 321 | if (result == NULL) { | ||
| 322 | die(STATE_UNKNOWN, _("allocation failed")); | ||
| 323 | } | ||
| 324 | const byte_unit KibiBytes_factor = 1024; | ||
| 325 | const byte_unit MebiBytes_factor = 1048576; | ||
| 326 | const byte_unit GibiBytes_factor = 1073741824; | ||
| 327 | const byte_unit TebiBytes_factor = 1099511627776; | ||
| 328 | const byte_unit PebiBytes_factor = 1125899906842624; | ||
| 329 | const byte_unit ExbiBytes_factor = 1152921504606846976; | ||
| 330 | const byte_unit KiloBytes_factor = 1000; | ||
| 331 | const byte_unit MegaBytes_factor = 1000000; | ||
| 332 | const byte_unit GigaBytes_factor = 1000000000; | ||
| 333 | const byte_unit TeraBytes_factor = 1000000000000; | ||
| 334 | const byte_unit PetaBytes_factor = 1000000000000000; | ||
| 335 | const byte_unit ExaBytes_factor = 1000000000000000000; | ||
| 336 | |||
| 337 | if (use_si_units) { | ||
| 338 | // SI units, powers of 10 | ||
| 339 | if (value < KiloBytes_factor) { | ||
| 340 | snprintf(result, RANDOM_STRING_LENGTH, "%llu B", value); | ||
| 341 | } else if (value < MegaBytes_factor) { | ||
| 342 | snprintf(result, RANDOM_STRING_LENGTH, "%llu KB", value / KiloBytes_factor); | ||
| 343 | } else if (value < GigaBytes_factor) { | ||
| 344 | snprintf(result, RANDOM_STRING_LENGTH, "%llu MB", value / MegaBytes_factor); | ||
| 345 | } else if (value < TeraBytes_factor) { | ||
| 346 | snprintf(result, RANDOM_STRING_LENGTH, "%llu GB", value / GigaBytes_factor); | ||
| 347 | } else if (value < PetaBytes_factor) { | ||
| 348 | snprintf(result, RANDOM_STRING_LENGTH, "%llu TB", value / TeraBytes_factor); | ||
| 349 | } else if (value < ExaBytes_factor) { | ||
| 350 | snprintf(result, RANDOM_STRING_LENGTH, "%llu PB", value / PetaBytes_factor); | ||
| 351 | } else { | ||
| 352 | snprintf(result, RANDOM_STRING_LENGTH, "%llu EB", value / ExaBytes_factor); | ||
| 353 | } | ||
| 354 | } else { | ||
| 355 | // IEC units, powers of 2 ^ 10 | ||
| 356 | if (value < KibiBytes_factor) { | ||
| 357 | snprintf(result, RANDOM_STRING_LENGTH, "%llu B", value); | ||
| 358 | } else if (value < MebiBytes_factor) { | ||
| 359 | snprintf(result, RANDOM_STRING_LENGTH, "%llu KiB", value / KibiBytes_factor); | ||
| 360 | } else if (value < GibiBytes_factor) { | ||
| 361 | snprintf(result, RANDOM_STRING_LENGTH, "%llu MiB", value / MebiBytes_factor); | ||
| 362 | } else if (value < TebiBytes_factor) { | ||
| 363 | snprintf(result, RANDOM_STRING_LENGTH, "%llu GiB", value / GibiBytes_factor); | ||
| 364 | } else if (value < PebiBytes_factor) { | ||
| 365 | snprintf(result, RANDOM_STRING_LENGTH, "%llu TiB", value / TebiBytes_factor); | ||
| 366 | } else if (value < ExbiBytes_factor) { | ||
| 367 | snprintf(result, RANDOM_STRING_LENGTH, "%llu PiB", value / PebiBytes_factor); | ||
| 368 | } else { | ||
| 369 | snprintf(result, RANDOM_STRING_LENGTH, "%llu EiB", value / ExbiBytes_factor); | ||
| 370 | } | ||
| 371 | } | ||
| 372 | |||
| 373 | return result; | ||
| 374 | } | ||
| 375 | |||
| 376 | filesystem_list filesystem_list_init() { | ||
| 377 | filesystem_list tmp = { | ||
| 378 | .length = 0, | ||
| 379 | .first = NULL, | ||
| 380 | }; | ||
| 381 | return tmp; | ||
| 382 | } | ||
| 383 | |||
| 384 | parameter_list_elem *mp_int_fs_list_append(filesystem_list *list, const char *name) { | ||
| 385 | parameter_list_elem *current = list->first; | ||
| 386 | parameter_list_elem *new_path = (struct parameter_list *)malloc(sizeof *new_path); | ||
| 387 | *new_path = parameter_list_init(name); | ||
| 388 | |||
| 389 | if (current == NULL) { | ||
| 390 | list->first = new_path; | ||
| 391 | new_path->prev = NULL; | ||
| 392 | list->length = 1; | ||
| 393 | } else { | ||
| 394 | while (current->next) { | ||
| 395 | current = current->next; | ||
| 396 | } | ||
| 397 | current->next = new_path; | ||
| 398 | new_path->prev = current; | ||
| 399 | list->length++; | ||
| 400 | } | ||
| 401 | return new_path; | ||
| 402 | } | ||
| 403 | |||
| 404 | parameter_list_elem *mp_int_fs_list_find(filesystem_list list, const char *name) { | ||
| 405 | if (list.length == 0) { | ||
| 406 | return NULL; | ||
| 407 | } | ||
| 408 | |||
| 409 | for (parameter_list_elem *temp_list = list.first; temp_list; temp_list = temp_list->next) { | ||
| 410 | if (!strcmp(temp_list->name, name)) { | ||
| 411 | return temp_list; | ||
| 412 | } | ||
| 413 | } | ||
| 414 | |||
| 415 | return NULL; | ||
| 416 | } | ||
| 417 | |||
| 418 | parameter_list_elem *mp_int_fs_list_del(filesystem_list *list, parameter_list_elem *item) { | ||
| 419 | if (list->length == 0) { | ||
| 420 | return NULL; | ||
| 421 | } | ||
| 422 | |||
| 423 | if (item == NULL) { | ||
| 424 | // Got NULL for item, interpret this as "delete first element" | ||
| 425 | // as a kind of compatibility to the old function | ||
| 426 | item = list->first; | ||
| 427 | } | ||
| 428 | |||
| 429 | if (list->first == item) { | ||
| 430 | list->length--; | ||
| 431 | |||
| 432 | list->first = item->next; | ||
| 433 | if (list->first) { | ||
| 434 | list->first->prev = NULL; | ||
| 435 | } | ||
| 436 | return list->first; | ||
| 437 | } | ||
| 438 | |||
| 439 | // Was not the first element, continue | ||
| 440 | parameter_list_elem *prev = list->first; | ||
| 441 | parameter_list_elem *current = list->first->next; | ||
| 442 | |||
| 443 | while (current != item && current != NULL) { | ||
| 444 | prev = current; | ||
| 445 | current = current->next; | ||
| 446 | } | ||
| 447 | |||
| 448 | if (current == NULL) { | ||
| 449 | // didn't find that element .... | ||
| 450 | return NULL; | ||
| 451 | } | ||
| 452 | |||
| 453 | // remove the element | ||
| 454 | parameter_list_elem *next = current->next; | ||
| 455 | prev->next = next; | ||
| 456 | list->length--; | ||
| 457 | if (next) { | ||
| 458 | next->prev = prev; | ||
| 459 | } | ||
| 460 | |||
| 461 | if (item->name) { | ||
| 462 | free(item->name); | ||
| 463 | } | ||
| 464 | free(item); | ||
| 465 | |||
| 466 | return next; | ||
| 467 | } | ||
| 468 | |||
| 469 | parameter_list_elem *mp_int_fs_list_get_next(parameter_list_elem *current) { | ||
| 470 | if (!current) { | ||
| 471 | return NULL; | ||
| 472 | } | ||
| 473 | return current->next; | ||
| 474 | } | ||
| 475 | |||
| 476 | void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, | ||
| 477 | bool exact) { | ||
| 478 | for (parameter_list_elem *elem = list.first; elem; elem = mp_int_fs_list_get_next(elem)) { | ||
| 479 | if (!elem->best_match) { | ||
| 480 | size_t name_len = strlen(elem->name); | ||
| 481 | struct mount_entry *best_match = NULL; | ||
| 482 | |||
| 483 | /* set best match if path name exactly matches a mounted device name */ | ||
| 484 | for (struct mount_entry *mount_entry = mount_list; mount_entry; | ||
| 485 | mount_entry = mount_entry->me_next) { | ||
| 486 | if (strcmp(mount_entry->me_devname, elem->name) == 0) { | ||
| 487 | struct fs_usage fsp; | ||
| 488 | if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= | ||
| 489 | 0) { | ||
| 490 | best_match = mount_entry; | ||
| 491 | } | ||
| 492 | } | ||
| 493 | } | ||
| 494 | |||
| 495 | /* set best match by directory name if no match was found by devname */ | ||
| 496 | if (!best_match) { | ||
| 497 | size_t best_match_len = 0; | ||
| 498 | for (struct mount_entry *mount_entry = mount_list; mount_entry; | ||
| 499 | mount_entry = mount_entry->me_next) { | ||
| 500 | size_t len = strlen(mount_entry->me_mountdir); | ||
| 501 | |||
| 502 | if ((!exact && | ||
| 503 | (best_match_len <= len && len <= name_len && | ||
| 504 | (len == 1 || strncmp(mount_entry->me_mountdir, elem->name, len) == 0))) || | ||
| 505 | (exact && strcmp(mount_entry->me_mountdir, elem->name) == 0)) { | ||
| 506 | struct fs_usage fsp; | ||
| 507 | |||
| 508 | if (get_fs_usage(mount_entry->me_mountdir, mount_entry->me_devname, &fsp) >= | ||
| 509 | 0) { | ||
| 510 | best_match = mount_entry; | ||
| 511 | best_match_len = len; | ||
| 512 | } | ||
| 513 | } | ||
| 514 | } | ||
| 515 | } | ||
| 516 | |||
| 517 | if (best_match) { | ||
| 518 | elem->best_match = best_match; | ||
| 519 | } else { | ||
| 520 | elem->best_match = | ||
| 521 | NULL; /* Not sure why this is needed as it should be null on initialisation */ | ||
| 522 | } | ||
| 523 | |||
| 524 | // No filesystem without a mount_entry! | ||
| 525 | // assert(elem->best_match != NULL); | ||
| 526 | } | ||
| 527 | } | ||
| 528 | } | ||
diff --git a/plugins/check_disk.d/utils_disk.h b/plugins/check_disk.d/utils_disk.h new file mode 100644 index 00000000..c96d4296 --- /dev/null +++ b/plugins/check_disk.d/utils_disk.h | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | #pragma once | ||
| 2 | /* Header file for utils_disk */ | ||
| 3 | |||
| 4 | #include "../../config.h" | ||
| 5 | #include "../../gl/mountlist.h" | ||
| 6 | #include "../../lib/utils_base.h" | ||
| 7 | #include "../../lib/output.h" | ||
| 8 | #include "regex.h" | ||
| 9 | #include <stdint.h> | ||
| 10 | |||
| 11 | typedef unsigned long long byte_unit; | ||
| 12 | |||
| 13 | typedef enum { | ||
| 14 | Humanized, | ||
| 15 | Bytes, | ||
| 16 | KibiBytes, | ||
| 17 | MebiBytes, | ||
| 18 | GibiBytes, | ||
| 19 | TebiBytes, | ||
| 20 | PebiBytes, | ||
| 21 | ExbiBytes, | ||
| 22 | KiloBytes, | ||
| 23 | MegaBytes, | ||
| 24 | GigaBytes, | ||
| 25 | TeraBytes, | ||
| 26 | PetaBytes, | ||
| 27 | ExaBytes, | ||
| 28 | } byte_unit_enum; | ||
| 29 | |||
| 30 | typedef struct name_list string_list; | ||
| 31 | struct name_list { | ||
| 32 | char *name; | ||
| 33 | string_list *next; | ||
| 34 | }; | ||
| 35 | |||
| 36 | struct regex_list { | ||
| 37 | regex_t regex; | ||
| 38 | struct regex_list *next; | ||
| 39 | }; | ||
| 40 | |||
| 41 | typedef struct parameter_list parameter_list_elem; | ||
| 42 | struct parameter_list { | ||
| 43 | char *name; | ||
| 44 | char *group; | ||
| 45 | |||
| 46 | mp_thresholds freespace_units; | ||
| 47 | mp_thresholds freespace_percent; | ||
| 48 | mp_thresholds freeinodes_percent; | ||
| 49 | |||
| 50 | struct mount_entry *best_match; | ||
| 51 | |||
| 52 | uintmax_t inodes_free_to_root; | ||
| 53 | uintmax_t inodes_free; | ||
| 54 | uintmax_t inodes_used; | ||
| 55 | uintmax_t inodes_total; | ||
| 56 | |||
| 57 | uint64_t used_bytes; | ||
| 58 | uint64_t free_bytes; | ||
| 59 | uint64_t total_bytes; | ||
| 60 | |||
| 61 | parameter_list_elem *next; | ||
| 62 | parameter_list_elem *prev; | ||
| 63 | }; | ||
| 64 | |||
| 65 | typedef struct { | ||
| 66 | size_t length; | ||
| 67 | parameter_list_elem *first; | ||
| 68 | } filesystem_list; | ||
| 69 | |||
| 70 | filesystem_list filesystem_list_init(); | ||
| 71 | |||
| 72 | typedef struct { | ||
| 73 | char *name; | ||
| 74 | char *filesystem_type; | ||
| 75 | bool is_group; | ||
| 76 | |||
| 77 | mp_thresholds freespace_bytes_thresholds; | ||
| 78 | mp_thresholds freespace_percent_thresholds; | ||
| 79 | mp_thresholds freeinodes_percent_thresholds; | ||
| 80 | |||
| 81 | uintmax_t inodes_free_to_root; | ||
| 82 | uintmax_t inodes_free; | ||
| 83 | uintmax_t inodes_used; | ||
| 84 | uintmax_t inodes_total; | ||
| 85 | |||
| 86 | uintmax_t used_bytes; | ||
| 87 | uintmax_t free_bytes; | ||
| 88 | uintmax_t total_bytes; | ||
| 89 | } measurement_unit; | ||
| 90 | |||
| 91 | typedef struct measurement_unit_list measurement_unit_list; | ||
| 92 | struct measurement_unit_list { | ||
| 93 | measurement_unit unit; | ||
| 94 | measurement_unit_list *next; | ||
| 95 | }; | ||
| 96 | |||
| 97 | typedef struct { | ||
| 98 | // Output options | ||
| 99 | bool erronly; | ||
| 100 | bool display_mntp; | ||
| 101 | /* show only local filesystems. */ | ||
| 102 | bool show_local_fs; | ||
| 103 | /* show only local filesystems but call stat() on remote ones. */ | ||
| 104 | bool stat_remote_fs; | ||
| 105 | bool display_inodes_perfdata; | ||
| 106 | |||
| 107 | bool exact_match; | ||
| 108 | bool freespace_ignore_reserved; | ||
| 109 | |||
| 110 | bool ignore_missing; | ||
| 111 | bool path_ignored; | ||
| 112 | |||
| 113 | /* Linked list of filesystem types to omit. | ||
| 114 | If the list is empty, don't exclude any types. */ | ||
| 115 | struct regex_list *fs_exclude_list; | ||
| 116 | /* Linked list of filesystem types to check. | ||
| 117 | If the list is empty, include all types. */ | ||
| 118 | struct regex_list *fs_include_list; | ||
| 119 | struct name_list *device_path_exclude_list; | ||
| 120 | filesystem_list path_select_list; | ||
| 121 | /* Linked list of mounted filesystems. */ | ||
| 122 | struct mount_entry *mount_list; | ||
| 123 | struct name_list *seen; | ||
| 124 | |||
| 125 | byte_unit_enum display_unit; | ||
| 126 | // byte_unit unit; | ||
| 127 | |||
| 128 | bool output_format_is_set; | ||
| 129 | mp_output_format output_format; | ||
| 130 | } check_disk_config; | ||
| 131 | |||
| 132 | void np_add_name(struct name_list **list, const char *name); | ||
| 133 | bool np_find_name(struct name_list *list, const char *name); | ||
| 134 | bool np_seen_name(struct name_list *list, const char *name); | ||
| 135 | int np_add_regex(struct regex_list **list, const char *regex, int cflags); | ||
| 136 | bool np_find_regmatch(struct regex_list *list, const char *name); | ||
| 137 | |||
| 138 | parameter_list_elem parameter_list_init(const char *); | ||
| 139 | |||
| 140 | parameter_list_elem *mp_int_fs_list_append(filesystem_list *list, const char *name); | ||
| 141 | parameter_list_elem *mp_int_fs_list_find(filesystem_list list, const char *name); | ||
| 142 | parameter_list_elem *mp_int_fs_list_del(filesystem_list *list, parameter_list_elem *item); | ||
| 143 | parameter_list_elem *mp_int_fs_list_get_next(parameter_list_elem *current); | ||
| 144 | void mp_int_fs_list_set_best_match(filesystem_list list, struct mount_entry *mount_list, | ||
| 145 | bool exact); | ||
| 146 | |||
| 147 | measurement_unit measurement_unit_init(); | ||
| 148 | measurement_unit_list *add_measurement_list(measurement_unit_list *list, measurement_unit elem); | ||
| 149 | measurement_unit add_filesystem_to_measurement_unit(measurement_unit unit, | ||
| 150 | parameter_list_elem filesystem); | ||
| 151 | measurement_unit create_measurement_unit_from_filesystem(parameter_list_elem filesystem, | ||
| 152 | bool display_mntp); | ||
| 153 | |||
| 154 | int search_parameter_list(parameter_list_elem *list, const char *name); | ||
| 155 | bool np_regex_match_mount_entry(struct mount_entry *, regex_t *); | ||
| 156 | |||
| 157 | char *get_unit_string(byte_unit_enum); | ||
| 158 | check_disk_config check_disk_config_init(); | ||
| 159 | |||
| 160 | char *humanize_byte_value(unsigned long long value, bool use_si_units); | ||
diff --git a/plugins/check_dns.c b/plugins/check_dns.c index 95f33083..56f91dae 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c | |||
| @@ -48,7 +48,8 @@ typedef struct { | |||
| 48 | } check_dns_config_wrapper; | 48 | } check_dns_config_wrapper; |
| 49 | static check_dns_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | 49 | static check_dns_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 50 | static check_dns_config_wrapper validate_arguments(check_dns_config_wrapper /*config_wrapper*/); | 50 | static check_dns_config_wrapper validate_arguments(check_dns_config_wrapper /*config_wrapper*/); |
| 51 | static mp_state_enum error_scan(char * /*input_buffer*/, bool * /*is_nxdomain*/, const char /*dns_server*/[ADDRESS_LENGTH]); | 51 | static mp_state_enum error_scan(char * /*input_buffer*/, bool * /*is_nxdomain*/, |
| 52 | const char /*dns_server*/[ADDRESS_LENGTH]); | ||
| 52 | static bool ip_match_cidr(const char * /*addr*/, const char * /*cidr_ro*/); | 53 | static bool ip_match_cidr(const char * /*addr*/, const char * /*cidr_ro*/); |
| 53 | static unsigned long ip2long(const char * /*src*/); | 54 | static unsigned long ip2long(const char * /*src*/); |
| 54 | static void print_help(void); | 55 | static void print_help(void); |
| @@ -127,7 +128,8 @@ int main(int argc, char **argv) { | |||
| 127 | puts(chld_out.line[i]); | 128 | puts(chld_out.line[i]); |
| 128 | } | 129 | } |
| 129 | 130 | ||
| 130 | if (strcasestr(chld_out.line[i], ".in-addr.arpa") || strcasestr(chld_out.line[i], ".ip6.arpa")) { | 131 | if (strcasestr(chld_out.line[i], ".in-addr.arpa") || |
| 132 | strcasestr(chld_out.line[i], ".ip6.arpa")) { | ||
| 131 | if ((strstr(chld_out.line[i], "canonical name = ") != NULL)) { | 133 | if ((strstr(chld_out.line[i], "canonical name = ") != NULL)) { |
| 132 | continue; | 134 | continue; |
| 133 | } | 135 | } |
| @@ -145,7 +147,8 @@ int main(int argc, char **argv) { | |||
| 145 | if (strstr(chld_out.line[i], "Server:") && strlen(config.dns_server) > 0) { | 147 | if (strstr(chld_out.line[i], "Server:") && strlen(config.dns_server) > 0) { |
| 146 | char *temp_buffer = strchr(chld_out.line[i], ':'); | 148 | char *temp_buffer = strchr(chld_out.line[i], ':'); |
| 147 | if (temp_buffer == NULL) { | 149 | if (temp_buffer == NULL) { |
| 148 | die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Server line\n"), NSLOOKUP_COMMAND); | 150 | die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Server line\n"), |
| 151 | NSLOOKUP_COMMAND); | ||
| 149 | } | 152 | } |
| 150 | 153 | ||
| 151 | temp_buffer++; | 154 | temp_buffer++; |
| @@ -157,21 +160,25 @@ int main(int argc, char **argv) { | |||
| 157 | 160 | ||
| 158 | strip(temp_buffer); | 161 | strip(temp_buffer); |
| 159 | if (strlen(temp_buffer) == 0) { | 162 | if (strlen(temp_buffer) == 0) { |
| 160 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty server string\n"), NSLOOKUP_COMMAND); | 163 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty server string\n"), |
| 164 | NSLOOKUP_COMMAND); | ||
| 161 | } | 165 | } |
| 162 | 166 | ||
| 163 | if (strcmp(temp_buffer, config.dns_server) != 0) { | 167 | if (strcmp(temp_buffer, config.dns_server) != 0) { |
| 164 | die(STATE_CRITICAL, _("DNS CRITICAL - No response from DNS %s\n"), config.dns_server); | 168 | die(STATE_CRITICAL, _("DNS CRITICAL - No response from DNS %s\n"), |
| 169 | config.dns_server); | ||
| 165 | } | 170 | } |
| 166 | } | 171 | } |
| 167 | 172 | ||
| 168 | /* the server is responding, we just got the host name... */ | 173 | /* the server is responding, we just got the host name... */ |
| 169 | if (strstr(chld_out.line[i], "Name:")) { | 174 | if (strstr(chld_out.line[i], "Name:")) { |
| 170 | parse_address = true; | 175 | parse_address = true; |
| 171 | } else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) { | 176 | } else if (parse_address && (strstr(chld_out.line[i], "Address:") || |
| 177 | strstr(chld_out.line[i], "Addresses:"))) { | ||
| 172 | char *temp_buffer = strchr(chld_out.line[i], ':'); | 178 | char *temp_buffer = strchr(chld_out.line[i], ':'); |
| 173 | if (temp_buffer == NULL) { | 179 | if (temp_buffer == NULL) { |
| 174 | die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Address line\n"), NSLOOKUP_COMMAND); | 180 | die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Address line\n"), |
| 181 | NSLOOKUP_COMMAND); | ||
| 175 | } | 182 | } |
| 176 | 183 | ||
| 177 | temp_buffer++; | 184 | temp_buffer++; |
| @@ -183,7 +190,8 @@ int main(int argc, char **argv) { | |||
| 183 | 190 | ||
| 184 | strip(temp_buffer); | 191 | strip(temp_buffer); |
| 185 | if (strlen(temp_buffer) == 0) { | 192 | if (strlen(temp_buffer) == 0) { |
| 186 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty host name string\n"), NSLOOKUP_COMMAND); | 193 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty host name string\n"), |
| 194 | NSLOOKUP_COMMAND); | ||
| 187 | } | 195 | } |
| 188 | 196 | ||
| 189 | addresses[n_addresses++] = strdup(temp_buffer); | 197 | addresses[n_addresses++] = strdup(temp_buffer); |
| @@ -209,7 +217,8 @@ int main(int argc, char **argv) { | |||
| 209 | } | 217 | } |
| 210 | 218 | ||
| 211 | if (error_scan(chld_err.line[i], &is_nxdomain, config.dns_server) != STATE_OK) { | 219 | if (error_scan(chld_err.line[i], &is_nxdomain, config.dns_server) != STATE_OK) { |
| 212 | result = max_state(result, error_scan(chld_err.line[i], &is_nxdomain, config.dns_server)); | 220 | result = |
| 221 | max_state(result, error_scan(chld_err.line[i], &is_nxdomain, config.dns_server)); | ||
| 213 | msg = strchr(input_buffer, ':'); | 222 | msg = strchr(input_buffer, ':'); |
| 214 | if (msg) { | 223 | if (msg) { |
| 215 | msg++; | 224 | msg++; |
| @@ -242,7 +251,8 @@ int main(int argc, char **argv) { | |||
| 242 | } | 251 | } |
| 243 | *adrp = 0; | 252 | *adrp = 0; |
| 244 | } else { | 253 | } else { |
| 245 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), NSLOOKUP_COMMAND); | 254 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), |
| 255 | NSLOOKUP_COMMAND); | ||
| 246 | } | 256 | } |
| 247 | 257 | ||
| 248 | /* compare to expected address */ | 258 | /* compare to expected address */ |
| @@ -255,7 +265,8 @@ int main(int argc, char **argv) { | |||
| 255 | for (size_t i = 0; i < config.expected_address_cnt; i++) { | 265 | for (size_t i = 0; i < config.expected_address_cnt; i++) { |
| 256 | /* check if we get a match on 'raw' ip or cidr */ | 266 | /* check if we get a match on 'raw' ip or cidr */ |
| 257 | for (size_t j = 0; j < n_addresses; j++) { | 267 | for (size_t j = 0; j < n_addresses; j++) { |
| 258 | if (strcmp(addresses[j], config.expected_address[i]) == 0 || ip_match_cidr(addresses[j], config.expected_address[i])) { | 268 | if (strcmp(addresses[j], config.expected_address[i]) == 0 || |
| 269 | ip_match_cidr(addresses[j], config.expected_address[i])) { | ||
| 259 | result = STATE_OK; | 270 | result = STATE_OK; |
| 260 | addr_match &= ~(1 << j); | 271 | addr_match &= ~(1 << j); |
| 261 | expect_match &= ~(1 << i); | 272 | expect_match &= ~(1 << i); |
| @@ -279,7 +290,8 @@ int main(int argc, char **argv) { | |||
| 279 | if (config.expect_nxdomain) { | 290 | if (config.expect_nxdomain) { |
| 280 | if (!is_nxdomain) { | 291 | if (!is_nxdomain) { |
| 281 | result = STATE_CRITICAL; | 292 | result = STATE_CRITICAL; |
| 282 | xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), config.query_address, address); | 293 | xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), config.query_address, |
| 294 | address); | ||
| 283 | } else { | 295 | } else { |
| 284 | if (address != NULL) { | 296 | if (address != NULL) { |
| 285 | free(address); | 297 | free(address); |
| @@ -291,7 +303,8 @@ int main(int argc, char **argv) { | |||
| 291 | /* check if authoritative */ | 303 | /* check if authoritative */ |
| 292 | if (result == STATE_OK && config.expect_authority && non_authoritative) { | 304 | if (result == STATE_OK && config.expect_authority && non_authoritative) { |
| 293 | result = STATE_CRITICAL; | 305 | result = STATE_CRITICAL; |
| 294 | xasprintf(&msg, _("server %s is not authoritative for %s"), config.dns_server, config.query_address); | 306 | xasprintf(&msg, _("server %s is not authoritative for %s"), config.dns_server, |
| 307 | config.query_address); | ||
| 295 | } | 308 | } |
| 296 | 309 | ||
| 297 | long microsec = deltime(tv); | 310 | long microsec = deltime(tv); |
| @@ -306,24 +319,36 @@ int main(int argc, char **argv) { | |||
| 306 | } else if (result == STATE_CRITICAL) { | 319 | } else if (result == STATE_CRITICAL) { |
| 307 | printf("DNS %s: ", _("CRITICAL")); | 320 | printf("DNS %s: ", _("CRITICAL")); |
| 308 | } | 321 | } |
| 309 | printf(ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time); | 322 | printf(ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), |
| 323 | elapsed_time); | ||
| 310 | printf(_(". %s returns %s"), config.query_address, address); | 324 | printf(_(". %s returns %s"), config.query_address, address); |
| 311 | if ((config.time_thresholds->warning != NULL) && (config.time_thresholds->critical != NULL)) { | 325 | if ((config.time_thresholds->warning != NULL) && |
| 312 | printf("|%s\n", fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, true, | 326 | (config.time_thresholds->critical != NULL)) { |
| 327 | printf("|%s\n", | ||
| 328 | fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, | ||
| 329 | true, config.time_thresholds->critical->end, true, 0, false, 0)); | ||
| 330 | } else if ((config.time_thresholds->warning == NULL) && | ||
| 331 | (config.time_thresholds->critical != NULL)) { | ||
| 332 | printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, true, | ||
| 313 | config.time_thresholds->critical->end, true, 0, false, 0)); | 333 | config.time_thresholds->critical->end, true, 0, false, 0)); |
| 314 | } else if ((config.time_thresholds->warning == NULL) && (config.time_thresholds->critical != NULL)) { | 334 | } else if ((config.time_thresholds->warning != NULL) && |
| 315 | printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, true, config.time_thresholds->critical->end, true, 0, false, 0)); | 335 | (config.time_thresholds->critical == NULL)) { |
| 316 | } else if ((config.time_thresholds->warning != NULL) && (config.time_thresholds->critical == NULL)) { | 336 | printf("|%s\n", |
| 317 | printf("|%s\n", fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, false, 0, true, 0, false, 0)); | 337 | fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, |
| 338 | false, 0, true, 0, false, 0)); | ||
| 318 | } else { | 339 | } else { |
| 319 | printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, false, 0)); | 340 | printf("|%s\n", |
| 341 | fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, false, 0)); | ||
| 320 | } | 342 | } |
| 321 | } else if (result == STATE_WARNING) { | 343 | } else if (result == STATE_WARNING) { |
| 322 | printf(_("DNS WARNING - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); | 344 | printf(_("DNS WARNING - %s\n"), |
| 345 | !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); | ||
| 323 | } else if (result == STATE_CRITICAL) { | 346 | } else if (result == STATE_CRITICAL) { |
| 324 | printf(_("DNS CRITICAL - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); | 347 | printf(_("DNS CRITICAL - %s\n"), |
| 348 | !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); | ||
| 325 | } else { | 349 | } else { |
| 326 | printf(_("DNS UNKNOWN - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); | 350 | printf(_("DNS UNKNOWN - %s\n"), |
| 351 | !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); | ||
| 327 | } | 352 | } |
| 328 | 353 | ||
| 329 | exit(result); | 354 | exit(result); |
| @@ -342,29 +367,34 @@ bool ip_match_cidr(const char *addr, const char *cidr_ro) { | |||
| 342 | mask = atoi(mask_c); | 367 | mask = atoi(mask_c); |
| 343 | 368 | ||
| 344 | /* https://www.cryptobells.com/verifying-ips-in-a-subnet-in-php/ */ | 369 | /* https://www.cryptobells.com/verifying-ips-in-a-subnet-in-php/ */ |
| 345 | return (ip2long(addr) & ~((1 << (32 - mask)) - 1)) == (ip2long(subnet) >> (32 - mask)) << (32 - mask); | 370 | return (ip2long(addr) & ~((1 << (32 - mask)) - 1)) == (ip2long(subnet) >> (32 - mask)) |
| 371 | << (32 - mask); | ||
| 346 | } | 372 | } |
| 347 | 373 | ||
| 348 | unsigned long ip2long(const char *src) { | 374 | unsigned long ip2long(const char *src) { |
| 349 | unsigned long ip[4]; | 375 | unsigned long ip[4]; |
| 350 | /* http://computer-programming-forum.com/47-c-language/1376ffb92a12c471.htm */ | 376 | /* http://computer-programming-forum.com/47-c-language/1376ffb92a12c471.htm */ |
| 351 | return (sscanf(src, "%3lu.%3lu.%3lu.%3lu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4 && ip[0] < 256 && ip[1] < 256 && ip[2] < 256 && | 377 | return (sscanf(src, "%3lu.%3lu.%3lu.%3lu", &ip[0], &ip[1], &ip[2], &ip[3]) == 4 && |
| 352 | ip[3] < 256) | 378 | ip[0] < 256 && ip[1] < 256 && ip[2] < 256 && ip[3] < 256) |
| 353 | ? ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3] | 379 | ? ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3] |
| 354 | : 0; | 380 | : 0; |
| 355 | } | 381 | } |
| 356 | 382 | ||
| 357 | mp_state_enum error_scan(char *input_buffer, bool *is_nxdomain, const char dns_server[ADDRESS_LENGTH]) { | 383 | mp_state_enum error_scan(char *input_buffer, bool *is_nxdomain, |
| 384 | const char dns_server[ADDRESS_LENGTH]) { | ||
| 358 | 385 | ||
| 359 | const int nxdomain = strstr(input_buffer, "Non-existent") || strstr(input_buffer, "** server can't find") || | 386 | const int nxdomain = strstr(input_buffer, "Non-existent") || |
| 387 | strstr(input_buffer, "** server can't find") || | ||
| 360 | strstr(input_buffer, "** Can't find") || strstr(input_buffer, "NXDOMAIN"); | 388 | strstr(input_buffer, "** Can't find") || strstr(input_buffer, "NXDOMAIN"); |
| 361 | if (nxdomain) { | 389 | if (nxdomain) { |
| 362 | *is_nxdomain = true; | 390 | *is_nxdomain = true; |
| 363 | } | 391 | } |
| 364 | 392 | ||
| 365 | /* the DNS lookup timed out */ | 393 | /* the DNS lookup timed out */ |
| 366 | if (strstr(input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) || | 394 | if (strstr(input_buffer, |
| 367 | strstr(input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) || | 395 | _("Note: nslookup is deprecated and may be removed from future releases.")) || |
| 396 | strstr(input_buffer, | ||
| 397 | _("Consider using the `dig' or `host' programs instead. Run nslookup with")) || | ||
| 368 | strstr(input_buffer, _("the `-sil[ent]' option to prevent this message from appearing."))) { | 398 | strstr(input_buffer, _("the `-sil[ent]' option to prevent this message from appearing."))) { |
| 369 | return STATE_OK; | 399 | return STATE_OK; |
| 370 | } | 400 | } |
| @@ -382,8 +412,9 @@ mp_state_enum error_scan(char *input_buffer, bool *is_nxdomain, const char dns_s | |||
| 382 | } | 412 | } |
| 383 | 413 | ||
| 384 | /* Connection was refused */ | 414 | /* Connection was refused */ |
| 385 | else if (strstr(input_buffer, "Connection refused") || strstr(input_buffer, "Couldn't find server") || | 415 | else if (strstr(input_buffer, "Connection refused") || |
| 386 | strstr(input_buffer, "Refused") || (strstr(input_buffer, "** server can't find") && strstr(input_buffer, ": REFUSED"))) { | 416 | strstr(input_buffer, "Couldn't find server") || strstr(input_buffer, "Refused") || |
| 417 | (strstr(input_buffer, "** server can't find") && strstr(input_buffer, ": REFUSED"))) { | ||
| 387 | die(STATE_CRITICAL, _("Connection to DNS %s was refused\n"), dns_server); | 418 | die(STATE_CRITICAL, _("Connection to DNS %s was refused\n"), dns_server); |
| 388 | } | 419 | } |
| 389 | 420 | ||
| @@ -504,20 +535,24 @@ check_dns_config_wrapper process_arguments(int argc, char **argv) { | |||
| 504 | if (strchr(optarg, ',') != NULL) { | 535 | if (strchr(optarg, ',') != NULL) { |
| 505 | char *comma = strchr(optarg, ','); | 536 | char *comma = strchr(optarg, ','); |
| 506 | while (comma != NULL) { | 537 | while (comma != NULL) { |
| 507 | result.config.expected_address = | 538 | result.config.expected_address = (char **)realloc( |
| 508 | (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); | 539 | result.config.expected_address, |
| 509 | result.config.expected_address[result.config.expected_address_cnt] = strndup(optarg, comma - optarg); | 540 | (result.config.expected_address_cnt + 1) * sizeof(char **)); |
| 541 | result.config.expected_address[result.config.expected_address_cnt] = | ||
| 542 | strndup(optarg, comma - optarg); | ||
| 510 | result.config.expected_address_cnt++; | 543 | result.config.expected_address_cnt++; |
| 511 | optarg = comma + 1; | 544 | optarg = comma + 1; |
| 512 | comma = strchr(optarg, ','); | 545 | comma = strchr(optarg, ','); |
| 513 | } | 546 | } |
| 514 | result.config.expected_address = | 547 | result.config.expected_address = |
| 515 | (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); | 548 | (char **)realloc(result.config.expected_address, |
| 549 | (result.config.expected_address_cnt + 1) * sizeof(char **)); | ||
| 516 | result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg); | 550 | result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg); |
| 517 | result.config.expected_address_cnt++; | 551 | result.config.expected_address_cnt++; |
| 518 | } else { | 552 | } else { |
| 519 | result.config.expected_address = | 553 | result.config.expected_address = |
| 520 | (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); | 554 | (char **)realloc(result.config.expected_address, |
| 555 | (result.config.expected_address_cnt + 1) * sizeof(char **)); | ||
| 521 | result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg); | 556 | result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg); |
| 522 | result.config.expected_address_cnt++; | 557 | result.config.expected_address_cnt++; |
| 523 | } | 558 | } |
| @@ -586,9 +621,11 @@ void print_help(void) { | |||
| 586 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | 621 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); |
| 587 | printf(COPYRIGHT, copyright, email); | 622 | printf(COPYRIGHT, copyright, email); |
| 588 | 623 | ||
| 589 | printf("%s\n", _("This plugin uses the nslookup program to obtain the IP address for the given host/domain query.")); | 624 | printf("%s\n", _("This plugin uses the nslookup program to obtain the IP address for the given " |
| 625 | "host/domain query.")); | ||
| 590 | printf("%s\n", _("An optional DNS server to use may be specified.")); | 626 | printf("%s\n", _("An optional DNS server to use may be specified.")); |
| 591 | printf("%s\n", _("If no DNS server is specified, the default server(s) specified in /etc/resolv.conf will be used.")); | 627 | printf("%s\n", _("If no DNS server is specified, the default server(s) specified in " |
| 628 | "/etc/resolv.conf will be used.")); | ||
| 592 | 629 | ||
| 593 | printf("\n\n"); | 630 | printf("\n\n"); |
| 594 | 631 | ||
| @@ -602,11 +639,14 @@ void print_help(void) { | |||
| 602 | printf(" -s, --server=HOST\n"); | 639 | printf(" -s, --server=HOST\n"); |
| 603 | printf(" %s\n", _("Optional DNS server you want to use for the lookup")); | 640 | printf(" %s\n", _("Optional DNS server you want to use for the lookup")); |
| 604 | printf(" -a, --expected-address=IP-ADDRESS|CIDR|HOST\n"); | 641 | printf(" -a, --expected-address=IP-ADDRESS|CIDR|HOST\n"); |
| 605 | printf(" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end")); | 642 | printf(" %s\n", |
| 606 | printf(" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any")); | 643 | _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end")); |
| 644 | printf(" %s\n", | ||
| 645 | _("with a dot (.). This option can be repeated multiple times (Returns OK if any")); | ||
| 607 | printf(" %s\n", _("value matches).")); | 646 | printf(" %s\n", _("value matches).")); |
| 608 | printf(" -n, --expect-nxdomain\n"); | 647 | printf(" -n, --expect-nxdomain\n"); |
| 609 | printf(" %s\n", _("Expect the DNS server to return NXDOMAIN (i.e. the domain was not found)")); | 648 | printf(" %s\n", |
| 649 | _("Expect the DNS server to return NXDOMAIN (i.e. the domain was not found)")); | ||
| 610 | printf(" %s\n", _("Cannot be used together with -a")); | 650 | printf(" %s\n", _("Cannot be used together with -a")); |
| 611 | printf(" -A, --expect-authority\n"); | 651 | printf(" -A, --expect-authority\n"); |
| 612 | printf(" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup")); | 652 | printf(" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup")); |
| @@ -615,7 +655,8 @@ void print_help(void) { | |||
| 615 | printf(" -c, --critical=seconds\n"); | 655 | printf(" -c, --critical=seconds\n"); |
| 616 | printf(" %s\n", _("Return critical if elapsed time exceeds value. Default off")); | 656 | printf(" %s\n", _("Return critical if elapsed time exceeds value. Default off")); |
| 617 | printf(" -L, --all\n"); | 657 | printf(" -L, --all\n"); |
| 618 | printf(" %s\n", _("Return critical if the list of expected addresses does not match all addresses")); | 658 | printf(" %s\n", |
| 659 | _("Return critical if the list of expected addresses does not match all addresses")); | ||
| 619 | printf(" %s\n", _("returned. Default off")); | 660 | printf(" %s\n", _("returned. Default off")); |
| 620 | 661 | ||
| 621 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 662 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| @@ -625,5 +666,7 @@ void print_help(void) { | |||
| 625 | 666 | ||
| 626 | void print_usage(void) { | 667 | void print_usage(void) { |
| 627 | printf("%s\n", _("Usage:")); | 668 | printf("%s\n", _("Usage:")); |
| 628 | printf("%s -H host [-s server] [-a expected-address] [-n] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname); | 669 | printf("%s -H host [-s server] [-a expected-address] [-n] [-A] [-t timeout] [-w warn] [-c " |
| 670 | "crit] [-L]\n", | ||
| 671 | progname); | ||
| 629 | } | 672 | } |
diff --git a/plugins/check_dummy.c b/plugins/check_dummy.c index 19f6c046..602d5868 100644 --- a/plugins/check_dummy.c +++ b/plugins/check_dummy.c | |||
| @@ -45,18 +45,19 @@ int main(int argc, char **argv) { | |||
| 45 | bindtextdomain(PACKAGE, LOCALEDIR); | 45 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 46 | textdomain(PACKAGE); | 46 | textdomain(PACKAGE); |
| 47 | 47 | ||
| 48 | if (argc < 2) | 48 | if (argc < 2) { |
| 49 | usage4(_("Could not parse arguments")); | 49 | usage4(_("Could not parse arguments")); |
| 50 | else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0) { | 50 | } else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0) { |
| 51 | print_revision(progname, NP_VERSION); | 51 | print_revision(progname, NP_VERSION); |
| 52 | exit(STATE_UNKNOWN); | 52 | exit(STATE_UNKNOWN); |
| 53 | } else if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { | 53 | } else if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { |
| 54 | print_help(); | 54 | print_help(); |
| 55 | exit(STATE_UNKNOWN); | 55 | exit(STATE_UNKNOWN); |
| 56 | } else if (!is_integer(argv[1])) | 56 | } else if (!is_integer(argv[1])) { |
| 57 | usage4(_("Arguments to check_dummy must be an integer")); | 57 | usage4(_("Arguments to check_dummy must be an integer")); |
| 58 | else | 58 | } else { |
| 59 | result = atoi(argv[1]); | 59 | result = atoi(argv[1]); |
| 60 | } | ||
| 60 | 61 | ||
| 61 | switch (result) { | 62 | switch (result) { |
| 62 | case STATE_OK: | 63 | case STATE_OK: |
| @@ -78,8 +79,9 @@ int main(int argc, char **argv) { | |||
| 78 | return STATE_UNKNOWN; | 79 | return STATE_UNKNOWN; |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | if (argc >= 3) | 82 | if (argc >= 3) { |
| 82 | printf(": %s", argv[2]); | 83 | printf(": %s", argv[2]); |
| 84 | } | ||
| 83 | 85 | ||
| 84 | printf("\n"); | 86 | printf("\n"); |
| 85 | 87 | ||
| @@ -92,7 +94,8 @@ void print_help(void) { | |||
| 92 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | 94 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); |
| 93 | printf(COPYRIGHT, copyright, email); | 95 | printf(COPYRIGHT, copyright, email); |
| 94 | 96 | ||
| 95 | printf("%s\n", _("This plugin will simply return the state corresponding to the numeric value")); | 97 | printf("%s\n", |
| 98 | _("This plugin will simply return the state corresponding to the numeric value")); | ||
| 96 | 99 | ||
| 97 | printf("%s\n", _("of the <state> argument with optional text")); | 100 | printf("%s\n", _("of the <state> argument with optional text")); |
| 98 | 101 | ||
diff --git a/plugins/check_fping.c b/plugins/check_fping.c index ec7abb67..6160c2cb 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c | |||
| @@ -46,8 +46,9 @@ enum { | |||
| 46 | RTA = 1 | 46 | RTA = 1 |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | static mp_state_enum textscan(char *buf, const char * /*server_name*/, bool /*crta_p*/, double /*crta*/, bool /*wrta_p*/, double /*wrta*/, | 49 | static mp_state_enum textscan(char *buf, const char * /*server_name*/, bool /*crta_p*/, |
| 50 | bool /*cpl_p*/, int /*cpl*/, bool /*wpl_p*/, int /*wpl*/, bool /*alive_p*/); | 50 | double /*crta*/, bool /*wrta_p*/, double /*wrta*/, bool /*cpl_p*/, |
| 51 | int /*cpl*/, bool /*wpl_p*/, int /*wpl*/, bool /*alive_p*/); | ||
| 51 | 52 | ||
| 52 | typedef struct { | 53 | typedef struct { |
| 53 | int errorcode; | 54 | int errorcode; |
| @@ -79,6 +80,24 @@ int main(int argc, char **argv) { | |||
| 79 | server = strscpy(server, config.server_name); | 80 | server = strscpy(server, config.server_name); |
| 80 | 81 | ||
| 81 | char *option_string = ""; | 82 | char *option_string = ""; |
| 83 | char *fping_prog = NULL; | ||
| 84 | |||
| 85 | /* First determine if the target is dualstack or ipv6 only. */ | ||
| 86 | bool server_is_inet6_addr = is_inet6_addr(server); | ||
| 87 | |||
| 88 | /* | ||
| 89 | * If the user requested -6 OR the user made no assertion and the address is v6 or dualstack | ||
| 90 | * -> we use ipv6 | ||
| 91 | * If the user requested -4 OR the user made no assertion and the address is v4 ONLY | ||
| 92 | * -> we use ipv4 | ||
| 93 | */ | ||
| 94 | if (address_family == AF_INET6 || (address_family == AF_UNSPEC && server_is_inet6_addr)) { | ||
| 95 | xasprintf(&option_string, "%s-6 ", option_string); | ||
| 96 | } else { | ||
| 97 | xasprintf(&option_string, "%s-4 ", option_string); | ||
| 98 | } | ||
| 99 | fping_prog = strdup(PATH_TO_FPING); | ||
| 100 | |||
| 82 | /* compose the command */ | 101 | /* compose the command */ |
| 83 | if (config.target_timeout) { | 102 | if (config.target_timeout) { |
| 84 | xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout); | 103 | xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout); |
| @@ -99,19 +118,28 @@ int main(int argc, char **argv) { | |||
| 99 | xasprintf(&option_string, "%s-R ", option_string); | 118 | xasprintf(&option_string, "%s-R ", option_string); |
| 100 | } | 119 | } |
| 101 | 120 | ||
| 102 | char *fping_prog = NULL; | 121 | if (config.fwmark_set) { |
| 103 | #ifdef PATH_TO_FPING6 | 122 | xasprintf(&option_string, "%s--fwmark %u ", option_string, config.fwmark); |
| 104 | if (address_family != AF_INET && is_inet6_addr(server)) { | 123 | } |
| 105 | fping_prog = strdup(PATH_TO_FPING6); | 124 | |
| 106 | } else { | 125 | if (config.icmp_timestamp) { |
| 107 | fping_prog = strdup(PATH_TO_FPING); | 126 | xasprintf(&option_string, "%s--icmp-timestamp ", option_string); |
| 127 | } | ||
| 128 | |||
| 129 | if (config.check_source) { | ||
| 130 | xasprintf(&option_string, "%s--check-source ", option_string); | ||
| 108 | } | 131 | } |
| 109 | #else | ||
| 110 | fping_prog = strdup(PATH_TO_FPING); | ||
| 111 | #endif | ||
| 112 | 132 | ||
| 113 | char *command_line = NULL; | 133 | char *command_line = NULL; |
| 114 | xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server); | 134 | |
| 135 | if (config.icmp_timestamp) { | ||
| 136 | // no packet size settable for ICMP timestamp | ||
| 137 | xasprintf(&command_line, "%s %s -c %d %s", fping_prog, option_string, config.packet_count, | ||
| 138 | server); | ||
| 139 | } else { | ||
| 140 | xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, | ||
| 141 | config.packet_size, config.packet_count, server); | ||
| 142 | } | ||
| 115 | 143 | ||
| 116 | if (verbose) { | 144 | if (verbose) { |
| 117 | printf("%s\n", command_line); | 145 | printf("%s\n", command_line); |
| @@ -135,8 +163,9 @@ int main(int argc, char **argv) { | |||
| 135 | if (verbose) { | 163 | if (verbose) { |
| 136 | printf("%s", input_buffer); | 164 | printf("%s", input_buffer); |
| 137 | } | 165 | } |
| 138 | status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, config.crta, config.wrta_p, config.wrta, | 166 | status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, |
| 139 | config.cpl_p, config.cpl, config.wpl_p, config.wpl, config.alive_p)); | 167 | config.crta, config.wrta_p, config.wrta, config.cpl_p, |
| 168 | config.cpl, config.wpl_p, config.wpl, config.alive_p)); | ||
| 140 | } | 169 | } |
| 141 | 170 | ||
| 142 | /* If we get anything on STDERR, at least set warning */ | 171 | /* If we get anything on STDERR, at least set warning */ |
| @@ -145,8 +174,9 @@ int main(int argc, char **argv) { | |||
| 145 | if (verbose) { | 174 | if (verbose) { |
| 146 | printf("%s", input_buffer); | 175 | printf("%s", input_buffer); |
| 147 | } | 176 | } |
| 148 | status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, config.crta, config.wrta_p, config.wrta, | 177 | status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p, |
| 149 | config.cpl_p, config.cpl, config.wpl_p, config.wpl, config.alive_p)); | 178 | config.crta, config.wrta_p, config.wrta, config.cpl_p, |
| 179 | config.cpl, config.wpl_p, config.wpl, config.alive_p)); | ||
| 150 | } | 180 | } |
| 151 | (void)fclose(child_stderr); | 181 | (void)fclose(child_stderr); |
| 152 | 182 | ||
| @@ -175,8 +205,8 @@ int main(int argc, char **argv) { | |||
| 175 | return status; | 205 | return status; |
| 176 | } | 206 | } |
| 177 | 207 | ||
| 178 | mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double crta, bool wrta_p, double wrta, bool cpl_p, int cpl, | 208 | mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double crta, bool wrta_p, |
| 179 | bool wpl_p, int wpl, bool alive_p) { | 209 | double wrta, bool cpl_p, int cpl, bool wpl_p, int wpl, bool alive_p) { |
| 180 | /* stops testing after the first successful reply. */ | 210 | /* stops testing after the first successful reply. */ |
| 181 | double rta; | 211 | double rta; |
| 182 | double loss; | 212 | double loss; |
| @@ -189,7 +219,8 @@ mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double c | |||
| 189 | die(STATE_OK, _("FPING %s - %s (rta=%f ms)|%s\n"), state_text(STATE_OK), server_name, rta, | 219 | die(STATE_OK, _("FPING %s - %s (rta=%f ms)|%s\n"), state_text(STATE_OK), server_name, rta, |
| 190 | /* No loss since we only waited for the first reply | 220 | /* No loss since we only waited for the first reply |
| 191 | perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), */ | 221 | perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), */ |
| 192 | fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); | 222 | fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, |
| 223 | false, 0)); | ||
| 193 | } | 224 | } |
| 194 | 225 | ||
| 195 | mp_state_enum status = STATE_UNKNOWN; | 226 | mp_state_enum status = STATE_UNKNOWN; |
| @@ -230,9 +261,11 @@ mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double c | |||
| 230 | } else { | 261 | } else { |
| 231 | status = STATE_OK; | 262 | status = STATE_OK; |
| 232 | } | 263 | } |
| 233 | die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta, | 264 | die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), |
| 265 | server_name, loss, rta, | ||
| 234 | perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0), | 266 | perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0), |
| 235 | fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); | 267 | fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, |
| 268 | false, 0)); | ||
| 236 | 269 | ||
| 237 | } else if (strstr(buf, "xmt/rcv/%loss")) { | 270 | } else if (strstr(buf, "xmt/rcv/%loss")) { |
| 238 | /* no min/max/avg if host was unreachable in fping v2.2.b1 */ | 271 | /* no min/max/avg if host was unreachable in fping v2.2.b1 */ |
| @@ -268,13 +301,38 @@ mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double c | |||
| 268 | 301 | ||
| 269 | /* process command-line arguments */ | 302 | /* process command-line arguments */ |
| 270 | check_fping_config_wrapper process_arguments(int argc, char **argv) { | 303 | check_fping_config_wrapper process_arguments(int argc, char **argv) { |
| 271 | static struct option longopts[] = { | 304 | enum { |
| 272 | {"hostname", required_argument, 0, 'H'}, {"sourceip", required_argument, 0, 'S'}, {"sourceif", required_argument, 0, 'I'}, | 305 | FWMARK_OPT = CHAR_MAX + 1, |
| 273 | {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"alive", no_argument, 0, 'a'}, | 306 | ICMP_TIMESTAMP_OPT, |
| 274 | {"bytes", required_argument, 0, 'b'}, {"number", required_argument, 0, 'n'}, {"target-timeout", required_argument, 0, 'T'}, | 307 | CHECK_SOURCE_OPT, |
| 275 | {"interval", required_argument, 0, 'i'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, | 308 | }; |
| 276 | {"help", no_argument, 0, 'h'}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, | 309 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, |
| 277 | {"dontfrag", no_argument, 0, 'M'}, {"random", no_argument, 0, 'R'}, {0, 0, 0, 0}}; | 310 | {"sourceip", required_argument, 0, 'S'}, |
| 311 | {"sourceif", required_argument, 0, 'I'}, | ||
| 312 | {"critical", required_argument, 0, 'c'}, | ||
| 313 | {"warning", required_argument, 0, 'w'}, | ||
| 314 | {"alive", no_argument, 0, 'a'}, | ||
| 315 | {"bytes", required_argument, 0, 'b'}, | ||
| 316 | {"number", required_argument, 0, 'n'}, | ||
| 317 | {"target-timeout", required_argument, 0, 'T'}, | ||
| 318 | {"interval", required_argument, 0, 'i'}, | ||
| 319 | {"verbose", no_argument, 0, 'v'}, | ||
| 320 | {"version", no_argument, 0, 'V'}, | ||
| 321 | {"help", no_argument, 0, 'h'}, | ||
| 322 | {"use-ipv4", no_argument, 0, '4'}, | ||
| 323 | {"use-ipv6", no_argument, 0, '6'}, | ||
| 324 | {"dontfrag", no_argument, 0, 'M'}, | ||
| 325 | {"random", no_argument, 0, 'R'}, | ||
| 326 | #ifdef FPING_VERSION_5_2_OR_HIGHER | ||
| 327 | // only available with fping version >= 5.2 | ||
| 328 | {"fwmark", required_argument, NULL, FWMARK_OPT}, | ||
| 329 | # ifdef FPING_VERSION_5_3_OR_HIGHER | ||
| 330 | // only available with fping version >= 5.3 | ||
| 331 | {"icmp-timestamp", no_argument, NULL, ICMP_TIMESTAMP_OPT}, | ||
| 332 | {"check-source", no_argument, NULL, CHECK_SOURCE_OPT}, | ||
| 333 | # endif | ||
| 334 | #endif | ||
| 335 | {0, 0, 0, 0}}; | ||
| 278 | 336 | ||
| 279 | char *rv[2]; | 337 | char *rv[2]; |
| 280 | rv[PL] = NULL; | 338 | rv[PL] = NULL; |
| @@ -299,8 +357,9 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) { | |||
| 299 | argc--; | 357 | argc--; |
| 300 | } | 358 | } |
| 301 | 359 | ||
| 302 | while (1) { | 360 | while (true) { |
| 303 | int option_index = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); | 361 | int option_index = |
| 362 | getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); | ||
| 304 | 363 | ||
| 305 | if (option_index == -1 || option_index == EOF || option_index == 1) { | 364 | if (option_index == -1 || option_index == EOF || option_index == 1) { |
| 306 | break; | 365 | break; |
| @@ -340,11 +399,7 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) { | |||
| 340 | address_family = AF_INET; | 399 | address_family = AF_INET; |
| 341 | break; | 400 | break; |
| 342 | case '6': /* IPv6 only */ | 401 | case '6': /* IPv6 only */ |
| 343 | #ifdef USE_IPV6 | ||
| 344 | address_family = AF_INET6; | 402 | address_family = AF_INET6; |
| 345 | #else | ||
| 346 | usage(_("IPv6 support not available\n")); | ||
| 347 | #endif | ||
| 348 | break; | 403 | break; |
| 349 | case 'c': | 404 | case 'c': |
| 350 | get_threshold(optarg, rv); | 405 | get_threshold(optarg, rv); |
| @@ -406,6 +461,20 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) { | |||
| 406 | case 'M': | 461 | case 'M': |
| 407 | result.config.dontfrag = true; | 462 | result.config.dontfrag = true; |
| 408 | break; | 463 | break; |
| 464 | case FWMARK_OPT: | ||
| 465 | if (is_intpos(optarg)) { | ||
| 466 | result.config.fwmark = (unsigned int)atol(optarg); | ||
| 467 | result.config.fwmark_set = true; | ||
| 468 | } else { | ||
| 469 | usage(_("fwmark must be a positive integer")); | ||
| 470 | } | ||
| 471 | break; | ||
| 472 | case ICMP_TIMESTAMP_OPT: | ||
| 473 | result.config.icmp_timestamp = true; | ||
| 474 | break; | ||
| 475 | case CHECK_SOURCE_OPT: | ||
| 476 | result.config.check_source = true; | ||
| 477 | break; | ||
| 409 | } | 478 | } |
| 410 | } | 479 | } |
| 411 | 480 | ||
| @@ -427,10 +496,12 @@ int get_threshold(char *arg, char *rv[2]) { | |||
| 427 | if (arg2) { | 496 | if (arg2) { |
| 428 | arg1[strcspn(arg1, ",:")] = 0; | 497 | arg1[strcspn(arg1, ",:")] = 0; |
| 429 | if (strstr(arg1, "%") && strstr(arg2, "%")) { | 498 | if (strstr(arg1, "%") && strstr(arg2, "%")) { |
| 430 | die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, arg); | 499 | die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, |
| 500 | arg); | ||
| 431 | } | 501 | } |
| 432 | if (!strstr(arg1, "%") && !strstr(arg2, "%")) { | 502 | if (!strstr(arg1, "%") && !strstr(arg2, "%")) { |
| 433 | die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, arg); | 503 | die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, |
| 504 | arg); | ||
| 434 | } | 505 | } |
| 435 | } | 506 | } |
| 436 | 507 | ||
| @@ -456,7 +527,8 @@ void print_help(void) { | |||
| 456 | printf("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n"); | 527 | printf("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n"); |
| 457 | printf(COPYRIGHT, copyright, email); | 528 | printf(COPYRIGHT, copyright, email); |
| 458 | 529 | ||
| 459 | printf("%s\n", _("This plugin will use the fping command to ping the specified host for a fast check")); | 530 | printf("%s\n", |
| 531 | _("This plugin will use the fping command to ping the specified host for a fast check")); | ||
| 460 | 532 | ||
| 461 | printf("%s\n", _("Note that it is necessary to set the suid flag on fping.")); | 533 | printf("%s\n", _("Note that it is necessary to set the suid flag on fping.")); |
| 462 | 534 | ||
| @@ -470,7 +542,8 @@ void print_help(void) { | |||
| 470 | printf(UT_IPv46); | 542 | printf(UT_IPv46); |
| 471 | 543 | ||
| 472 | printf(" %s\n", "-H, --hostname=HOST"); | 544 | printf(" %s\n", "-H, --hostname=HOST"); |
| 473 | printf(" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)")); | 545 | printf(" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, " |
| 546 | "reducing system load)")); | ||
| 474 | printf(" %s\n", "-w, --warning=THRESHOLD"); | 547 | printf(" %s\n", "-w, --warning=THRESHOLD"); |
| 475 | printf(" %s\n", _("warning threshold pair")); | 548 | printf(" %s\n", _("warning threshold pair")); |
| 476 | printf(" %s\n", "-c, --critical=THRESHOLD"); | 549 | printf(" %s\n", "-c, --critical=THRESHOLD"); |
| @@ -484,7 +557,8 @@ void print_help(void) { | |||
| 484 | printf(" %s\n", "-T, --target-timeout=INTEGER"); | 557 | printf(" %s\n", "-T, --target-timeout=INTEGER"); |
| 485 | printf(" %s (default: fping's default for -t)\n", _("Target timeout (ms)")); | 558 | printf(" %s (default: fping's default for -t)\n", _("Target timeout (ms)")); |
| 486 | printf(" %s\n", "-i, --interval=INTEGER"); | 559 | printf(" %s\n", "-i, --interval=INTEGER"); |
| 487 | printf(" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets")); | 560 | printf(" %s (default: fping's default for -p)\n", |
| 561 | _("Interval (ms) between sending packets")); | ||
| 488 | printf(" %s\n", "-S, --sourceip=HOST"); | 562 | printf(" %s\n", "-S, --sourceip=HOST"); |
| 489 | printf(" %s\n", _("name or IP Address of sourceip")); | 563 | printf(" %s\n", _("name or IP Address of sourceip")); |
| 490 | printf(" %s\n", "-I, --sourceif=IF"); | 564 | printf(" %s\n", "-I, --sourceif=IF"); |
| @@ -493,9 +567,20 @@ void print_help(void) { | |||
| 493 | printf(" %s\n", _("set the Don't Fragment flag")); | 567 | printf(" %s\n", _("set the Don't Fragment flag")); |
| 494 | printf(" %s\n", "-R, --random"); | 568 | printf(" %s\n", "-R, --random"); |
| 495 | printf(" %s\n", _("random packet data (to foil link data compression)")); | 569 | printf(" %s\n", _("random packet data (to foil link data compression)")); |
| 570 | #ifdef FPING_VERSION_5_2_OR_HIGHER | ||
| 571 | printf(" %s\n", "--fwmark=INTEGER"); | ||
| 572 | printf(" %s\n", _("set the routing mark to INTEGER (fping option)")); | ||
| 573 | # ifdef FPING_VERSION_5_3_OR_HIGHER | ||
| 574 | printf(" %s\n", "--icmp-timestamp"); | ||
| 575 | printf(" %s\n", _("use ICMP Timestamp instead of ICMP Echo (fping option)")); | ||
| 576 | printf(" %s\n", "--check-source"); | ||
| 577 | printf(" %s\n", _("discard replies not from target address (fping option)")); | ||
| 578 | # endif | ||
| 579 | #endif | ||
| 496 | printf(UT_VERBOSE); | 580 | printf(UT_VERBOSE); |
| 497 | printf("\n"); | 581 | printf("\n"); |
| 498 | printf(" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)")); | 582 | printf(" %s\n", |
| 583 | _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)")); | ||
| 499 | printf(" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of")); | 584 | printf(" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of")); |
| 500 | printf(" %s\n", _("packet loss to trigger an alarm state.")); | 585 | printf(" %s\n", _("packet loss to trigger an alarm state.")); |
| 501 | 586 | ||
| @@ -507,5 +592,6 @@ void print_help(void) { | |||
| 507 | 592 | ||
| 508 | void print_usage(void) { | 593 | void print_usage(void) { |
| 509 | printf("%s\n", _("Usage:")); | 594 | printf("%s\n", _("Usage:")); |
| 510 | printf(" %s <host_address> -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n", progname); | 595 | printf(" %s <host_address> -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n", |
| 596 | progname); | ||
| 511 | } | 597 | } |
diff --git a/plugins/check_fping.d/config.h b/plugins/check_fping.d/config.h index a0697bf3..d3e50565 100644 --- a/plugins/check_fping.d/config.h +++ b/plugins/check_fping.d/config.h | |||
| @@ -29,6 +29,20 @@ typedef struct { | |||
| 29 | bool cpl_p; | 29 | bool cpl_p; |
| 30 | int wpl; | 30 | int wpl; |
| 31 | bool wpl_p; | 31 | bool wpl_p; |
| 32 | |||
| 33 | // only available with fping version >= 5.2 | ||
| 34 | // for a given uint _fwmark_ fping sets _fwmark_ as a firewall mark | ||
| 35 | // in the packets | ||
| 36 | unsigned int fwmark; | ||
| 37 | bool fwmark_set; | ||
| 38 | |||
| 39 | // only available with fping version >= 5.3 | ||
| 40 | // Setting icmp_timestamp tells fping to use ICMP Timestamp (ICMP type 13) instead | ||
| 41 | // of ICMP Echo | ||
| 42 | bool icmp_timestamp; | ||
| 43 | |||
| 44 | // Setting check_source lets fping discard replies which are not from the target address | ||
| 45 | bool check_source; | ||
| 32 | } check_fping_config; | 46 | } check_fping_config; |
| 33 | 47 | ||
| 34 | check_fping_config check_fping_config_init() { | 48 | check_fping_config check_fping_config_init() { |
| @@ -53,6 +67,15 @@ check_fping_config check_fping_config_init() { | |||
| 53 | .cpl_p = false, | 67 | .cpl_p = false, |
| 54 | .wpl = 0, | 68 | .wpl = 0, |
| 55 | .wpl_p = false, | 69 | .wpl_p = false, |
| 70 | |||
| 71 | // only available with fping version >= 5.2 | ||
| 72 | .fwmark = 0, | ||
| 73 | .fwmark_set = false, // just to be deterministic | ||
| 74 | |||
| 75 | // only available with fping version >= 5.3 | ||
| 76 | .icmp_timestamp = false, | ||
| 77 | .check_source = false, | ||
| 78 | |||
| 56 | }; | 79 | }; |
| 57 | return tmp; | 80 | return tmp; |
| 58 | } | 81 | } |
diff --git a/plugins/check_game.c b/plugins/check_game.c index c0193b03..974a7253 100644 --- a/plugins/check_game.c +++ b/plugins/check_game.c | |||
| @@ -77,7 +77,8 @@ int main(int argc, char **argv) { | |||
| 77 | 77 | ||
| 78 | /* create the command line to execute */ | 78 | /* create the command line to execute */ |
| 79 | char *command_line = NULL; | 79 | char *command_line = NULL; |
| 80 | xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, config.game_type, config.server_ip); | 80 | xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, |
| 81 | config.game_type, config.server_ip); | ||
| 81 | 82 | ||
| 82 | if (config.port) { | 83 | if (config.port) { |
| 83 | xasprintf(&command_line, "%s:%-d", command_line, config.port); | 84 | xasprintf(&command_line, "%s:%-d", command_line, config.port); |
| @@ -130,11 +131,13 @@ int main(int argc, char **argv) { | |||
| 130 | printf(_("CRITICAL - Game server timeout\n")); | 131 | printf(_("CRITICAL - Game server timeout\n")); |
| 131 | result = STATE_CRITICAL; | 132 | result = STATE_CRITICAL; |
| 132 | } else { | 133 | } else { |
| 133 | printf("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", ret[config.qstat_game_players], ret[config.qstat_game_players_max], | 134 | printf("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", ret[config.qstat_game_players], |
| 134 | ret[config.qstat_game_field], ret[config.qstat_map_field], ret[config.qstat_ping_field], | 135 | ret[config.qstat_game_players_max], ret[config.qstat_game_field], |
| 135 | perfdata("players", atol(ret[config.qstat_game_players]), "", false, 0, false, 0, true, 0, true, | 136 | ret[config.qstat_map_field], ret[config.qstat_ping_field], |
| 136 | atol(ret[config.qstat_game_players_max])), | 137 | perfdata("players", atol(ret[config.qstat_game_players]), "", false, 0, false, 0, |
| 137 | fperfdata("ping", strtod(ret[config.qstat_ping_field], NULL), "", false, 0, false, 0, true, 0, false, 0)); | 138 | true, 0, true, atol(ret[config.qstat_game_players_max])), |
| 139 | fperfdata("ping", strtod(ret[config.qstat_ping_field], NULL), "", false, 0, false, 0, | ||
| 140 | true, 0, false, 0)); | ||
| 138 | } | 141 | } |
| 139 | 142 | ||
| 140 | exit(result); | 143 | exit(result); |
| @@ -144,19 +147,20 @@ int main(int argc, char **argv) { | |||
| 144 | #define max_players_field_index 130 | 147 | #define max_players_field_index 130 |
| 145 | 148 | ||
| 146 | check_game_config_wrapper process_arguments(int argc, char **argv) { | 149 | check_game_config_wrapper process_arguments(int argc, char **argv) { |
| 147 | static struct option long_opts[] = {{"help", no_argument, 0, 'h'}, | 150 | static struct option long_opts[] = { |
| 148 | {"version", no_argument, 0, 'V'}, | 151 | {"help", no_argument, 0, 'h'}, |
| 149 | {"verbose", no_argument, 0, 'v'}, | 152 | {"version", no_argument, 0, 'V'}, |
| 150 | {"timeout", required_argument, 0, 't'}, | 153 | {"verbose", no_argument, 0, 'v'}, |
| 151 | {"hostname", required_argument, 0, 'H'}, | 154 | {"timeout", required_argument, 0, 't'}, |
| 152 | {"port", required_argument, 0, 'P'}, | 155 | {"hostname", required_argument, 0, 'H'}, |
| 153 | {"game-type", required_argument, 0, 'G'}, | 156 | {"port", required_argument, 0, 'P'}, |
| 154 | {"map-field", required_argument, 0, 'm'}, | 157 | {"game-type", required_argument, 0, 'G'}, |
| 155 | {"ping-field", required_argument, 0, 'p'}, | 158 | {"map-field", required_argument, 0, 'm'}, |
| 156 | {"game-field", required_argument, 0, 'g'}, | 159 | {"ping-field", required_argument, 0, 'p'}, |
| 157 | {"players-field", required_argument, 0, players_field_index}, | 160 | {"game-field", required_argument, 0, 'g'}, |
| 158 | {"max-players-field", required_argument, 0, max_players_field_index}, | 161 | {"players-field", required_argument, 0, players_field_index}, |
| 159 | {0, 0, 0, 0}}; | 162 | {"max-players-field", required_argument, 0, max_players_field_index}, |
| 163 | {0, 0, 0, 0}}; | ||
| 160 | 164 | ||
| 161 | check_game_config_wrapper result = { | 165 | check_game_config_wrapper result = { |
| 162 | .config = check_game_config_init(), | 166 | .config = check_game_config_init(), |
| @@ -216,21 +220,24 @@ check_game_config_wrapper process_arguments(int argc, char **argv) { | |||
| 216 | break; | 220 | break; |
| 217 | case 'p': /* index of ping field */ | 221 | case 'p': /* index of ping field */ |
| 218 | result.config.qstat_ping_field = atoi(optarg); | 222 | result.config.qstat_ping_field = atoi(optarg); |
| 219 | if (result.config.qstat_ping_field < 0 || result.config.qstat_ping_field > QSTAT_MAX_RETURN_ARGS) { | 223 | if (result.config.qstat_ping_field < 0 || |
| 224 | result.config.qstat_ping_field > QSTAT_MAX_RETURN_ARGS) { | ||
| 220 | result.errorcode = ERROR; | 225 | result.errorcode = ERROR; |
| 221 | return result; | 226 | return result; |
| 222 | } | 227 | } |
| 223 | break; | 228 | break; |
| 224 | case 'm': /* index on map field */ | 229 | case 'm': /* index on map field */ |
| 225 | result.config.qstat_map_field = atoi(optarg); | 230 | result.config.qstat_map_field = atoi(optarg); |
| 226 | if (result.config.qstat_map_field < 0 || result.config.qstat_map_field > QSTAT_MAX_RETURN_ARGS) { | 231 | if (result.config.qstat_map_field < 0 || |
| 232 | result.config.qstat_map_field > QSTAT_MAX_RETURN_ARGS) { | ||
| 227 | result.errorcode = ERROR; | 233 | result.errorcode = ERROR; |
| 228 | return result; | 234 | return result; |
| 229 | } | 235 | } |
| 230 | break; | 236 | break; |
| 231 | case 'g': /* index of game field */ | 237 | case 'g': /* index of game field */ |
| 232 | result.config.qstat_game_field = atoi(optarg); | 238 | result.config.qstat_game_field = atoi(optarg); |
| 233 | if (result.config.qstat_game_field < 0 || result.config.qstat_game_field > QSTAT_MAX_RETURN_ARGS) { | 239 | if (result.config.qstat_game_field < 0 || |
| 240 | result.config.qstat_game_field > QSTAT_MAX_RETURN_ARGS) { | ||
| 234 | result.errorcode = ERROR; | 241 | result.errorcode = ERROR; |
| 235 | return result; | 242 | return result; |
| 236 | } | 243 | } |
| @@ -240,14 +247,16 @@ check_game_config_wrapper process_arguments(int argc, char **argv) { | |||
| 240 | if (result.config.qstat_game_players_max == 0) { | 247 | if (result.config.qstat_game_players_max == 0) { |
| 241 | result.config.qstat_game_players_max = result.config.qstat_game_players - 1; | 248 | result.config.qstat_game_players_max = result.config.qstat_game_players - 1; |
| 242 | } | 249 | } |
| 243 | if (result.config.qstat_game_players < 0 || result.config.qstat_game_players > QSTAT_MAX_RETURN_ARGS) { | 250 | if (result.config.qstat_game_players < 0 || |
| 251 | result.config.qstat_game_players > QSTAT_MAX_RETURN_ARGS) { | ||
| 244 | result.errorcode = ERROR; | 252 | result.errorcode = ERROR; |
| 245 | return result; | 253 | return result; |
| 246 | } | 254 | } |
| 247 | break; | 255 | break; |
| 248 | case max_players_field_index: /* index of max players field */ | 256 | case max_players_field_index: /* index of max players field */ |
| 249 | result.config.qstat_game_players_max = atoi(optarg); | 257 | result.config.qstat_game_players_max = atoi(optarg); |
| 250 | if (result.config.qstat_game_players_max < 0 || result.config.qstat_game_players_max > QSTAT_MAX_RETURN_ARGS) { | 258 | if (result.config.qstat_game_players_max < 0 || |
| 259 | result.config.qstat_game_players_max > QSTAT_MAX_RETURN_ARGS) { | ||
| 251 | result.errorcode = ERROR; | 260 | result.errorcode = ERROR; |
| 252 | return result; | 261 | return result; |
| 253 | } | 262 | } |
| @@ -286,7 +295,7 @@ void print_help(void) { | |||
| 286 | printf(UT_HELP_VRSN); | 295 | printf(UT_HELP_VRSN); |
| 287 | printf(UT_EXTRA_OPTS); | 296 | printf(UT_EXTRA_OPTS); |
| 288 | printf(" -H, --hostname=ADDRESS\n" | 297 | printf(" -H, --hostname=ADDRESS\n" |
| 289 | " Host name, IP Address, or unix socket (must be an absolute path)\n"); | 298 | " Host name, IP Address, or unix socket (must be an absolute path)\n"); |
| 290 | printf(" %s\n", "-P"); | 299 | printf(" %s\n", "-P"); |
| 291 | printf(" %s\n", _("Optional port to connect to")); | 300 | printf(" %s\n", _("Optional port to connect to")); |
| 292 | printf(" %s\n", "-g"); | 301 | printf(" %s\n", "-g"); |
| @@ -300,8 +309,10 @@ void print_help(void) { | |||
| 300 | 309 | ||
| 301 | printf("\n"); | 310 | printf("\n"); |
| 302 | printf("%s\n", _("Notes:")); | 311 | printf("%s\n", _("Notes:")); |
| 303 | printf(" %s\n", _("This plugin uses the 'qstat' command, the popular game server status query tool.")); | 312 | printf(" %s\n", |
| 304 | printf(" %s\n", _("If you don't have the package installed, you will need to download it from")); | 313 | _("This plugin uses the 'qstat' command, the popular game server status query tool.")); |
| 314 | printf(" %s\n", | ||
| 315 | _("If you don't have the package installed, you will need to download it from")); | ||
| 305 | printf(" %s\n", _("https://github.com/multiplay/qstat before you can use this plugin.")); | 316 | printf(" %s\n", _("https://github.com/multiplay/qstat before you can use this plugin.")); |
| 306 | 317 | ||
| 307 | printf(UT_SUPPORT); | 318 | printf(UT_SUPPORT); |
| @@ -309,7 +320,8 @@ void print_help(void) { | |||
| 309 | 320 | ||
| 310 | void print_usage(void) { | 321 | void print_usage(void) { |
| 311 | printf("%s\n", _("Usage:")); | 322 | printf("%s\n", _("Usage:")); |
| 312 | printf(" %s [-hvV] [-P port] [-t timeout] [-g game_field] [-m map_field] [-p ping_field] [-G game-time] [-H hostname] <game> " | 323 | printf(" %s [-hvV] [-P port] [-t timeout] [-g game_field] [-m map_field] [-p ping_field] [-G " |
| 324 | "game-time] [-H hostname] <game> " | ||
| 313 | "<ip_address>\n", | 325 | "<ip_address>\n", |
| 314 | progname); | 326 | progname); |
| 315 | } | 327 | } |
diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c index 62417fd6..9907abc5 100644 --- a/plugins/check_hpjd.c +++ b/plugins/check_hpjd.c | |||
| @@ -85,13 +85,16 @@ int main(int argc, char **argv) { | |||
| 85 | char query_string[512]; | 85 | char query_string[512]; |
| 86 | /* removed ' 2>1' at end of command 10/27/1999 - EG */ | 86 | /* removed ' 2>1' at end of command 10/27/1999 - EG */ |
| 87 | /* create the query string */ | 87 | /* create the query string */ |
| 88 | sprintf(query_string, "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0", HPJD_LINE_STATUS, HPJD_PAPER_STATUS, | 88 | sprintf(query_string, "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0", |
| 89 | HPJD_INTERVENTION_REQUIRED, HPJD_GD_PERIPHERAL_ERROR, HPJD_GD_PAPER_JAM, HPJD_GD_PAPER_OUT, HPJD_GD_TONER_LOW, | 89 | HPJD_LINE_STATUS, HPJD_PAPER_STATUS, HPJD_INTERVENTION_REQUIRED, |
| 90 | HPJD_GD_PAGE_PUNT, HPJD_GD_MEMORY_OUT, HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY); | 90 | HPJD_GD_PERIPHERAL_ERROR, HPJD_GD_PAPER_JAM, HPJD_GD_PAPER_OUT, HPJD_GD_TONER_LOW, |
| 91 | HPJD_GD_PAGE_PUNT, HPJD_GD_MEMORY_OUT, HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, | ||
| 92 | HPJD_GD_STATUS_DISPLAY); | ||
| 91 | 93 | ||
| 92 | /* get the command to run */ | 94 | /* get the command to run */ |
| 93 | char command_line[1024]; | 95 | char command_line[1024]; |
| 94 | sprintf(command_line, "%s -OQa -m : -v 1 -c %s %s:%u %s", PATH_TO_SNMPGET, config.community, config.address, config.port, query_string); | 96 | sprintf(command_line, "%s -OQa -m : -v 1 -c %s %s:%u %s", PATH_TO_SNMPGET, config.community, |
| 97 | config.address, config.port, query_string); | ||
| 95 | 98 | ||
| 96 | /* run the command */ | 99 | /* run the command */ |
| 97 | child_process = spopen(command_line); | 100 | child_process = spopen(command_line); |
| @@ -177,7 +180,8 @@ int main(int argc, char **argv) { | |||
| 177 | strcpy(display_message, temp_buffer + 1); | 180 | strcpy(display_message, temp_buffer + 1); |
| 178 | break; | 181 | break; |
| 179 | default: /* fold multiline message */ | 182 | default: /* fold multiline message */ |
| 180 | strncat(display_message, input_buffer, sizeof(display_message) - strlen(display_message) - 1); | 183 | strncat(display_message, input_buffer, |
| 184 | sizeof(display_message) - strlen(display_message) - 1); | ||
| 181 | } | 185 | } |
| 182 | } | 186 | } |
| 183 | 187 | ||
diff --git a/plugins/check_http.c b/plugins/check_http.c index baff682a..d2f080c7 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c | |||
| @@ -1,35 +1,35 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Monitoring check_http plugin | 3 | * Monitoring check_http plugin |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 1999-2024 Monitoring Plugins Development Team | 6 | * Copyright (c) 1999-2024 Monitoring Plugins Development Team |
| 7 | * | 7 | * |
| 8 | * Description: | 8 | * Description: |
| 9 | * | 9 | * |
| 10 | * This file contains the check_http plugin | 10 | * This file contains the check_http plugin |
| 11 | * | 11 | * |
| 12 | * This plugin tests the HTTP service on the specified host. It can test | 12 | * This plugin tests the HTTP service on the specified host. It can test |
| 13 | * normal (http) and secure (https) servers, follow redirects, search for | 13 | * normal (http) and secure (https) servers, follow redirects, search for |
| 14 | * strings and regular expressions, check connection times, and report on | 14 | * strings and regular expressions, check connection times, and report on |
| 15 | * certificate expiration times. | 15 | * certificate expiration times. |
| 16 | * | 16 | * |
| 17 | * | 17 | * |
| 18 | * This program is free software: you can redistribute it and/or modify | 18 | * This program is free software: you can redistribute it and/or modify |
| 19 | * it under the terms of the GNU General Public License as published by | 19 | * it under the terms of the GNU General Public License as published by |
| 20 | * the Free Software Foundation, either version 3 of the License, or | 20 | * the Free Software Foundation, either version 3 of the License, or |
| 21 | * (at your option) any later version. | 21 | * (at your option) any later version. |
| 22 | * | 22 | * |
| 23 | * This program is distributed in the hope that it will be useful, | 23 | * This program is distributed in the hope that it will be useful, |
| 24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 26 | * GNU General Public License for more details. | 26 | * GNU General Public License for more details. |
| 27 | * | 27 | * |
| 28 | * You should have received a copy of the GNU General Public License | 28 | * You should have received a copy of the GNU General Public License |
| 29 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 29 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 30 | * | 30 | * |
| 31 | * | 31 | * |
| 32 | *****************************************************************************/ | 32 | *****************************************************************************/ |
| 33 | 33 | ||
| 34 | const char *progname = "check_http"; | 34 | const char *progname = "check_http"; |
| 35 | const char *copyright = "1999-2024"; | 35 | const char *copyright = "1999-2024"; |
| @@ -41,7 +41,6 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 41 | #include "base64.h" | 41 | #include "base64.h" |
| 42 | #include "netutils.h" | 42 | #include "netutils.h" |
| 43 | #include "utils.h" | 43 | #include "utils.h" |
| 44 | #include "base64.h" | ||
| 45 | #include <ctype.h> | 44 | #include <ctype.h> |
| 46 | 45 | ||
| 47 | #define STICKY_NONE 0 | 46 | #define STICKY_NONE 0 |
| @@ -50,1346 +49,1394 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 50 | 49 | ||
| 51 | #define HTTP_EXPECT "HTTP/1." | 50 | #define HTTP_EXPECT "HTTP/1." |
| 52 | enum { | 51 | enum { |
| 53 | MAX_IPV4_HOSTLENGTH = 255, | 52 | MAX_IPV4_HOSTLENGTH = 255, |
| 54 | HTTP_PORT = 80, | 53 | HTTP_PORT = 80, |
| 55 | HTTPS_PORT = 443, | 54 | HTTPS_PORT = 443, |
| 56 | MAX_PORT = 65535, | 55 | MAX_PORT = 65535, |
| 57 | DEFAULT_MAX_REDIRS = 15 | 56 | DEFAULT_MAX_REDIRS = 15 |
| 58 | }; | 57 | }; |
| 59 | 58 | ||
| 60 | #ifdef HAVE_SSL | 59 | #ifdef HAVE_SSL |
| 61 | bool check_cert = false; | 60 | static bool check_cert = false; |
| 62 | bool continue_after_check_cert = false; | 61 | static bool continue_after_check_cert = false; |
| 63 | int ssl_version = 0; | 62 | static int ssl_version = 0; |
| 64 | int days_till_exp_warn, days_till_exp_crit; | 63 | static int days_till_exp_warn, days_till_exp_crit; |
| 65 | char *randbuff; | 64 | # define my_recv(buf, len) ((use_ssl) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) |
| 66 | X509 *server_cert; | 65 | # define my_send(buf, len) ((use_ssl) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) |
| 67 | # define my_recv(buf, len) ((use_ssl) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) | ||
| 68 | # define my_send(buf, len) ((use_ssl) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) | ||
| 69 | #else /* ifndef HAVE_SSL */ | 66 | #else /* ifndef HAVE_SSL */ |
| 70 | # define my_recv(buf, len) read(sd, buf, len) | 67 | # define my_recv(buf, len) read(sd, buf, len) |
| 71 | # define my_send(buf, len) send(sd, buf, len, 0) | 68 | # define my_send(buf, len) send(sd, buf, len, 0) |
| 72 | #endif /* HAVE_SSL */ | 69 | #endif /* HAVE_SSL */ |
| 73 | bool no_body = false; | 70 | static bool no_body = false; |
| 74 | int maximum_age = -1; | 71 | static int maximum_age = -1; |
| 75 | 72 | ||
| 76 | enum { | 73 | enum { |
| 77 | REGS = 2, | 74 | REGS = 2, |
| 78 | MAX_RE_SIZE = 1024 | 75 | MAX_RE_SIZE = 1024 |
| 79 | }; | 76 | }; |
| 80 | #include "regex.h" | 77 | #include "regex.h" |
| 81 | regex_t preg; | 78 | static regex_t preg; |
| 82 | regmatch_t pmatch[REGS]; | 79 | static regmatch_t pmatch[REGS]; |
| 83 | char regexp[MAX_RE_SIZE]; | 80 | static char regexp[MAX_RE_SIZE]; |
| 84 | char errbuf[MAX_INPUT_BUFFER]; | 81 | static char errbuf[MAX_INPUT_BUFFER]; |
| 85 | int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; | 82 | static int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; |
| 86 | int errcode; | 83 | static int errcode; |
| 87 | int invert_regex = 0; | 84 | static int invert_regex = 0; |
| 88 | int state_regex = STATE_CRITICAL; | 85 | static int state_regex = STATE_CRITICAL; |
| 89 | 86 | ||
| 90 | struct timeval tv; | 87 | static struct timeval tv; |
| 91 | struct timeval tv_temp; | 88 | static struct timeval tv_temp; |
| 92 | 89 | ||
| 93 | #define HTTP_URL "/" | 90 | #define HTTP_URL "/" |
| 94 | #define CRLF "\r\n" | 91 | #define CRLF "\r\n" |
| 95 | 92 | ||
| 96 | bool specify_port = false; | 93 | static bool specify_port = false; |
| 97 | int server_port = HTTP_PORT; | 94 | static int server_port = HTTP_PORT; |
| 98 | int virtual_port = 0; | 95 | static int virtual_port = 0; |
| 99 | char server_port_text[6] = ""; | 96 | static char server_type[6] = "http"; |
| 100 | char server_type[6] = "http"; | 97 | static char *server_address; |
| 101 | char *server_address; | 98 | static char *host_name; |
| 102 | char *host_name; | 99 | static int host_name_length; |
| 103 | int host_name_length; | 100 | static char *server_url; |
| 104 | char *server_url; | 101 | static char *user_agent; |
| 105 | char *user_agent; | 102 | static int server_url_length; |
| 106 | int server_url_length; | 103 | static int server_expect_yn = 0; |
| 107 | int server_expect_yn = 0; | 104 | static char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; |
| 108 | char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; | 105 | static char header_expect[MAX_INPUT_BUFFER] = ""; |
| 109 | char header_expect[MAX_INPUT_BUFFER] = ""; | 106 | static char string_expect[MAX_INPUT_BUFFER] = ""; |
| 110 | char string_expect[MAX_INPUT_BUFFER] = ""; | 107 | static char *warning_thresholds = NULL; |
| 111 | char *warning_thresholds = NULL; | 108 | static char *critical_thresholds = NULL; |
| 112 | char *critical_thresholds = NULL; | 109 | static thresholds *thlds; |
| 113 | thresholds *thlds; | 110 | static char user_auth[MAX_INPUT_BUFFER] = ""; |
| 114 | char user_auth[MAX_INPUT_BUFFER] = ""; | 111 | static char proxy_auth[MAX_INPUT_BUFFER] = ""; |
| 115 | char proxy_auth[MAX_INPUT_BUFFER] = ""; | 112 | static bool display_html = false; |
| 116 | bool display_html = false; | 113 | static char **http_opt_headers; |
| 117 | char **http_opt_headers; | 114 | static int http_opt_headers_count = 0; |
| 118 | int http_opt_headers_count = 0; | 115 | static int onredirect = STATE_OK; |
| 119 | int onredirect = STATE_OK; | 116 | static int followsticky = STICKY_NONE; |
| 120 | int followsticky = STICKY_NONE; | 117 | static bool use_ssl = false; |
| 121 | bool use_ssl = false; | 118 | static bool use_sni = false; |
| 122 | bool use_sni = false; | 119 | static bool verbose = false; |
| 123 | bool verbose = false; | 120 | static bool show_extended_perfdata = false; |
| 124 | bool show_extended_perfdata = false; | 121 | static bool show_body = false; |
| 125 | bool show_body = false; | 122 | static int sd; |
| 126 | int sd; | 123 | static int min_page_len = 0; |
| 127 | int min_page_len = 0; | 124 | static int max_page_len = 0; |
| 128 | int max_page_len = 0; | 125 | static int redir_depth = 0; |
| 129 | int redir_depth = 0; | 126 | static int max_depth = DEFAULT_MAX_REDIRS; |
| 130 | int max_depth = DEFAULT_MAX_REDIRS; | 127 | static char *http_method; |
| 131 | char *http_method; | 128 | static char *http_method_proxy; |
| 132 | char *http_method_proxy; | 129 | static char *http_post_data; |
| 133 | char *http_post_data; | 130 | static char *http_content_type; |
| 134 | char *http_content_type; | 131 | static char buffer[MAX_INPUT_BUFFER]; |
| 135 | char buffer[MAX_INPUT_BUFFER]; | 132 | static char *client_cert = NULL; |
| 136 | char *client_cert = NULL; | 133 | static char *client_privkey = NULL; |
| 137 | char *client_privkey = NULL; | ||
| 138 | 134 | ||
| 139 | // Forward function declarations | 135 | // Forward function declarations |
| 140 | bool process_arguments (int, char **); | 136 | static bool process_arguments(int /*argc*/, char ** /*argv*/); |
| 141 | int check_http (void); | 137 | static int check_http(void); |
| 142 | void redir (char *pos, char *status_line); | 138 | static void redir(char *pos, char *status_line); |
| 143 | bool server_type_check(const char *type); | 139 | static bool server_type_check(const char *type); |
| 144 | int server_port_check(int ssl_flag); | 140 | static int server_port_check(int ssl_flag); |
| 145 | char *perfd_time (double microsec); | 141 | static char *perfd_time(double elapsed_time); |
| 146 | char *perfd_time_connect (double microsec); | 142 | static char *perfd_time_connect(double elapsed_time_connect); |
| 147 | char *perfd_time_ssl (double microsec); | 143 | static char *perfd_time_ssl(double elapsed_time_ssl); |
| 148 | char *perfd_time_firstbyte (double microsec); | 144 | static char *perfd_time_firstbyte(double elapsed_time_firstbyte); |
| 149 | char *perfd_time_headers (double microsec); | 145 | static char *perfd_time_headers(double elapsed_time_headers); |
| 150 | char *perfd_time_transfer (double microsec); | 146 | static char *perfd_time_transfer(double elapsed_time_transfer); |
| 151 | char *perfd_size (int page_len); | 147 | static char *perfd_size(int page_len); |
| 152 | void print_help (void); | 148 | void print_help(void); |
| 153 | void print_usage (void); | 149 | void print_usage(void); |
| 154 | char *unchunk_content(const char *content); | 150 | static char *unchunk_content(const char *content); |
| 155 | 151 | ||
| 156 | int | 152 | int main(int argc, char **argv) { |
| 157 | main (int argc, char **argv) | 153 | int result = STATE_UNKNOWN; |
| 158 | { | 154 | |
| 159 | int result = STATE_UNKNOWN; | 155 | setlocale(LC_ALL, ""); |
| 160 | 156 | bindtextdomain(PACKAGE, LOCALEDIR); | |
| 161 | setlocale (LC_ALL, ""); | 157 | textdomain(PACKAGE); |
| 162 | bindtextdomain (PACKAGE, LOCALEDIR); | 158 | |
| 163 | textdomain (PACKAGE); | 159 | /* Set default URL. Must be malloced for subsequent realloc if --onredirect=follow */ |
| 164 | 160 | server_url = strdup(HTTP_URL); | |
| 165 | /* Set default URL. Must be malloced for subsequent realloc if --onredirect=follow */ | 161 | server_url_length = strlen(server_url); |
| 166 | server_url = strdup(HTTP_URL); | 162 | xasprintf(&user_agent, "User-Agent: check_http/v%s (monitoring-plugins %s)", NP_VERSION, |
| 167 | server_url_length = strlen(server_url); | 163 | VERSION); |
| 168 | xasprintf (&user_agent, "User-Agent: check_http/v%s (monitoring-plugins %s)", | 164 | |
| 169 | NP_VERSION, VERSION); | 165 | /* Parse extra opts if any */ |
| 170 | 166 | argv = np_extra_opts(&argc, argv, progname); | |
| 171 | /* Parse extra opts if any */ | 167 | |
| 172 | argv=np_extra_opts (&argc, argv, progname); | 168 | if (!process_arguments(argc, argv)) { |
| 173 | 169 | usage4(_("Could not parse arguments")); | |
| 174 | if (process_arguments (argc, argv) == false) | 170 | } |
| 175 | usage4 (_("Could not parse arguments")); | 171 | |
| 176 | 172 | if (display_html) { | |
| 177 | if (display_html == true) | 173 | printf("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", use_ssl ? "https" : "http", |
| 178 | printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", | 174 | host_name ? host_name : server_address, server_port, server_url); |
| 179 | use_ssl ? "https" : "http", host_name ? host_name : server_address, | 175 | } |
| 180 | server_port, server_url); | 176 | |
| 181 | 177 | /* initialize alarm signal handling, set socket timeout, start timer */ | |
| 182 | /* initialize alarm signal handling, set socket timeout, start timer */ | 178 | (void)signal(SIGALRM, socket_timeout_alarm_handler); |
| 183 | (void) signal (SIGALRM, socket_timeout_alarm_handler); | 179 | (void)alarm(socket_timeout); |
| 184 | (void) alarm (socket_timeout); | 180 | gettimeofday(&tv, NULL); |
| 185 | gettimeofday (&tv, NULL); | 181 | |
| 186 | 182 | result = check_http(); | |
| 187 | result = check_http (); | 183 | return result; |
| 188 | return result; | ||
| 189 | } | 184 | } |
| 190 | 185 | ||
| 191 | /* check whether a file exists */ | 186 | /* check whether a file exists */ |
| 192 | void | 187 | void test_file(char *path) { |
| 193 | test_file (char *path) | 188 | if (access(path, R_OK) == 0) { |
| 194 | { | 189 | return; |
| 195 | if (access(path, R_OK) == 0) | 190 | } |
| 196 | return; | 191 | usage2(_("file does not exist or is not readable"), path); |
| 197 | usage2 (_("file does not exist or is not readable"), path); | ||
| 198 | } | 192 | } |
| 199 | 193 | ||
| 200 | /* | 194 | /* |
| 201 | * process command-line arguments | 195 | * process command-line arguments |
| 202 | * returns true on success, false otherwise | 196 | * returns true on success, false otherwise |
| 203 | */ | 197 | */ |
| 204 | bool process_arguments (int argc, char **argv) | 198 | bool process_arguments(int argc, char **argv) { |
| 205 | { | 199 | int c = 1; |
| 206 | int c = 1; | 200 | char *p; |
| 207 | char *p; | 201 | char *temp; |
| 208 | char *temp; | 202 | |
| 209 | 203 | enum { | |
| 210 | enum { | 204 | INVERT_REGEX = CHAR_MAX + 1, |
| 211 | INVERT_REGEX = CHAR_MAX + 1, | 205 | SNI_OPTION, |
| 212 | SNI_OPTION, | 206 | MAX_REDIRS_OPTION, |
| 213 | MAX_REDIRS_OPTION, | 207 | CONTINUE_AFTER_CHECK_CERT, |
| 214 | CONTINUE_AFTER_CHECK_CERT, | 208 | STATE_REGEX |
| 215 | STATE_REGEX | 209 | }; |
| 216 | }; | 210 | |
| 217 | 211 | int option = 0; | |
| 218 | int option = 0; | 212 | static struct option longopts[] = { |
| 219 | static struct option longopts[] = { | 213 | STD_LONG_OPTS, |
| 220 | STD_LONG_OPTS, | 214 | {"link", no_argument, 0, 'L'}, |
| 221 | {"link", no_argument, 0, 'L'}, | 215 | {"nohtml", no_argument, 0, 'n'}, |
| 222 | {"nohtml", no_argument, 0, 'n'}, | 216 | {"ssl", optional_argument, 0, 'S'}, |
| 223 | {"ssl", optional_argument, 0, 'S'}, | 217 | {"sni", no_argument, 0, SNI_OPTION}, |
| 224 | {"sni", no_argument, 0, SNI_OPTION}, | 218 | {"post", required_argument, 0, 'P'}, |
| 225 | {"post", required_argument, 0, 'P'}, | 219 | {"method", required_argument, 0, 'j'}, |
| 226 | {"method", required_argument, 0, 'j'}, | 220 | {"IP-address", required_argument, 0, 'I'}, |
| 227 | {"IP-address", required_argument, 0, 'I'}, | 221 | {"url", required_argument, 0, 'u'}, |
| 228 | {"url", required_argument, 0, 'u'}, | 222 | {"port", required_argument, 0, 'p'}, |
| 229 | {"port", required_argument, 0, 'p'}, | 223 | {"authorization", required_argument, 0, 'a'}, |
| 230 | {"authorization", required_argument, 0, 'a'}, | 224 | {"proxy-authorization", required_argument, 0, 'b'}, |
| 231 | {"proxy-authorization", required_argument, 0, 'b'}, | 225 | {"header-string", required_argument, 0, 'd'}, |
| 232 | {"header-string", required_argument, 0, 'd'}, | 226 | {"string", required_argument, 0, 's'}, |
| 233 | {"string", required_argument, 0, 's'}, | 227 | {"expect", required_argument, 0, 'e'}, |
| 234 | {"expect", required_argument, 0, 'e'}, | 228 | {"regex", required_argument, 0, 'r'}, |
| 235 | {"regex", required_argument, 0, 'r'}, | 229 | {"ereg", required_argument, 0, 'r'}, |
| 236 | {"ereg", required_argument, 0, 'r'}, | 230 | {"eregi", required_argument, 0, 'R'}, |
| 237 | {"eregi", required_argument, 0, 'R'}, | 231 | {"linespan", no_argument, 0, 'l'}, |
| 238 | {"linespan", no_argument, 0, 'l'}, | 232 | {"onredirect", required_argument, 0, 'f'}, |
| 239 | {"onredirect", required_argument, 0, 'f'}, | 233 | {"certificate", required_argument, 0, 'C'}, |
| 240 | {"certificate", required_argument, 0, 'C'}, | 234 | {"client-cert", required_argument, 0, 'J'}, |
| 241 | {"client-cert", required_argument, 0, 'J'}, | 235 | {"private-key", required_argument, 0, 'K'}, |
| 242 | {"private-key", required_argument, 0, 'K'}, | 236 | {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT}, |
| 243 | {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT}, | 237 | {"useragent", required_argument, 0, 'A'}, |
| 244 | {"useragent", required_argument, 0, 'A'}, | 238 | {"header", required_argument, 0, 'k'}, |
| 245 | {"header", required_argument, 0, 'k'}, | 239 | {"no-body", no_argument, 0, 'N'}, |
| 246 | {"no-body", no_argument, 0, 'N'}, | 240 | {"max-age", required_argument, 0, 'M'}, |
| 247 | {"max-age", required_argument, 0, 'M'}, | 241 | {"content-type", required_argument, 0, 'T'}, |
| 248 | {"content-type", required_argument, 0, 'T'}, | 242 | {"pagesize", required_argument, 0, 'm'}, |
| 249 | {"pagesize", required_argument, 0, 'm'}, | 243 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, |
| 250 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, | 244 | {"state-regex", required_argument, 0, STATE_REGEX}, |
| 251 | {"state-regex", required_argument, 0, STATE_REGEX}, | 245 | {"use-ipv4", no_argument, 0, '4'}, |
| 252 | {"use-ipv4", no_argument, 0, '4'}, | 246 | {"use-ipv6", no_argument, 0, '6'}, |
| 253 | {"use-ipv6", no_argument, 0, '6'}, | 247 | {"extended-perfdata", no_argument, 0, 'E'}, |
| 254 | {"extended-perfdata", no_argument, 0, 'E'}, | 248 | {"show-body", no_argument, 0, 'B'}, |
| 255 | {"show-body", no_argument, 0, 'B'}, | 249 | {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION}, |
| 256 | {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION}, | 250 | {0, 0, 0, 0}}; |
| 257 | {0, 0, 0, 0} | 251 | |
| 258 | }; | 252 | if (argc < 2) { |
| 259 | 253 | return false; | |
| 260 | if (argc < 2) | 254 | } |
| 261 | return false; | 255 | |
| 262 | 256 | for (c = 1; c < argc; c++) { | |
| 263 | for (c = 1; c < argc; c++) { | 257 | if (strcmp("-to", argv[c]) == 0) { |
| 264 | if (strcmp ("-to", argv[c]) == 0) | 258 | strcpy(argv[c], "-t"); |
| 265 | strcpy (argv[c], "-t"); | 259 | } |
| 266 | if (strcmp ("-hn", argv[c]) == 0) | 260 | if (strcmp("-hn", argv[c]) == 0) { |
| 267 | strcpy (argv[c], "-H"); | 261 | strcpy(argv[c], "-H"); |
| 268 | if (strcmp ("-wt", argv[c]) == 0) | 262 | } |
| 269 | strcpy (argv[c], "-w"); | 263 | if (strcmp("-wt", argv[c]) == 0) { |
| 270 | if (strcmp ("-ct", argv[c]) == 0) | 264 | strcpy(argv[c], "-w"); |
| 271 | strcpy (argv[c], "-c"); | 265 | } |
| 272 | if (strcmp ("-nohtml", argv[c]) == 0) | 266 | if (strcmp("-ct", argv[c]) == 0) { |
| 273 | strcpy (argv[c], "-n"); | 267 | strcpy(argv[c], "-c"); |
| 274 | } | 268 | } |
| 275 | 269 | if (strcmp("-nohtml", argv[c]) == 0) { | |
| 276 | while (1) { | 270 | strcpy(argv[c], "-n"); |
| 277 | c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:NEB", longopts, &option); | 271 | } |
| 278 | if (c == -1 || c == EOF) | 272 | } |
| 279 | break; | 273 | |
| 280 | 274 | while (1) { | |
| 281 | switch (c) { | 275 | c = getopt_long(argc, argv, |
| 282 | case '?': /* usage */ | 276 | "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:NEB", |
| 283 | usage5 (); | 277 | longopts, &option); |
| 284 | break; | 278 | if (c == -1 || c == EOF) { |
| 285 | case 'h': /* help */ | 279 | break; |
| 286 | print_help (); | 280 | } |
| 287 | exit (STATE_UNKNOWN); | 281 | |
| 288 | break; | 282 | switch (c) { |
| 289 | case 'V': /* version */ | 283 | case '?': /* usage */ |
| 290 | print_revision (progname, NP_VERSION); | 284 | usage5(); |
| 291 | exit (STATE_UNKNOWN); | 285 | break; |
| 292 | break; | 286 | case 'h': /* help */ |
| 293 | case 't': /* timeout period */ | 287 | print_help(); |
| 294 | if (!is_intnonneg (optarg)) | 288 | exit(STATE_UNKNOWN); |
| 295 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 289 | break; |
| 296 | else | 290 | case 'V': /* version */ |
| 297 | socket_timeout = atoi (optarg); | 291 | print_revision(progname, NP_VERSION); |
| 298 | break; | 292 | exit(STATE_UNKNOWN); |
| 299 | case 'c': /* critical time threshold */ | 293 | break; |
| 300 | critical_thresholds = optarg; | 294 | case 't': /* timeout period */ |
| 301 | break; | 295 | if (!is_intnonneg(optarg)) { |
| 302 | case 'w': /* warning time threshold */ | 296 | usage2(_("Timeout interval must be a positive integer"), optarg); |
| 303 | warning_thresholds = optarg; | 297 | } else { |
| 304 | break; | 298 | socket_timeout = atoi(optarg); |
| 305 | case 'A': /* User Agent String */ | 299 | } |
| 306 | xasprintf (&user_agent, "User-Agent: %s", optarg); | 300 | break; |
| 307 | break; | 301 | case 'c': /* critical time threshold */ |
| 308 | case 'k': /* Additional headers */ | 302 | critical_thresholds = optarg; |
| 309 | if (http_opt_headers_count == 0) | 303 | break; |
| 310 | http_opt_headers = malloc (sizeof (char *) * (++http_opt_headers_count)); | 304 | case 'w': /* warning time threshold */ |
| 311 | else | 305 | warning_thresholds = optarg; |
| 312 | http_opt_headers = realloc (http_opt_headers, sizeof (char *) * (++http_opt_headers_count)); | 306 | break; |
| 313 | http_opt_headers[http_opt_headers_count - 1] = optarg; | 307 | case 'A': /* User Agent String */ |
| 314 | /* xasprintf (&http_opt_headers, "%s", optarg); */ | 308 | xasprintf(&user_agent, "User-Agent: %s", optarg); |
| 315 | break; | 309 | break; |
| 316 | case 'L': /* show html link */ | 310 | case 'k': /* Additional headers */ |
| 317 | display_html = true; | 311 | if (http_opt_headers_count == 0) { |
| 318 | break; | 312 | http_opt_headers = malloc(sizeof(char *) * (++http_opt_headers_count)); |
| 319 | case 'n': /* do not show html link */ | 313 | } else { |
| 320 | display_html = false; | 314 | http_opt_headers = |
| 321 | break; | 315 | realloc(http_opt_headers, sizeof(char *) * (++http_opt_headers_count)); |
| 322 | case 'C': /* Check SSL cert validity */ | 316 | } |
| 317 | http_opt_headers[http_opt_headers_count - 1] = optarg; | ||
| 318 | /* xasprintf (&http_opt_headers, "%s", optarg); */ | ||
| 319 | break; | ||
| 320 | case 'L': /* show html link */ | ||
| 321 | display_html = true; | ||
| 322 | break; | ||
| 323 | case 'n': /* do not show html link */ | ||
| 324 | display_html = false; | ||
| 325 | break; | ||
| 326 | case 'C': /* Check SSL cert validity */ | ||
| 323 | #ifdef HAVE_SSL | 327 | #ifdef HAVE_SSL |
| 324 | if ((temp=strchr(optarg,','))!=NULL) { | 328 | if ((temp = strchr(optarg, ',')) != NULL) { |
| 325 | *temp='\0'; | 329 | *temp = '\0'; |
| 326 | if (!is_intnonneg (optarg)) | 330 | if (!is_intnonneg(optarg)) { |
| 327 | usage2 (_("Invalid certificate expiration period"), optarg); | 331 | usage2(_("Invalid certificate expiration period"), optarg); |
| 328 | days_till_exp_warn = atoi(optarg); | 332 | } |
| 329 | *temp=','; | 333 | days_till_exp_warn = atoi(optarg); |
| 330 | temp++; | 334 | *temp = ','; |
| 331 | if (!is_intnonneg (temp)) | 335 | temp++; |
| 332 | usage2 (_("Invalid certificate expiration period"), temp); | 336 | if (!is_intnonneg(temp)) { |
| 333 | days_till_exp_crit = atoi (temp); | 337 | usage2(_("Invalid certificate expiration period"), temp); |
| 334 | } | 338 | } |
| 335 | else { | 339 | days_till_exp_crit = atoi(temp); |
| 336 | days_till_exp_crit=0; | 340 | } else { |
| 337 | if (!is_intnonneg (optarg)) | 341 | days_till_exp_crit = 0; |
| 338 | usage2 (_("Invalid certificate expiration period"), optarg); | 342 | if (!is_intnonneg(optarg)) { |
| 339 | days_till_exp_warn = atoi (optarg); | 343 | usage2(_("Invalid certificate expiration period"), optarg); |
| 340 | } | 344 | } |
| 341 | check_cert = true; | 345 | days_till_exp_warn = atoi(optarg); |
| 342 | goto enable_ssl; | 346 | } |
| 347 | check_cert = true; | ||
| 348 | goto enable_ssl; | ||
| 343 | #endif | 349 | #endif |
| 344 | case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */ | 350 | case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */ |
| 345 | #ifdef HAVE_SSL | 351 | #ifdef HAVE_SSL |
| 346 | continue_after_check_cert = true; | 352 | continue_after_check_cert = true; |
| 347 | break; | 353 | break; |
| 348 | #endif | 354 | #endif |
| 349 | case 'J': /* use client certificate */ | 355 | case 'J': /* use client certificate */ |
| 350 | #ifdef HAVE_SSL | 356 | #ifdef HAVE_SSL |
| 351 | test_file(optarg); | 357 | test_file(optarg); |
| 352 | client_cert = optarg; | 358 | client_cert = optarg; |
| 353 | goto enable_ssl; | 359 | goto enable_ssl; |
| 354 | #endif | 360 | #endif |
| 355 | case 'K': /* use client private key */ | 361 | case 'K': /* use client private key */ |
| 356 | #ifdef HAVE_SSL | 362 | #ifdef HAVE_SSL |
| 357 | test_file(optarg); | 363 | test_file(optarg); |
| 358 | client_privkey = optarg; | 364 | client_privkey = optarg; |
| 359 | goto enable_ssl; | 365 | goto enable_ssl; |
| 360 | #endif | 366 | #endif |
| 361 | case 'S': /* use SSL */ | 367 | case 'S': /* use SSL */ |
| 362 | #ifdef HAVE_SSL | 368 | #ifdef HAVE_SSL |
| 363 | enable_ssl: | 369 | enable_ssl: |
| 364 | /* ssl_version initialized to 0 as a default. Only set if it's non-zero. This helps when we include multiple | 370 | /* ssl_version initialized to 0 as a default. Only set if it's non-zero. This helps |
| 365 | parameters, like -S and -C combinations */ | 371 | when we include multiple parameters, like -S and -C combinations */ |
| 366 | use_ssl = true; | 372 | use_ssl = true; |
| 367 | if (c=='S' && optarg != NULL) { | 373 | if (c == 'S' && optarg != NULL) { |
| 368 | int got_plus = strchr(optarg, '+') != NULL; | 374 | int got_plus = strchr(optarg, '+') != NULL; |
| 369 | 375 | ||
| 370 | if (!strncmp (optarg, "1.2", 3)) | 376 | if (!strncmp(optarg, "1.2", 3)) { |
| 371 | ssl_version = got_plus ? MP_TLSv1_2_OR_NEWER : MP_TLSv1_2; | 377 | ssl_version = got_plus ? MP_TLSv1_2_OR_NEWER : MP_TLSv1_2; |
| 372 | else if (!strncmp (optarg, "1.1", 3)) | 378 | } else if (!strncmp(optarg, "1.1", 3)) { |
| 373 | ssl_version = got_plus ? MP_TLSv1_1_OR_NEWER : MP_TLSv1_1; | 379 | ssl_version = got_plus ? MP_TLSv1_1_OR_NEWER : MP_TLSv1_1; |
| 374 | else if (optarg[0] == '1') | 380 | } else if (optarg[0] == '1') { |
| 375 | ssl_version = got_plus ? MP_TLSv1_OR_NEWER : MP_TLSv1; | 381 | ssl_version = got_plus ? MP_TLSv1_OR_NEWER : MP_TLSv1; |
| 376 | else if (optarg[0] == '3') | 382 | } else if (optarg[0] == '3') { |
| 377 | ssl_version = got_plus ? MP_SSLv3_OR_NEWER : MP_SSLv3; | 383 | ssl_version = got_plus ? MP_SSLv3_OR_NEWER : MP_SSLv3; |
| 378 | else if (optarg[0] == '2') | 384 | } else if (optarg[0] == '2') { |
| 379 | ssl_version = got_plus ? MP_SSLv2_OR_NEWER : MP_SSLv2; | 385 | ssl_version = got_plus ? MP_SSLv2_OR_NEWER : MP_SSLv2; |
| 380 | else | 386 | } else { |
| 381 | usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); | 387 | usage4(_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with " |
| 382 | } | 388 | "optional '+' suffix)")); |
| 383 | if (specify_port == false) | 389 | } |
| 384 | server_port = HTTPS_PORT; | 390 | } |
| 391 | if (!specify_port) { | ||
| 392 | server_port = HTTPS_PORT; | ||
| 393 | } | ||
| 385 | #else | 394 | #else |
| 386 | /* -C -J and -K fall through to here without SSL */ | 395 | /* -C -J and -K fall through to here without SSL */ |
| 387 | usage4 (_("Invalid option - SSL is not available")); | 396 | usage4(_("Invalid option - SSL is not available")); |
| 388 | #endif | 397 | #endif |
| 389 | break; | 398 | break; |
| 390 | case SNI_OPTION: | 399 | case SNI_OPTION: |
| 391 | use_sni = true; | 400 | use_sni = true; |
| 392 | break; | 401 | break; |
| 393 | case MAX_REDIRS_OPTION: | 402 | case MAX_REDIRS_OPTION: |
| 394 | if (!is_intnonneg (optarg)) | 403 | if (!is_intnonneg(optarg)) { |
| 395 | usage2 (_("Invalid max_redirs count"), optarg); | 404 | usage2(_("Invalid max_redirs count"), optarg); |
| 396 | else { | 405 | } else { |
| 397 | max_depth = atoi (optarg); | 406 | max_depth = atoi(optarg); |
| 398 | } | 407 | } |
| 399 | break; | 408 | break; |
| 400 | case 'f': /* onredirect */ | 409 | case 'f': /* onredirect */ |
| 401 | if (!strcmp (optarg, "stickyport")) | 410 | if (!strcmp(optarg, "stickyport")) { |
| 402 | onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT; | 411 | onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST | STICKY_PORT; |
| 403 | else if (!strcmp (optarg, "sticky")) | 412 | } else if (!strcmp(optarg, "sticky")) { |
| 404 | onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST; | 413 | onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST; |
| 405 | else if (!strcmp (optarg, "follow")) | 414 | } else if (!strcmp(optarg, "follow")) { |
| 406 | onredirect = STATE_DEPENDENT, followsticky = STICKY_NONE; | 415 | onredirect = STATE_DEPENDENT, followsticky = STICKY_NONE; |
| 407 | else if (!strcmp (optarg, "unknown")) | 416 | } else if (!strcmp(optarg, "unknown")) { |
| 408 | onredirect = STATE_UNKNOWN; | 417 | onredirect = STATE_UNKNOWN; |
| 409 | else if (!strcmp (optarg, "ok")) | 418 | } else if (!strcmp(optarg, "ok")) { |
| 410 | onredirect = STATE_OK; | 419 | onredirect = STATE_OK; |
| 411 | else if (!strcmp (optarg, "warning")) | 420 | } else if (!strcmp(optarg, "warning")) { |
| 412 | onredirect = STATE_WARNING; | 421 | onredirect = STATE_WARNING; |
| 413 | else if (!strcmp (optarg, "critical")) | 422 | } else if (!strcmp(optarg, "critical")) { |
| 414 | onredirect = STATE_CRITICAL; | 423 | onredirect = STATE_CRITICAL; |
| 415 | else usage2 (_("Invalid onredirect option"), optarg); | 424 | } else { |
| 416 | if (verbose) | 425 | usage2(_("Invalid onredirect option"), optarg); |
| 417 | printf(_("option f:%d \n"), onredirect); | 426 | } |
| 418 | break; | 427 | if (verbose) { |
| 419 | /* Note: H, I, and u must be malloc'd or will fail on redirects */ | 428 | printf(_("option f:%d \n"), onredirect); |
| 420 | case 'H': /* Host Name (virtual host) */ | 429 | } |
| 421 | host_name = strdup (optarg); | 430 | break; |
| 422 | if (host_name[0] == '[') { | 431 | /* Note: H, I, and u must be malloc'd or will fail on redirects */ |
| 423 | if ((p = strstr (host_name, "]:")) != NULL) { /* [IPv6]:port */ | 432 | case 'H': /* Host Name (virtual host) */ |
| 424 | virtual_port = atoi (p + 2); | 433 | host_name = strdup(optarg); |
| 425 | /* cut off the port */ | 434 | if (host_name[0] == '[') { |
| 426 | host_name_length = strlen (host_name) - strlen (p) - 1; | 435 | if ((p = strstr(host_name, "]:")) != NULL) { /* [IPv6]:port */ |
| 427 | free (host_name); | 436 | virtual_port = atoi(p + 2); |
| 428 | host_name = strndup (optarg, host_name_length); | 437 | /* cut off the port */ |
| 429 | if (specify_port == false) | 438 | host_name_length = strlen(host_name) - strlen(p) - 1; |
| 430 | server_port = virtual_port; | 439 | free(host_name); |
| 431 | } | 440 | host_name = strndup(optarg, host_name_length); |
| 432 | } else if ((p = strchr (host_name, ':')) != NULL | 441 | if (!specify_port) { |
| 433 | && strchr (++p, ':') == NULL) { /* IPv4:port or host:port */ | 442 | server_port = virtual_port; |
| 434 | virtual_port = atoi (p); | 443 | } |
| 435 | /* cut off the port */ | 444 | } |
| 436 | host_name_length = strlen (host_name) - strlen (p) - 1; | 445 | } else if ((p = strchr(host_name, ':')) != NULL && |
| 437 | free (host_name); | 446 | strchr(++p, ':') == NULL) { /* IPv4:port or host:port */ |
| 438 | host_name = strndup (optarg, host_name_length); | 447 | virtual_port = atoi(p); |
| 439 | if (specify_port == false) | 448 | /* cut off the port */ |
| 440 | server_port = virtual_port; | 449 | host_name_length = strlen(host_name) - strlen(p) - 1; |
| 441 | } | 450 | free(host_name); |
| 442 | break; | 451 | host_name = strndup(optarg, host_name_length); |
| 443 | case 'I': /* Server IP-address */ | 452 | if (!specify_port) { |
| 444 | server_address = strdup (optarg); | 453 | server_port = virtual_port; |
| 445 | break; | 454 | } |
| 446 | case 'u': /* URL path */ | 455 | } |
| 447 | server_url = strdup (optarg); | 456 | break; |
| 448 | server_url_length = strlen (server_url); | 457 | case 'I': /* Server IP-address */ |
| 449 | break; | 458 | server_address = strdup(optarg); |
| 450 | case 'p': /* Server port */ | 459 | break; |
| 451 | if (!is_intnonneg (optarg)) | 460 | case 'u': /* URL path */ |
| 452 | usage2 (_("Invalid port number"), optarg); | 461 | server_url = strdup(optarg); |
| 453 | else { | 462 | server_url_length = strlen(server_url); |
| 454 | server_port = atoi (optarg); | 463 | break; |
| 455 | specify_port = true; | 464 | case 'p': /* Server port */ |
| 456 | } | 465 | if (!is_intnonneg(optarg)) { |
| 457 | break; | 466 | usage2(_("Invalid port number"), optarg); |
| 458 | case 'a': /* authorization info */ | 467 | } else { |
| 459 | strncpy (user_auth, optarg, MAX_INPUT_BUFFER - 1); | 468 | server_port = atoi(optarg); |
| 460 | user_auth[MAX_INPUT_BUFFER - 1] = 0; | 469 | specify_port = true; |
| 461 | break; | 470 | } |
| 462 | case 'b': /* proxy-authorization info */ | 471 | break; |
| 463 | strncpy (proxy_auth, optarg, MAX_INPUT_BUFFER - 1); | 472 | case 'a': /* authorization info */ |
| 464 | proxy_auth[MAX_INPUT_BUFFER - 1] = 0; | 473 | strncpy(user_auth, optarg, MAX_INPUT_BUFFER - 1); |
| 465 | break; | 474 | user_auth[MAX_INPUT_BUFFER - 1] = 0; |
| 466 | case 'P': /* HTTP POST data in URL encoded format; ignored if settings already */ | 475 | break; |
| 467 | if (! http_post_data) | 476 | case 'b': /* proxy-authorization info */ |
| 468 | http_post_data = strdup (optarg); | 477 | strncpy(proxy_auth, optarg, MAX_INPUT_BUFFER - 1); |
| 469 | if (! http_method) | 478 | proxy_auth[MAX_INPUT_BUFFER - 1] = 0; |
| 470 | http_method = strdup("POST"); | 479 | break; |
| 471 | break; | 480 | case 'P': /* HTTP POST data in URL encoded format; ignored if settings already */ |
| 472 | case 'j': /* Set HTTP method */ | 481 | if (!http_post_data) { |
| 473 | if (http_method) | 482 | http_post_data = strdup(optarg); |
| 474 | free(http_method); | 483 | } |
| 475 | http_method = strdup (optarg); | 484 | if (!http_method) { |
| 476 | char *tmp; | 485 | http_method = strdup("POST"); |
| 477 | if ((tmp = strstr(http_method, ":")) != NULL) { | 486 | } |
| 478 | tmp[0] = '\0'; // set the ":" in the middle to 0 | 487 | break; |
| 479 | http_method_proxy = ++tmp; // this points to the second part | 488 | case 'j': /* Set HTTP method */ |
| 480 | } | 489 | if (http_method) { |
| 481 | break; | 490 | free(http_method); |
| 482 | case 'd': /* string or substring */ | 491 | } |
| 483 | strncpy (header_expect, optarg, MAX_INPUT_BUFFER - 1); | 492 | http_method = strdup(optarg); |
| 484 | header_expect[MAX_INPUT_BUFFER - 1] = 0; | 493 | char *tmp; |
| 485 | break; | 494 | if ((tmp = strstr(http_method, ":")) != NULL) { |
| 486 | case 's': /* string or substring */ | 495 | tmp[0] = '\0'; // set the ":" in the middle to 0 |
| 487 | strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); | 496 | http_method_proxy = ++tmp; // this points to the second part |
| 488 | string_expect[MAX_INPUT_BUFFER - 1] = 0; | 497 | } |
| 489 | break; | 498 | break; |
| 490 | case 'e': /* string or substring */ | 499 | case 'd': /* string or substring */ |
| 491 | strncpy (server_expect, optarg, MAX_INPUT_BUFFER - 1); | 500 | strncpy(header_expect, optarg, MAX_INPUT_BUFFER - 1); |
| 492 | server_expect[MAX_INPUT_BUFFER - 1] = 0; | 501 | header_expect[MAX_INPUT_BUFFER - 1] = 0; |
| 493 | server_expect_yn = 1; | 502 | break; |
| 494 | break; | 503 | case 's': /* string or substring */ |
| 495 | case 'T': /* Content-type */ | 504 | strncpy(string_expect, optarg, MAX_INPUT_BUFFER - 1); |
| 496 | xasprintf (&http_content_type, "%s", optarg); | 505 | string_expect[MAX_INPUT_BUFFER - 1] = 0; |
| 497 | break; | 506 | break; |
| 498 | case 'l': /* linespan */ | 507 | case 'e': /* string or substring */ |
| 499 | cflags &= ~REG_NEWLINE; | 508 | strncpy(server_expect, optarg, MAX_INPUT_BUFFER - 1); |
| 500 | break; | 509 | server_expect[MAX_INPUT_BUFFER - 1] = 0; |
| 501 | case 'R': /* regex */ | 510 | server_expect_yn = 1; |
| 502 | cflags |= REG_ICASE; | 511 | break; |
| 512 | case 'T': /* Content-type */ | ||
| 513 | xasprintf(&http_content_type, "%s", optarg); | ||
| 514 | break; | ||
| 515 | case 'l': /* linespan */ | ||
| 516 | cflags &= ~REG_NEWLINE; | ||
| 517 | break; | ||
| 518 | case 'R': /* regex */ | ||
| 519 | cflags |= REG_ICASE; | ||
| 503 | // fall through | 520 | // fall through |
| 504 | case 'r': /* regex */ | 521 | case 'r': /* regex */ |
| 505 | strncpy (regexp, optarg, MAX_RE_SIZE - 1); | 522 | strncpy(regexp, optarg, MAX_RE_SIZE - 1); |
| 506 | regexp[MAX_RE_SIZE - 1] = 0; | 523 | regexp[MAX_RE_SIZE - 1] = 0; |
| 507 | errcode = regcomp (&preg, regexp, cflags); | 524 | errcode = regcomp(&preg, regexp, cflags); |
| 508 | if (errcode != 0) { | 525 | if (errcode != 0) { |
| 509 | (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); | 526 | (void)regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); |
| 510 | printf (_("Could Not Compile Regular Expression: %s"), errbuf); | 527 | printf(_("Could Not Compile Regular Expression: %s"), errbuf); |
| 511 | return false; | 528 | return false; |
| 512 | } | 529 | } |
| 513 | break; | 530 | break; |
| 514 | case INVERT_REGEX: | 531 | case INVERT_REGEX: |
| 515 | invert_regex = 1; | 532 | invert_regex = 1; |
| 516 | break; | 533 | break; |
| 517 | case STATE_REGEX: | 534 | case STATE_REGEX: |
| 518 | if (!strcmp (optarg, "critical")) | 535 | if (!strcmp(optarg, "critical")) { |
| 519 | state_regex = STATE_CRITICAL; | 536 | state_regex = STATE_CRITICAL; |
| 520 | else if (!strcmp (optarg, "warning")) | 537 | } else if (!strcmp(optarg, "warning")) { |
| 521 | state_regex = STATE_WARNING; | 538 | state_regex = STATE_WARNING; |
| 522 | else usage2 (_("Invalid state-regex option"), optarg); | 539 | } else { |
| 523 | break; | 540 | usage2(_("Invalid state-regex option"), optarg); |
| 524 | case '4': | 541 | } |
| 525 | address_family = AF_INET; | 542 | break; |
| 526 | break; | 543 | case '4': |
| 527 | case '6': | 544 | address_family = AF_INET; |
| 545 | break; | ||
| 546 | case '6': | ||
| 528 | #ifdef USE_IPV6 | 547 | #ifdef USE_IPV6 |
| 529 | address_family = AF_INET6; | 548 | address_family = AF_INET6; |
| 530 | #else | 549 | #else |
| 531 | usage4 (_("IPv6 support not available")); | 550 | usage4(_("IPv6 support not available")); |
| 532 | #endif | 551 | #endif |
| 533 | break; | 552 | break; |
| 534 | case 'v': /* verbose */ | 553 | case 'v': /* verbose */ |
| 535 | verbose = true; | 554 | verbose = true; |
| 536 | break; | 555 | break; |
| 537 | case 'm': /* min_page_length */ | 556 | case 'm': /* min_page_length */ |
| 538 | { | 557 | { |
| 539 | char *tmp; | 558 | char *tmp; |
| 540 | if (strchr(optarg, ':') != (char *)NULL) { | 559 | if (strchr(optarg, ':') != (char *)NULL) { |
| 541 | /* range, so get two values, min:max */ | 560 | /* range, so get two values, min:max */ |
| 542 | tmp = strtok(optarg, ":"); | 561 | tmp = strtok(optarg, ":"); |
| 543 | if (tmp == NULL) { | 562 | if (tmp == NULL) { |
| 544 | printf("Bad format: try \"-m min:max\"\n"); | 563 | printf("Bad format: try \"-m min:max\"\n"); |
| 545 | exit (STATE_WARNING); | 564 | exit(STATE_WARNING); |
| 546 | } else | 565 | } else { |
| 547 | min_page_len = atoi(tmp); | 566 | min_page_len = atoi(tmp); |
| 548 | 567 | } | |
| 549 | tmp = strtok(NULL, ":"); | 568 | |
| 550 | if (tmp == NULL) { | 569 | tmp = strtok(NULL, ":"); |
| 551 | printf("Bad format: try \"-m min:max\"\n"); | 570 | if (tmp == NULL) { |
| 552 | exit (STATE_WARNING); | 571 | printf("Bad format: try \"-m min:max\"\n"); |
| 553 | } else | 572 | exit(STATE_WARNING); |
| 554 | max_page_len = atoi(tmp); | 573 | } else { |
| 555 | } else | 574 | max_page_len = atoi(tmp); |
| 556 | min_page_len = atoi (optarg); | 575 | } |
| 557 | break; | 576 | } else { |
| 558 | } | 577 | min_page_len = atoi(optarg); |
| 559 | case 'N': /* no-body */ | 578 | } |
| 560 | no_body = true; | 579 | break; |
| 561 | break; | 580 | } |
| 562 | case 'M': /* max-age */ | 581 | case 'N': /* no-body */ |
| 563 | { | 582 | no_body = true; |
| 564 | int L = strlen(optarg); | 583 | break; |
| 565 | if (L && optarg[L-1] == 'm') | 584 | case 'M': /* max-age */ |
| 566 | maximum_age = atoi (optarg) * 60; | 585 | { |
| 567 | else if (L && optarg[L-1] == 'h') | 586 | int L = strlen(optarg); |
| 568 | maximum_age = atoi (optarg) * 60 * 60; | 587 | if (L && optarg[L - 1] == 'm') { |
| 569 | else if (L && optarg[L-1] == 'd') | 588 | maximum_age = atoi(optarg) * 60; |
| 570 | maximum_age = atoi (optarg) * 60 * 60 * 24; | 589 | } else if (L && optarg[L - 1] == 'h') { |
| 571 | else if (L && (optarg[L-1] == 's' || | 590 | maximum_age = atoi(optarg) * 60 * 60; |
| 572 | isdigit (optarg[L-1]))) | 591 | } else if (L && optarg[L - 1] == 'd') { |
| 573 | maximum_age = atoi (optarg); | 592 | maximum_age = atoi(optarg) * 60 * 60 * 24; |
| 574 | else { | 593 | } else if (L && (optarg[L - 1] == 's' || isdigit(optarg[L - 1]))) { |
| 575 | fprintf (stderr, "unparsable max-age: %s\n", optarg); | 594 | maximum_age = atoi(optarg); |
| 576 | exit (STATE_WARNING); | 595 | } else { |
| 577 | } | 596 | fprintf(stderr, "unparsable max-age: %s\n", optarg); |
| 578 | } | 597 | exit(STATE_WARNING); |
| 579 | break; | 598 | } |
| 580 | case 'E': /* show extended perfdata */ | 599 | } break; |
| 581 | show_extended_perfdata = true; | 600 | case 'E': /* show extended perfdata */ |
| 582 | break; | 601 | show_extended_perfdata = true; |
| 583 | case 'B': /* print body content after status line */ | 602 | break; |
| 584 | show_body = true; | 603 | case 'B': /* print body content after status line */ |
| 585 | break; | 604 | show_body = true; |
| 586 | } | 605 | break; |
| 587 | } | 606 | } |
| 588 | 607 | } | |
| 589 | c = optind; | 608 | |
| 590 | 609 | c = optind; | |
| 591 | if (server_address == NULL && c < argc) | 610 | |
| 592 | server_address = strdup (argv[c++]); | 611 | if (server_address == NULL && c < argc) { |
| 593 | 612 | server_address = strdup(argv[c++]); | |
| 594 | if (host_name == NULL && c < argc) | 613 | } |
| 595 | host_name = strdup (argv[c++]); | ||
| 596 | |||
| 597 | if (server_address == NULL) { | ||
| 598 | if (host_name == NULL) | ||
| 599 | usage4 (_("You must specify a server address or host name")); | ||
| 600 | else | ||
| 601 | server_address = strdup (host_name); | ||
| 602 | } | ||
| 603 | |||
| 604 | set_thresholds(&thlds, warning_thresholds, critical_thresholds); | ||
| 605 | |||
| 606 | if (critical_thresholds && thlds->critical->end>(double)socket_timeout) | ||
| 607 | socket_timeout = (int)thlds->critical->end + 1; | ||
| 608 | |||
| 609 | if (http_method == NULL) | ||
| 610 | http_method = strdup ("GET"); | ||
| 611 | |||
| 612 | if (http_method_proxy == NULL) | ||
| 613 | http_method_proxy = strdup ("GET"); | ||
| 614 | |||
| 615 | if (client_cert && !client_privkey) | ||
| 616 | usage4 (_("If you use a client certificate you must also specify a private key file")); | ||
| 617 | |||
| 618 | if (virtual_port == 0) | ||
| 619 | virtual_port = server_port; | ||
| 620 | |||
| 621 | return true; | ||
| 622 | } | ||
| 623 | 614 | ||
| 615 | if (host_name == NULL && c < argc) { | ||
| 616 | host_name = strdup(argv[c++]); | ||
| 617 | } | ||
| 618 | |||
| 619 | if (server_address == NULL) { | ||
| 620 | if (host_name == NULL) { | ||
| 621 | usage4(_("You must specify a server address or host name")); | ||
| 622 | } else { | ||
| 623 | server_address = strdup(host_name); | ||
| 624 | } | ||
| 625 | } | ||
| 624 | 626 | ||
| 627 | set_thresholds(&thlds, warning_thresholds, critical_thresholds); | ||
| 628 | |||
| 629 | if (critical_thresholds && thlds->critical->end > (double)socket_timeout) { | ||
| 630 | socket_timeout = (int)thlds->critical->end + 1; | ||
| 631 | } | ||
| 632 | |||
| 633 | if (http_method == NULL) { | ||
| 634 | http_method = strdup("GET"); | ||
| 635 | } | ||
| 636 | |||
| 637 | if (http_method_proxy == NULL) { | ||
| 638 | http_method_proxy = strdup("GET"); | ||
| 639 | } | ||
| 640 | |||
| 641 | if (client_cert && !client_privkey) { | ||
| 642 | usage4(_("If you use a client certificate you must also specify a private key file")); | ||
| 643 | } | ||
| 644 | |||
| 645 | if (virtual_port == 0) { | ||
| 646 | virtual_port = server_port; | ||
| 647 | } | ||
| 648 | |||
| 649 | return true; | ||
| 650 | } | ||
| 625 | 651 | ||
| 626 | /* Returns 1 if we're done processing the document body; 0 to keep going */ | 652 | /* Returns 1 if we're done processing the document body; 0 to keep going */ |
| 627 | static int | 653 | static int document_headers_done(char *full_page) { |
| 628 | document_headers_done (char *full_page) | 654 | const char *body; |
| 629 | { | ||
| 630 | const char *body; | ||
| 631 | 655 | ||
| 632 | for (body = full_page; *body; body++) { | 656 | for (body = full_page; *body; body++) { |
| 633 | if (!strncmp (body, "\n\n", 2) || !strncmp (body, "\n\r\n", 3)) | 657 | if (!strncmp(body, "\n\n", 2) || !strncmp(body, "\n\r\n", 3)) { |
| 634 | break; | 658 | break; |
| 635 | } | 659 | } |
| 660 | } | ||
| 636 | 661 | ||
| 637 | if (!*body) | 662 | if (!*body) { |
| 638 | return 0; /* haven't read end of headers yet */ | 663 | return 0; /* haven't read end of headers yet */ |
| 664 | } | ||
| 639 | 665 | ||
| 640 | full_page[body - full_page] = 0; | 666 | full_page[body - full_page] = 0; |
| 641 | return 1; | 667 | return 1; |
| 642 | } | 668 | } |
| 643 | 669 | ||
| 644 | static time_t | 670 | static time_t parse_time_string(const char *string) { |
| 645 | parse_time_string (const char *string) | 671 | struct tm tm; |
| 646 | { | 672 | time_t t; |
| 647 | struct tm tm; | 673 | memset(&tm, 0, sizeof(tm)); |
| 648 | time_t t; | 674 | |
| 649 | memset (&tm, 0, sizeof(tm)); | 675 | /* Like this: Tue, 25 Dec 2001 02:59:03 GMT */ |
| 650 | 676 | ||
| 651 | /* Like this: Tue, 25 Dec 2001 02:59:03 GMT */ | 677 | if (isupper(string[0]) && /* Tue */ |
| 652 | 678 | islower(string[1]) && islower(string[2]) && ',' == string[3] && ' ' == string[4] && | |
| 653 | if (isupper (string[0]) && /* Tue */ | 679 | (isdigit(string[5]) || string[5] == ' ') && /* 25 */ |
| 654 | islower (string[1]) && | 680 | isdigit(string[6]) && ' ' == string[7] && isupper(string[8]) && /* Dec */ |
| 655 | islower (string[2]) && | 681 | islower(string[9]) && islower(string[10]) && ' ' == string[11] && |
| 656 | ',' == string[3] && | 682 | isdigit(string[12]) && /* 2001 */ |
| 657 | ' ' == string[4] && | 683 | isdigit(string[13]) && isdigit(string[14]) && isdigit(string[15]) && ' ' == string[16] && |
| 658 | (isdigit(string[5]) || string[5] == ' ') && /* 25 */ | 684 | isdigit(string[17]) && /* 02: */ |
| 659 | isdigit (string[6]) && | 685 | isdigit(string[18]) && ':' == string[19] && isdigit(string[20]) && /* 59: */ |
| 660 | ' ' == string[7] && | 686 | isdigit(string[21]) && ':' == string[22] && isdigit(string[23]) && /* 03 */ |
| 661 | isupper (string[8]) && /* Dec */ | 687 | isdigit(string[24]) && ' ' == string[25] && 'G' == string[26] && /* GMT */ |
| 662 | islower (string[9]) && | 688 | 'M' == string[27] && /* GMT */ |
| 663 | islower (string[10]) && | 689 | 'T' == string[28]) { |
| 664 | ' ' == string[11] && | 690 | |
| 665 | isdigit (string[12]) && /* 2001 */ | 691 | tm.tm_sec = 10 * (string[23] - '0') + (string[24] - '0'); |
| 666 | isdigit (string[13]) && | 692 | tm.tm_min = 10 * (string[20] - '0') + (string[21] - '0'); |
| 667 | isdigit (string[14]) && | 693 | tm.tm_hour = 10 * (string[17] - '0') + (string[18] - '0'); |
| 668 | isdigit (string[15]) && | 694 | tm.tm_mday = 10 * (string[5] == ' ' ? 0 : string[5] - '0') + (string[6] - '0'); |
| 669 | ' ' == string[16] && | 695 | tm.tm_mon = (!strncmp(string + 8, "Jan", 3) ? 0 |
| 670 | isdigit (string[17]) && /* 02: */ | 696 | : !strncmp(string + 8, "Feb", 3) ? 1 |
| 671 | isdigit (string[18]) && | 697 | : !strncmp(string + 8, "Mar", 3) ? 2 |
| 672 | ':' == string[19] && | 698 | : !strncmp(string + 8, "Apr", 3) ? 3 |
| 673 | isdigit (string[20]) && /* 59: */ | 699 | : !strncmp(string + 8, "May", 3) ? 4 |
| 674 | isdigit (string[21]) && | 700 | : !strncmp(string + 8, "Jun", 3) ? 5 |
| 675 | ':' == string[22] && | 701 | : !strncmp(string + 8, "Jul", 3) ? 6 |
| 676 | isdigit (string[23]) && /* 03 */ | 702 | : !strncmp(string + 8, "Aug", 3) ? 7 |
| 677 | isdigit (string[24]) && | 703 | : !strncmp(string + 8, "Sep", 3) ? 8 |
| 678 | ' ' == string[25] && | 704 | : !strncmp(string + 8, "Oct", 3) ? 9 |
| 679 | 'G' == string[26] && /* GMT */ | 705 | : !strncmp(string + 8, "Nov", 3) ? 10 |
| 680 | 'M' == string[27] && /* GMT */ | 706 | : !strncmp(string + 8, "Dec", 3) ? 11 |
| 681 | 'T' == string[28]) { | 707 | : -1); |
| 682 | 708 | tm.tm_year = ((1000 * (string[12] - '0') + 100 * (string[13] - '0') + | |
| 683 | tm.tm_sec = 10 * (string[23]-'0') + (string[24]-'0'); | 709 | 10 * (string[14] - '0') + (string[15] - '0')) - |
| 684 | tm.tm_min = 10 * (string[20]-'0') + (string[21]-'0'); | 710 | 1900); |
| 685 | tm.tm_hour = 10 * (string[17]-'0') + (string[18]-'0'); | 711 | |
| 686 | tm.tm_mday = 10 * (string[5] == ' ' ? 0 : string[5]-'0') + (string[6]-'0'); | 712 | tm.tm_isdst = 0; /* GMT is never in DST, right? */ |
| 687 | tm.tm_mon = (!strncmp (string+8, "Jan", 3) ? 0 : | 713 | |
| 688 | !strncmp (string+8, "Feb", 3) ? 1 : | 714 | if (tm.tm_mon < 0 || tm.tm_mday < 1 || tm.tm_mday > 31) { |
| 689 | !strncmp (string+8, "Mar", 3) ? 2 : | 715 | return 0; |
| 690 | !strncmp (string+8, "Apr", 3) ? 3 : | 716 | } |
| 691 | !strncmp (string+8, "May", 3) ? 4 : | 717 | |
| 692 | !strncmp (string+8, "Jun", 3) ? 5 : | 718 | /* |
| 693 | !strncmp (string+8, "Jul", 3) ? 6 : | 719 | This is actually wrong: we need to subtract the local timezone |
| 694 | !strncmp (string+8, "Aug", 3) ? 7 : | 720 | offset from GMT from this value. But, that's ok in this usage, |
| 695 | !strncmp (string+8, "Sep", 3) ? 8 : | 721 | because we only comparing these two GMT dates against each other, |
| 696 | !strncmp (string+8, "Oct", 3) ? 9 : | 722 | so it doesn't matter what time zone we parse them in. |
| 697 | !strncmp (string+8, "Nov", 3) ? 10 : | 723 | */ |
| 698 | !strncmp (string+8, "Dec", 3) ? 11 : | 724 | |
| 699 | -1); | 725 | t = mktime(&tm); |
| 700 | tm.tm_year = ((1000 * (string[12]-'0') + | 726 | if (t == (time_t)-1) { |
| 701 | 100 * (string[13]-'0') + | 727 | t = 0; |
| 702 | 10 * (string[14]-'0') + | 728 | } |
| 703 | (string[15]-'0')) | 729 | |
| 704 | - 1900); | 730 | if (verbose) { |
| 705 | 731 | const char *s = string; | |
| 706 | tm.tm_isdst = 0; /* GMT is never in DST, right? */ | 732 | while (*s && *s != '\r' && *s != '\n') { |
| 707 | 733 | fputc(*s++, stdout); | |
| 708 | if (tm.tm_mon < 0 || tm.tm_mday < 1 || tm.tm_mday > 31) | 734 | } |
| 709 | return 0; | 735 | printf(" ==> %lu\n", (unsigned long)t); |
| 710 | 736 | } | |
| 711 | /* | 737 | |
| 712 | This is actually wrong: we need to subtract the local timezone | 738 | return t; |
| 713 | offset from GMT from this value. But, that's ok in this usage, | 739 | } |
| 714 | because we only comparing these two GMT dates against each other, | 740 | return 0; |
| 715 | so it doesn't matter what time zone we parse them in. | ||
| 716 | */ | ||
| 717 | |||
| 718 | t = mktime (&tm); | ||
| 719 | if (t == (time_t) -1) t = 0; | ||
| 720 | |||
| 721 | if (verbose) { | ||
| 722 | const char *s = string; | ||
| 723 | while (*s && *s != '\r' && *s != '\n') | ||
| 724 | fputc (*s++, stdout); | ||
| 725 | printf (" ==> %lu\n", (unsigned long) t); | ||
| 726 | } | ||
| 727 | |||
| 728 | return t; | ||
| 729 | |||
| 730 | } else { | ||
| 731 | return 0; | ||
| 732 | } | ||
| 733 | } | 741 | } |
| 734 | 742 | ||
| 735 | /* Checks if the server 'reply' is one of the expected 'statuscodes' */ | 743 | /* Checks if the server 'reply' is one of the expected 'statuscodes' */ |
| 736 | static int | 744 | static int expected_statuscode(const char *reply, const char *statuscodes) { |
| 737 | expected_statuscode (const char *reply, const char *statuscodes) | 745 | char *expected; |
| 738 | { | 746 | char *code; |
| 739 | char *expected, *code; | 747 | int result = 0; |
| 740 | int result = 0; | 748 | |
| 741 | 749 | if ((expected = strdup(statuscodes)) == NULL) { | |
| 742 | if ((expected = strdup (statuscodes)) == NULL) | 750 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n")); |
| 743 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n")); | 751 | } |
| 744 | 752 | ||
| 745 | for (code = strtok (expected, ","); code != NULL; code = strtok (NULL, ",")) | 753 | for (code = strtok(expected, ","); code != NULL; code = strtok(NULL, ",")) { |
| 746 | if (strstr (reply, code) != NULL) { | 754 | if (strstr(reply, code) != NULL) { |
| 747 | result = 1; | 755 | result = 1; |
| 748 | break; | 756 | break; |
| 749 | } | 757 | } |
| 750 | 758 | } | |
| 751 | free (expected); | 759 | |
| 752 | return result; | 760 | free(expected); |
| 761 | return result; | ||
| 753 | } | 762 | } |
| 754 | 763 | ||
| 755 | static int | 764 | static int check_document_dates(const char *headers, char **msg) { |
| 756 | check_document_dates (const char *headers, char **msg) | 765 | const char *s; |
| 757 | { | 766 | char *server_date = 0; |
| 758 | const char *s; | 767 | char *document_date = 0; |
| 759 | char *server_date = 0; | 768 | int date_result = STATE_OK; |
| 760 | char *document_date = 0; | 769 | |
| 761 | int date_result = STATE_OK; | 770 | s = headers; |
| 762 | 771 | while (*s) { | |
| 763 | s = headers; | 772 | const char *field = s; |
| 764 | while (*s) { | 773 | const char *value = 0; |
| 765 | const char *field = s; | 774 | |
| 766 | const char *value = 0; | 775 | /* Find the end of the header field */ |
| 767 | 776 | while (*s && !isspace(*s) && *s != ':') { | |
| 768 | /* Find the end of the header field */ | 777 | s++; |
| 769 | while (*s && !isspace(*s) && *s != ':') | 778 | } |
| 770 | s++; | 779 | |
| 771 | 780 | /* Remember the header value, if any. */ | |
| 772 | /* Remember the header value, if any. */ | 781 | if (*s == ':') { |
| 773 | if (*s == ':') | 782 | value = ++s; |
| 774 | value = ++s; | 783 | } |
| 775 | 784 | ||
| 776 | /* Skip to the end of the header, including continuation lines. */ | 785 | /* Skip to the end of the header, including continuation lines. */ |
| 777 | while (*s && !(*s == '\n' && (s[1] != ' ' && s[1] != '\t'))) | 786 | while (*s && !(*s == '\n' && (s[1] != ' ' && s[1] != '\t'))) { |
| 778 | s++; | 787 | s++; |
| 779 | 788 | } | |
| 780 | /* Avoid stepping over end-of-string marker */ | 789 | |
| 781 | if (*s) | 790 | /* Avoid stepping over end-of-string marker */ |
| 782 | s++; | 791 | if (*s) { |
| 783 | 792 | s++; | |
| 784 | /* Process this header. */ | 793 | } |
| 785 | if (value && value > field+2) { | 794 | |
| 786 | char *ff = (char *) malloc (value-field); | 795 | /* Process this header. */ |
| 787 | char *ss = ff; | 796 | if (value && value > field + 2) { |
| 788 | while (field < value-1) | 797 | char *ff = (char *)malloc(value - field); |
| 789 | *ss++ = tolower(*field++); | 798 | char *ss = ff; |
| 790 | *ss++ = 0; | 799 | while (field < value - 1) { |
| 791 | 800 | *ss++ = tolower(*field++); | |
| 792 | if (!strcmp (ff, "date") || !strcmp (ff, "last-modified")) { | 801 | } |
| 793 | const char *e; | 802 | *ss++ = 0; |
| 794 | while (*value && isspace (*value)) | 803 | |
| 795 | value++; | 804 | if (!strcmp(ff, "date") || !strcmp(ff, "last-modified")) { |
| 796 | for (e = value; *e && *e != '\r' && *e != '\n'; e++) | 805 | const char *e; |
| 797 | ; | 806 | while (*value && isspace(*value)) { |
| 798 | ss = (char *) malloc (e - value + 1); | 807 | value++; |
| 799 | strncpy (ss, value, e - value); | 808 | } |
| 800 | ss[e - value] = 0; | 809 | for (e = value; *e && *e != '\r' && *e != '\n'; e++) { |
| 801 | if (!strcmp (ff, "date")) { | 810 | ; |
| 802 | if (server_date) free (server_date); | 811 | } |
| 803 | server_date = ss; | 812 | ss = (char *)malloc(e - value + 1); |
| 804 | } else { | 813 | strncpy(ss, value, e - value); |
| 805 | if (document_date) free (document_date); | 814 | ss[e - value] = 0; |
| 806 | document_date = ss; | 815 | if (!strcmp(ff, "date")) { |
| 807 | } | 816 | if (server_date) { |
| 808 | } | 817 | free(server_date); |
| 809 | free (ff); | 818 | } |
| 810 | } | 819 | server_date = ss; |
| 811 | } | 820 | } else { |
| 812 | 821 | if (document_date) { | |
| 813 | /* Done parsing the body. Now check the dates we (hopefully) parsed. */ | 822 | free(document_date); |
| 814 | if (!server_date || !*server_date) { | 823 | } |
| 815 | xasprintf (msg, _("%sServer date unknown, "), *msg); | 824 | document_date = ss; |
| 816 | date_result = max_state_alt(STATE_UNKNOWN, date_result); | 825 | } |
| 817 | } else if (!document_date || !*document_date) { | 826 | } |
| 818 | xasprintf (msg, _("%sDocument modification date unknown, "), *msg); | 827 | free(ff); |
| 819 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 828 | } |
| 820 | } else { | 829 | } |
| 821 | time_t srv_data = parse_time_string (server_date); | 830 | |
| 822 | time_t doc_data = parse_time_string (document_date); | 831 | /* Done parsing the body. Now check the dates we (hopefully) parsed. */ |
| 823 | 832 | if (!server_date || !*server_date) { | |
| 824 | if (srv_data <= 0) { | 833 | xasprintf(msg, _("%sServer date unknown, "), *msg); |
| 825 | xasprintf (msg, _("%sServer date \"%100s\" unparsable, "), *msg, server_date); | 834 | date_result = max_state_alt(STATE_UNKNOWN, date_result); |
| 826 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 835 | } else if (!document_date || !*document_date) { |
| 827 | } else if (doc_data <= 0) { | 836 | xasprintf(msg, _("%sDocument modification date unknown, "), *msg); |
| 828 | xasprintf (msg, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date); | 837 | date_result = max_state_alt(STATE_CRITICAL, date_result); |
| 829 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 838 | } else { |
| 830 | } else if (doc_data > srv_data + 30) { | 839 | time_t srv_data = parse_time_string(server_date); |
| 831 | xasprintf (msg, _("%sDocument is %d seconds in the future, "), *msg, (int)doc_data - (int)srv_data); | 840 | time_t doc_data = parse_time_string(document_date); |
| 832 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 841 | |
| 833 | } else if (doc_data < srv_data - maximum_age) { | 842 | if (srv_data <= 0) { |
| 834 | int n = (srv_data - doc_data); | 843 | xasprintf(msg, _("%sServer date \"%100s\" unparsable, "), *msg, server_date); |
| 835 | if (n > (60 * 60 * 24 * 2)) { | 844 | date_result = max_state_alt(STATE_CRITICAL, date_result); |
| 836 | xasprintf (msg, _("%sLast modified %.1f days ago, "), *msg, ((float) n) / (60 * 60 * 24)); | 845 | } else if (doc_data <= 0) { |
| 837 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 846 | xasprintf(msg, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date); |
| 838 | } else { | 847 | date_result = max_state_alt(STATE_CRITICAL, date_result); |
| 839 | xasprintf (msg, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), (n / 60) % 60, n % 60); | 848 | } else if (doc_data > srv_data + 30) { |
| 840 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 849 | xasprintf(msg, _("%sDocument is %d seconds in the future, "), *msg, |
| 841 | } | 850 | (int)doc_data - (int)srv_data); |
| 842 | } | 851 | date_result = max_state_alt(STATE_CRITICAL, date_result); |
| 843 | free (server_date); | 852 | } else if (doc_data < srv_data - maximum_age) { |
| 844 | free (document_date); | 853 | int n = (srv_data - doc_data); |
| 845 | } | 854 | if (n > (60 * 60 * 24 * 2)) { |
| 846 | return date_result; | 855 | xasprintf(msg, _("%sLast modified %.1f days ago, "), *msg, |
| 856 | ((float)n) / (60 * 60 * 24)); | ||
| 857 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
| 858 | } else { | ||
| 859 | xasprintf(msg, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), | ||
| 860 | (n / 60) % 60, n % 60); | ||
| 861 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
| 862 | } | ||
| 863 | } | ||
| 864 | free(server_date); | ||
| 865 | free(document_date); | ||
| 866 | } | ||
| 867 | return date_result; | ||
| 847 | } | 868 | } |
| 848 | 869 | ||
| 849 | int | 870 | int get_content_length(const char *headers) { |
| 850 | get_content_length (const char *headers) | 871 | const char *s; |
| 851 | { | 872 | int content_length = 0; |
| 852 | const char *s; | 873 | |
| 853 | int content_length = 0; | 874 | s = headers; |
| 854 | 875 | while (*s) { | |
| 855 | s = headers; | 876 | const char *field = s; |
| 856 | while (*s) { | 877 | const char *value = 0; |
| 857 | const char *field = s; | 878 | |
| 858 | const char *value = 0; | 879 | /* Find the end of the header field */ |
| 859 | 880 | while (*s && !isspace(*s) && *s != ':') { | |
| 860 | /* Find the end of the header field */ | 881 | s++; |
| 861 | while (*s && !isspace(*s) && *s != ':') | 882 | } |
| 862 | s++; | 883 | |
| 863 | 884 | /* Remember the header value, if any. */ | |
| 864 | /* Remember the header value, if any. */ | 885 | if (*s == ':') { |
| 865 | if (*s == ':') | 886 | value = ++s; |
| 866 | value = ++s; | 887 | } |
| 867 | 888 | ||
| 868 | /* Skip to the end of the header, including continuation lines. */ | 889 | /* Skip to the end of the header, including continuation lines. */ |
| 869 | while (*s && !(*s == '\n' && (s[1] != ' ' && s[1] != '\t'))) | 890 | while (*s && !(*s == '\n' && (s[1] != ' ' && s[1] != '\t'))) { |
| 870 | s++; | 891 | s++; |
| 871 | 892 | } | |
| 872 | /* Avoid stepping over end-of-string marker */ | 893 | |
| 873 | if (*s) | 894 | /* Avoid stepping over end-of-string marker */ |
| 874 | s++; | 895 | if (*s) { |
| 875 | 896 | s++; | |
| 876 | /* Process this header. */ | 897 | } |
| 877 | if (value && value > field+2) { | 898 | |
| 878 | char *ff = (char *) malloc (value-field); | 899 | /* Process this header. */ |
| 879 | char *ss = ff; | 900 | if (value && value > field + 2) { |
| 880 | while (field < value-1) | 901 | char *ff = (char *)malloc(value - field); |
| 881 | *ss++ = tolower(*field++); | 902 | char *ss = ff; |
| 882 | *ss++ = 0; | 903 | while (field < value - 1) { |
| 883 | 904 | *ss++ = tolower(*field++); | |
| 884 | if (!strcmp (ff, "content-length")) { | 905 | } |
| 885 | const char *e; | 906 | *ss++ = 0; |
| 886 | while (*value && isspace (*value)) | 907 | |
| 887 | value++; | 908 | if (!strcmp(ff, "content-length")) { |
| 888 | for (e = value; *e && *e != '\r' && *e != '\n'; e++) | 909 | const char *e; |
| 889 | ; | 910 | while (*value && isspace(*value)) { |
| 890 | ss = (char *) malloc (e - value + 1); | 911 | value++; |
| 891 | strncpy (ss, value, e - value); | 912 | } |
| 892 | ss[e - value] = 0; | 913 | for (e = value; *e && *e != '\r' && *e != '\n'; e++) { |
| 893 | content_length = atoi(ss); | 914 | ; |
| 894 | free (ss); | 915 | } |
| 895 | } | 916 | ss = (char *)malloc(e - value + 1); |
| 896 | free (ff); | 917 | strncpy(ss, value, e - value); |
| 897 | } | 918 | ss[e - value] = 0; |
| 898 | } | 919 | content_length = atoi(ss); |
| 899 | return (content_length); | 920 | free(ss); |
| 921 | } | ||
| 922 | free(ff); | ||
| 923 | } | ||
| 924 | } | ||
| 925 | return (content_length); | ||
| 900 | } | 926 | } |
| 901 | 927 | ||
| 902 | char * | 928 | char *prepend_slash(char *path) { |
| 903 | prepend_slash (char *path) | 929 | char *newpath; |
| 904 | { | ||
| 905 | char *newpath; | ||
| 906 | 930 | ||
| 907 | if (path[0] == '/') | 931 | if (path[0] == '/') { |
| 908 | return path; | 932 | return path; |
| 933 | } | ||
| 909 | 934 | ||
| 910 | if ((newpath = malloc (strlen(path) + 2)) == NULL) | 935 | if ((newpath = malloc(strlen(path) + 2)) == NULL) { |
| 911 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n")); | 936 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n")); |
| 912 | newpath[0] = '/'; | 937 | } |
| 913 | strcpy (newpath + 1, path); | 938 | newpath[0] = '/'; |
| 914 | free (path); | 939 | strcpy(newpath + 1, path); |
| 915 | return newpath; | 940 | free(path); |
| 941 | return newpath; | ||
| 916 | } | 942 | } |
| 917 | 943 | ||
| 918 | int | 944 | int check_http(void) { |
| 919 | check_http (void) | 945 | char *msg; |
| 920 | { | 946 | char *status_line; |
| 921 | char *msg; | 947 | char *status_code; |
| 922 | char *status_line; | 948 | char *header; |
| 923 | char *status_code; | 949 | char *page; |
| 924 | char *header; | 950 | char *auth; |
| 925 | char *page; | 951 | int http_status; |
| 926 | char *auth; | 952 | int i = 0; |
| 927 | int http_status; | 953 | size_t pagesize = 0; |
| 928 | int i = 0; | 954 | char *full_page; |
| 929 | size_t pagesize = 0; | 955 | char *full_page_new; |
| 930 | char *full_page; | 956 | char *buf; |
| 931 | char *full_page_new; | 957 | char *pos; |
| 932 | char *buf; | 958 | long microsec = 0L; |
| 933 | char *pos; | 959 | double elapsed_time = 0.0; |
| 934 | long microsec = 0L; | 960 | long microsec_connect = 0L; |
| 935 | double elapsed_time = 0.0; | 961 | double elapsed_time_connect = 0.0; |
| 936 | long microsec_connect = 0L; | 962 | long microsec_ssl = 0L; |
| 937 | double elapsed_time_connect = 0.0; | 963 | double elapsed_time_ssl = 0.0; |
| 938 | long microsec_ssl = 0L; | 964 | long microsec_firstbyte = 0L; |
| 939 | double elapsed_time_ssl = 0.0; | 965 | double elapsed_time_firstbyte = 0.0; |
| 940 | long microsec_firstbyte = 0L; | 966 | long microsec_headers = 0L; |
| 941 | double elapsed_time_firstbyte = 0.0; | 967 | double elapsed_time_headers = 0.0; |
| 942 | long microsec_headers = 0L; | 968 | long microsec_transfer = 0L; |
| 943 | double elapsed_time_headers = 0.0; | 969 | double elapsed_time_transfer = 0.0; |
| 944 | long microsec_transfer = 0L; | 970 | int page_len = 0; |
| 945 | double elapsed_time_transfer = 0.0; | 971 | int result = STATE_OK; |
| 946 | int page_len = 0; | 972 | char *force_host_header = NULL; |
| 947 | int result = STATE_OK; | 973 | |
| 948 | char *force_host_header = NULL; | 974 | /* try to connect to the host at the given port number */ |
| 949 | 975 | gettimeofday(&tv_temp, NULL); | |
| 950 | /* try to connect to the host at the given port number */ | 976 | if (my_tcp_connect(server_address, server_port, &sd) != STATE_OK) { |
| 951 | gettimeofday (&tv_temp, NULL); | 977 | die(STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n")); |
| 952 | if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) | 978 | } |
| 953 | die (STATE_CRITICAL, _("HTTP CRITICAL - Unable to open TCP socket\n")); | 979 | microsec_connect = deltime(tv_temp); |
| 954 | microsec_connect = deltime (tv_temp); | 980 | |
| 955 | 981 | /* if we are called with the -I option, the -j method is CONNECT and */ | |
| 956 | /* if we are called with the -I option, the -j method is CONNECT and */ | 982 | /* we received -S for SSL, then we tunnel the request through a proxy*/ |
| 957 | /* we received -S for SSL, then we tunnel the request through a proxy*/ | 983 | /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */ |
| 958 | /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */ | 984 | |
| 959 | 985 | if (server_address != NULL && strcmp(http_method, "CONNECT") == 0 && host_name != NULL && | |
| 960 | if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 | 986 | use_ssl) { |
| 961 | && host_name != NULL && use_ssl == true) { | 987 | |
| 962 | 988 | if (verbose) { | |
| 963 | if (verbose) printf ("Entering CONNECT tunnel mode with proxy %s:%d to dst %s:%d\n", server_address, server_port, host_name, HTTPS_PORT); | 989 | printf("Entering CONNECT tunnel mode with proxy %s:%d to dst %s:%d\n", server_address, |
| 964 | asprintf (&buf, "%s %s:%d HTTP/1.1\r\n%s\r\n", http_method, host_name, HTTPS_PORT, user_agent); | 990 | server_port, host_name, HTTPS_PORT); |
| 965 | if (strlen(proxy_auth)) { | 991 | } |
| 966 | base64_encode_alloc (proxy_auth, strlen (proxy_auth), &auth); | 992 | asprintf(&buf, "%s %s:%d HTTP/1.1\r\n%s\r\n", http_method, host_name, HTTPS_PORT, |
| 967 | xasprintf (&buf, "%sProxy-Authorization: Basic %s\r\n", buf, auth); | 993 | user_agent); |
| 968 | } | 994 | if (strlen(proxy_auth)) { |
| 969 | /* optionally send any other header tag */ | 995 | base64_encode_alloc(proxy_auth, strlen(proxy_auth), &auth); |
| 970 | if (http_opt_headers_count) { | 996 | xasprintf(&buf, "%sProxy-Authorization: Basic %s\r\n", buf, auth); |
| 971 | for (i = 0; i < http_opt_headers_count ; i++) { | 997 | } |
| 972 | if (force_host_header != http_opt_headers[i]) { | 998 | /* optionally send any other header tag */ |
| 973 | xasprintf (&buf, "%s%s\r\n", buf, http_opt_headers[i]); | 999 | if (http_opt_headers_count) { |
| 974 | } | 1000 | for (i = 0; i < http_opt_headers_count; i++) { |
| 975 | } | 1001 | if (force_host_header != http_opt_headers[i]) { |
| 976 | /* This cannot be free'd here because a redirection will then try to access this and segfault */ | 1002 | xasprintf(&buf, "%s%s\r\n", buf, http_opt_headers[i]); |
| 977 | /* Covered in a testcase in tests/check_http.t */ | 1003 | } |
| 978 | /* free(http_opt_headers); */ | 1004 | } |
| 979 | } | 1005 | /* This cannot be free'd here because a redirection will then try to access this and |
| 980 | asprintf (&buf, "%sProxy-Connection: keep-alive\r\n", buf); | 1006 | * segfault */ |
| 981 | asprintf (&buf, "%sHost: %s\r\n", buf, host_name); | 1007 | /* Covered in a testcase in tests/check_http.t */ |
| 982 | /* we finished our request, send empty line with CRLF */ | 1008 | /* free(http_opt_headers); */ |
| 983 | asprintf (&buf, "%s%s", buf, CRLF); | 1009 | } |
| 984 | if (verbose) printf ("%s\n", buf); | 1010 | asprintf(&buf, "%sProxy-Connection: keep-alive\r\n", buf); |
| 985 | send(sd, buf, strlen (buf), 0); | 1011 | asprintf(&buf, "%sHost: %s\r\n", buf, host_name); |
| 986 | buf[0]='\0'; | 1012 | /* we finished our request, send empty line with CRLF */ |
| 987 | 1013 | asprintf(&buf, "%s%s", buf, CRLF); | |
| 988 | if (verbose) printf ("Receive response from proxy\n"); | 1014 | if (verbose) { |
| 989 | read (sd, buffer, MAX_INPUT_BUFFER-1); | 1015 | printf("%s\n", buf); |
| 990 | if (verbose) printf ("%s", buffer); | 1016 | } |
| 991 | /* Here we should check if we got HTTP/1.1 200 Connection established */ | 1017 | send(sd, buf, strlen(buf), 0); |
| 992 | } | 1018 | buf[0] = '\0'; |
| 1019 | |||
| 1020 | if (verbose) { | ||
| 1021 | printf("Receive response from proxy\n"); | ||
| 1022 | } | ||
| 1023 | read(sd, buffer, MAX_INPUT_BUFFER - 1); | ||
| 1024 | if (verbose) { | ||
| 1025 | printf("%s", buffer); | ||
| 1026 | } | ||
| 1027 | /* Here we should check if we got HTTP/1.1 200 Connection established */ | ||
| 1028 | } | ||
| 993 | #ifdef HAVE_SSL | 1029 | #ifdef HAVE_SSL |
| 994 | elapsed_time_connect = (double)microsec_connect / 1.0e6; | 1030 | elapsed_time_connect = (double)microsec_connect / 1.0e6; |
| 995 | if (use_ssl == true) { | 1031 | if (use_ssl) { |
| 996 | gettimeofday (&tv_temp, NULL); | 1032 | gettimeofday(&tv_temp, NULL); |
| 997 | result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey); | 1033 | result = np_net_ssl_init_with_hostname_version_and_cert( |
| 998 | if (verbose) printf ("SSL initialized\n"); | 1034 | sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey); |
| 999 | if (result != STATE_OK) | 1035 | if (verbose) { |
| 1000 | die (STATE_CRITICAL, NULL); | 1036 | printf("SSL initialized\n"); |
| 1001 | microsec_ssl = deltime (tv_temp); | 1037 | } |
| 1002 | elapsed_time_ssl = (double)microsec_ssl / 1.0e6; | 1038 | if (result != STATE_OK) { |
| 1003 | if (check_cert == true) { | 1039 | die(STATE_CRITICAL, _("HTTP CRITICAL - SSL error\n")); |
| 1004 | result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); | 1040 | } |
| 1005 | if (continue_after_check_cert == false) { | 1041 | microsec_ssl = deltime(tv_temp); |
| 1006 | if (sd) close(sd); | 1042 | elapsed_time_ssl = (double)microsec_ssl / 1.0e6; |
| 1007 | np_net_ssl_cleanup(); | 1043 | if (check_cert) { |
| 1008 | return result; | 1044 | result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); |
| 1009 | } | 1045 | if (!continue_after_check_cert) { |
| 1010 | } | 1046 | if (sd) { |
| 1011 | } | 1047 | close(sd); |
| 1048 | } | ||
| 1049 | np_net_ssl_cleanup(); | ||
| 1050 | return result; | ||
| 1051 | } | ||
| 1052 | } | ||
| 1053 | } | ||
| 1012 | #endif /* HAVE_SSL */ | 1054 | #endif /* HAVE_SSL */ |
| 1013 | 1055 | ||
| 1014 | if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 | 1056 | if (server_address != NULL && strcmp(http_method, "CONNECT") == 0 && host_name != NULL && |
| 1015 | && host_name != NULL && use_ssl == true) | 1057 | use_ssl) { |
| 1016 | asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method_proxy, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); | 1058 | asprintf(&buf, "%s %s %s\r\n%s\r\n", http_method_proxy, server_url, |
| 1017 | else | 1059 | host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); |
| 1018 | asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); | 1060 | } else { |
| 1019 | 1061 | asprintf(&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, | |
| 1020 | /* tell HTTP/1.1 servers not to keep the connection alive */ | 1062 | host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); |
| 1021 | xasprintf (&buf, "%sConnection: close\r\n", buf); | 1063 | } |
| 1022 | 1064 | ||
| 1023 | /* check if Host header is explicitly set in options */ | 1065 | /* tell HTTP/1.1 servers not to keep the connection alive */ |
| 1024 | if (http_opt_headers_count) { | 1066 | xasprintf(&buf, "%sConnection: close\r\n", buf); |
| 1025 | for (i = 0; i < http_opt_headers_count ; i++) { | 1067 | |
| 1026 | if (strncmp(http_opt_headers[i], "Host:", 5) == 0) { | 1068 | /* check if Host header is explicitly set in options */ |
| 1027 | force_host_header = http_opt_headers[i]; | 1069 | if (http_opt_headers_count) { |
| 1028 | } | 1070 | for (i = 0; i < http_opt_headers_count; i++) { |
| 1029 | } | 1071 | if (strncmp(http_opt_headers[i], "Host:", 5) == 0) { |
| 1030 | } | 1072 | force_host_header = http_opt_headers[i]; |
| 1031 | 1073 | } | |
| 1032 | /* optionally send the host header info */ | 1074 | } |
| 1033 | if (host_name) { | 1075 | } |
| 1034 | if (force_host_header) { | 1076 | |
| 1035 | xasprintf (&buf, "%s%s\r\n", buf, force_host_header); | 1077 | /* optionally send the host header info */ |
| 1036 | } | 1078 | if (host_name) { |
| 1037 | else { | 1079 | if (force_host_header) { |
| 1038 | /* | 1080 | xasprintf(&buf, "%s%s\r\n", buf, force_host_header); |
| 1039 | * Specify the port only if we're using a non-default port (see RFC 2616, | 1081 | } else { |
| 1040 | * 14.23). Some server applications/configurations cause trouble if the | 1082 | /* |
| 1041 | * (default) port is explicitly specified in the "Host:" header line. | 1083 | * Specify the port only if we're using a non-default port (see RFC 2616, |
| 1042 | */ | 1084 | * 14.23). Some server applications/configurations cause trouble if the |
| 1043 | if ((use_ssl == false && virtual_port == HTTP_PORT) || | 1085 | * (default) port is explicitly specified in the "Host:" header line. |
| 1044 | (use_ssl == true && virtual_port == HTTPS_PORT) || | 1086 | */ |
| 1045 | (server_address != NULL && strcmp(http_method, "CONNECT") == 0 | 1087 | if ((!use_ssl && virtual_port == HTTP_PORT) || |
| 1046 | && host_name != NULL && use_ssl == true)) | 1088 | (use_ssl && virtual_port == HTTPS_PORT) || |
| 1047 | xasprintf (&buf, "%sHost: %s\r\n", buf, host_name); | 1089 | (server_address != NULL && strcmp(http_method, "CONNECT") == 0 && |
| 1048 | else | 1090 | host_name != NULL && use_ssl)) { |
| 1049 | xasprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, virtual_port); | 1091 | xasprintf(&buf, "%sHost: %s\r\n", buf, host_name); |
| 1050 | } | 1092 | } else { |
| 1051 | } | 1093 | xasprintf(&buf, "%sHost: %s:%d\r\n", buf, host_name, virtual_port); |
| 1052 | 1094 | } | |
| 1053 | /* optionally send any other header tag */ | 1095 | } |
| 1054 | if (http_opt_headers_count) { | 1096 | } |
| 1055 | for (i = 0; i < http_opt_headers_count ; i++) { | 1097 | |
| 1056 | if (force_host_header != http_opt_headers[i]) { | 1098 | /* optionally send any other header tag */ |
| 1057 | xasprintf (&buf, "%s%s\r\n", buf, http_opt_headers[i]); | 1099 | if (http_opt_headers_count) { |
| 1058 | } | 1100 | for (i = 0; i < http_opt_headers_count; i++) { |
| 1059 | } | 1101 | if (force_host_header != http_opt_headers[i]) { |
| 1060 | /* This cannot be free'd here because a redirection will then try to access this and segfault */ | 1102 | xasprintf(&buf, "%s%s\r\n", buf, http_opt_headers[i]); |
| 1061 | /* Covered in a testcase in tests/check_http.t */ | 1103 | } |
| 1062 | /* free(http_opt_headers); */ | 1104 | } |
| 1063 | } | 1105 | /* This cannot be free'd here because a redirection will then try to access this and |
| 1064 | 1106 | * segfault */ | |
| 1065 | /* optionally send the authentication info */ | 1107 | /* Covered in a testcase in tests/check_http.t */ |
| 1066 | if (strlen(user_auth)) { | 1108 | /* free(http_opt_headers); */ |
| 1067 | base64_encode_alloc (user_auth, strlen (user_auth), &auth); | 1109 | } |
| 1068 | xasprintf (&buf, "%sAuthorization: Basic %s\r\n", buf, auth); | 1110 | |
| 1069 | } | 1111 | /* optionally send the authentication info */ |
| 1070 | 1112 | if (strlen(user_auth)) { | |
| 1071 | /* optionally send the proxy authentication info */ | 1113 | base64_encode_alloc(user_auth, strlen(user_auth), &auth); |
| 1072 | if (strlen(proxy_auth)) { | 1114 | xasprintf(&buf, "%sAuthorization: Basic %s\r\n", buf, auth); |
| 1073 | base64_encode_alloc (proxy_auth, strlen (proxy_auth), &auth); | 1115 | } |
| 1074 | xasprintf (&buf, "%sProxy-Authorization: Basic %s\r\n", buf, auth); | 1116 | |
| 1075 | } | 1117 | /* optionally send the proxy authentication info */ |
| 1076 | 1118 | if (strlen(proxy_auth)) { | |
| 1077 | /* either send http POST data (any data, not only POST)*/ | 1119 | base64_encode_alloc(proxy_auth, strlen(proxy_auth), &auth); |
| 1078 | if (http_post_data) { | 1120 | xasprintf(&buf, "%sProxy-Authorization: Basic %s\r\n", buf, auth); |
| 1079 | if (http_content_type) { | 1121 | } |
| 1080 | xasprintf (&buf, "%sContent-Type: %s\r\n", buf, http_content_type); | 1122 | |
| 1081 | } else { | 1123 | /* either send http POST data (any data, not only POST)*/ |
| 1082 | xasprintf (&buf, "%sContent-Type: application/x-www-form-urlencoded\r\n", buf); | 1124 | if (http_post_data) { |
| 1083 | } | 1125 | if (http_content_type) { |
| 1084 | 1126 | xasprintf(&buf, "%sContent-Type: %s\r\n", buf, http_content_type); | |
| 1085 | xasprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, (int)strlen (http_post_data)); | 1127 | } else { |
| 1086 | xasprintf (&buf, "%s%s", buf, http_post_data); | 1128 | xasprintf(&buf, "%sContent-Type: application/x-www-form-urlencoded\r\n", buf); |
| 1087 | } else { | 1129 | } |
| 1088 | /* or just a newline so the server knows we're done with the request */ | 1130 | |
| 1089 | xasprintf (&buf, "%s%s", buf, CRLF); | 1131 | xasprintf(&buf, "%sContent-Length: %i\r\n\r\n", buf, (int)strlen(http_post_data)); |
| 1090 | } | 1132 | xasprintf(&buf, "%s%s", buf, http_post_data); |
| 1091 | 1133 | } else { | |
| 1092 | if (verbose) printf ("%s\n", buf); | 1134 | /* or just a newline so the server knows we're done with the request */ |
| 1093 | gettimeofday (&tv_temp, NULL); | 1135 | xasprintf(&buf, "%s%s", buf, CRLF); |
| 1094 | my_send (buf, strlen (buf)); | 1136 | } |
| 1095 | microsec_headers = deltime (tv_temp); | 1137 | |
| 1096 | elapsed_time_headers = (double)microsec_headers / 1.0e6; | 1138 | if (verbose) { |
| 1097 | 1139 | printf("%s\n", buf); | |
| 1098 | /* fetch the page */ | 1140 | } |
| 1099 | full_page = strdup(""); | 1141 | gettimeofday(&tv_temp, NULL); |
| 1100 | gettimeofday (&tv_temp, NULL); | 1142 | my_send(buf, strlen(buf)); |
| 1101 | while ((i = my_recv (buffer, MAX_INPUT_BUFFER-1)) > 0) { | 1143 | microsec_headers = deltime(tv_temp); |
| 1102 | if ((i >= 1) && (elapsed_time_firstbyte <= 0.000001)) { | 1144 | elapsed_time_headers = (double)microsec_headers / 1.0e6; |
| 1103 | microsec_firstbyte = deltime (tv_temp); | 1145 | |
| 1104 | elapsed_time_firstbyte = (double)microsec_firstbyte / 1.0e6; | 1146 | /* fetch the page */ |
| 1105 | } | 1147 | full_page = strdup(""); |
| 1106 | while ((pos = memchr(buffer, '\0', i))) { | 1148 | gettimeofday(&tv_temp, NULL); |
| 1107 | /* replace nul character with a blank */ | 1149 | while ((i = my_recv(buffer, MAX_INPUT_BUFFER - 1)) > 0) { |
| 1108 | *pos = ' '; | 1150 | if ((i >= 1) && (elapsed_time_firstbyte <= 0.000001)) { |
| 1109 | } | 1151 | microsec_firstbyte = deltime(tv_temp); |
| 1110 | buffer[i] = '\0'; | 1152 | elapsed_time_firstbyte = (double)microsec_firstbyte / 1.0e6; |
| 1111 | 1153 | } | |
| 1112 | if ((full_page_new = realloc(full_page, pagesize + i + 1)) == NULL) | 1154 | while ((pos = memchr(buffer, '\0', i))) { |
| 1113 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate memory for full_page\n")); | 1155 | /* replace nul character with a blank */ |
| 1114 | 1156 | *pos = ' '; | |
| 1115 | memmove(&full_page_new[pagesize], buffer, i + 1); | 1157 | } |
| 1116 | 1158 | buffer[i] = '\0'; | |
| 1117 | full_page = full_page_new; | 1159 | |
| 1118 | 1160 | if ((full_page_new = realloc(full_page, pagesize + i + 1)) == NULL) { | |
| 1119 | pagesize += i; | 1161 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate memory for full_page\n")); |
| 1120 | 1162 | } | |
| 1121 | if (no_body && document_headers_done (full_page)) { | 1163 | |
| 1122 | i = 0; | 1164 | memmove(&full_page_new[pagesize], buffer, i + 1); |
| 1123 | break; | 1165 | |
| 1124 | } | 1166 | full_page = full_page_new; |
| 1125 | } | 1167 | |
| 1126 | microsec_transfer = deltime (tv_temp); | 1168 | pagesize += i; |
| 1127 | elapsed_time_transfer = (double)microsec_transfer / 1.0e6; | 1169 | |
| 1128 | 1170 | if (no_body && document_headers_done(full_page)) { | |
| 1129 | if (i < 0 && errno != ECONNRESET) { | 1171 | i = 0; |
| 1130 | die(STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n")); | 1172 | break; |
| 1131 | } | 1173 | } |
| 1132 | 1174 | } | |
| 1133 | /* return a CRITICAL status if we couldn't read any data */ | 1175 | microsec_transfer = deltime(tv_temp); |
| 1134 | if (pagesize == (size_t) 0) | 1176 | elapsed_time_transfer = (double)microsec_transfer / 1.0e6; |
| 1135 | die (STATE_CRITICAL, _("HTTP CRITICAL - No data received from host\n")); | 1177 | |
| 1136 | 1178 | if (i < 0 && errno != ECONNRESET) { | |
| 1137 | /* close the connection */ | 1179 | die(STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n")); |
| 1138 | if (sd) close(sd); | 1180 | } |
| 1181 | |||
| 1182 | /* return a CRITICAL status if we couldn't read any data */ | ||
| 1183 | if (pagesize == (size_t)0) { | ||
| 1184 | die(STATE_CRITICAL, _("HTTP CRITICAL - No data received from host\n")); | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | /* close the connection */ | ||
| 1188 | if (sd) { | ||
| 1189 | close(sd); | ||
| 1190 | } | ||
| 1139 | #ifdef HAVE_SSL | 1191 | #ifdef HAVE_SSL |
| 1140 | np_net_ssl_cleanup(); | 1192 | np_net_ssl_cleanup(); |
| 1141 | #endif | 1193 | #endif |
| 1142 | 1194 | ||
| 1143 | /* Save check time */ | 1195 | /* Save check time */ |
| 1144 | microsec = deltime (tv); | 1196 | microsec = deltime(tv); |
| 1145 | elapsed_time = (double)microsec / 1.0e6; | 1197 | elapsed_time = (double)microsec / 1.0e6; |
| 1146 | 1198 | ||
| 1147 | /* leave full_page untouched so we can free it later */ | 1199 | /* leave full_page untouched so we can free it later */ |
| 1148 | page = full_page; | 1200 | page = full_page; |
| 1149 | 1201 | ||
| 1150 | if (verbose) | 1202 | if (verbose) { |
| 1151 | printf ("%s://%s:%d%s is %d characters\n", | 1203 | printf("%s://%s:%d%s is %d characters\n", use_ssl ? "https" : "http", server_address, |
| 1152 | use_ssl ? "https" : "http", server_address, | 1204 | server_port, server_url, (int)pagesize); |
| 1153 | server_port, server_url, (int)pagesize); | 1205 | } |
| 1154 | 1206 | ||
| 1155 | /* find status line and null-terminate it */ | 1207 | /* find status line and null-terminate it */ |
| 1156 | status_line = page; | 1208 | status_line = page; |
| 1157 | page += (size_t) strcspn (page, "\r\n"); | 1209 | page += (size_t)strcspn(page, "\r\n"); |
| 1158 | pos = page; | 1210 | pos = page; |
| 1159 | page += (size_t) strspn (page, "\r\n"); | 1211 | page += (size_t)strspn(page, "\r\n"); |
| 1160 | status_line[strcspn(status_line, "\r\n")] = 0; | 1212 | status_line[strcspn(status_line, "\r\n")] = 0; |
| 1161 | strip (status_line); | 1213 | strip(status_line); |
| 1162 | if (verbose) | 1214 | if (verbose) { |
| 1163 | printf ("STATUS: %s\n", status_line); | 1215 | printf("STATUS: %s\n", status_line); |
| 1164 | 1216 | } | |
| 1165 | /* find header info and null-terminate it */ | 1217 | |
| 1166 | header = page; | 1218 | /* find header info and null-terminate it */ |
| 1167 | while (strcspn (page, "\r\n") > 0) { | 1219 | header = page; |
| 1168 | page += (size_t) strcspn (page, "\r\n"); | 1220 | while (strcspn(page, "\r\n") > 0) { |
| 1169 | pos = page; | 1221 | page += (size_t)strcspn(page, "\r\n"); |
| 1170 | if ((strspn (page, "\r") == 1 && strspn (page, "\r\n") >= 2) || | 1222 | pos = page; |
| 1171 | (strspn (page, "\n") == 1 && strspn (page, "\r\n") >= 2)) | 1223 | if ((strspn(page, "\r") == 1 && strspn(page, "\r\n") >= 2) || |
| 1172 | page += (size_t) 2; | 1224 | (strspn(page, "\n") == 1 && strspn(page, "\r\n") >= 2)) { |
| 1173 | else | 1225 | page += (size_t)2; |
| 1174 | page += (size_t) 1; | 1226 | } else { |
| 1175 | } | 1227 | page += (size_t)1; |
| 1176 | page += (size_t) strspn (page, "\r\n"); | 1228 | } |
| 1177 | header[pos - header] = 0; | 1229 | } |
| 1178 | if (verbose) | 1230 | page += (size_t)strspn(page, "\r\n"); |
| 1179 | printf ("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header, | 1231 | header[pos - header] = 0; |
| 1180 | (no_body ? " [[ skipped ]]" : page)); | 1232 | if (verbose) { |
| 1181 | 1233 | printf("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header, | |
| 1182 | /* make sure the status line matches the response we are looking for */ | 1234 | (no_body ? " [[ skipped ]]" : page)); |
| 1183 | if (!expected_statuscode (status_line, server_expect)) { | 1235 | } |
| 1184 | if (server_port == HTTP_PORT) | 1236 | |
| 1185 | xasprintf (&msg, | 1237 | /* make sure the status line matches the response we are looking for */ |
| 1186 | _("Invalid HTTP response received from host: %s\n"), | 1238 | if (!expected_statuscode(status_line, server_expect)) { |
| 1187 | status_line); | 1239 | if (server_port == HTTP_PORT) { |
| 1188 | else | 1240 | xasprintf(&msg, _("Invalid HTTP response received from host: %s\n"), status_line); |
| 1189 | xasprintf (&msg, | 1241 | } else { |
| 1190 | _("Invalid HTTP response received from host on port %d: %s\n"), | 1242 | xasprintf(&msg, _("Invalid HTTP response received from host on port %d: %s\n"), |
| 1191 | server_port, status_line); | 1243 | server_port, status_line); |
| 1192 | if (show_body) | 1244 | } |
| 1193 | xasprintf (&msg, _("%s\n%s"), msg, page); | 1245 | if (show_body) { |
| 1194 | die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg); | 1246 | xasprintf(&msg, _("%s\n%s"), msg, page); |
| 1195 | } | 1247 | } |
| 1196 | 1248 | die(STATE_CRITICAL, "HTTP CRITICAL - %s", msg); | |
| 1197 | /* Bypass normal status line check if server_expect was set by user and not default */ | 1249 | } |
| 1198 | /* NOTE: After this if/else block msg *MUST* be an asprintf-allocated string */ | 1250 | |
| 1199 | if ( server_expect_yn ) { | 1251 | /* Bypass normal status line check if server_expect was set by user and not default */ |
| 1200 | xasprintf (&msg, | 1252 | /* NOTE: After this if/else block msg *MUST* be an asprintf-allocated string */ |
| 1201 | _("Status line output matched \"%s\" - "), server_expect); | 1253 | if (server_expect_yn) { |
| 1202 | if (verbose) | 1254 | xasprintf(&msg, _("Status line output matched \"%s\" - "), server_expect); |
| 1203 | printf ("%s\n",msg); | 1255 | if (verbose) { |
| 1204 | } | 1256 | printf("%s\n", msg); |
| 1205 | else { | 1257 | } |
| 1206 | /* Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF */ | 1258 | } else { |
| 1207 | /* HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT */ | 1259 | /* Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF */ |
| 1208 | /* Status-Code = 3 DIGITS */ | 1260 | /* HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT */ |
| 1209 | 1261 | /* Status-Code = 3 DIGITS */ | |
| 1210 | status_code = strchr (status_line, ' ') + sizeof (char); | 1262 | |
| 1211 | if (strspn (status_code, "1234567890") != 3) | 1263 | status_code = strchr(status_line, ' ') + sizeof(char); |
| 1212 | die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status Line (%s)\n"), status_line); | 1264 | if (strspn(status_code, "1234567890") != 3) { |
| 1213 | 1265 | die(STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status Line (%s)\n"), status_line); | |
| 1214 | http_status = atoi (status_code); | 1266 | } |
| 1215 | 1267 | ||
| 1216 | /* check the return code */ | 1268 | http_status = atoi(status_code); |
| 1217 | 1269 | ||
| 1218 | if (http_status >= 600 || http_status < 100) { | 1270 | /* check the return code */ |
| 1219 | die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%s)\n"), status_line); | 1271 | |
| 1220 | } | 1272 | if (http_status >= 600 || http_status < 100) { |
| 1221 | /* server errors result in a critical state */ | 1273 | die(STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%s)\n"), status_line); |
| 1222 | else if (http_status >= 500) { | 1274 | } |
| 1223 | xasprintf (&msg, _("%s - "), status_line); | 1275 | /* server errors result in a critical state */ |
| 1224 | result = STATE_CRITICAL; | 1276 | else if (http_status >= 500) { |
| 1225 | } | 1277 | xasprintf(&msg, _("%s - "), status_line); |
| 1226 | /* client errors result in a warning state */ | 1278 | result = STATE_CRITICAL; |
| 1227 | else if (http_status >= 400) { | 1279 | } |
| 1228 | xasprintf (&msg, _("%s - "), status_line); | 1280 | /* client errors result in a warning state */ |
| 1229 | result = max_state_alt(STATE_WARNING, result); | 1281 | else if (http_status >= 400) { |
| 1230 | } | 1282 | xasprintf(&msg, _("%s - "), status_line); |
| 1231 | /* check redirected page if specified */ | 1283 | result = max_state_alt(STATE_WARNING, result); |
| 1232 | else if (http_status >= 300) { | 1284 | } |
| 1233 | 1285 | /* check redirected page if specified */ | |
| 1234 | if (onredirect == STATE_DEPENDENT) | 1286 | else if (http_status >= 300) { |
| 1235 | redir (header, status_line); | 1287 | |
| 1236 | else | 1288 | if (onredirect == STATE_DEPENDENT) { |
| 1237 | result = max_state_alt(onredirect, result); | 1289 | redir(header, status_line); |
| 1238 | xasprintf (&msg, _("%s - "), status_line); | 1290 | } else { |
| 1239 | } /* end if (http_status >= 300) */ | 1291 | result = max_state_alt(onredirect, result); |
| 1240 | else { | 1292 | } |
| 1241 | /* Print OK status anyway */ | 1293 | xasprintf(&msg, _("%s - "), status_line); |
| 1242 | xasprintf (&msg, _("%s - "), status_line); | 1294 | } /* end if (http_status >= 300) */ |
| 1243 | } | 1295 | else { |
| 1244 | 1296 | /* Print OK status anyway */ | |
| 1245 | } /* end else (server_expect_yn) */ | 1297 | xasprintf(&msg, _("%s - "), status_line); |
| 1246 | 1298 | } | |
| 1247 | /* reset the alarm - must be called *after* redir or we'll never die on redirects! */ | 1299 | |
| 1248 | alarm (0); | 1300 | } /* end else (server_expect_yn) */ |
| 1249 | 1301 | ||
| 1250 | if (maximum_age >= 0) { | 1302 | /* reset the alarm - must be called *after* redir or we'll never die on redirects! */ |
| 1251 | result = max_state_alt(check_document_dates(header, &msg), result); | 1303 | alarm(0); |
| 1252 | } | 1304 | |
| 1253 | 1305 | if (maximum_age >= 0) { | |
| 1254 | /* Page and Header content checks go here */ | 1306 | result = max_state_alt(check_document_dates(header, &msg), result); |
| 1255 | if (strlen(header_expect) > 0) { | 1307 | } |
| 1256 | if (strstr(header, header_expect) == NULL) { | 1308 | |
| 1257 | // We did not find the header, the rest is for building the output and setting the state | 1309 | /* Page and Header content checks go here */ |
| 1258 | char output_header_search[30] = ""; | 1310 | if (strlen(header_expect) > 0) { |
| 1259 | 1311 | if (strstr(header, header_expect) == NULL) { | |
| 1260 | strncpy(&output_header_search[0], header_expect, | 1312 | // We did not find the header, the rest is for building the output and setting the state |
| 1261 | sizeof(output_header_search)); | 1313 | char output_header_search[30] = ""; |
| 1262 | 1314 | ||
| 1263 | if (output_header_search[sizeof(output_header_search) - 1] != '\0') { | 1315 | strncpy(&output_header_search[0], header_expect, sizeof(output_header_search)); |
| 1264 | bcopy("...", | 1316 | |
| 1265 | &output_header_search[sizeof(output_header_search) - 4], | 1317 | if (output_header_search[sizeof(output_header_search) - 1] != '\0') { |
| 1266 | 4); | 1318 | bcopy("...", &output_header_search[sizeof(output_header_search) - 4], 4); |
| 1267 | } | 1319 | } |
| 1268 | 1320 | ||
| 1269 | xasprintf (&msg, | 1321 | xasprintf(&msg, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, |
| 1270 | _("%sheader '%s' not found on '%s://%s:%d%s', "), | 1322 | output_header_search, use_ssl ? "https" : "http", |
| 1271 | msg, | 1323 | host_name ? host_name : server_address, server_port, server_url); |
| 1272 | output_header_search, use_ssl ? "https" : "http", | 1324 | |
| 1273 | host_name ? host_name : server_address, server_port, | 1325 | result = STATE_CRITICAL; |
| 1274 | server_url); | 1326 | } |
| 1275 | 1327 | } | |
| 1276 | result = STATE_CRITICAL; | 1328 | |
| 1277 | } | 1329 | // At this point we should test if the content is chunked and unchunk it, so |
| 1278 | } | 1330 | // it can be searched (and possibly printed) |
| 1279 | 1331 | const char *chunked_header_regex_string = "Transfer-Encoding: *chunked *"; | |
| 1280 | // At this point we should test if the content is chunked and unchunk it, so | 1332 | regex_t chunked_header_regex; |
| 1281 | // it can be searched (and possibly printed) | 1333 | |
| 1282 | const char *chunked_header_regex_string = "Transfer-Encoding: *chunked *"; | 1334 | if (regcomp(&chunked_header_regex, chunked_header_regex_string, REG_ICASE)) { |
| 1283 | regex_t chunked_header_regex; | 1335 | die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), |
| 1284 | 1336 | "Failed to compile chunked_header_regex regex"); | |
| 1285 | if (regcomp(&chunked_header_regex, chunked_header_regex_string, REG_ICASE)) { | 1337 | } |
| 1286 | die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to compile chunked_header_regex regex"); | 1338 | |
| 1287 | } | 1339 | regmatch_t chre_pmatch[1]; // We actually do not care about this, since we only want to know IF |
| 1288 | 1340 | // it was found | |
| 1289 | regmatch_t chre_pmatch[1]; // We actually do not care about this, since we only want to know IF it was found | 1341 | |
| 1290 | 1342 | if (!no_body && regexec(&chunked_header_regex, header, 1, chre_pmatch, 0) == 0) { | |
| 1291 | if (!no_body && regexec(&chunked_header_regex, header, 1, chre_pmatch, 0) == 0) { | 1343 | if (verbose) { |
| 1292 | if (verbose) { | 1344 | printf("Found chunked content\n"); |
| 1293 | printf("Found chunked content\n"); | 1345 | } |
| 1294 | } | 1346 | // We actually found the chunked header |
| 1295 | // We actually found the chunked header | 1347 | char *tmp = unchunk_content(page); |
| 1296 | char *tmp = unchunk_content(page); | 1348 | if (tmp == NULL) { |
| 1297 | if (tmp == NULL) { | 1349 | die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), |
| 1298 | die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to unchunk message body"); | 1350 | "Failed to unchunk message body"); |
| 1299 | } | 1351 | } |
| 1300 | page = tmp; | 1352 | page = tmp; |
| 1301 | } | 1353 | } |
| 1302 | 1354 | ||
| 1303 | if (strlen(string_expect) > 0) { | 1355 | if (strlen(string_expect) > 0) { |
| 1304 | if (!strstr(page, string_expect)) { | 1356 | if (!strstr(page, string_expect)) { |
| 1305 | // We found the string the body, the rest is for building the output | 1357 | // We found the string the body, the rest is for building the output |
| 1306 | char output_string_search[30] = ""; | 1358 | char output_string_search[30] = ""; |
| 1307 | strncpy(&output_string_search[0], string_expect, | 1359 | strncpy(&output_string_search[0], string_expect, sizeof(output_string_search)); |
| 1308 | sizeof(output_string_search)); | 1360 | if (output_string_search[sizeof(output_string_search) - 1] != '\0') { |
| 1309 | if (output_string_search[sizeof(output_string_search) - 1] != '\0') { | 1361 | bcopy("...", &output_string_search[sizeof(output_string_search) - 4], 4); |
| 1310 | bcopy("...", &output_string_search[sizeof(output_string_search) - 4], | 1362 | } |
| 1311 | 4); | 1363 | xasprintf(&msg, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, |
| 1312 | } | 1364 | output_string_search, use_ssl ? "https" : "http", |
| 1313 | xasprintf (&msg, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); | 1365 | host_name ? host_name : server_address, server_port, server_url); |
| 1314 | result = STATE_CRITICAL; | 1366 | result = STATE_CRITICAL; |
| 1315 | } | 1367 | } |
| 1316 | } | 1368 | } |
| 1317 | 1369 | ||
| 1318 | if (strlen(regexp) > 0) { | 1370 | if (strlen(regexp) > 0) { |
| 1319 | errcode = regexec(&preg, page, REGS, pmatch, 0); | 1371 | errcode = regexec(&preg, page, REGS, pmatch, 0); |
| 1320 | if ((errcode == 0 && invert_regex == 0) || | 1372 | if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { |
| 1321 | (errcode == REG_NOMATCH && invert_regex == 1)) { | 1373 | /* OK - No-op to avoid changing the logic around it */ |
| 1322 | /* OK - No-op to avoid changing the logic around it */ | 1374 | result = max_state_alt(STATE_OK, result); |
| 1323 | result = max_state_alt(STATE_OK, result); | 1375 | } else if ((errcode == REG_NOMATCH && invert_regex == 0) || |
| 1324 | } | 1376 | (errcode == 0 && invert_regex == 1)) { |
| 1325 | else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) { | 1377 | if (invert_regex == 0) { |
| 1326 | if (invert_regex == 0) | 1378 | xasprintf(&msg, _("%spattern not found, "), msg); |
| 1327 | xasprintf (&msg, _("%spattern not found, "), msg); | 1379 | } else { |
| 1328 | else | 1380 | xasprintf(&msg, _("%spattern found, "), msg); |
| 1329 | xasprintf (&msg, _("%spattern found, "), msg); | 1381 | } |
| 1330 | result = state_regex; | 1382 | result = state_regex; |
| 1331 | } | 1383 | } else { |
| 1332 | else { | 1384 | /* FIXME: Shouldn't that be UNKNOWN? */ |
| 1333 | /* FIXME: Shouldn't that be UNKNOWN? */ | 1385 | regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); |
| 1334 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); | 1386 | xasprintf(&msg, _("%sExecute Error: %s, "), msg, errbuf); |
| 1335 | xasprintf (&msg, _("%sExecute Error: %s, "), msg, errbuf); | 1387 | result = STATE_CRITICAL; |
| 1336 | result = STATE_CRITICAL; | 1388 | } |
| 1337 | } | 1389 | } |
| 1338 | } | 1390 | |
| 1339 | 1391 | /* make sure the page is of an appropriate size */ | |
| 1340 | /* make sure the page is of an appropriate size */ | 1392 | /* page_len = get_content_length(header); */ |
| 1341 | /* page_len = get_content_length(header); */ | 1393 | /* FIXME: Will this work with -N ? IMHO we should use |
| 1342 | /* FIXME: Will this work with -N ? IMHO we should use | 1394 | * get_content_length(header) and always check if it's different than the |
| 1343 | * get_content_length(header) and always check if it's different than the | 1395 | * returned pagesize |
| 1344 | * returned pagesize | 1396 | */ |
| 1345 | */ | 1397 | /* FIXME: IIRC pagesize returns headers - shouldn't we make |
| 1346 | /* FIXME: IIRC pagesize returns headers - shouldn't we make | 1398 | * it == get_content_length(header) ?? |
| 1347 | * it == get_content_length(header) ?? | 1399 | */ |
| 1348 | */ | 1400 | page_len = pagesize; |
| 1349 | page_len = pagesize; | 1401 | if ((max_page_len > 0) && (page_len > max_page_len)) { |
| 1350 | if ((max_page_len > 0) && (page_len > max_page_len)) { | 1402 | xasprintf(&msg, _("%spage size %d too large, "), msg, page_len); |
| 1351 | xasprintf (&msg, _("%spage size %d too large, "), msg, page_len); | 1403 | result = max_state_alt(STATE_WARNING, result); |
| 1352 | result = max_state_alt(STATE_WARNING, result); | 1404 | } else if ((min_page_len > 0) && (page_len < min_page_len)) { |
| 1353 | } else if ((min_page_len > 0) && (page_len < min_page_len)) { | 1405 | xasprintf(&msg, _("%spage size %d too small, "), msg, page_len); |
| 1354 | xasprintf (&msg, _("%spage size %d too small, "), msg, page_len); | 1406 | result = max_state_alt(STATE_WARNING, result); |
| 1355 | result = max_state_alt(STATE_WARNING, result); | 1407 | } |
| 1356 | } | 1408 | |
| 1357 | 1409 | /* Cut-off trailing characters */ | |
| 1358 | /* Cut-off trailing characters */ | 1410 | if (msg[strlen(msg) - 2] == ',') { |
| 1359 | if(msg[strlen(msg)-2] == ',') | 1411 | msg[strlen(msg) - 2] = '\0'; |
| 1360 | msg[strlen(msg)-2] = '\0'; | 1412 | } else { |
| 1361 | else | 1413 | msg[strlen(msg) - 3] = '\0'; |
| 1362 | msg[strlen(msg)-3] = '\0'; | 1414 | } |
| 1363 | 1415 | ||
| 1364 | /* check elapsed time */ | 1416 | /* check elapsed time */ |
| 1365 | if (show_extended_perfdata) | 1417 | if (show_extended_perfdata) { |
| 1366 | xasprintf (&msg, | 1418 | xasprintf( |
| 1367 | _("%s - %d bytes in %.3f second response time %s|%s %s %s %s %s %s %s"), | 1419 | &msg, _("%s - %d bytes in %.3f second response time %s|%s %s %s %s %s %s %s"), msg, |
| 1368 | msg, page_len, elapsed_time, | 1420 | page_len, elapsed_time, (display_html ? "</A>" : ""), perfd_time(elapsed_time), |
| 1369 | (display_html ? "</A>" : ""), | 1421 | perfd_size(page_len), perfd_time_connect(elapsed_time_connect), |
| 1370 | perfd_time (elapsed_time), | 1422 | use_ssl ? perfd_time_ssl(elapsed_time_ssl) : "", |
| 1371 | perfd_size (page_len), | 1423 | perfd_time_headers(elapsed_time_headers), perfd_time_firstbyte(elapsed_time_firstbyte), |
| 1372 | perfd_time_connect (elapsed_time_connect), | 1424 | perfd_time_transfer(elapsed_time_transfer)); |
| 1373 | use_ssl == true ? perfd_time_ssl (elapsed_time_ssl) : "", | 1425 | } else { |
| 1374 | perfd_time_headers (elapsed_time_headers), | 1426 | xasprintf(&msg, _("%s - %d bytes in %.3f second response time %s|%s %s"), msg, page_len, |
| 1375 | perfd_time_firstbyte (elapsed_time_firstbyte), | 1427 | elapsed_time, (display_html ? "</A>" : ""), perfd_time(elapsed_time), |
| 1376 | perfd_time_transfer (elapsed_time_transfer)); | 1428 | perfd_size(page_len)); |
| 1377 | else | 1429 | } |
| 1378 | xasprintf (&msg, | 1430 | |
| 1379 | _("%s - %d bytes in %.3f second response time %s|%s %s"), | 1431 | if (show_body) { |
| 1380 | msg, page_len, elapsed_time, | 1432 | xasprintf(&msg, _("%s\n%s"), msg, page); |
| 1381 | (display_html ? "</A>" : ""), | 1433 | } |
| 1382 | perfd_time (elapsed_time), | 1434 | |
| 1383 | perfd_size (page_len)); | 1435 | result = max_state_alt(get_status(elapsed_time, thlds), result); |
| 1384 | 1436 | ||
| 1385 | if (show_body) | 1437 | die(result, "HTTP %s: %s\n", state_text(result), msg); |
| 1386 | xasprintf (&msg, _("%s\n%s"), msg, page); | 1438 | /* die failed? */ |
| 1387 | 1439 | return STATE_UNKNOWN; | |
| 1388 | result = max_state_alt(get_status(elapsed_time, thlds), result); | ||
| 1389 | |||
| 1390 | die (result, "HTTP %s: %s\n", state_text(result), msg); | ||
| 1391 | /* die failed? */ | ||
| 1392 | return STATE_UNKNOWN; | ||
| 1393 | } | 1440 | } |
| 1394 | 1441 | ||
| 1395 | /* Receivces a pointer to the beginning of the body of a HTTP message | 1442 | /* Receivces a pointer to the beginning of the body of a HTTP message |
| @@ -1398,94 +1445,95 @@ check_http (void) | |||
| 1398 | * The result must be freed by the caller. | 1445 | * The result must be freed by the caller. |
| 1399 | */ | 1446 | */ |
| 1400 | char *unchunk_content(const char *content) { | 1447 | char *unchunk_content(const char *content) { |
| 1401 | // https://en.wikipedia.org/wiki/Chunked_transfer_encoding | 1448 | // https://en.wikipedia.org/wiki/Chunked_transfer_encoding |
| 1402 | // https://www.rfc-editor.org/rfc/rfc7230#section-4.1 | 1449 | // https://www.rfc-editor.org/rfc/rfc7230#section-4.1 |
| 1403 | char *result = NULL; | 1450 | char *result = NULL; |
| 1404 | char *start_of_chunk; | 1451 | char *start_of_chunk; |
| 1405 | char* end_of_chunk; | 1452 | char *end_of_chunk; |
| 1406 | long size_of_chunk; | 1453 | long size_of_chunk; |
| 1407 | const char *pointer = content; | 1454 | const char *pointer = content; |
| 1408 | char *endptr; | 1455 | char *endptr; |
| 1409 | long length_of_chunk = 0; | 1456 | long length_of_chunk = 0; |
| 1410 | size_t overall_size = 0; | 1457 | size_t overall_size = 0; |
| 1411 | 1458 | ||
| 1412 | while (true) { | 1459 | while (true) { |
| 1413 | size_of_chunk = strtol(pointer, &endptr, 16); | 1460 | size_of_chunk = strtol(pointer, &endptr, 16); |
| 1414 | if (size_of_chunk == LONG_MIN || size_of_chunk == LONG_MAX) { | 1461 | if (size_of_chunk == LONG_MIN || size_of_chunk == LONG_MAX) { |
| 1415 | // Apparently underflow or overflow, should not happen | 1462 | // Apparently underflow or overflow, should not happen |
| 1416 | if (verbose) { | 1463 | if (verbose) { |
| 1417 | printf("Got an underflow or overflow from strtol at: %u\n", __LINE__); | 1464 | printf("Got an underflow or overflow from strtol at: %u\n", __LINE__); |
| 1418 | } | 1465 | } |
| 1419 | return NULL; | 1466 | return NULL; |
| 1420 | } | 1467 | } |
| 1421 | if (endptr == pointer) { | 1468 | if (endptr == pointer) { |
| 1422 | // Apparently this was not a number | 1469 | // Apparently this was not a number |
| 1423 | if (verbose) { | 1470 | if (verbose) { |
| 1424 | printf("Chunked content did not start with a number at all (Line: %u)\n", __LINE__); | 1471 | printf("Chunked content did not start with a number at all (Line: %u)\n", __LINE__); |
| 1425 | } | 1472 | } |
| 1426 | return NULL; | 1473 | return NULL; |
| 1427 | } | 1474 | } |
| 1428 | 1475 | ||
| 1429 | // So, we got the length of the chunk | 1476 | // So, we got the length of the chunk |
| 1430 | if (*endptr == ';') { | 1477 | if (*endptr == ';') { |
| 1431 | // Chunk extension starts here | 1478 | // Chunk extension starts here |
| 1432 | while (*endptr != '\r') { | 1479 | while (*endptr != '\r') { |
| 1433 | endptr++; | 1480 | endptr++; |
| 1434 | } | 1481 | } |
| 1435 | } | 1482 | } |
| 1436 | 1483 | ||
| 1437 | start_of_chunk = endptr + 2; | 1484 | start_of_chunk = endptr + 2; |
| 1438 | end_of_chunk = start_of_chunk + size_of_chunk; | 1485 | end_of_chunk = start_of_chunk + size_of_chunk; |
| 1439 | length_of_chunk = (long)(end_of_chunk - start_of_chunk); | 1486 | length_of_chunk = (long)(end_of_chunk - start_of_chunk); |
| 1440 | pointer = end_of_chunk + 2; //Next number should be here | 1487 | pointer = end_of_chunk + 2; // Next number should be here |
| 1441 | 1488 | ||
| 1442 | if (length_of_chunk == 0) { | 1489 | if (length_of_chunk == 0) { |
| 1443 | // Chunk length is 0, so this is the last one | 1490 | // Chunk length is 0, so this is the last one |
| 1444 | break; | 1491 | break; |
| 1445 | } | 1492 | } |
| 1446 | 1493 | ||
| 1447 | overall_size += length_of_chunk; | 1494 | overall_size += length_of_chunk; |
| 1448 | 1495 | ||
| 1449 | if (result == NULL) { | 1496 | if (result == NULL) { |
| 1450 | // Size of the chunk plus the ending NULL byte | 1497 | // Size of the chunk plus the ending NULL byte |
| 1451 | result = (char *)malloc(length_of_chunk +1); | 1498 | result = (char *)malloc(length_of_chunk + 1); |
| 1452 | if (result == NULL) { | 1499 | if (result == NULL) { |
| 1453 | if (verbose) { | 1500 | if (verbose) { |
| 1454 | printf("Failed to allocate memory for unchunked body\n"); | 1501 | printf("Failed to allocate memory for unchunked body\n"); |
| 1455 | } | 1502 | } |
| 1456 | return NULL; | 1503 | return NULL; |
| 1457 | } | 1504 | } |
| 1458 | } else { | 1505 | } else { |
| 1459 | // Enlarge memory to the new size plus the ending NULL byte | 1506 | // Enlarge memory to the new size plus the ending NULL byte |
| 1460 | void *tmp = realloc(result, overall_size +1); | 1507 | void *tmp = realloc(result, overall_size + 1); |
| 1461 | if (tmp == NULL) { | 1508 | if (tmp == NULL) { |
| 1462 | if (verbose) { | 1509 | if (verbose) { |
| 1463 | printf("Failed to allocate memory for unchunked body\n"); | 1510 | printf("Failed to allocate memory for unchunked body\n"); |
| 1464 | } | 1511 | } |
| 1465 | return NULL; | 1512 | return NULL; |
| 1466 | } else { | 1513 | } |
| 1467 | result = tmp; | 1514 | result = tmp; |
| 1468 | } | 1515 | } |
| 1469 | } | 1516 | |
| 1470 | 1517 | memcpy(result + (overall_size - size_of_chunk), start_of_chunk, size_of_chunk); | |
| 1471 | memcpy(result + (overall_size - size_of_chunk), start_of_chunk, size_of_chunk); | 1518 | } |
| 1472 | } | 1519 | |
| 1473 | 1520 | if (overall_size == 0 && result == NULL) { | |
| 1474 | if (overall_size == 0 && result == NULL) { | 1521 | // We might just have received the end chunk without previous content, so result is never |
| 1475 | // We might just have received the end chunk without previous content, so result is never allocated | 1522 | // allocated |
| 1476 | result = calloc(1, sizeof(char)); | 1523 | result = calloc(1, sizeof(char)); |
| 1477 | // No error handling here, we can only return NULL anyway | 1524 | // No error handling here, we can only return NULL anyway |
| 1478 | } else { | 1525 | } else { |
| 1479 | result[overall_size] = '\0'; | 1526 | result[overall_size] = '\0'; |
| 1480 | } | 1527 | } |
| 1481 | return result; | 1528 | return result; |
| 1482 | } | 1529 | } |
| 1483 | 1530 | ||
| 1484 | /* per RFC 2396 */ | 1531 | /* per RFC 2396 */ |
| 1485 | #define URI_HTTP "%5[HTPShtps]" | 1532 | #define URI_HTTP "%5[HTPShtps]" |
| 1486 | #define URI_HOST "%255[-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" | 1533 | #define URI_HOST "%255[-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" |
| 1487 | #define URI_PORT "%6d" /* MAX_PORT's width is 5 chars, 6 to detect overflow */ | 1534 | #define URI_PORT "%6d" /* MAX_PORT's width is 5 chars, 6 to detect overflow */ |
| 1488 | #define URI_PATH "%[-_.!~*'();/?:@&=+$,%#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" | 1535 | #define URI_PATH \ |
| 1536 | "%[-_.!~*'();/?:@&=+$,%#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" | ||
| 1489 | #define HD1 URI_HTTP "://" URI_HOST ":" URI_PORT "/" URI_PATH | 1537 | #define HD1 URI_HTTP "://" URI_HOST ":" URI_PORT "/" URI_PATH |
| 1490 | #define HD2 URI_HTTP "://" URI_HOST "/" URI_PATH | 1538 | #define HD2 URI_HTTP "://" URI_HOST "/" URI_PATH |
| 1491 | #define HD3 URI_HTTP "://" URI_HOST ":" URI_PORT | 1539 | #define HD3 URI_HTTP "://" URI_HOST ":" URI_PORT |
| @@ -1494,414 +1542,431 @@ char *unchunk_content(const char *content) { | |||
| 1494 | #define HD5 "//" URI_HOST "/" URI_PATH | 1542 | #define HD5 "//" URI_HOST "/" URI_PATH |
| 1495 | #define HD6 URI_PATH | 1543 | #define HD6 URI_PATH |
| 1496 | 1544 | ||
| 1497 | void | 1545 | void redir(char *pos, char *status_line) { |
| 1498 | redir (char *pos, char *status_line) | 1546 | int i = 0; |
| 1499 | { | 1547 | char *x; |
| 1500 | int i = 0; | 1548 | char xx[2]; |
| 1501 | char *x; | 1549 | char type[6]; |
| 1502 | char xx[2]; | 1550 | char *addr; |
| 1503 | char type[6]; | 1551 | char *url; |
| 1504 | char *addr; | 1552 | |
| 1505 | char *url; | 1553 | addr = malloc(MAX_IPV4_HOSTLENGTH + 1); |
| 1506 | 1554 | if (addr == NULL) { | |
| 1507 | addr = malloc (MAX_IPV4_HOSTLENGTH + 1); | 1555 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate addr\n")); |
| 1508 | if (addr == NULL) | 1556 | } |
| 1509 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate addr\n")); | 1557 | |
| 1510 | 1558 | memset(addr, 0, MAX_IPV4_HOSTLENGTH); | |
| 1511 | memset(addr, 0, MAX_IPV4_HOSTLENGTH); | 1559 | url = malloc(strcspn(pos, "\r\n")); |
| 1512 | url = malloc (strcspn (pos, "\r\n")); | 1560 | if (url == NULL) { |
| 1513 | if (url == NULL) | 1561 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n")); |
| 1514 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n")); | 1562 | } |
| 1515 | 1563 | ||
| 1516 | while (pos) { | 1564 | while (pos) { |
| 1517 | sscanf (pos, "%1[Ll]%*1[Oo]%*1[Cc]%*1[Aa]%*1[Tt]%*1[Ii]%*1[Oo]%*1[Nn]:%n", xx, &i); | 1565 | sscanf(pos, "%1[Ll]%*1[Oo]%*1[Cc]%*1[Aa]%*1[Tt]%*1[Ii]%*1[Oo]%*1[Nn]:%n", xx, &i); |
| 1518 | if (i == 0) { | 1566 | if (i == 0) { |
| 1519 | pos += (size_t) strcspn (pos, "\r\n"); | 1567 | pos += (size_t)strcspn(pos, "\r\n"); |
| 1520 | pos += (size_t) strspn (pos, "\r\n"); | 1568 | pos += (size_t)strspn(pos, "\r\n"); |
| 1521 | if (strlen(pos) == 0) | 1569 | if (strlen(pos) == 0) { |
| 1522 | die (STATE_UNKNOWN, | 1570 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not find redirect location - %s%s\n"), |
| 1523 | _("HTTP UNKNOWN - Could not find redirect location - %s%s\n"), | 1571 | status_line, (display_html ? "</A>" : "")); |
| 1524 | status_line, (display_html ? "</A>" : "")); | 1572 | } |
| 1525 | continue; | 1573 | continue; |
| 1526 | } | 1574 | } |
| 1527 | 1575 | ||
| 1528 | pos += i; | 1576 | pos += i; |
| 1529 | pos += strspn (pos, " \t"); | 1577 | pos += strspn(pos, " \t"); |
| 1530 | 1578 | ||
| 1531 | /* | 1579 | /* |
| 1532 | * RFC 2616 (4.2): ``Header fields can be extended over multiple lines by | 1580 | * RFC 2616 (4.2): ``Header fields can be extended over multiple lines by |
| 1533 | * preceding each extra line with at least one SP or HT.'' | 1581 | * preceding each extra line with at least one SP or HT.'' |
| 1534 | */ | 1582 | */ |
| 1535 | for (; (i = strspn (pos, "\r\n")); pos += i) { | 1583 | for (; (i = strspn(pos, "\r\n")); pos += i) { |
| 1536 | pos += i; | 1584 | pos += i; |
| 1537 | if (!(i = strspn (pos, " \t"))) { | 1585 | if (!(i = strspn(pos, " \t"))) { |
| 1538 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Empty redirect location%s\n"), | 1586 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Empty redirect location%s\n"), |
| 1539 | display_html ? "</A>" : ""); | 1587 | display_html ? "</A>" : ""); |
| 1540 | } | 1588 | } |
| 1541 | } | 1589 | } |
| 1542 | 1590 | ||
| 1543 | url = realloc (url, strcspn (pos, "\r\n") + 1); | 1591 | url = realloc(url, strcspn(pos, "\r\n") + 1); |
| 1544 | if (url == NULL) | 1592 | if (url == NULL) { |
| 1545 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n")); | 1593 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n")); |
| 1546 | 1594 | } | |
| 1547 | /* URI_HTTP, URI_HOST, URI_PORT, URI_PATH */ | 1595 | |
| 1548 | if (sscanf (pos, HD1, type, addr, &i, url) == 4) { | 1596 | /* URI_HTTP, URI_HOST, URI_PORT, URI_PATH */ |
| 1549 | url = prepend_slash (url); | 1597 | if (sscanf(pos, HD1, type, addr, &i, url) == 4) { |
| 1550 | use_ssl = server_type_check (type); | 1598 | url = prepend_slash(url); |
| 1551 | } | 1599 | use_ssl = server_type_check(type); |
| 1552 | 1600 | } | |
| 1553 | /* URI_HTTP URI_HOST URI_PATH */ | 1601 | |
| 1554 | else if (sscanf (pos, HD2, type, addr, url) == 3 ) { | 1602 | /* URI_HTTP URI_HOST URI_PATH */ |
| 1555 | url = prepend_slash (url); | 1603 | else if (sscanf(pos, HD2, type, addr, url) == 3) { |
| 1556 | use_ssl = server_type_check (type); | 1604 | url = prepend_slash(url); |
| 1557 | i = server_port_check (use_ssl); | 1605 | use_ssl = server_type_check(type); |
| 1558 | } | 1606 | i = server_port_check(use_ssl); |
| 1559 | 1607 | } | |
| 1560 | /* URI_HTTP URI_HOST URI_PORT */ | 1608 | |
| 1561 | else if (sscanf (pos, HD3, type, addr, &i) == 3) { | 1609 | /* URI_HTTP URI_HOST URI_PORT */ |
| 1562 | strcpy (url, HTTP_URL); | 1610 | else if (sscanf(pos, HD3, type, addr, &i) == 3) { |
| 1563 | use_ssl = server_type_check (type); | 1611 | strcpy(url, HTTP_URL); |
| 1564 | } | 1612 | use_ssl = server_type_check(type); |
| 1565 | 1613 | } | |
| 1566 | /* URI_HTTP URI_HOST */ | 1614 | |
| 1567 | else if (sscanf (pos, HD4, type, addr) == 2) { | 1615 | /* URI_HTTP URI_HOST */ |
| 1568 | strcpy (url, HTTP_URL); | 1616 | else if (sscanf(pos, HD4, type, addr) == 2) { |
| 1569 | use_ssl = server_type_check (type); | 1617 | strcpy(url, HTTP_URL); |
| 1570 | i = server_port_check (use_ssl); | 1618 | use_ssl = server_type_check(type); |
| 1571 | } | 1619 | i = server_port_check(use_ssl); |
| 1572 | /* URI_HTTP, URI_HOST, URI_PATH */ | 1620 | } |
| 1573 | else if (sscanf (pos, HD5, addr, url) == 2) { | 1621 | /* URI_HTTP, URI_HOST, URI_PATH */ |
| 1574 | if(use_ssl){ | 1622 | else if (sscanf(pos, HD5, addr, url) == 2) { |
| 1575 | strcpy (type,"https"); | 1623 | if (use_ssl) { |
| 1576 | } | 1624 | strcpy(type, "https"); |
| 1577 | else{ | 1625 | } else { |
| 1578 | strcpy (type, server_type); | 1626 | strcpy(type, server_type); |
| 1579 | } | 1627 | } |
| 1580 | xasprintf (&url, "/%s", url); | 1628 | xasprintf(&url, "/%s", url); |
| 1581 | use_ssl = server_type_check (type); | 1629 | use_ssl = server_type_check(type); |
| 1582 | i = server_port_check (use_ssl); | 1630 | i = server_port_check(use_ssl); |
| 1583 | } | 1631 | } |
| 1584 | 1632 | ||
| 1585 | /* URI_PATH */ | 1633 | /* URI_PATH */ |
| 1586 | else if (sscanf (pos, HD6, url) == 1) { | 1634 | else if (sscanf(pos, HD6, url) == 1) { |
| 1587 | /* relative url */ | 1635 | /* relative url */ |
| 1588 | if ((url[0] != '/')) { | 1636 | if ((url[0] != '/')) { |
| 1589 | if ((x = strrchr(server_url, '/'))) | 1637 | if ((x = strrchr(server_url, '/'))) { |
| 1590 | *x = '\0'; | 1638 | *x = '\0'; |
| 1591 | xasprintf (&url, "%s/%s", server_url, url); | 1639 | } |
| 1592 | } | 1640 | xasprintf(&url, "%s/%s", server_url, url); |
| 1593 | i = server_port; | 1641 | } |
| 1594 | strcpy (type, server_type); | 1642 | i = server_port; |
| 1595 | strcpy (addr, host_name ? host_name : server_address); | 1643 | strcpy(type, server_type); |
| 1596 | } | 1644 | strcpy(addr, host_name ? host_name : server_address); |
| 1597 | 1645 | } | |
| 1598 | else { | 1646 | |
| 1599 | die (STATE_UNKNOWN, | 1647 | else { |
| 1600 | _("HTTP UNKNOWN - Could not parse redirect location - %s%s\n"), | 1648 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not parse redirect location - %s%s\n"), pos, |
| 1601 | pos, (display_html ? "</A>" : "")); | 1649 | (display_html ? "</A>" : "")); |
| 1602 | } | 1650 | } |
| 1603 | 1651 | ||
| 1604 | break; | 1652 | break; |
| 1605 | 1653 | ||
| 1606 | } /* end while (pos) */ | 1654 | } /* end while (pos) */ |
| 1607 | 1655 | ||
| 1608 | if (++redir_depth > max_depth) | 1656 | if (++redir_depth > max_depth) { |
| 1609 | die (STATE_WARNING, | 1657 | die(STATE_WARNING, |
| 1610 | _("HTTP WARNING - maximum redirection depth %d exceeded - %s://%s:%d%s%s\n"), | 1658 | _("HTTP WARNING - maximum redirection depth %d exceeded - %s://%s:%d%s%s\n"), max_depth, |
| 1611 | max_depth, type, addr, i, url, (display_html ? "</A>" : "")); | 1659 | type, addr, i, url, (display_html ? "</A>" : "")); |
| 1612 | 1660 | } | |
| 1613 | if (server_port==i && | 1661 | |
| 1614 | !strncmp(server_address, addr, MAX_IPV4_HOSTLENGTH) && | 1662 | if (server_port == i && !strncmp(server_address, addr, MAX_IPV4_HOSTLENGTH) && |
| 1615 | (host_name && !strncmp(host_name, addr, MAX_IPV4_HOSTLENGTH)) && | 1663 | (host_name && !strncmp(host_name, addr, MAX_IPV4_HOSTLENGTH)) && !strcmp(server_url, url)) { |
| 1616 | !strcmp(server_url, url)) | 1664 | die(STATE_CRITICAL, |
| 1617 | die (STATE_CRITICAL, | 1665 | _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s%s\n"), type, |
| 1618 | _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s%s\n"), | 1666 | addr, i, url, (display_html ? "</A>" : "")); |
| 1619 | type, addr, i, url, (display_html ? "</A>" : "")); | 1667 | } |
| 1620 | 1668 | ||
| 1621 | strcpy (server_type, type); | 1669 | strcpy(server_type, type); |
| 1622 | 1670 | ||
| 1623 | free (host_name); | 1671 | free(host_name); |
| 1624 | host_name = strndup (addr, MAX_IPV4_HOSTLENGTH); | 1672 | host_name = strndup(addr, MAX_IPV4_HOSTLENGTH); |
| 1625 | 1673 | ||
| 1626 | if (!(followsticky & STICKY_HOST)) { | 1674 | if (!(followsticky & STICKY_HOST)) { |
| 1627 | free (server_address); | 1675 | free(server_address); |
| 1628 | server_address = strndup (addr, MAX_IPV4_HOSTLENGTH); | 1676 | server_address = strndup(addr, MAX_IPV4_HOSTLENGTH); |
| 1629 | } | 1677 | } |
| 1630 | if (!(followsticky & STICKY_PORT)) { | 1678 | if (!(followsticky & STICKY_PORT)) { |
| 1631 | server_port = i; | 1679 | server_port = i; |
| 1632 | } | 1680 | } |
| 1633 | 1681 | ||
| 1634 | free (server_url); | 1682 | free(server_url); |
| 1635 | server_url = url; | 1683 | server_url = url; |
| 1636 | 1684 | ||
| 1637 | if (server_port > MAX_PORT) | 1685 | if (server_port > MAX_PORT) { |
| 1638 | die (STATE_UNKNOWN, | 1686 | die(STATE_UNKNOWN, _("HTTP UNKNOWN - Redirection to port above %d - %s://%s:%d%s%s\n"), |
| 1639 | _("HTTP UNKNOWN - Redirection to port above %d - %s://%s:%d%s%s\n"), | 1687 | MAX_PORT, server_type, server_address, server_port, server_url, |
| 1640 | MAX_PORT, server_type, server_address, server_port, server_url, | 1688 | display_html ? "</A>" : ""); |
| 1641 | display_html ? "</A>" : ""); | 1689 | } |
| 1642 | |||
| 1643 | /* reset virtual port */ | ||
| 1644 | virtual_port = server_port; | ||
| 1645 | |||
| 1646 | if (verbose) | ||
| 1647 | printf (_("Redirection to %s://%s:%d%s\n"), server_type, | ||
| 1648 | host_name ? host_name : server_address, server_port, server_url); | ||
| 1649 | |||
| 1650 | free(addr); | ||
| 1651 | check_http (); | ||
| 1652 | } | ||
| 1653 | 1690 | ||
| 1691 | /* reset virtual port */ | ||
| 1692 | virtual_port = server_port; | ||
| 1654 | 1693 | ||
| 1655 | bool | 1694 | if (verbose) { |
| 1656 | server_type_check (const char *type) | 1695 | printf(_("Redirection to %s://%s:%d%s\n"), server_type, |
| 1657 | { | 1696 | host_name ? host_name : server_address, server_port, server_url); |
| 1658 | if (strcmp (type, "https")) | 1697 | } |
| 1659 | return false; | 1698 | |
| 1660 | else | 1699 | free(addr); |
| 1661 | return true; | 1700 | check_http(); |
| 1662 | } | 1701 | } |
| 1663 | 1702 | ||
| 1664 | int | 1703 | bool server_type_check(const char *type) { return (!(bool)strcmp(type, "https")); } |
| 1665 | server_port_check (int ssl_flag) | 1704 | |
| 1666 | { | 1705 | int server_port_check(int ssl_flag) { |
| 1667 | if (ssl_flag) | 1706 | if (ssl_flag) { |
| 1668 | return HTTPS_PORT; | 1707 | return HTTPS_PORT; |
| 1669 | else | 1708 | } |
| 1670 | return HTTP_PORT; | 1709 | return HTTP_PORT; |
| 1671 | } | 1710 | } |
| 1672 | 1711 | ||
| 1673 | char *perfd_time (double elapsed_time) | 1712 | char *perfd_time(double elapsed_time) { |
| 1674 | { | 1713 | return fperfdata("time", elapsed_time, "s", thlds->warning, |
| 1675 | return fperfdata ("time", elapsed_time, "s", | 1714 | thlds->warning ? thlds->warning->end : 0, thlds->critical, |
| 1676 | thlds->warning?true:false, thlds->warning?thlds->warning->end:0, | 1715 | thlds->critical ? thlds->critical->end : 0, true, 0, true, socket_timeout); |
| 1677 | thlds->critical?true:false, thlds->critical?thlds->critical->end:0, | ||
| 1678 | true, 0, true, socket_timeout); | ||
| 1679 | } | 1716 | } |
| 1680 | 1717 | ||
| 1681 | char *perfd_time_connect (double elapsed_time_connect) | 1718 | char *perfd_time_connect(double elapsed_time_connect) { |
| 1682 | { | 1719 | return fperfdata("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, |
| 1683 | return fperfdata ("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, socket_timeout); | 1720 | socket_timeout); |
| 1684 | } | 1721 | } |
| 1685 | 1722 | ||
| 1686 | char *perfd_time_ssl (double elapsed_time_ssl) | 1723 | char *perfd_time_ssl(double elapsed_time_ssl) { |
| 1687 | { | 1724 | return fperfdata("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, |
| 1688 | return fperfdata ("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, socket_timeout); | 1725 | socket_timeout); |
| 1689 | } | 1726 | } |
| 1690 | 1727 | ||
| 1691 | char *perfd_time_headers (double elapsed_time_headers) | 1728 | char *perfd_time_headers(double elapsed_time_headers) { |
| 1692 | { | 1729 | return fperfdata("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, |
| 1693 | return fperfdata ("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, socket_timeout); | 1730 | socket_timeout); |
| 1694 | } | 1731 | } |
| 1695 | 1732 | ||
| 1696 | char *perfd_time_firstbyte (double elapsed_time_firstbyte) | 1733 | char *perfd_time_firstbyte(double elapsed_time_firstbyte) { |
| 1697 | { | 1734 | return fperfdata("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, |
| 1698 | return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, true, socket_timeout); | 1735 | true, socket_timeout); |
| 1699 | } | 1736 | } |
| 1700 | 1737 | ||
| 1701 | char *perfd_time_transfer (double elapsed_time_transfer) | 1738 | char *perfd_time_transfer(double elapsed_time_transfer) { |
| 1702 | { | 1739 | return fperfdata("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, |
| 1703 | return fperfdata ("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, true, socket_timeout); | 1740 | true, socket_timeout); |
| 1704 | } | 1741 | } |
| 1705 | 1742 | ||
| 1706 | char *perfd_size (int page_len) | 1743 | char *perfd_size(int page_len) { |
| 1707 | { | 1744 | return perfdata("size", page_len, "B", (min_page_len > 0), min_page_len, (min_page_len > 0), 0, |
| 1708 | return perfdata ("size", page_len, "B", | 1745 | true, 0, false, 0); |
| 1709 | (min_page_len>0?true:false), min_page_len, | ||
| 1710 | (min_page_len>0?true:false), 0, | ||
| 1711 | true, 0, false, 0); | ||
| 1712 | } | 1746 | } |
| 1713 | 1747 | ||
| 1714 | void | 1748 | void print_help(void) { |
| 1715 | print_help (void) | 1749 | print_revision(progname, NP_VERSION); |
| 1716 | { | ||
| 1717 | print_revision (progname, NP_VERSION); | ||
| 1718 | 1750 | ||
| 1719 | printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | 1751 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); |
| 1720 | printf (COPYRIGHT, copyright, email); | 1752 | printf(COPYRIGHT, copyright, email); |
| 1721 | 1753 | ||
| 1722 | printf ("%s\n", _("This plugin tests the HTTP service on the specified host. It can test")); | 1754 | printf("%s\n", _("This plugin tests the HTTP service on the specified host. It can test")); |
| 1723 | printf ("%s\n", _("normal (http) and secure (https) servers, follow redirects, search for")); | 1755 | printf("%s\n", _("normal (http) and secure (https) servers, follow redirects, search for")); |
| 1724 | printf ("%s\n", _("strings and regular expressions, check connection times, and report on")); | 1756 | printf("%s\n", _("strings and regular expressions, check connection times, and report on")); |
| 1725 | printf ("%s\n", _("certificate expiration times.")); | 1757 | printf("%s\n", _("certificate expiration times.")); |
| 1726 | 1758 | ||
| 1727 | printf ("\n\n"); | 1759 | printf("\n"); |
| 1760 | printf("%s\n", _("ATTENTION!")); | ||
| 1761 | printf("\n"); | ||
| 1762 | printf("%s\n", _("THIS PLUGIN IS DEPRECATED. The functionality was reimplemented by the")); | ||
| 1763 | printf("%s\n", _("check_curl plugin, which can be used as a drop-in replacement. You should")); | ||
| 1764 | printf("%s\n", _("migrate your checks over to check_curl, because check_http is going to be")); | ||
| 1765 | printf("%s\n", _("removed sooner than later. Just replace check_http with check_curl in your")); | ||
| 1766 | printf("%s\n", _("check command definitions.")); | ||
| 1767 | printf("%s\n", | ||
| 1768 | _("Report issues to: https://github.com/monitoring-plugins/monitoring-plugins/issues")); | ||
| 1728 | 1769 | ||
| 1729 | print_usage (); | 1770 | printf("\n\n"); |
| 1771 | |||
| 1772 | print_usage(); | ||
| 1730 | 1773 | ||
| 1731 | #ifdef HAVE_SSL | 1774 | #ifdef HAVE_SSL |
| 1732 | printf (_("In the first form, make an HTTP request.")); | 1775 | printf(_("In the first form, make an HTTP request.")); |
| 1733 | printf (_("In the second form, connect to the server and check the TLS certificate.")); | 1776 | printf(_("In the second form, connect to the server and check the TLS certificate.")); |
| 1734 | #endif | 1777 | #endif |
| 1735 | printf (_("NOTE: One or both of -H and -I must be specified")); | 1778 | printf(_("NOTE: One or both of -H and -I must be specified")); |
| 1736 | 1779 | ||
| 1737 | printf ("\n"); | 1780 | printf("\n"); |
| 1738 | 1781 | ||
| 1739 | printf (UT_HELP_VRSN); | 1782 | printf(UT_HELP_VRSN); |
| 1740 | printf (UT_EXTRA_OPTS); | 1783 | printf(UT_EXTRA_OPTS); |
| 1741 | 1784 | ||
| 1742 | printf (" %s\n", "-H, --hostname=ADDRESS"); | 1785 | printf(" %s\n", "-H, --hostname=ADDRESS"); |
| 1743 | printf (" %s\n", _("Host name argument for servers using host headers (virtual host)")); | 1786 | printf(" %s\n", _("Host name argument for servers using host headers (virtual host)")); |
| 1744 | printf (" %s\n", _("Append a port to include it in the header (eg: example.com:5000)")); | 1787 | printf(" %s\n", _("Append a port to include it in the header (eg: example.com:5000)")); |
| 1745 | printf (" %s\n", "-I, --IP-address=ADDRESS"); | 1788 | printf(" %s\n", "-I, --IP-address=ADDRESS"); |
| 1746 | printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); | 1789 | printf(" %s\n", |
| 1747 | printf (" %s\n", "-p, --port=INTEGER"); | 1790 | _("IP address or name (use numeric address if possible to bypass DNS lookup).")); |
| 1748 | printf (" %s", _("Port number (default: ")); | 1791 | printf(" %s\n", "-p, --port=INTEGER"); |
| 1749 | printf ("%d)\n", HTTP_PORT); | 1792 | printf(" %s", _("Port number (default: ")); |
| 1793 | printf("%d)\n", HTTP_PORT); | ||
| 1750 | 1794 | ||
| 1751 | printf (UT_IPv46); | 1795 | printf(UT_IPv46); |
| 1752 | 1796 | ||
| 1753 | #ifdef HAVE_SSL | 1797 | #ifdef HAVE_SSL |
| 1754 | printf (" %s\n", "-S, --ssl=VERSION[+]"); | 1798 | printf(" %s\n", "-S, --ssl=VERSION[+]"); |
| 1755 | printf (" %s\n", _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents")); | 1799 | printf(" %s\n", |
| 1756 | printf (" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,")); | 1800 | _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents")); |
| 1757 | printf (" %s\n", _("1.2 = TLSv1.2). With a '+' suffix, newer versions are also accepted.")); | 1801 | printf(" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,")); |
| 1758 | printf (" %s\n", "--sni"); | 1802 | printf(" %s\n", _("1.2 = TLSv1.2). With a '+' suffix, newer versions are also accepted.")); |
| 1759 | printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); | 1803 | printf(" %s\n", "--sni"); |
| 1760 | printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); | 1804 | printf(" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); |
| 1761 | printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); | 1805 | printf(" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); |
| 1762 | printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use")); | 1806 | printf(" %s\n", |
| 1763 | printf (" %s\n", _(" --continue-after-certificate to override this behavior)")); | 1807 | _("Minimum number of days a certificate has to be valid. Port defaults to 443")); |
| 1764 | printf (" %s\n", "--continue-after-certificate"); | 1808 | printf(" %s\n", |
| 1765 | printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check.")); | 1809 | _("(when this option is used the URL is not checked by default. You can use")); |
| 1766 | printf (" %s\n", _("Does nothing unless -C is used.")); | 1810 | printf(" %s\n", _(" --continue-after-certificate to override this behavior)")); |
| 1767 | printf (" %s\n", "-J, --client-cert=FILE"); | 1811 | printf(" %s\n", "--continue-after-certificate"); |
| 1768 | printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); | 1812 | printf(" %s\n", |
| 1769 | printf (" %s\n", _("to be used in establishing the SSL session")); | 1813 | _("Allows the HTTP check to continue after performing the certificate check.")); |
| 1770 | printf (" %s\n", "-K, --private-key=FILE"); | 1814 | printf(" %s\n", _("Does nothing unless -C is used.")); |
| 1771 | printf (" %s\n", _("Name of file containing the private key (PEM format)")); | 1815 | printf(" %s\n", "-J, --client-cert=FILE"); |
| 1772 | printf (" %s\n", _("matching the client certificate")); | 1816 | printf(" %s\n", _("Name of file that contains the client certificate (PEM format)")); |
| 1817 | printf(" %s\n", _("to be used in establishing the SSL session")); | ||
| 1818 | printf(" %s\n", "-K, --private-key=FILE"); | ||
| 1819 | printf(" %s\n", _("Name of file containing the private key (PEM format)")); | ||
| 1820 | printf(" %s\n", _("matching the client certificate")); | ||
| 1773 | #endif | 1821 | #endif |
| 1774 | 1822 | ||
| 1775 | printf (" %s\n", "-e, --expect=STRING"); | 1823 | printf(" %s\n", "-e, --expect=STRING"); |
| 1776 | printf (" %s\n", _("Comma-delimited list of strings, at least one of them is expected in")); | 1824 | printf(" %s\n", _("Comma-delimited list of strings, at least one of them is expected in")); |
| 1777 | printf (" %s", _("the first (status) line of the server response (default: ")); | 1825 | printf(" %s", _("the first (status) line of the server response (default: ")); |
| 1778 | printf ("%s)\n", HTTP_EXPECT); | 1826 | printf("%s)\n", HTTP_EXPECT); |
| 1779 | printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)")); | 1827 | printf(" %s\n", |
| 1780 | printf (" %s\n", "-d, --header-string=STRING"); | 1828 | _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)")); |
| 1781 | printf (" %s\n", _("String to expect in the response headers")); | 1829 | printf(" %s\n", "-d, --header-string=STRING"); |
| 1782 | printf (" %s\n", "-s, --string=STRING"); | 1830 | printf(" %s\n", _("String to expect in the response headers")); |
| 1783 | printf (" %s\n", _("String to expect in the content")); | 1831 | printf(" %s\n", "-s, --string=STRING"); |
| 1784 | printf (" %s\n", "-u, --url=PATH"); | 1832 | printf(" %s\n", _("String to expect in the content")); |
| 1785 | printf (" %s\n", _("URL to GET or POST (default: /)")); | 1833 | printf(" %s\n", "-u, --url=PATH"); |
| 1786 | printf (" %s\n", "-P, --post=STRING"); | 1834 | printf(" %s\n", _("URL to GET or POST (default: /)")); |
| 1787 | printf (" %s\n", _("URL decoded http POST data")); | 1835 | printf(" %s\n", "-P, --post=STRING"); |
| 1788 | printf (" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT, CONNECT:POST)"); | 1836 | printf(" %s\n", _("URL decoded http POST data")); |
| 1789 | printf (" %s\n", _("Set HTTP method.")); | 1837 | printf(" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, " |
| 1790 | printf (" %s\n", "-N, --no-body"); | 1838 | "CONNECT, CONNECT:POST)"); |
| 1791 | printf (" %s\n", _("Don't wait for document body: stop reading after headers.")); | 1839 | printf(" %s\n", _("Set HTTP method.")); |
| 1792 | printf (" %s\n", _("(Note that this still does an HTTP GET or POST, not a HEAD.)")); | 1840 | printf(" %s\n", "-N, --no-body"); |
| 1793 | printf (" %s\n", "-M, --max-age=SECONDS"); | 1841 | printf(" %s\n", _("Don't wait for document body: stop reading after headers.")); |
| 1794 | printf (" %s\n", _("Warn if document is more than SECONDS old. the number can also be of")); | 1842 | printf(" %s\n", _("(Note that this still does an HTTP GET or POST, not a HEAD.)")); |
| 1795 | printf (" %s\n", _("the form \"10m\" for minutes, \"10h\" for hours, or \"10d\" for days.")); | 1843 | printf(" %s\n", "-M, --max-age=SECONDS"); |
| 1796 | printf (" %s\n", "-T, --content-type=STRING"); | 1844 | printf(" %s\n", _("Warn if document is more than SECONDS old. the number can also be of")); |
| 1797 | printf (" %s\n", _("specify Content-Type header media type when POSTing\n")); | 1845 | printf(" %s\n", _("the form \"10m\" for minutes, \"10h\" for hours, or \"10d\" for days.")); |
| 1798 | 1846 | printf(" %s\n", "-T, --content-type=STRING"); | |
| 1799 | printf (" %s\n", "-l, --linespan"); | 1847 | printf(" %s\n", _("specify Content-Type header media type when POSTing\n")); |
| 1800 | printf (" %s\n", _("Allow regex to span newlines (must precede -r or -R)")); | 1848 | |
| 1801 | printf (" %s\n", "-r, --regex, --ereg=STRING"); | 1849 | printf(" %s\n", "-l, --linespan"); |
| 1802 | printf (" %s\n", _("Search page for regex STRING")); | 1850 | printf(" %s\n", _("Allow regex to span newlines (must precede -r or -R)")); |
| 1803 | printf (" %s\n", "-R, --eregi=STRING"); | 1851 | printf(" %s\n", "-r, --regex, --ereg=STRING"); |
| 1804 | printf (" %s\n", _("Search page for case-insensitive regex STRING")); | 1852 | printf(" %s\n", _("Search page for regex STRING")); |
| 1805 | printf (" %s\n", "--invert-regex"); | 1853 | printf(" %s\n", "-R, --eregi=STRING"); |
| 1806 | printf (" %s\n", _("Return STATE if found, OK if not (STATE is CRITICAL, per default)")); | 1854 | printf(" %s\n", _("Search page for case-insensitive regex STRING")); |
| 1807 | printf (" %s\n", _("can be changed with --state--regex)")); | 1855 | printf(" %s\n", "--invert-regex"); |
| 1808 | printf (" %s\n", "--state-regex=STATE"); | 1856 | printf(" %s\n", _("Return STATE if found, OK if not (STATE is CRITICAL, per default)")); |
| 1809 | printf (" %s\n", _("Return STATE if regex is found, OK if not\n")); | 1857 | printf(" %s\n", _("can be changed with --state--regex)")); |
| 1810 | 1858 | printf(" %s\n", "--state-regex=STATE"); | |
| 1811 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); | 1859 | printf(" %s\n", _("Return STATE if regex is found, OK if not\n")); |
| 1812 | printf (" %s\n", _("Username:password on sites with basic authentication")); | 1860 | |
| 1813 | printf (" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); | 1861 | printf(" %s\n", "-a, --authorization=AUTH_PAIR"); |
| 1814 | printf (" %s\n", _("Username:password on proxy-servers with basic authentication")); | 1862 | printf(" %s\n", _("Username:password on sites with basic authentication")); |
| 1815 | printf (" %s\n", "-A, --useragent=STRING"); | 1863 | printf(" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); |
| 1816 | printf (" %s\n", _("String to be sent in http header as \"User Agent\"")); | 1864 | printf(" %s\n", _("Username:password on proxy-servers with basic authentication")); |
| 1817 | printf (" %s\n", "-k, --header=STRING"); | 1865 | printf(" %s\n", "-A, --useragent=STRING"); |
| 1818 | printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers")); | 1866 | printf(" %s\n", _("String to be sent in http header as \"User Agent\"")); |
| 1819 | printf (" %s\n", "-E, --extended-perfdata"); | 1867 | printf(" %s\n", "-k, --header=STRING"); |
| 1820 | printf (" %s\n", _("Print additional performance data")); | 1868 | printf( |
| 1821 | printf (" %s\n", "-B, --show-body"); | 1869 | " %s\n", |
| 1822 | printf (" %s\n", _("Print body content below status line")); | 1870 | _("Any other tags to be sent in http header. Use multiple times for additional headers")); |
| 1823 | printf (" %s\n", "-L, --link"); | 1871 | printf(" %s\n", "-E, --extended-perfdata"); |
| 1824 | printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); | 1872 | printf(" %s\n", _("Print additional performance data")); |
| 1825 | printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); | 1873 | printf(" %s\n", "-B, --show-body"); |
| 1826 | printf (" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the")); | 1874 | printf(" %s\n", _("Print body content below status line")); |
| 1827 | printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); | 1875 | printf(" %s\n", "-L, --link"); |
| 1828 | printf (" %s\n", "--max-redirs=INTEGER"); | 1876 | printf(" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); |
| 1829 | printf (" %s", _("Maximal number of redirects (default: ")); | 1877 | printf(" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); |
| 1830 | printf ("%d)\n", DEFAULT_MAX_REDIRS); | 1878 | printf(" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the")); |
| 1831 | printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); | 1879 | printf(" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); |
| 1832 | printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); | 1880 | printf(" %s\n", "--max-redirs=INTEGER"); |
| 1833 | printf (UT_WARN_CRIT); | 1881 | printf(" %s", _("Maximal number of redirects (default: ")); |
| 1834 | 1882 | printf("%d)\n", DEFAULT_MAX_REDIRS); | |
| 1835 | printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 1883 | printf(" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); |
| 1836 | 1884 | printf(" %s\n", | |
| 1837 | printf (UT_VERBOSE); | 1885 | _("Minimum page size required (bytes) : Maximum page size required (bytes)")); |
| 1838 | 1886 | printf(UT_WARN_CRIT); | |
| 1839 | printf ("\n"); | 1887 | |
| 1840 | printf ("%s\n", _("Notes:")); | 1888 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 1841 | printf (" %s\n", _("This plugin will attempt to open an HTTP connection with the host.")); | 1889 | |
| 1842 | printf (" %s\n", _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL")); | 1890 | printf(UT_VERBOSE); |
| 1843 | printf (" %s\n", _("other errors return STATE_UNKNOWN. Successful connects, but incorrect response")); | 1891 | |
| 1844 | printf (" %s\n", _("messages from the host result in STATE_WARNING return values. If you are")); | 1892 | printf("\n"); |
| 1845 | printf (" %s\n", _("checking a virtual server that uses 'host headers' you must supply the FQDN")); | 1893 | printf("%s\n", _("Notes:")); |
| 1846 | printf (" %s\n", _("(fully qualified domain name) as the [host_name] argument.")); | 1894 | printf(" %s\n", _("This plugin will attempt to open an HTTP connection with the host.")); |
| 1895 | printf(" %s\n", | ||
| 1896 | _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL")); | ||
| 1897 | printf(" %s\n", | ||
| 1898 | _("other errors return STATE_UNKNOWN. Successful connects, but incorrect response")); | ||
| 1899 | printf(" %s\n", _("messages from the host result in STATE_WARNING return values. If you are")); | ||
| 1900 | printf(" %s\n", | ||
| 1901 | _("checking a virtual server that uses 'host headers' you must supply the FQDN")); | ||
| 1902 | printf(" %s\n", _("(fully qualified domain name) as the [host_name] argument.")); | ||
| 1847 | 1903 | ||
| 1848 | #ifdef HAVE_SSL | 1904 | #ifdef HAVE_SSL |
| 1849 | printf ("\n"); | 1905 | printf("\n"); |
| 1850 | printf (" %s\n", _("This plugin can also check whether an SSL enabled web server is able to")); | 1906 | printf(" %s\n", _("This plugin can also check whether an SSL enabled web server is able to")); |
| 1851 | printf (" %s\n", _("serve content (optionally within a specified time) or whether the X509 ")); | 1907 | printf(" %s\n", _("serve content (optionally within a specified time) or whether the X509 ")); |
| 1852 | printf (" %s\n", _("certificate is still valid for the specified number of days.")); | 1908 | printf(" %s\n", _("certificate is still valid for the specified number of days.")); |
| 1853 | printf ("\n"); | 1909 | printf("\n"); |
| 1854 | printf (" %s\n", _("Please note that this plugin does not check if the presented server")); | 1910 | printf(" %s\n", _("Please note that this plugin does not check if the presented server")); |
| 1855 | printf (" %s\n", _("certificate matches the hostname of the server, or if the certificate")); | 1911 | printf(" %s\n", _("certificate matches the hostname of the server, or if the certificate")); |
| 1856 | printf (" %s\n", _("has a valid chain of trust to one of the locally installed CAs.")); | 1912 | printf(" %s\n", _("has a valid chain of trust to one of the locally installed CAs.")); |
| 1857 | printf ("\n"); | 1913 | printf("\n"); |
| 1858 | printf ("%s\n", _("Examples:")); | 1914 | printf("%s\n", _("Examples:")); |
| 1859 | printf (" %s\n\n", "CHECK CONTENT: check_http -w 5 -c 10 --ssl -H www.verisign.com"); | 1915 | printf(" %s\n\n", "CHECK CONTENT: check_http -w 5 -c 10 --ssl -H www.verisign.com"); |
| 1860 | printf (" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,")); | 1916 | printf(" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,")); |
| 1861 | printf (" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); | 1917 | printf(" %s\n", |
| 1862 | printf (" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | 1918 | _("a STATE_OK will be returned. When the server returns its content but exceeds")); |
| 1863 | printf (" %s\n", _("a STATE_CRITICAL will be returned.")); | 1919 | printf(" %s\n", |
| 1864 | printf ("\n"); | 1920 | _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); |
| 1865 | printf (" %s\n\n", "CHECK CERTIFICATE: check_http -H www.verisign.com -C 14"); | 1921 | printf(" %s\n", _("a STATE_CRITICAL will be returned.")); |
| 1866 | printf (" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); | 1922 | printf("\n"); |
| 1867 | printf (" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than")); | 1923 | printf(" %s\n\n", "CHECK CERTIFICATE: check_http -H www.verisign.com -C 14"); |
| 1868 | printf (" %s\n", _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); | 1924 | printf(" %s\n", |
| 1869 | printf (" %s\n\n", _("the certificate is expired.")); | 1925 | _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); |
| 1870 | printf ("\n"); | 1926 | printf(" %s\n", |
| 1871 | printf (" %s\n\n", "CHECK CERTIFICATE: check_http -H www.verisign.com -C 30,14"); | 1927 | _("a STATE_OK is returned. When the certificate is still valid, but for less than")); |
| 1872 | printf (" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 30 days,")); | 1928 | printf(" %s\n", |
| 1873 | printf (" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than")); | 1929 | _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); |
| 1874 | printf (" %s\n", _("30 days, but more than 14 days, a STATE_WARNING is returned.")); | 1930 | printf(" %s\n\n", _("the certificate is expired.")); |
| 1875 | printf (" %s\n", _("A STATE_CRITICAL will be returned when certificate expires in less than 14 days")); | 1931 | printf("\n"); |
| 1876 | 1932 | printf(" %s\n\n", "CHECK CERTIFICATE: check_http -H www.verisign.com -C 30,14"); | |
| 1877 | printf (" %s\n\n", "CHECK SSL WEBSERVER CONTENT VIA PROXY USING HTTP 1.1 CONNECT: "); | 1933 | printf(" %s\n", |
| 1878 | printf (" %s\n", _("check_http -I 192.168.100.35 -p 80 -u https://www.verisign.com/ -S -j CONNECT -H www.verisign.com ")); | 1934 | _("When the certificate of 'www.verisign.com' is valid for more than 30 days,")); |
| 1879 | printf (" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> -S(sl) -j CONNECT -H <webserver>")); | 1935 | printf(" %s\n", |
| 1880 | printf (" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); | 1936 | _("a STATE_OK is returned. When the certificate is still valid, but for less than")); |
| 1881 | printf (" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | 1937 | printf(" %s\n", _("30 days, but more than 14 days, a STATE_WARNING is returned.")); |
| 1882 | printf (" %s\n", _("a STATE_CRITICAL will be returned. By adding a colon to the method you can set the method used")); | 1938 | printf(" %s\n", |
| 1883 | printf (" %s\n", _("inside the proxied connection: -j CONNECT:POST")); | 1939 | _("A STATE_CRITICAL will be returned when certificate expires in less than 14 days")); |
| 1940 | |||
| 1941 | printf(" %s\n\n", "CHECK SSL WEBSERVER CONTENT VIA PROXY USING HTTP 1.1 CONNECT: "); | ||
| 1942 | printf(" %s\n", _("check_http -I 192.168.100.35 -p 80 -u https://www.verisign.com/ -S -j " | ||
| 1943 | "CONNECT -H www.verisign.com ")); | ||
| 1944 | printf(" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> " | ||
| 1945 | "-S(sl) -j CONNECT -H <webserver>")); | ||
| 1946 | printf(" %s\n", | ||
| 1947 | _("a STATE_OK will be returned. When the server returns its content but exceeds")); | ||
| 1948 | printf(" %s\n", | ||
| 1949 | _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | ||
| 1950 | printf(" %s\n", _("a STATE_CRITICAL will be returned. By adding a colon to the method you can " | ||
| 1951 | "set the method used")); | ||
| 1952 | printf(" %s\n", _("inside the proxied connection: -j CONNECT:POST")); | ||
| 1884 | 1953 | ||
| 1885 | #endif | 1954 | #endif |
| 1886 | 1955 | ||
| 1887 | printf (UT_SUPPORT); | 1956 | printf(UT_SUPPORT); |
| 1888 | |||
| 1889 | } | 1957 | } |
| 1890 | 1958 | ||
| 1891 | 1959 | void print_usage(void) { | |
| 1892 | 1960 | printf("%s\n", _("Usage:")); | |
| 1893 | void | 1961 | printf(" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n", progname); |
| 1894 | print_usage (void) | 1962 | printf(" [-J <client certificate file>] [-K <private key>]\n"); |
| 1895 | { | 1963 | printf(" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); |
| 1896 | printf ("%s\n", _("Usage:")); | 1964 | printf(" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport>]\n"); |
| 1897 | printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); | 1965 | printf(" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive " |
| 1898 | printf (" [-J <client certificate file>] [-K <private key>]\n"); | 1966 | "regex>]\n"); |
| 1899 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); | 1967 | printf(" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); |
| 1900 | printf (" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport>]\n"); | 1968 | printf(" [-A string] [-k string] [-S <version>] [--sni]\n"); |
| 1901 | printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); | 1969 | printf(" [-T <content-type>] [-j method]\n"); |
| 1902 | printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); | 1970 | printf(" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n", progname); |
| 1903 | printf (" [-A string] [-k string] [-S <version>] [--sni]\n"); | 1971 | printf(" [-p <port>] [-t <timeout>] [-4|-6] [--sni]\n"); |
| 1904 | printf (" [-T <content-type>] [-j method]\n"); | ||
| 1905 | printf (" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n",progname); | ||
| 1906 | printf (" [-p <port>] [-t <timeout>] [-4|-6] [--sni]\n"); | ||
| 1907 | } | 1972 | } |
diff --git a/plugins/check_ide_smart.c b/plugins/check_ide_smart.c index 9640ef70..16fe3d01 100644 --- a/plugins/check_ide_smart.c +++ b/plugins/check_ide_smart.c | |||
| @@ -56,7 +56,6 @@ void print_usage(void); | |||
| 56 | # include <sys/device.h> | 56 | # include <sys/device.h> |
| 57 | # include <sys/param.h> | 57 | # include <sys/param.h> |
| 58 | # include <sys/sysctl.h> | 58 | # include <sys/sysctl.h> |
| 59 | # include <sys/videoio.h> /* for __u8 and friends */ | ||
| 60 | # include <sys/scsiio.h> | 59 | # include <sys/scsiio.h> |
| 61 | # include <sys/ataio.h> | 60 | # include <sys/ataio.h> |
| 62 | # include <dev/ata/atareg.h> | 61 | # include <dev/ata/atareg.h> |
| @@ -79,48 +78,47 @@ void print_usage(void); | |||
| 79 | #define UNKNOWN -1 | 78 | #define UNKNOWN -1 |
| 80 | 79 | ||
| 81 | typedef struct threshold_s { | 80 | typedef struct threshold_s { |
| 82 | __u8 id; | 81 | uint8_t id; |
| 83 | __u8 threshold; | 82 | uint8_t threshold; |
| 84 | __u8 reserved[10]; | 83 | uint8_t reserved[10]; |
| 85 | } __attribute__((packed)) threshold_t; | 84 | } __attribute__((packed)) threshold_t; |
| 86 | 85 | ||
| 87 | typedef struct thresholds_s { | 86 | typedef struct thresholds_s { |
| 88 | __u16 revision; | 87 | uint16_t revision; |
| 89 | threshold_t thresholds[NR_ATTRIBUTES]; | 88 | threshold_t thresholds[NR_ATTRIBUTES]; |
| 90 | __u8 reserved[18]; | 89 | uint8_t reserved[18]; |
| 91 | __u8 vendor[131]; | 90 | uint8_t vendor[131]; |
| 92 | __u8 checksum; | 91 | uint8_t checksum; |
| 93 | } __attribute__((packed)) thresholds_t; | 92 | } __attribute__((packed)) thresholds_t; |
| 94 | 93 | ||
| 95 | typedef struct value_s { | 94 | typedef struct value_s { |
| 96 | __u8 id; | 95 | uint8_t id; |
| 97 | __u16 status; | 96 | uint16_t status; |
| 98 | __u8 value; | 97 | uint8_t value; |
| 99 | __u8 vendor[8]; | 98 | uint8_t vendor[8]; |
| 100 | } __attribute__((packed)) value_t; | 99 | } __attribute__((packed)) value_t; |
| 101 | 100 | ||
| 102 | typedef struct values_s { | 101 | typedef struct values_s { |
| 103 | __u16 revision; | 102 | uint16_t revision; |
| 104 | value_t values[NR_ATTRIBUTES]; | 103 | value_t values[NR_ATTRIBUTES]; |
| 105 | __u8 offline_status; | 104 | uint8_t offline_status; |
| 106 | __u8 vendor1; | 105 | uint8_t vendor1; |
| 107 | __u16 offline_timeout; | 106 | uint16_t offline_timeout; |
| 108 | __u8 vendor2; | 107 | uint8_t vendor2; |
| 109 | __u8 offline_capability; | 108 | uint8_t offline_capability; |
| 110 | __u16 smart_capability; | 109 | uint16_t smart_capability; |
| 111 | __u8 reserved[16]; | 110 | uint8_t reserved[16]; |
| 112 | __u8 vendor[125]; | 111 | uint8_t vendor[125]; |
| 113 | __u8 checksum; | 112 | uint8_t checksum; |
| 114 | } __attribute__((packed)) values_t; | 113 | } __attribute__((packed)) values_t; |
| 115 | 114 | ||
| 116 | static struct { | 115 | static struct { |
| 117 | __u8 value; | 116 | uint8_t value; |
| 118 | char *text; | 117 | char *text; |
| 119 | } offline_status_text[] = {{0x00, "NeverStarted"}, {0x02, "Completed"}, {0x04, "Suspended"}, | 118 | } offline_status_text[] = {{0x00, "NeverStarted"}, {0x02, "Completed"}, {0x04, "Suspended"}, {0x05, "Aborted"}, {0x06, "Failed"}, {0, 0}}; |
| 120 | {0x05, "Aborted"}, {0x06, "Failed"}, {0, 0}}; | ||
| 121 | 119 | ||
| 122 | static struct { | 120 | static struct { |
| 123 | __u8 value; | 121 | uint8_t value; |
| 124 | char *text; | 122 | char *text; |
| 125 | } smart_command[] = {{SMART_ENABLE, "SMART_ENABLE"}, | 123 | } smart_command[] = {{SMART_ENABLE, "SMART_ENABLE"}, |
| 126 | {SMART_DISABLE, "SMART_DISABLE"}, | 124 | {SMART_DISABLE, "SMART_DISABLE"}, |
| @@ -140,7 +138,7 @@ static int smart_read_values(int, values_t *); | |||
| 140 | static int nagios(values_t *, thresholds_t *); | 138 | static int nagios(values_t *, thresholds_t *); |
| 141 | static void print_value(value_t *, threshold_t *); | 139 | static void print_value(value_t *, threshold_t *); |
| 142 | static void print_values(values_t *, thresholds_t *); | 140 | static void print_values(values_t *, thresholds_t *); |
| 143 | static int smart_cmd_simple(int, enum SmartCommand, __u8, bool); | 141 | static int smart_cmd_simple(int, enum SmartCommand, uint8_t, bool); |
| 144 | static int smart_read_thresholds(int, thresholds_t *); | 142 | static int smart_read_thresholds(int, thresholds_t *); |
| 145 | static bool verbose = false; | 143 | static bool verbose = false; |
| 146 | 144 | ||
| @@ -175,8 +173,9 @@ int main(int argc, char *argv[]) { | |||
| 175 | 173 | ||
| 176 | o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex); | 174 | o = getopt_long(argc, argv, "+d:iq10nhVv", longopts, &longindex); |
| 177 | 175 | ||
| 178 | if (o == -1 || o == EOF || o == 1) | 176 | if (o == -1 || o == EOF || o == 1) { |
| 179 | break; | 177 | break; |
| 178 | } | ||
| 180 | 179 | ||
| 181 | switch (o) { | 180 | switch (o) { |
| 182 | case 'd': | 181 | case 'd': |
| @@ -234,8 +233,9 @@ int main(int argc, char *argv[]) { | |||
| 234 | smart_read_values(fd, &values); | 233 | smart_read_values(fd, &values); |
| 235 | smart_read_thresholds(fd, &thresholds); | 234 | smart_read_thresholds(fd, &thresholds); |
| 236 | retval = nagios(&values, &thresholds); | 235 | retval = nagios(&values, &thresholds); |
| 237 | if (verbose) | 236 | if (verbose) { |
| 238 | print_values(&values, &thresholds); | 237 | print_values(&values, &thresholds); |
| 238 | } | ||
| 239 | 239 | ||
| 240 | close(fd); | 240 | close(fd); |
| 241 | return retval; | 241 | return retval; |
| @@ -254,7 +254,7 @@ char *get_offline_text(int status) { | |||
| 254 | int smart_read_values(int fd, values_t *values) { | 254 | int smart_read_values(int fd, values_t *values) { |
| 255 | #ifdef __linux__ | 255 | #ifdef __linux__ |
| 256 | int e; | 256 | int e; |
| 257 | __u8 args[4 + 512]; | 257 | uint8_t args[4 + 512]; |
| 258 | args[0] = WIN_SMART; | 258 | args[0] = WIN_SMART; |
| 259 | args[1] = 0; | 259 | args[1] = 0; |
| 260 | args[2] = SMART_READ_VALUES; | 260 | args[2] = SMART_READ_VALUES; |
| @@ -282,8 +282,9 @@ int smart_read_values(int fd, values_t *values) { | |||
| 282 | req.cylinder = WDSMART_CYL; | 282 | req.cylinder = WDSMART_CYL; |
| 283 | 283 | ||
| 284 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { | 284 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { |
| 285 | if (req.retsts != ATACMD_OK) | 285 | if (req.retsts != ATACMD_OK) { |
| 286 | errno = ENODEV; | 286 | errno = ENODEV; |
| 287 | } | ||
| 287 | } | 288 | } |
| 288 | 289 | ||
| 289 | if (errno != 0) { | 290 | if (errno != 0) { |
| @@ -370,22 +371,24 @@ void print_values(values_t *p, thresholds_t *t) { | |||
| 370 | p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : ""); | 371 | p->smart_capability & 1 ? "SaveOnStandBy" : "", p->smart_capability & 2 ? "AutoSave" : ""); |
| 371 | } | 372 | } |
| 372 | 373 | ||
| 373 | int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_error) { | 374 | int smart_cmd_simple(int fd, enum SmartCommand command, uint8_t val0, bool show_error) { |
| 374 | int e = STATE_UNKNOWN; | 375 | int e = STATE_UNKNOWN; |
| 375 | #ifdef __linux__ | 376 | #ifdef __linux__ |
| 376 | __u8 args[4]; | 377 | uint8_t args[4]; |
| 377 | args[0] = WIN_SMART; | 378 | args[0] = WIN_SMART; |
| 378 | args[1] = val0; | 379 | args[1] = val0; |
| 379 | args[2] = smart_command[command].value; | 380 | args[2] = smart_command[command].value; |
| 380 | args[3] = 0; | 381 | args[3] = 0; |
| 381 | if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { | 382 | if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { |
| 382 | e = STATE_CRITICAL; | 383 | e = STATE_CRITICAL; |
| 383 | if (show_error) | 384 | if (show_error) { |
| 384 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); | 385 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); |
| 386 | } | ||
| 385 | } else { | 387 | } else { |
| 386 | e = STATE_OK; | 388 | e = STATE_OK; |
| 387 | if (show_error) | 389 | if (show_error) { |
| 388 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); | 390 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); |
| 391 | } | ||
| 389 | } | 392 | } |
| 390 | 393 | ||
| 391 | #endif /* __linux__ */ | 394 | #endif /* __linux__ */ |
| @@ -401,20 +404,24 @@ int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_err | |||
| 401 | req.sec_count = val0; | 404 | req.sec_count = val0; |
| 402 | 405 | ||
| 403 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { | 406 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { |
| 404 | if (req.retsts != ATACMD_OK) | 407 | if (req.retsts != ATACMD_OK) { |
| 405 | errno = ENODEV; | 408 | errno = ENODEV; |
| 406 | if (req.cylinder != WDSMART_CYL) | 409 | } |
| 410 | if (req.cylinder != WDSMART_CYL) { | ||
| 407 | errno = ENODEV; | 411 | errno = ENODEV; |
| 412 | } | ||
| 408 | } | 413 | } |
| 409 | 414 | ||
| 410 | if (errno != 0) { | 415 | if (errno != 0) { |
| 411 | e = STATE_CRITICAL; | 416 | e = STATE_CRITICAL; |
| 412 | if (show_error) | 417 | if (show_error) { |
| 413 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); | 418 | printf(_("CRITICAL - %s: %s\n"), smart_command[command].text, strerror(errno)); |
| 419 | } | ||
| 414 | } else { | 420 | } else { |
| 415 | e = STATE_OK; | 421 | e = STATE_OK; |
| 416 | if (show_error) | 422 | if (show_error) { |
| 417 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); | 423 | printf(_("OK - Command sent (%s)\n"), smart_command[command].text); |
| 424 | } | ||
| 418 | } | 425 | } |
| 419 | 426 | ||
| 420 | #endif /* __NetBSD__ */ | 427 | #endif /* __NetBSD__ */ |
| @@ -424,7 +431,7 @@ int smart_cmd_simple(int fd, enum SmartCommand command, __u8 val0, bool show_err | |||
| 424 | int smart_read_thresholds(int fd, thresholds_t *thresholds) { | 431 | int smart_read_thresholds(int fd, thresholds_t *thresholds) { |
| 425 | #ifdef __linux__ | 432 | #ifdef __linux__ |
| 426 | int e; | 433 | int e; |
| 427 | __u8 args[4 + 512]; | 434 | uint8_t args[4 + 512]; |
| 428 | args[0] = WIN_SMART; | 435 | args[0] = WIN_SMART; |
| 429 | args[1] = 0; | 436 | args[1] = 0; |
| 430 | args[2] = SMART_READ_THRESHOLDS; | 437 | args[2] = SMART_READ_THRESHOLDS; |
| @@ -452,8 +459,9 @@ int smart_read_thresholds(int fd, thresholds_t *thresholds) { | |||
| 452 | req.cylinder = WDSMART_CYL; | 459 | req.cylinder = WDSMART_CYL; |
| 453 | 460 | ||
| 454 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { | 461 | if (ioctl(fd, ATAIOCCOMMAND, &req) == 0) { |
| 455 | if (req.retsts != ATACMD_OK) | 462 | if (req.retsts != ATACMD_OK) { |
| 456 | errno = ENODEV; | 463 | errno = ENODEV; |
| 464 | } | ||
| 457 | } | 465 | } |
| 458 | 466 | ||
| 459 | if (errno != 0) { | 467 | if (errno != 0) { |
diff --git a/plugins/check_ldap.c b/plugins/check_ldap.c index 597644bd..1b2e2826 100644 --- a/plugins/check_ldap.c +++ b/plugins/check_ldap.c | |||
| @@ -27,12 +27,11 @@ | |||
| 27 | *****************************************************************************/ | 27 | *****************************************************************************/ |
| 28 | 28 | ||
| 29 | /* progname may be check_ldaps */ | 29 | /* progname may be check_ldaps */ |
| 30 | char *progname = "check_ldap"; | 30 | #include "output.h" |
| 31 | const char *copyright = "2000-2024"; | ||
| 32 | const char *email = "devel@monitoring-plugins.org"; | ||
| 33 | |||
| 34 | #include "common.h" | 31 | #include "common.h" |
| 35 | #include "netutils.h" | 32 | #include "netutils.h" |
| 33 | #include "perfdata.h" | ||
| 34 | #include "thresholds.h" | ||
| 36 | #include "utils.h" | 35 | #include "utils.h" |
| 37 | #include "check_ldap.d/config.h" | 36 | #include "check_ldap.d/config.h" |
| 38 | 37 | ||
| @@ -41,6 +40,10 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 41 | #define LDAP_DEPRECATED 1 | 40 | #define LDAP_DEPRECATED 1 |
| 42 | #include <ldap.h> | 41 | #include <ldap.h> |
| 43 | 42 | ||
| 43 | char *progname = "check_ldap"; | ||
| 44 | const char *copyright = "2000-2024"; | ||
| 45 | const char *email = "devel@monitoring-plugins.org"; | ||
| 46 | |||
| 44 | enum { | 47 | enum { |
| 45 | DEFAULT_PORT = 389 | 48 | DEFAULT_PORT = 389 |
| 46 | }; | 49 | }; |
| @@ -79,6 +82,10 @@ int main(int argc, char *argv[]) { | |||
| 79 | 82 | ||
| 80 | const check_ldap_config config = tmp_config.config; | 83 | const check_ldap_config config = tmp_config.config; |
| 81 | 84 | ||
| 85 | if (config.output_format_is_set) { | ||
| 86 | mp_set_format(config.output_format); | ||
| 87 | } | ||
| 88 | |||
| 82 | /* initialize alarm signal handling */ | 89 | /* initialize alarm signal handling */ |
| 83 | signal(SIGALRM, socket_timeout_alarm_handler); | 90 | signal(SIGALRM, socket_timeout_alarm_handler); |
| 84 | 91 | ||
| @@ -89,96 +96,172 @@ int main(int argc, char *argv[]) { | |||
| 89 | struct timeval start_time; | 96 | struct timeval start_time; |
| 90 | gettimeofday(&start_time, NULL); | 97 | gettimeofday(&start_time, NULL); |
| 91 | 98 | ||
| 99 | mp_check overall = mp_check_init(); | ||
| 100 | |||
| 92 | LDAP *ldap_connection; | 101 | LDAP *ldap_connection; |
| 93 | /* initialize ldap */ | 102 | /* initialize ldap */ |
| 103 | { | ||
| 94 | #ifdef HAVE_LDAP_INIT | 104 | #ifdef HAVE_LDAP_INIT |
| 95 | if (!(ldap_connection = ldap_init(config.ld_host, config.ld_port))) { | 105 | mp_subcheck sc_ldap_init = mp_subcheck_init(); |
| 96 | printf("Could not connect to the server at port %i\n", config.ld_port); | 106 | if (!(ldap_connection = ldap_init(config.ld_host, config.ld_port))) { |
| 97 | return STATE_CRITICAL; | 107 | xasprintf(&sc_ldap_init.output, "could not connect to the server at port %i", |
| 98 | } | 108 | config.ld_port); |
| 109 | sc_ldap_init = mp_set_subcheck_state(sc_ldap_init, STATE_CRITICAL); | ||
| 110 | mp_add_subcheck_to_check(&overall, sc_ldap_init); | ||
| 111 | mp_exit(overall); | ||
| 112 | } else { | ||
| 113 | xasprintf(&sc_ldap_init.output, "connected to the server at port %i", config.ld_port); | ||
| 114 | sc_ldap_init = mp_set_subcheck_state(sc_ldap_init, STATE_OK); | ||
| 115 | mp_add_subcheck_to_check(&overall, sc_ldap_init); | ||
| 116 | } | ||
| 99 | #else | 117 | #else |
| 100 | if (!(ld = ldap_open(config.ld_host, config.ld_port))) { | 118 | mp_subcheck sc_ldap_init = mp_subcheck_init(); |
| 101 | if (verbose) { | 119 | if (!(ld = ldap_open(config.ld_host, config.ld_port))) { |
| 102 | ldap_perror(ldap_connection, "ldap_open"); | 120 | if (verbose) { |
| 121 | ldap_perror(ldap_connection, "ldap_open"); | ||
| 122 | } | ||
| 123 | xasprintf(&sc_ldap_init.output, "Could not connect to the server at port %i"), config.ld_port); | ||
| 124 | sc_ldap_init = mp_set_subcheck_state(sc_ldap_init, STATE_CRITICAL); | ||
| 125 | mp_add_subcheck_to_check(&overall, sc_ldap_init); | ||
| 126 | mp_exit(overall); | ||
| 127 | } else { | ||
| 128 | xasprintf(&sc_ldap_init.output, "connected to the server at port %i", config.ld_port); | ||
| 129 | sc_ldap_init = mp_set_subcheck_state(sc_ldap_init, STATE_OK); | ||
| 130 | mp_add_subcheck_to_check(&overall, sc_ldap_init); | ||
| 103 | } | 131 | } |
| 104 | printf(_("Could not connect to the server at port %i\n"), config.ld_port); | ||
| 105 | return STATE_CRITICAL; | ||
| 106 | } | ||
| 107 | #endif /* HAVE_LDAP_INIT */ | 132 | #endif /* HAVE_LDAP_INIT */ |
| 133 | } | ||
| 108 | 134 | ||
| 109 | #ifdef HAVE_LDAP_SET_OPTION | 135 | #ifdef HAVE_LDAP_SET_OPTION |
| 110 | /* set ldap options */ | 136 | /* set ldap options */ |
| 111 | if (ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &config.ld_protocol) != LDAP_OPT_SUCCESS) { | 137 | mp_subcheck sc_ldap_set_opts = mp_subcheck_init(); |
| 112 | printf(_("Could not set protocol version %d\n"), config.ld_protocol); | 138 | if (ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &config.ld_protocol) != |
| 113 | return STATE_CRITICAL; | 139 | LDAP_OPT_SUCCESS) { |
| 140 | xasprintf(&sc_ldap_set_opts.output, "Could not set protocol version %d", | ||
| 141 | config.ld_protocol); | ||
| 142 | sc_ldap_set_opts = mp_set_subcheck_state(sc_ldap_set_opts, STATE_CRITICAL); | ||
| 143 | mp_add_subcheck_to_check(&overall, sc_ldap_set_opts); | ||
| 144 | mp_exit(overall); | ||
| 145 | } else { | ||
| 146 | xasprintf(&sc_ldap_set_opts.output, "set protocol version %d", config.ld_protocol); | ||
| 147 | sc_ldap_set_opts = mp_set_subcheck_state(sc_ldap_set_opts, STATE_OK); | ||
| 148 | mp_add_subcheck_to_check(&overall, sc_ldap_set_opts); | ||
| 114 | } | 149 | } |
| 115 | #endif | 150 | #endif |
| 116 | 151 | ||
| 117 | int version = 3; | 152 | int version = 3; |
| 118 | int tls; | 153 | int tls; |
| 119 | if (config.ld_port == LDAPS_PORT || config.ssl_on_connect) { | 154 | { |
| 155 | if (config.ld_port == LDAPS_PORT || config.ssl_on_connect) { | ||
| 120 | #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) | 156 | #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) |
| 121 | /* ldaps: set option tls */ | 157 | /* ldaps: set option tls */ |
| 122 | tls = LDAP_OPT_X_TLS_HARD; | 158 | tls = LDAP_OPT_X_TLS_HARD; |
| 123 | 159 | ||
| 124 | if (ldap_set_option(ldap_connection, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) { | 160 | mp_subcheck sc_ldap_tls_init = mp_subcheck_init(); |
| 125 | if (verbose) { | 161 | if (ldap_set_option(ldap_connection, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) { |
| 126 | ldap_perror(ldap_connection, "ldaps_option"); | 162 | if (verbose) { |
| 163 | ldap_perror(ldap_connection, "ldaps_option"); | ||
| 164 | } | ||
| 165 | xasprintf(&sc_ldap_tls_init.output, "could not init TLS at port %i!", | ||
| 166 | config.ld_port); | ||
| 167 | sc_ldap_tls_init = mp_set_subcheck_state(sc_ldap_tls_init, STATE_CRITICAL); | ||
| 168 | mp_add_subcheck_to_check(&overall, sc_ldap_tls_init); | ||
| 169 | mp_exit(overall); | ||
| 170 | } else { | ||
| 171 | xasprintf(&sc_ldap_tls_init.output, "initiated TLS at port %i!", config.ld_port); | ||
| 172 | sc_ldap_tls_init = mp_set_subcheck_state(sc_ldap_tls_init, STATE_OK); | ||
| 173 | mp_add_subcheck_to_check(&overall, sc_ldap_tls_init); | ||
| 127 | } | 174 | } |
| 128 | printf(_("Could not init TLS at port %i!\n"), config.ld_port); | ||
| 129 | return STATE_CRITICAL; | ||
| 130 | } | ||
| 131 | #else | 175 | #else |
| 132 | printf(_("TLS not supported by the libraries!\n")); | 176 | printf(_("TLS not supported by the libraries!\n")); |
| 133 | return STATE_CRITICAL; | 177 | exit(STATE_CRITICAL); |
| 134 | #endif /* LDAP_OPT_X_TLS */ | 178 | #endif /* LDAP_OPT_X_TLS */ |
| 135 | } else if (config.starttls) { | 179 | } else if (config.starttls) { |
| 136 | #if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S) | 180 | #if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S) |
| 137 | /* ldap with startTLS: set option version */ | 181 | /* ldap with startTLS: set option version */ |
| 138 | if (ldap_get_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { | 182 | if (ldap_get_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version) == |
| 139 | if (version < LDAP_VERSION3) { | 183 | LDAP_OPT_SUCCESS) { |
| 140 | version = LDAP_VERSION3; | 184 | if (version < LDAP_VERSION3) { |
| 141 | ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version); | 185 | version = LDAP_VERSION3; |
| 186 | ldap_set_option(ldap_connection, LDAP_OPT_PROTOCOL_VERSION, &version); | ||
| 187 | } | ||
| 142 | } | 188 | } |
| 143 | } | 189 | /* call start_tls */ |
| 144 | /* call start_tls */ | 190 | mp_subcheck sc_ldap_starttls = mp_subcheck_init(); |
| 145 | if (ldap_start_tls_s(ldap_connection, NULL, NULL) != LDAP_SUCCESS) { | 191 | if (ldap_start_tls_s(ldap_connection, NULL, NULL) != LDAP_SUCCESS) { |
| 146 | if (verbose) { | 192 | if (verbose) { |
| 147 | ldap_perror(ldap_connection, "ldap_start_tls"); | 193 | ldap_perror(ldap_connection, "ldap_start_tls"); |
| 194 | } | ||
| 195 | xasprintf(&sc_ldap_starttls.output, "could not init STARTTLS at port %i!", | ||
| 196 | config.ld_port); | ||
| 197 | sc_ldap_starttls = mp_set_subcheck_state(sc_ldap_starttls, STATE_CRITICAL); | ||
| 198 | mp_add_subcheck_to_check(&overall, sc_ldap_starttls); | ||
| 199 | mp_exit(overall); | ||
| 200 | } else { | ||
| 201 | xasprintf(&sc_ldap_starttls.output, "initiated STARTTLS at port %i!", | ||
| 202 | config.ld_port); | ||
| 203 | sc_ldap_starttls = mp_set_subcheck_state(sc_ldap_starttls, STATE_OK); | ||
| 204 | mp_add_subcheck_to_check(&overall, sc_ldap_starttls); | ||
| 148 | } | 205 | } |
| 149 | printf(_("Could not init startTLS at port %i!\n"), config.ld_port); | ||
| 150 | return STATE_CRITICAL; | ||
| 151 | } | ||
| 152 | #else | 206 | #else |
| 153 | printf(_("startTLS not supported by the library, needs LDAPv3!\n")); | 207 | printf(_("startTLS not supported by the library, needs LDAPv3!\n")); |
| 154 | return STATE_CRITICAL; | 208 | exit(STATE_CRITICAL); |
| 155 | #endif /* HAVE_LDAP_START_TLS_S */ | 209 | #endif /* HAVE_LDAP_START_TLS_S */ |
| 210 | } | ||
| 156 | } | 211 | } |
| 157 | 212 | ||
| 158 | /* bind to the ldap server */ | 213 | /* bind to the ldap server */ |
| 159 | if (ldap_bind_s(ldap_connection, config.ld_binddn, config.ld_passwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { | 214 | { |
| 160 | if (verbose) { | 215 | mp_subcheck sc_ldap_bind = mp_subcheck_init(); |
| 161 | ldap_perror(ldap_connection, "ldap_bind"); | 216 | int ldap_error = |
| 217 | ldap_bind_s(ldap_connection, config.ld_binddn, config.ld_passwd, LDAP_AUTH_SIMPLE); | ||
| 218 | if (ldap_error != LDAP_SUCCESS) { | ||
| 219 | if (verbose) { | ||
| 220 | ldap_perror(ldap_connection, "ldap_bind"); | ||
| 221 | } | ||
| 222 | |||
| 223 | xasprintf(&sc_ldap_bind.output, "could not bind to the LDAP server: %s", | ||
| 224 | ldap_err2string(ldap_error)); | ||
| 225 | sc_ldap_bind = mp_set_subcheck_state(sc_ldap_bind, STATE_CRITICAL); | ||
| 226 | mp_add_subcheck_to_check(&overall, sc_ldap_bind); | ||
| 227 | mp_exit(overall); | ||
| 228 | } else { | ||
| 229 | xasprintf(&sc_ldap_bind.output, "execute bind to the LDAP server"); | ||
| 230 | sc_ldap_bind = mp_set_subcheck_state(sc_ldap_bind, STATE_OK); | ||
| 231 | mp_add_subcheck_to_check(&overall, sc_ldap_bind); | ||
| 162 | } | 232 | } |
| 163 | printf(_("Could not bind to the LDAP server\n")); | ||
| 164 | return STATE_CRITICAL; | ||
| 165 | } | 233 | } |
| 166 | 234 | ||
| 167 | LDAPMessage *result; | 235 | LDAPMessage *result; |
| 168 | int num_entries = 0; | ||
| 169 | /* do a search of all objectclasses in the base dn */ | 236 | /* do a search of all objectclasses in the base dn */ |
| 170 | if (ldap_search_s(ldap_connection, config.ld_base, | 237 | { |
| 171 | (config.crit_entries != NULL || config.warn_entries != NULL) ? LDAP_SCOPE_SUBTREE : LDAP_SCOPE_BASE, config.ld_attr, | 238 | mp_subcheck sc_ldap_search = mp_subcheck_init(); |
| 172 | NULL, 0, &result) != LDAP_SUCCESS) { | 239 | int ldap_error = ldap_search_s( |
| 173 | if (verbose) { | 240 | ldap_connection, config.ld_base, |
| 174 | ldap_perror(ldap_connection, "ldap_search"); | 241 | (config.entries_thresholds.warning_is_set || config.entries_thresholds.critical_is_set) |
| 242 | ? LDAP_SCOPE_SUBTREE | ||
| 243 | : LDAP_SCOPE_BASE, | ||
| 244 | config.ld_attr, NULL, 0, &result); | ||
| 245 | |||
| 246 | if (ldap_error != LDAP_SUCCESS) { | ||
| 247 | if (verbose) { | ||
| 248 | ldap_perror(ldap_connection, "ldap_search"); | ||
| 249 | } | ||
| 250 | xasprintf(&sc_ldap_search.output, "could not search/find objectclasses in %s: %s", | ||
| 251 | config.ld_base, ldap_err2string(ldap_error)); | ||
| 252 | sc_ldap_search = mp_set_subcheck_state(sc_ldap_search, STATE_CRITICAL); | ||
| 253 | mp_add_subcheck_to_check(&overall, sc_ldap_search); | ||
| 254 | mp_exit(overall); | ||
| 255 | } else { | ||
| 256 | xasprintf(&sc_ldap_search.output, "search/find objectclasses in %s", config.ld_base); | ||
| 257 | sc_ldap_search = mp_set_subcheck_state(sc_ldap_search, STATE_OK); | ||
| 258 | mp_add_subcheck_to_check(&overall, sc_ldap_search); | ||
| 175 | } | 259 | } |
| 176 | printf(_("Could not search/find objectclasses in %s\n"), config.ld_base); | ||
| 177 | return STATE_CRITICAL; | ||
| 178 | } | 260 | } |
| 179 | 261 | ||
| 180 | if (config.crit_entries != NULL || config.warn_entries != NULL) { | 262 | int num_entries = ldap_count_entries(ldap_connection, result); |
| 181 | num_entries = ldap_count_entries(ldap_connection, result); | 263 | if (verbose) { |
| 264 | printf("entries found: %d\n", num_entries); | ||
| 182 | } | 265 | } |
| 183 | 266 | ||
| 184 | /* unbind from the ldap server */ | 267 | /* unbind from the ldap server */ |
| @@ -188,48 +271,50 @@ int main(int argc, char *argv[]) { | |||
| 188 | alarm(0); | 271 | alarm(0); |
| 189 | 272 | ||
| 190 | /* calculate the elapsed time and compare to thresholds */ | 273 | /* calculate the elapsed time and compare to thresholds */ |
| 191 | |||
| 192 | long microsec = deltime(start_time); | 274 | long microsec = deltime(start_time); |
| 193 | double elapsed_time = (double)microsec / 1.0e6; | 275 | double elapsed_time = (double)microsec / 1.0e6; |
| 194 | mp_state_enum status = STATE_UNKNOWN; | 276 | mp_perfdata pd_connection_time = perfdata_init(); |
| 195 | if (config.crit_time_set && elapsed_time > config.crit_time) { | 277 | pd_connection_time.label = "time"; |
| 196 | status = STATE_CRITICAL; | 278 | pd_connection_time.value = mp_create_pd_value(elapsed_time); |
| 197 | } else if (config.warn_time_set && elapsed_time > config.warn_time) { | 279 | pd_connection_time = mp_pd_set_thresholds(pd_connection_time, config.connection_time_threshold); |
| 198 | status = STATE_WARNING; | ||
| 199 | } else { | ||
| 200 | status = STATE_OK; | ||
| 201 | } | ||
| 202 | 280 | ||
| 203 | if (config.entries_thresholds != NULL) { | 281 | mp_subcheck sc_connection_time = mp_subcheck_init(); |
| 204 | if (verbose) { | 282 | mp_add_perfdata_to_subcheck(&sc_connection_time, pd_connection_time); |
| 205 | printf("entries found: %d\n", num_entries); | 283 | |
| 206 | print_thresholds("entry thresholds", config.entries_thresholds); | 284 | mp_state_enum connection_time_state = mp_get_pd_status(pd_connection_time); |
| 207 | } | 285 | sc_connection_time = mp_set_subcheck_state(sc_connection_time, connection_time_state); |
| 208 | mp_state_enum status_entries = get_status(num_entries, config.entries_thresholds); | ||
| 209 | if (status_entries == STATE_CRITICAL) { | ||
| 210 | status = STATE_CRITICAL; | ||
| 211 | } else if (status != STATE_CRITICAL) { | ||
| 212 | status = status_entries; | ||
| 213 | } | ||
| 214 | } | ||
| 215 | 286 | ||
| 216 | /* print out the result */ | 287 | if (connection_time_state == STATE_OK) { |
| 217 | if (config.crit_entries != NULL || config.warn_entries != NULL) { | 288 | xasprintf(&sc_connection_time.output, "connection time %.3fs is within thresholds", |
| 218 | printf(_("LDAP %s - found %d entries in %.3f seconds|%s %s\n"), state_text(status), num_entries, elapsed_time, | 289 | elapsed_time); |
| 219 | fperfdata("time", elapsed_time, "s", config.warn_time_set, config.warn_time, config.crit_time_set, config.crit_time, true, 0, | ||
| 220 | false, 0), | ||
| 221 | sperfdata("entries", (double)num_entries, "", config.warn_entries, config.crit_entries, true, 0.0, false, 0.0)); | ||
| 222 | } else { | 290 | } else { |
| 223 | printf(_("LDAP %s - %.3f seconds response time|%s\n"), state_text(status), elapsed_time, | 291 | xasprintf(&sc_connection_time.output, "connection time %.3fs is violating thresholds", |
| 224 | fperfdata("time", elapsed_time, "s", config.warn_time_set, config.warn_time, config.crit_time_set, config.crit_time, true, 0, | 292 | elapsed_time); |
| 225 | false, 0)); | ||
| 226 | } | 293 | } |
| 227 | 294 | ||
| 228 | exit(status); | 295 | mp_add_subcheck_to_check(&overall, sc_connection_time); |
| 296 | |||
| 297 | mp_perfdata pd_num_entries = perfdata_init(); | ||
| 298 | pd_num_entries.label = "entries"; | ||
| 299 | pd_num_entries.value = mp_create_pd_value(num_entries); | ||
| 300 | pd_num_entries = mp_pd_set_thresholds(pd_num_entries, config.entries_thresholds); | ||
| 301 | |||
| 302 | mp_subcheck sc_num_entries = mp_subcheck_init(); | ||
| 303 | mp_add_perfdata_to_subcheck(&sc_num_entries, pd_num_entries); | ||
| 304 | xasprintf(&sc_num_entries.output, "found %d entries", num_entries); | ||
| 305 | sc_num_entries = mp_set_subcheck_state(sc_num_entries, mp_get_pd_status(pd_num_entries)); | ||
| 306 | |||
| 307 | mp_add_subcheck_to_check(&overall, sc_num_entries); | ||
| 308 | |||
| 309 | mp_exit(overall); | ||
| 229 | } | 310 | } |
| 230 | 311 | ||
| 231 | /* process command-line arguments */ | 312 | /* process command-line arguments */ |
| 232 | check_ldap_config_wrapper process_arguments(int argc, char **argv) { | 313 | check_ldap_config_wrapper process_arguments(int argc, char **argv) { |
| 314 | enum { | ||
| 315 | output_format_index = CHAR_MAX + 1, | ||
| 316 | }; | ||
| 317 | |||
| 233 | /* initialize the long option struct */ | 318 | /* initialize the long option struct */ |
| 234 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, | 319 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, |
| 235 | {"version", no_argument, 0, 'V'}, | 320 | {"version", no_argument, 0, 'V'}, |
| @@ -253,6 +338,7 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) { | |||
| 253 | {"warn-entries", required_argument, 0, 'W'}, | 338 | {"warn-entries", required_argument, 0, 'W'}, |
| 254 | {"crit-entries", required_argument, 0, 'C'}, | 339 | {"crit-entries", required_argument, 0, 'C'}, |
| 255 | {"verbose", no_argument, 0, 'v'}, | 340 | {"verbose", no_argument, 0, 'v'}, |
| 341 | {"output-format", required_argument, 0, output_format_index}, | ||
| 256 | {0, 0, 0, 0}}; | 342 | {0, 0, 0, 0}}; |
| 257 | 343 | ||
| 258 | check_ldap_config_wrapper result = { | 344 | check_ldap_config_wrapper result = { |
| @@ -273,7 +359,8 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) { | |||
| 273 | 359 | ||
| 274 | int option = 0; | 360 | int option = 0; |
| 275 | while (true) { | 361 | while (true) { |
| 276 | int option_index = getopt_long(argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:C:W:", longopts, &option); | 362 | int option_index = |
| 363 | getopt_long(argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:C:W:", longopts, &option); | ||
| 277 | 364 | ||
| 278 | if (option_index == -1 || option_index == EOF) { | 365 | if (option_index == -1 || option_index == EOF) { |
| 279 | break; | 366 | break; |
| @@ -311,20 +398,38 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) { | |||
| 311 | case 'P': | 398 | case 'P': |
| 312 | result.config.ld_passwd = optarg; | 399 | result.config.ld_passwd = optarg; |
| 313 | break; | 400 | break; |
| 314 | case 'w': | 401 | case 'w': { |
| 315 | result.config.warn_time_set = true; | 402 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 316 | result.config.warn_time = strtod(optarg, NULL); | 403 | if (tmp.error != MP_PARSING_SUCCES) { |
| 317 | break; | 404 | die(STATE_UNKNOWN, "failed to parse warning connection time threshold"); |
| 318 | case 'c': | 405 | } |
| 319 | result.config.crit_time_set = true; | 406 | result.config.connection_time_threshold = |
| 320 | result.config.crit_time = strtod(optarg, NULL); | 407 | mp_thresholds_set_warn(result.config.connection_time_threshold, tmp.range); |
| 321 | break; | 408 | } break; |
| 322 | case 'W': | 409 | case 'c': { |
| 323 | result.config.warn_entries = optarg; | 410 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 324 | break; | 411 | if (tmp.error != MP_PARSING_SUCCES) { |
| 325 | case 'C': | 412 | die(STATE_UNKNOWN, "failed to parse critical connection time threshold"); |
| 326 | result.config.crit_entries = optarg; | 413 | } |
| 327 | break; | 414 | result.config.connection_time_threshold = |
| 415 | mp_thresholds_set_crit(result.config.connection_time_threshold, tmp.range); | ||
| 416 | } break; | ||
| 417 | case 'W': { | ||
| 418 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 419 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 420 | die(STATE_UNKNOWN, "failed to parse number of entries warning threshold"); | ||
| 421 | } | ||
| 422 | result.config.entries_thresholds = | ||
| 423 | mp_thresholds_set_warn(result.config.entries_thresholds, tmp.range); | ||
| 424 | } break; | ||
| 425 | case 'C': { | ||
| 426 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 427 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 428 | die(STATE_UNKNOWN, "failed to parse number of entries critical threshold"); | ||
| 429 | } | ||
| 430 | result.config.entries_thresholds = | ||
| 431 | mp_thresholds_set_crit(result.config.entries_thresholds, tmp.range); | ||
| 432 | } break; | ||
| 328 | #ifdef HAVE_LDAP_SET_OPTION | 433 | #ifdef HAVE_LDAP_SET_OPTION |
| 329 | case '2': | 434 | case '2': |
| 330 | result.config.ld_protocol = 2; | 435 | result.config.ld_protocol = 2; |
| @@ -363,6 +468,18 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) { | |||
| 363 | usage(_("IPv6 support not available\n")); | 468 | usage(_("IPv6 support not available\n")); |
| 364 | #endif | 469 | #endif |
| 365 | break; | 470 | break; |
| 471 | case output_format_index: { | ||
| 472 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 473 | if (!parser.parsing_success) { | ||
| 474 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 475 | printf("Invalid output format: %s\n", optarg); | ||
| 476 | exit(STATE_UNKNOWN); | ||
| 477 | } | ||
| 478 | |||
| 479 | result.config.output_format_is_set = true; | ||
| 480 | result.config.output_format = parser.output_format; | ||
| 481 | break; | ||
| 482 | } | ||
| 366 | default: | 483 | default: |
| 367 | usage5(); | 484 | usage5(); |
| 368 | } | 485 | } |
| @@ -381,7 +498,8 @@ check_ldap_config_wrapper process_arguments(int argc, char **argv) { | |||
| 381 | result.config.ld_port = DEFAULT_PORT; | 498 | result.config.ld_port = DEFAULT_PORT; |
| 382 | } | 499 | } |
| 383 | 500 | ||
| 384 | if (strstr(argv[0], "check_ldaps") && !result.config.starttls && !result.config.ssl_on_connect) { | 501 | if (strstr(argv[0], "check_ldaps") && !result.config.starttls && |
| 502 | !result.config.ssl_on_connect) { | ||
| 385 | result.config.starttls = true; | 503 | result.config.starttls = true; |
| 386 | } | 504 | } |
| 387 | 505 | ||
| @@ -397,10 +515,6 @@ check_ldap_config_wrapper validate_arguments(check_ldap_config_wrapper config_wr | |||
| 397 | usage4(_("Please specify the LDAP base\n")); | 515 | usage4(_("Please specify the LDAP base\n")); |
| 398 | } | 516 | } |
| 399 | 517 | ||
| 400 | if (config_wrapper.config.crit_entries != NULL || config_wrapper.config.warn_entries != NULL) { | ||
| 401 | set_thresholds(&config_wrapper.config.entries_thresholds, config_wrapper.config.warn_entries, config_wrapper.config.crit_entries); | ||
| 402 | } | ||
| 403 | |||
| 404 | if (config_wrapper.config.ld_passwd == NULL) { | 518 | if (config_wrapper.config.ld_passwd == NULL) { |
| 405 | config_wrapper.config.ld_passwd = getenv("LDAP_PASSWORD"); | 519 | config_wrapper.config.ld_passwd = getenv("LDAP_PASSWORD"); |
| 406 | } | 520 | } |
| @@ -435,11 +549,13 @@ void print_help(void) { | |||
| 435 | printf(" %s\n", "-D [--bind]"); | 549 | printf(" %s\n", "-D [--bind]"); |
| 436 | printf(" %s\n", _("ldap bind DN (if required)")); | 550 | printf(" %s\n", _("ldap bind DN (if required)")); |
| 437 | printf(" %s\n", "-P [--pass]"); | 551 | printf(" %s\n", "-P [--pass]"); |
| 438 | printf(" %s\n", _("ldap password (if required, or set the password through environment variable 'LDAP_PASSWORD')")); | 552 | printf(" %s\n", _("ldap password (if required, or set the password through environment " |
| 553 | "variable 'LDAP_PASSWORD')")); | ||
| 439 | printf(" %s\n", "-T [--starttls]"); | 554 | printf(" %s\n", "-T [--starttls]"); |
| 440 | printf(" %s\n", _("use starttls mechanism introduced in protocol version 3")); | 555 | printf(" %s\n", _("use starttls mechanism introduced in protocol version 3")); |
| 441 | printf(" %s\n", "-S [--ssl]"); | 556 | printf(" %s\n", "-S [--ssl]"); |
| 442 | printf(" %s %i\n", _("use ldaps (ldap v2 ssl method). this also sets the default port to"), LDAPS_PORT); | 557 | printf(" %s %i\n", _("use ldaps (ldap v2 ssl method). this also sets the default port to"), |
| 558 | LDAPS_PORT); | ||
| 443 | 559 | ||
| 444 | #ifdef HAVE_LDAP_SET_OPTION | 560 | #ifdef HAVE_LDAP_SET_OPTION |
| 445 | printf(" %s\n", "-2 [--ver2]"); | 561 | printf(" %s\n", "-2 [--ver2]"); |
| @@ -459,13 +575,16 @@ void print_help(void) { | |||
| 459 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 575 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 460 | 576 | ||
| 461 | printf(UT_VERBOSE); | 577 | printf(UT_VERBOSE); |
| 578 | printf(UT_OUTPUT_FORMAT); | ||
| 462 | 579 | ||
| 463 | printf("\n"); | 580 | printf("\n"); |
| 464 | printf("%s\n", _("Notes:")); | 581 | printf("%s\n", _("Notes:")); |
| 465 | printf(" %s\n", _("If this plugin is called via 'check_ldaps', method 'STARTTLS' will be")); | 582 | printf(" %s\n", _("If this plugin is called via 'check_ldaps', method 'STARTTLS' will be")); |
| 466 | printf(_(" implied (using default port %i) unless --port=636 is specified. In that case\n"), DEFAULT_PORT); | 583 | printf(_(" implied (using default port %i) unless --port=636 is specified. In that case\n"), |
| 584 | DEFAULT_PORT); | ||
| 467 | printf(" %s\n", _("'SSL on connect' will be used no matter how the plugin was called.")); | 585 | printf(" %s\n", _("'SSL on connect' will be used no matter how the plugin was called.")); |
| 468 | printf(" %s\n", _("This detection is deprecated, please use 'check_ldap' with the '--starttls' or '--ssl' flags")); | 586 | printf(" %s\n", _("This detection is deprecated, please use 'check_ldap' with the '--starttls' " |
| 587 | "or '--ssl' flags")); | ||
| 469 | printf(" %s\n", _("to define the behaviour explicitly instead.")); | 588 | printf(" %s\n", _("to define the behaviour explicitly instead.")); |
| 470 | printf(" %s\n", _("The parameters --warn-entries and --crit-entries are optional.")); | 589 | printf(" %s\n", _("The parameters --warn-entries and --crit-entries are optional.")); |
| 471 | 590 | ||
diff --git a/plugins/check_ldap.d/config.h b/plugins/check_ldap.d/config.h index c8a40610..50191725 100644 --- a/plugins/check_ldap.d/config.h +++ b/plugins/check_ldap.d/config.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "output.h" | ||
| 4 | #include "thresholds.h" | 5 | #include "thresholds.h" |
| 5 | #include <stddef.h> | 6 | #include <stddef.h> |
| 6 | 7 | ||
| @@ -25,13 +26,11 @@ typedef struct { | |||
| 25 | int ld_protocol; | 26 | int ld_protocol; |
| 26 | #endif | 27 | #endif |
| 27 | 28 | ||
| 28 | char *warn_entries; | 29 | mp_thresholds entries_thresholds; |
| 29 | char *crit_entries; | 30 | mp_thresholds connection_time_threshold; |
| 30 | thresholds *entries_thresholds; | 31 | |
| 31 | bool warn_time_set; | 32 | bool output_format_is_set; |
| 32 | double warn_time; | 33 | mp_output_format output_format; |
| 33 | bool crit_time_set; | ||
| 34 | double crit_time; | ||
| 35 | } check_ldap_config; | 34 | } check_ldap_config; |
| 36 | 35 | ||
| 37 | check_ldap_config check_ldap_config_init() { | 36 | check_ldap_config check_ldap_config_init() { |
| @@ -48,13 +47,10 @@ check_ldap_config check_ldap_config_init() { | |||
| 48 | .ld_protocol = DEFAULT_PROTOCOL, | 47 | .ld_protocol = DEFAULT_PROTOCOL, |
| 49 | #endif | 48 | #endif |
| 50 | 49 | ||
| 51 | .warn_entries = NULL, | 50 | .entries_thresholds = mp_thresholds_init(), |
| 52 | .crit_entries = NULL, | 51 | .connection_time_threshold = mp_thresholds_init(), |
| 53 | .entries_thresholds = NULL, | 52 | |
| 54 | .warn_time_set = false, | 53 | .output_format_is_set = false, |
| 55 | .warn_time = 0, | ||
| 56 | .crit_time_set = false, | ||
| 57 | .crit_time = 0, | ||
| 58 | }; | 54 | }; |
| 59 | return tmp; | 55 | return tmp; |
| 60 | } | 56 | } |
diff --git a/plugins/check_load.c b/plugins/check_load.c index 1431d130..644cd604 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c | |||
| @@ -1,350 +1,430 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Monitoring check_load plugin | 3 | * Monitoring check_load plugin |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 1999-2007 Monitoring Plugins Development Team | 6 | * Copyright (c) 1999-2007 Monitoring Plugins Development Team |
| 7 | * | 7 | * |
| 8 | * Description: | 8 | * Description: |
| 9 | * | 9 | * |
| 10 | * This file contains the check_load plugin | 10 | * This file contains the check_load plugin |
| 11 | * | 11 | * |
| 12 | * This plugin tests the current system load average. | 12 | * This plugin tests the current system load average. |
| 13 | * | 13 | * |
| 14 | * | 14 | * |
| 15 | * This program is free software: you can redistribute it and/or modify | 15 | * This program is free software: you can redistribute it and/or modify |
| 16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
| 17 | * the Free Software Foundation, either version 3 of the License, or | 17 | * the Free Software Foundation, either version 3 of the License, or |
| 18 | * (at your option) any later version. | 18 | * (at your option) any later version. |
| 19 | * | 19 | * |
| 20 | * This program is distributed in the hope that it will be useful, | 20 | * This program is distributed in the hope that it will be useful, |
| 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 23 | * GNU General Public License for more details. | 23 | * GNU General Public License for more details. |
| 24 | * | 24 | * |
| 25 | * You should have received a copy of the GNU General Public License | 25 | * You should have received a copy of the GNU General Public License |
| 26 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 26 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 27 | * | 27 | * |
| 28 | * | 28 | * |
| 29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
| 30 | 30 | ||
| 31 | const char *progname = "check_load"; | 31 | const char *progname = "check_load"; |
| 32 | const char *copyright = "1999-2022"; | 32 | const char *copyright = "1999-2022"; |
| 33 | const char *email = "devel@monitoring-plugins.org"; | 33 | const char *email = "devel@monitoring-plugins.org"; |
| 34 | 34 | ||
| 35 | #include "./common.h" | 35 | #include "./common.h" |
| 36 | #include <string.h> | ||
| 36 | #include "./runcmd.h" | 37 | #include "./runcmd.h" |
| 37 | #include "./utils.h" | 38 | #include "./utils.h" |
| 38 | #include "./popen.h" | 39 | #include "./popen.h" |
| 40 | #include "../lib/states.h" | ||
| 41 | #include "../lib/output.h" | ||
| 42 | #include "../lib/perfdata.h" | ||
| 43 | #include "../lib/thresholds.h" | ||
| 44 | #include "check_load.d/config.h" | ||
| 39 | 45 | ||
| 40 | #include <string.h> | 46 | // getloadavg comes from gnulib |
| 41 | 47 | #include "../gl/stdlib.h" | |
| 42 | #ifdef HAVE_SYS_LOADAVG_H | ||
| 43 | #include <sys/loadavg.h> | ||
| 44 | #endif | ||
| 45 | 48 | ||
| 46 | /* needed for compilation under NetBSD, as suggested by Andy Doran */ | 49 | /* needed for compilation under NetBSD, as suggested by Andy Doran */ |
| 47 | #ifndef LOADAVG_1MIN | 50 | #ifndef LOADAVG_1MIN |
| 48 | #define LOADAVG_1MIN 0 | 51 | # define LOADAVG_1MIN 0 |
| 49 | #define LOADAVG_5MIN 1 | 52 | # define LOADAVG_5MIN 1 |
| 50 | #define LOADAVG_15MIN 2 | 53 | # define LOADAVG_15MIN 2 |
| 51 | #endif /* !defined LOADAVG_1MIN */ | 54 | #endif /* !defined LOADAVG_1MIN */ |
| 52 | 55 | ||
| 56 | typedef struct { | ||
| 57 | int errorcode; | ||
| 58 | check_load_config config; | ||
| 59 | } check_load_config_wrapper; | ||
| 60 | static check_load_config_wrapper process_arguments(int argc, char **argv); | ||
| 61 | |||
| 62 | void print_help(void); | ||
| 63 | void print_usage(void); | ||
| 64 | typedef struct { | ||
| 65 | int errorcode; | ||
| 66 | char **top_processes; | ||
| 67 | } top_processes_result; | ||
| 68 | static top_processes_result print_top_consuming_processes(unsigned long n_procs_to_show); | ||
| 69 | |||
| 70 | typedef struct { | ||
| 71 | mp_range load[3]; | ||
| 72 | } parsed_thresholds; | ||
| 73 | static parsed_thresholds get_threshold(char *arg) { | ||
| 74 | size_t index; | ||
| 75 | char *str = arg; | ||
| 76 | char *tmp_pointer; | ||
| 77 | bool valid = false; | ||
| 78 | |||
| 79 | parsed_thresholds result = { | ||
| 80 | .load = | ||
| 81 | { | ||
| 82 | mp_range_init(), | ||
| 83 | mp_range_init(), | ||
| 84 | mp_range_init(), | ||
| 85 | }, | ||
| 86 | }; | ||
| 53 | 87 | ||
| 54 | static int process_arguments (int argc, char **argv); | 88 | size_t arg_length = strlen(arg); |
| 55 | static int validate_arguments (void); | 89 | for (index = 0; index < 3; index++) { |
| 56 | void print_help (void); | 90 | double tmp = strtod(str, &tmp_pointer); |
| 57 | void print_usage (void); | 91 | if (tmp_pointer == str) { |
| 58 | static int print_top_consuming_processes(); | 92 | break; |
| 59 | 93 | } | |
| 60 | static int n_procs_to_show = 0; | ||
| 61 | |||
| 62 | /* strictly for pretty-print usage in loops */ | ||
| 63 | static const int nums[3] = { 1, 5, 15 }; | ||
| 64 | |||
| 65 | /* provide some fairly sane defaults */ | ||
| 66 | double wload[3] = { 0.0, 0.0, 0.0 }; | ||
| 67 | double cload[3] = { 0.0, 0.0, 0.0 }; | ||
| 68 | #define la1 la[0] | ||
| 69 | #define la5 la[1] | ||
| 70 | #define la15 la[2] | ||
| 71 | |||
| 72 | char *status_line; | ||
| 73 | bool take_into_account_cpus = false; | ||
| 74 | |||
| 75 | static void | ||
| 76 | get_threshold(char *arg, double *th) | ||
| 77 | { | ||
| 78 | size_t i, n; | ||
| 79 | int valid = 0; | ||
| 80 | char *str = arg, *p; | ||
| 81 | 94 | ||
| 82 | n = strlen(arg); | 95 | result.load[index] = mp_range_set_end(result.load[index], mp_create_pd_value(tmp)); |
| 83 | for(i = 0; i < 3; i++) { | ||
| 84 | th[i] = strtod(str, &p); | ||
| 85 | if(p == str) break; | ||
| 86 | 96 | ||
| 87 | valid = 1; | 97 | valid = true; |
| 88 | str = p + 1; | 98 | str = tmp_pointer + 1; |
| 89 | if(n <= (size_t)(str - arg)) break; | 99 | if (arg_length <= (size_t)(str - arg)) { |
| 100 | break; | ||
| 101 | } | ||
| 90 | } | 102 | } |
| 91 | 103 | ||
| 92 | /* empty argument or non-floatish, so warn about it and die */ | 104 | /* empty argument or non-floatish, so warn about it and die */ |
| 93 | if(!i && !valid) usage (_("Warning threshold must be float or float triplet!\n")); | 105 | if (!index && !valid) { |
| 106 | usage(_("Warning threshold must be float or float triplet!\n")); | ||
| 107 | } | ||
| 94 | 108 | ||
| 95 | if(i != 2) { | 109 | if (index != 2) { |
| 96 | /* one or more numbers were given, so fill array with last | 110 | /* one or more numbers were given, so fill array with last |
| 97 | * we got (most likely to NOT produce the least expected result) */ | 111 | * we got (most likely to NOT produce the least expected result) */ |
| 98 | for(n = i; n < 3; n++) th[n] = th[i]; | 112 | for (size_t tmp_index = index; tmp_index < 3; tmp_index++) { |
| 113 | result.load[tmp_index] = result.load[index]; | ||
| 114 | } | ||
| 99 | } | 115 | } |
| 116 | return result; | ||
| 100 | } | 117 | } |
| 101 | 118 | ||
| 102 | 119 | int main(int argc, char **argv) { | |
| 103 | int | 120 | setlocale(LC_ALL, ""); |
| 104 | main (int argc, char **argv) | 121 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 105 | { | 122 | textdomain(PACKAGE); |
| 106 | int result = -1; | ||
| 107 | int i; | ||
| 108 | long numcpus; | ||
| 109 | |||
| 110 | double la[3] = { 0.0, 0.0, 0.0 }; /* NetBSD complains about uninitialized arrays */ | ||
| 111 | #ifndef HAVE_GETLOADAVG | ||
| 112 | char input_buffer[MAX_INPUT_BUFFER]; | ||
| 113 | #endif | ||
| 114 | |||
| 115 | setlocale (LC_ALL, ""); | ||
| 116 | bindtextdomain (PACKAGE, LOCALEDIR); | ||
| 117 | textdomain (PACKAGE); | ||
| 118 | setlocale(LC_NUMERIC, "POSIX"); | 123 | setlocale(LC_NUMERIC, "POSIX"); |
| 119 | 124 | ||
| 120 | /* Parse extra opts if any */ | 125 | /* Parse extra opts if any */ |
| 121 | argv = np_extra_opts (&argc, argv, progname); | 126 | argv = np_extra_opts(&argc, argv, progname); |
| 122 | 127 | ||
| 123 | if (process_arguments (argc, argv) == ERROR) | 128 | check_load_config_wrapper tmp_config = process_arguments(argc, argv); |
| 124 | usage4 (_("Could not parse arguments")); | 129 | if (tmp_config.errorcode == ERROR) { |
| 125 | 130 | usage4(_("Could not parse arguments")); | |
| 126 | #ifdef HAVE_GETLOADAVG | ||
| 127 | result = getloadavg (la, 3); | ||
| 128 | if (result != 3) | ||
| 129 | return STATE_UNKNOWN; | ||
| 130 | #else | ||
| 131 | child_process = spopen (PATH_TO_UPTIME); | ||
| 132 | if (child_process == NULL) { | ||
| 133 | printf (_("Error opening %s\n"), PATH_TO_UPTIME); | ||
| 134 | return STATE_UNKNOWN; | ||
| 135 | } | ||
| 136 | child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | ||
| 137 | if (child_stderr == NULL) { | ||
| 138 | printf (_("Could not open stderr for %s\n"), PATH_TO_UPTIME); | ||
| 139 | } | ||
| 140 | fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process); | ||
| 141 | if(strstr(input_buffer, "load average:")) { | ||
| 142 | sscanf (input_buffer, "%*[^l]load average: %lf, %lf, %lf", &la1, &la5, &la15); | ||
| 143 | } | ||
| 144 | else if(strstr(input_buffer, "load averages:")) { | ||
| 145 | sscanf (input_buffer, "%*[^l]load averages: %lf, %lf, %lf", &la1, &la5, &la15); | ||
| 146 | } | ||
| 147 | else { | ||
| 148 | printf (_("could not parse load from uptime %s: %d\n"), PATH_TO_UPTIME, result); | ||
| 149 | return STATE_UNKNOWN; | ||
| 150 | } | ||
| 151 | |||
| 152 | result = spclose (child_process); | ||
| 153 | if (result) { | ||
| 154 | printf (_("Error code %d returned in %s\n"), result, PATH_TO_UPTIME); | ||
| 155 | return STATE_UNKNOWN; | ||
| 156 | } | ||
| 157 | #endif | ||
| 158 | |||
| 159 | if ((la[0] < 0.0) || (la[1] < 0.0) || (la[2] < 0.0)) { | ||
| 160 | #ifdef HAVE_GETLOADAVG | ||
| 161 | printf (_("Error in getloadavg()\n")); | ||
| 162 | #else | ||
| 163 | printf (_("Error processing %s\n"), PATH_TO_UPTIME); | ||
| 164 | #endif | ||
| 165 | return STATE_UNKNOWN; | ||
| 166 | } | 131 | } |
| 167 | 132 | ||
| 168 | /* we got this far, so assume OK until we've measured */ | 133 | const check_load_config config = tmp_config.config; |
| 169 | result = STATE_OK; | 134 | |
| 135 | double load_values[3] = {0, 0, 0}; | ||
| 170 | 136 | ||
| 171 | xasprintf(&status_line, _("load average: %.2f, %.2f, %.2f"), la1, la5, la15); | 137 | // this should be getloadavg from gnulib, should work everywhereâ„¢ |
| 172 | xasprintf(&status_line, ("total %s"), status_line); | 138 | int error = getloadavg(load_values, 3); |
| 139 | if (error != 3) { | ||
| 140 | die(STATE_UNKNOWN, _("Failed to retrieve load values")); | ||
| 141 | } | ||
| 173 | 142 | ||
| 143 | mp_check overall = mp_check_init(); | ||
| 144 | if (config.output_format_set) { | ||
| 145 | mp_set_format(config.output_format); | ||
| 146 | } | ||
| 174 | 147 | ||
| 175 | double scaled_la[3] = { 0.0, 0.0, 0.0 }; | ||
| 176 | bool is_using_scaled_load_values = false; | 148 | bool is_using_scaled_load_values = false; |
| 177 | 149 | long numcpus; | |
| 178 | if (take_into_account_cpus == true && (numcpus = GET_NUMBER_OF_CPUS()) > 0) { | 150 | if (config.take_into_account_cpus && ((numcpus = GET_NUMBER_OF_CPUS()) > 0)) { |
| 179 | is_using_scaled_load_values = true; | 151 | is_using_scaled_load_values = true; |
| 180 | 152 | ||
| 181 | scaled_la[0] = la[0] / numcpus; | 153 | double scaled_la[3] = { |
| 182 | scaled_la[1] = la[1] / numcpus; | 154 | load_values[0] / numcpus, |
| 183 | scaled_la[2] = la[2] / numcpus; | 155 | load_values[1] / numcpus, |
| 156 | load_values[2] / numcpus, | ||
| 157 | }; | ||
| 158 | |||
| 159 | mp_subcheck scaled_load_sc = mp_subcheck_init(); | ||
| 160 | scaled_load_sc = mp_set_subcheck_default_state(scaled_load_sc, STATE_OK); | ||
| 161 | scaled_load_sc.output = "Scaled Load (divided by number of CPUs"; | ||
| 162 | |||
| 163 | mp_perfdata pd_scaled_load1 = perfdata_init(); | ||
| 164 | pd_scaled_load1.label = "scaled_load1"; | ||
| 165 | pd_scaled_load1 = mp_set_pd_value(pd_scaled_load1, scaled_la[0]); | ||
| 166 | pd_scaled_load1 = mp_pd_set_thresholds(pd_scaled_load1, config.th_load[0]); | ||
| 167 | |||
| 168 | mp_subcheck scaled_load_sc1 = mp_subcheck_init(); | ||
| 169 | scaled_load_sc1 = mp_set_subcheck_state(scaled_load_sc1, mp_get_pd_status(pd_scaled_load1)); | ||
| 170 | mp_add_perfdata_to_subcheck(&scaled_load_sc1, pd_scaled_load1); | ||
| 171 | xasprintf(&scaled_load_sc1.output, "1 Minute: %s", | ||
| 172 | pd_value_to_string(pd_scaled_load1.value)); | ||
| 173 | mp_add_subcheck_to_subcheck(&scaled_load_sc, scaled_load_sc1); | ||
| 174 | |||
| 175 | mp_perfdata pd_scaled_load5 = perfdata_init(); | ||
| 176 | pd_scaled_load5.label = "scaled_load5"; | ||
| 177 | pd_scaled_load5 = mp_set_pd_value(pd_scaled_load5, scaled_la[1]); | ||
| 178 | pd_scaled_load5 = mp_pd_set_thresholds(pd_scaled_load5, config.th_load[1]); | ||
| 179 | |||
| 180 | mp_subcheck scaled_load_sc5 = mp_subcheck_init(); | ||
| 181 | scaled_load_sc5 = mp_set_subcheck_state(scaled_load_sc5, mp_get_pd_status(pd_scaled_load5)); | ||
| 182 | mp_add_perfdata_to_subcheck(&scaled_load_sc5, pd_scaled_load5); | ||
| 183 | xasprintf(&scaled_load_sc5.output, "5 Minutes: %s", | ||
| 184 | pd_value_to_string(pd_scaled_load5.value)); | ||
| 185 | mp_add_subcheck_to_subcheck(&scaled_load_sc, scaled_load_sc5); | ||
| 186 | |||
| 187 | mp_perfdata pd_scaled_load15 = perfdata_init(); | ||
| 188 | pd_scaled_load15.label = "scaled_load15"; | ||
| 189 | pd_scaled_load15 = mp_set_pd_value(pd_scaled_load15, scaled_la[2]); | ||
| 190 | pd_scaled_load15 = mp_pd_set_thresholds(pd_scaled_load15, config.th_load[2]); | ||
| 191 | |||
| 192 | mp_subcheck scaled_load_sc15 = mp_subcheck_init(); | ||
| 193 | scaled_load_sc15 = | ||
| 194 | mp_set_subcheck_state(scaled_load_sc15, mp_get_pd_status(pd_scaled_load15)); | ||
| 195 | mp_add_perfdata_to_subcheck(&scaled_load_sc15, pd_scaled_load15); | ||
| 196 | xasprintf(&scaled_load_sc15.output, "15 Minutes: %s", | ||
| 197 | pd_value_to_string(pd_scaled_load15.value)); | ||
| 198 | mp_add_subcheck_to_subcheck(&scaled_load_sc, scaled_load_sc15); | ||
| 199 | |||
| 200 | mp_add_subcheck_to_check(&overall, scaled_load_sc); | ||
| 201 | } | ||
| 202 | |||
| 203 | mp_subcheck load_sc = mp_subcheck_init(); | ||
| 204 | load_sc = mp_set_subcheck_default_state(load_sc, STATE_OK); | ||
| 205 | load_sc.output = "Total Load"; | ||
| 184 | 206 | ||
| 185 | char *tmp = NULL; | 207 | mp_perfdata pd_load1 = perfdata_init(); |
| 186 | xasprintf(&tmp, _("load average: %.2f, %.2f, %.2f"), scaled_la[0], scaled_la[1], scaled_la[2]); | 208 | pd_load1.label = "load1"; |
| 187 | xasprintf(&status_line, "scaled %s - %s", tmp, status_line); | 209 | pd_load1 = mp_set_pd_value(pd_load1, load_values[0]); |
| 210 | if (!is_using_scaled_load_values) { | ||
| 211 | pd_load1 = mp_pd_set_thresholds(pd_load1, config.th_load[0]); | ||
| 188 | } | 212 | } |
| 189 | 213 | ||
| 190 | for(i = 0; i < 3; i++) { | 214 | mp_subcheck load_sc1 = mp_subcheck_init(); |
| 191 | if (is_using_scaled_load_values) { | 215 | load_sc1 = mp_set_subcheck_state(load_sc1, mp_get_pd_status(pd_load1)); |
| 192 | if(scaled_la[i] > cload[i]) { | 216 | mp_add_perfdata_to_subcheck(&load_sc1, pd_load1); |
| 193 | result = STATE_CRITICAL; | 217 | xasprintf(&load_sc1.output, "1 Minute: %s", pd_value_to_string(pd_load1.value)); |
| 194 | break; | 218 | mp_add_subcheck_to_subcheck(&load_sc, load_sc1); |
| 195 | } | 219 | |
| 196 | else if(scaled_la[i] > wload[i]) result = STATE_WARNING; | 220 | mp_perfdata pd_load5 = perfdata_init(); |
| 197 | } else { | 221 | pd_load5.label = "load5"; |
| 198 | if(la[i] > cload[i]) { | 222 | pd_load5 = mp_set_pd_value(pd_load5, load_values[1]); |
| 199 | result = STATE_CRITICAL; | 223 | if (!is_using_scaled_load_values) { |
| 200 | break; | 224 | pd_load5 = mp_pd_set_thresholds(pd_load5, config.th_load[1]); |
| 201 | } | ||
| 202 | else if(la[i] > wload[i]) result = STATE_WARNING; | ||
| 203 | } | ||
| 204 | } | 225 | } |
| 205 | 226 | ||
| 206 | printf("LOAD %s - %s|", state_text(result), status_line); | 227 | mp_subcheck load_sc5 = mp_subcheck_init(); |
| 207 | for(i = 0; i < 3; i++) { | 228 | load_sc5 = mp_set_subcheck_state(load_sc5, mp_get_pd_status(pd_load5)); |
| 208 | if (is_using_scaled_load_values) { | 229 | mp_add_perfdata_to_subcheck(&load_sc5, pd_load5); |
| 209 | printf("load%d=%.3f;;;0; ", nums[i], la[i]); | 230 | xasprintf(&load_sc5.output, "5 Minutes: %s", pd_value_to_string(pd_load5.value)); |
| 210 | printf("scaled_load%d=%.3f;%.3f;%.3f;0; ", nums[i], scaled_la[i], wload[i], cload[i]); | 231 | mp_add_subcheck_to_subcheck(&load_sc, load_sc5); |
| 211 | } else { | 232 | |
| 212 | printf("load%d=%.3f;%.3f;%.3f;0; ", nums[i], la[i], wload[i], cload[i]); | 233 | mp_perfdata pd_load15 = perfdata_init(); |
| 213 | } | 234 | pd_load15.label = "load15"; |
| 235 | pd_load15 = mp_set_pd_value(pd_load15, load_values[2]); | ||
| 236 | if (!is_using_scaled_load_values) { | ||
| 237 | pd_load15 = mp_pd_set_thresholds(pd_load15, config.th_load[2]); | ||
| 214 | } | 238 | } |
| 215 | 239 | ||
| 216 | putchar('\n'); | 240 | mp_subcheck load_sc15 = mp_subcheck_init(); |
| 217 | if (n_procs_to_show > 0) { | 241 | load_sc15 = mp_set_subcheck_state(load_sc15, mp_get_pd_status(pd_load15)); |
| 218 | print_top_consuming_processes(); | 242 | mp_add_perfdata_to_subcheck(&load_sc15, pd_load15); |
| 243 | xasprintf(&load_sc15.output, "15 Minutes: %s", pd_value_to_string(pd_load15.value)); | ||
| 244 | mp_add_subcheck_to_subcheck(&load_sc, load_sc15); | ||
| 245 | |||
| 246 | mp_add_subcheck_to_check(&overall, load_sc); | ||
| 247 | |||
| 248 | if (config.n_procs_to_show > 0) { | ||
| 249 | mp_subcheck top_proc_sc = mp_subcheck_init(); | ||
| 250 | top_proc_sc = mp_set_subcheck_state(top_proc_sc, STATE_OK); | ||
| 251 | top_processes_result top_proc = print_top_consuming_processes(config.n_procs_to_show); | ||
| 252 | xasprintf(&top_proc_sc.output, "Top %lu CPU time consuming processes", | ||
| 253 | config.n_procs_to_show); | ||
| 254 | |||
| 255 | if (top_proc.errorcode == OK) { | ||
| 256 | for (unsigned long i = 0; i < config.n_procs_to_show; i++) { | ||
| 257 | xasprintf(&top_proc_sc.output, "%s\n%s", top_proc_sc.output, | ||
| 258 | top_proc.top_processes[i]); | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | mp_add_subcheck_to_check(&overall, top_proc_sc); | ||
| 219 | } | 263 | } |
| 220 | return result; | ||
| 221 | } | ||
| 222 | 264 | ||
| 265 | mp_exit(overall); | ||
| 266 | } | ||
| 223 | 267 | ||
| 224 | /* process command-line arguments */ | 268 | /* process command-line arguments */ |
| 225 | static int | 269 | static check_load_config_wrapper process_arguments(int argc, char **argv) { |
| 226 | process_arguments (int argc, char **argv) | 270 | |
| 227 | { | 271 | enum { |
| 228 | int c = 0; | 272 | output_format_index = CHAR_MAX + 1, |
| 229 | |||
| 230 | int option = 0; | ||
| 231 | static struct option longopts[] = { | ||
| 232 | {"warning", required_argument, 0, 'w'}, | ||
| 233 | {"critical", required_argument, 0, 'c'}, | ||
| 234 | {"percpu", no_argument, 0, 'r'}, | ||
| 235 | {"version", no_argument, 0, 'V'}, | ||
| 236 | {"help", no_argument, 0, 'h'}, | ||
| 237 | {"procs-to-show", required_argument, 0, 'n'}, | ||
| 238 | {0, 0, 0, 0} | ||
| 239 | }; | 273 | }; |
| 240 | 274 | ||
| 241 | if (argc < 2) | 275 | static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, |
| 242 | return ERROR; | 276 | {"critical", required_argument, 0, 'c'}, |
| 277 | {"percpu", no_argument, 0, 'r'}, | ||
| 278 | {"version", no_argument, 0, 'V'}, | ||
| 279 | {"help", no_argument, 0, 'h'}, | ||
| 280 | {"procs-to-show", required_argument, 0, 'n'}, | ||
| 281 | {"output-format", required_argument, 0, output_format_index}, | ||
| 282 | {0, 0, 0, 0}}; | ||
| 283 | |||
| 284 | check_load_config_wrapper result = { | ||
| 285 | .errorcode = OK, | ||
| 286 | .config = check_load_config_init(), | ||
| 287 | }; | ||
| 243 | 288 | ||
| 244 | while (1) { | 289 | if (argc < 2) { |
| 245 | c = getopt_long (argc, argv, "Vhrc:w:n:", longopts, &option); | 290 | result.errorcode = ERROR; |
| 291 | return result; | ||
| 292 | } | ||
| 246 | 293 | ||
| 247 | if (c == -1 || c == EOF) | 294 | while (true) { |
| 248 | break; | 295 | int option = 0; |
| 296 | int option_index = getopt_long(argc, argv, "Vhrc:w:n:", longopts, &option); | ||
| 249 | 297 | ||
| 250 | switch (c) { | 298 | if (option_index == -1 || option_index == EOF) { |
| 251 | case 'w': /* warning time threshold */ | ||
| 252 | get_threshold(optarg, wload); | ||
| 253 | break; | 299 | break; |
| 254 | case 'c': /* critical time threshold */ | 300 | } |
| 255 | get_threshold(optarg, cload); | 301 | |
| 302 | switch (option_index) { | ||
| 303 | case output_format_index: { | ||
| 304 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 305 | if (!parser.parsing_success) { | ||
| 306 | printf("Invalid output format: %s\n", optarg); | ||
| 307 | exit(STATE_UNKNOWN); | ||
| 308 | } | ||
| 309 | |||
| 310 | result.config.output_format_set = true; | ||
| 311 | result.config.output_format = parser.output_format; | ||
| 256 | break; | 312 | break; |
| 313 | } | ||
| 314 | case 'w': /* warning time threshold */ { | ||
| 315 | parsed_thresholds warning_range = get_threshold(optarg); | ||
| 316 | result.config.th_load[0].warning = warning_range.load[0]; | ||
| 317 | result.config.th_load[0].warning_is_set = true; | ||
| 318 | |||
| 319 | result.config.th_load[1].warning = warning_range.load[1]; | ||
| 320 | result.config.th_load[1].warning_is_set = true; | ||
| 321 | |||
| 322 | result.config.th_load[2].warning = warning_range.load[2]; | ||
| 323 | result.config.th_load[2].warning_is_set = true; | ||
| 324 | } break; | ||
| 325 | case 'c': /* critical time threshold */ { | ||
| 326 | parsed_thresholds critical_range = get_threshold(optarg); | ||
| 327 | result.config.th_load[0].critical = critical_range.load[0]; | ||
| 328 | result.config.th_load[0].critical_is_set = true; | ||
| 329 | |||
| 330 | result.config.th_load[1].critical = critical_range.load[1]; | ||
| 331 | result.config.th_load[1].critical_is_set = true; | ||
| 332 | |||
| 333 | result.config.th_load[2].critical = critical_range.load[2]; | ||
| 334 | result.config.th_load[2].critical_is_set = true; | ||
| 335 | } break; | ||
| 257 | case 'r': /* Divide load average by number of CPUs */ | 336 | case 'r': /* Divide load average by number of CPUs */ |
| 258 | take_into_account_cpus = true; | 337 | result.config.take_into_account_cpus = true; |
| 259 | break; | 338 | break; |
| 260 | case 'V': /* version */ | 339 | case 'V': /* version */ |
| 261 | print_revision (progname, NP_VERSION); | 340 | print_revision(progname, NP_VERSION); |
| 262 | exit (STATE_UNKNOWN); | 341 | exit(STATE_UNKNOWN); |
| 263 | case 'h': /* help */ | 342 | case 'h': /* help */ |
| 264 | print_help (); | 343 | print_help(); |
| 265 | exit (STATE_UNKNOWN); | 344 | exit(STATE_UNKNOWN); |
| 266 | case 'n': | 345 | case 'n': |
| 267 | n_procs_to_show = atoi(optarg); | 346 | result.config.n_procs_to_show = (unsigned long)atol(optarg); |
| 268 | break; | 347 | break; |
| 269 | case '?': /* help */ | 348 | case '?': /* help */ |
| 270 | usage5 (); | 349 | usage5(); |
| 271 | } | 350 | } |
| 272 | } | 351 | } |
| 273 | 352 | ||
| 274 | c = optind; | 353 | int index = optind; |
| 275 | if (c == argc) | 354 | if (index == argc) { |
| 276 | return validate_arguments (); | 355 | return result; |
| 356 | } | ||
| 277 | 357 | ||
| 278 | /* handle the case if both arguments are missing, | 358 | /* handle the case if both arguments are missing, |
| 279 | * but not if only one is given without -c or -w flag */ | 359 | * but not if only one is given without -c or -w flag */ |
| 280 | if(c - argc == 2) { | 360 | if (index - argc == 2) { |
| 281 | get_threshold(argv[c++], wload); | 361 | parsed_thresholds warning_range = get_threshold(argv[index++]); |
| 282 | get_threshold(argv[c++], cload); | 362 | result.config.th_load[0].warning = warning_range.load[0]; |
| 283 | } | 363 | result.config.th_load[0].warning_is_set = true; |
| 284 | else if(c - argc == 1) { | 364 | |
| 285 | get_threshold(argv[c++], cload); | 365 | result.config.th_load[1].warning = warning_range.load[1]; |
| 286 | } | 366 | result.config.th_load[1].warning_is_set = true; |
| 287 | 367 | ||
| 288 | return validate_arguments (); | 368 | result.config.th_load[2].warning = warning_range.load[2]; |
| 289 | } | 369 | result.config.th_load[2].warning_is_set = true; |
| 290 | 370 | parsed_thresholds critical_range = get_threshold(argv[index++]); | |
| 291 | 371 | result.config.th_load[0].critical = critical_range.load[0]; | |
| 292 | static int | 372 | result.config.th_load[0].critical_is_set = true; |
| 293 | validate_arguments (void) | 373 | |
| 294 | { | 374 | result.config.th_load[1].critical = critical_range.load[1]; |
| 295 | int i = 0; | 375 | result.config.th_load[1].critical_is_set = true; |
| 296 | 376 | ||
| 297 | /* match cload first, as it will give the most friendly error message | 377 | result.config.th_load[2].critical = critical_range.load[2]; |
| 298 | * if user hasn't given the -c switch properly */ | 378 | result.config.th_load[2].critical_is_set = true; |
| 299 | for(i = 0; i < 3; i++) { | 379 | } else if (index - argc == 1) { |
| 300 | if(cload[i] < 0) | 380 | parsed_thresholds critical_range = get_threshold(argv[index++]); |
| 301 | die (STATE_UNKNOWN, _("Critical threshold for %d-minute load average is not specified\n"), nums[i]); | 381 | result.config.th_load[0].critical = critical_range.load[0]; |
| 302 | if(wload[i] < 0) | 382 | result.config.th_load[0].critical_is_set = true; |
| 303 | die (STATE_UNKNOWN, _("Warning threshold for %d-minute load average is not specified\n"), nums[i]); | 383 | |
| 304 | if(wload[i] > cload[i]) | 384 | result.config.th_load[1].critical = critical_range.load[1]; |
| 305 | die (STATE_UNKNOWN, _("Parameter inconsistency: %d-minute \"warning load\" is greater than \"critical load\"\n"), nums[i]); | 385 | result.config.th_load[1].critical_is_set = true; |
| 386 | |||
| 387 | result.config.th_load[2].critical = critical_range.load[2]; | ||
| 388 | result.config.th_load[2].critical_is_set = true; | ||
| 306 | } | 389 | } |
| 307 | 390 | ||
| 308 | return OK; | 391 | return result; |
| 309 | } | 392 | } |
| 310 | 393 | ||
| 394 | void print_help(void) { | ||
| 395 | print_revision(progname, NP_VERSION); | ||
| 311 | 396 | ||
| 312 | void | 397 | printf("Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br>\n"); |
| 313 | print_help (void) | 398 | printf(COPYRIGHT, copyright, email); |
| 314 | { | ||
| 315 | print_revision (progname, NP_VERSION); | ||
| 316 | 399 | ||
| 317 | printf ("Copyright (c) 1999 Felipe Gustavo de Almeida <galmeida@linux.ime.usp.br>\n"); | 400 | printf(_("This plugin tests the current system load average.")); |
| 318 | printf (COPYRIGHT, copyright, email); | ||
| 319 | 401 | ||
| 320 | printf (_("This plugin tests the current system load average.")); | 402 | printf("\n\n"); |
| 321 | 403 | ||
| 322 | printf ("\n\n"); | 404 | print_usage(); |
| 323 | 405 | ||
| 324 | print_usage (); | 406 | printf(UT_HELP_VRSN); |
| 407 | printf(UT_EXTRA_OPTS); | ||
| 325 | 408 | ||
| 326 | printf (UT_HELP_VRSN); | 409 | printf(" %s\n", "-w, --warning=WLOAD1,WLOAD5,WLOAD15"); |
| 327 | printf (UT_EXTRA_OPTS); | 410 | printf(" %s\n", _("Exit with WARNING status if load average exceeds WLOADn")); |
| 411 | printf(" %s\n", "-c, --critical=CLOAD1,CLOAD5,CLOAD15"); | ||
| 412 | printf(" %s\n", _("Exit with CRITICAL status if load average exceed CLOADn")); | ||
| 413 | printf(" %s\n", _("the load average format is the same used by \"uptime\" and \"w\"")); | ||
| 414 | printf(" %s\n", "-r, --percpu"); | ||
| 415 | printf(" %s\n", _("Divide the load averages by the number of CPUs (when possible)")); | ||
| 416 | printf(" %s\n", "-n, --procs-to-show=NUMBER_OF_PROCS"); | ||
| 417 | printf(" %s\n", _("Number of processes to show when printing the top consuming processes.")); | ||
| 418 | printf(" %s\n", _("NUMBER_OF_PROCS=0 disables this feature. Default value is 0")); | ||
| 328 | 419 | ||
| 329 | printf (" %s\n", "-w, --warning=WLOAD1,WLOAD5,WLOAD15"); | 420 | printf(UT_OUTPUT_FORMAT); |
| 330 | printf (" %s\n", _("Exit with WARNING status if load average exceeds WLOADn")); | 421 | printf(UT_SUPPORT); |
| 331 | printf (" %s\n", "-c, --critical=CLOAD1,CLOAD5,CLOAD15"); | ||
| 332 | printf (" %s\n", _("Exit with CRITICAL status if load average exceed CLOADn")); | ||
| 333 | printf (" %s\n", _("the load average format is the same used by \"uptime\" and \"w\"")); | ||
| 334 | printf (" %s\n", "-r, --percpu"); | ||
| 335 | printf (" %s\n", _("Divide the load averages by the number of CPUs (when possible)")); | ||
| 336 | printf (" %s\n", "-n, --procs-to-show=NUMBER_OF_PROCS"); | ||
| 337 | printf (" %s\n", _("Number of processes to show when printing the top consuming processes.")); | ||
| 338 | printf (" %s\n", _("NUMBER_OF_PROCS=0 disables this feature. Default value is 0")); | ||
| 339 | |||
| 340 | printf (UT_SUPPORT); | ||
| 341 | } | 422 | } |
| 342 | 423 | ||
| 343 | void | 424 | void print_usage(void) { |
| 344 | print_usage (void) | 425 | printf("%s\n", _("Usage:")); |
| 345 | { | 426 | printf("%s [-r] -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15 [-n NUMBER_OF_PROCS]\n", |
| 346 | printf ("%s\n", _("Usage:")); | 427 | progname); |
| 347 | printf ("%s [-r] -w WLOAD1,WLOAD5,WLOAD15 -c CLOAD1,CLOAD5,CLOAD15 [-n NUMBER_OF_PROCS]\n", progname); | ||
| 348 | } | 428 | } |
| 349 | 429 | ||
| 350 | #ifdef PS_USES_PROCPCPU | 430 | #ifdef PS_USES_PROCPCPU |
| @@ -356,36 +436,52 @@ int cmpstringp(const void *p1, const void *p2) { | |||
| 356 | int procrss = 0; | 436 | int procrss = 0; |
| 357 | float procpcpu = 0; | 437 | float procpcpu = 0; |
| 358 | char procstat[8]; | 438 | char procstat[8]; |
| 359 | #ifdef PS_USES_PROCETIME | 439 | # ifdef PS_USES_PROCETIME |
| 360 | char procetime[MAX_INPUT_BUFFER]; | 440 | char procetime[MAX_INPUT_BUFFER]; |
| 361 | #endif /* PS_USES_PROCETIME */ | 441 | # endif /* PS_USES_PROCETIME */ |
| 362 | char procprog[MAX_INPUT_BUFFER]; | 442 | char procprog[MAX_INPUT_BUFFER]; |
| 363 | int pos; | 443 | int pos; |
| 364 | sscanf (* (char * const *) p1, PS_FORMAT, PS_VARLIST); | 444 | sscanf(*(char *const *)p1, PS_FORMAT, PS_VARLIST); |
| 365 | float procpcpu1 = procpcpu; | 445 | float procpcpu1 = procpcpu; |
| 366 | sscanf (* (char * const *) p2, PS_FORMAT, PS_VARLIST); | 446 | sscanf(*(char *const *)p2, PS_FORMAT, PS_VARLIST); |
| 367 | return procpcpu1 < procpcpu; | 447 | return procpcpu1 < procpcpu; |
| 368 | } | 448 | } |
| 369 | #endif /* PS_USES_PROCPCPU */ | 449 | #endif /* PS_USES_PROCPCPU */ |
| 370 | 450 | ||
| 371 | static int print_top_consuming_processes() { | 451 | static top_processes_result print_top_consuming_processes(unsigned long n_procs_to_show) { |
| 372 | int i = 0; | 452 | top_processes_result result = { |
| 373 | struct output chld_out, chld_err; | 453 | .errorcode = OK, |
| 374 | if(np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0) != 0){ | 454 | }; |
| 455 | output chld_out; | ||
| 456 | output chld_err; | ||
| 457 | if (np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0) != 0) { | ||
| 375 | fprintf(stderr, _("'%s' exited with non-zero status.\n"), PS_COMMAND); | 458 | fprintf(stderr, _("'%s' exited with non-zero status.\n"), PS_COMMAND); |
| 376 | return STATE_UNKNOWN; | 459 | result.errorcode = ERROR; |
| 460 | return result; | ||
| 377 | } | 461 | } |
| 462 | |||
| 378 | if (chld_out.lines < 2) { | 463 | if (chld_out.lines < 2) { |
| 379 | fprintf(stderr, _("some error occurred getting procs list.\n")); | 464 | fprintf(stderr, _("some error occurred getting procs list.\n")); |
| 380 | return STATE_UNKNOWN; | 465 | result.errorcode = ERROR; |
| 466 | return result; | ||
| 381 | } | 467 | } |
| 468 | |||
| 382 | #ifdef PS_USES_PROCPCPU | 469 | #ifdef PS_USES_PROCPCPU |
| 383 | qsort(chld_out.line + 1, chld_out.lines - 1, sizeof(char*), cmpstringp); | 470 | qsort(chld_out.line + 1, chld_out.lines - 1, sizeof(char *), cmpstringp); |
| 384 | #endif /* PS_USES_PROCPCPU */ | 471 | #endif /* PS_USES_PROCPCPU */ |
| 385 | int lines_to_show = chld_out.lines < (size_t)(n_procs_to_show + 1) | 472 | unsigned long lines_to_show = |
| 386 | ? (int)chld_out.lines : n_procs_to_show + 1; | 473 | chld_out.lines < (size_t)(n_procs_to_show + 1) ? chld_out.lines : n_procs_to_show + 1; |
| 387 | for (i = 0; i < lines_to_show; i += 1) { | 474 | |
| 388 | printf("%s\n", chld_out.line[i]); | 475 | result.top_processes = calloc(lines_to_show, sizeof(char *)); |
| 476 | if (result.top_processes == NULL) { | ||
| 477 | // Failed allocation | ||
| 478 | result.errorcode = ERROR; | ||
| 479 | return result; | ||
| 389 | } | 480 | } |
| 390 | return OK; | 481 | |
| 482 | for (unsigned long i = 0; i < lines_to_show; i += 1) { | ||
| 483 | xasprintf(&result.top_processes[i], "%s", chld_out.line[i]); | ||
| 484 | } | ||
| 485 | |||
| 486 | return result; | ||
| 391 | } | 487 | } |
diff --git a/plugins/check_load.d/config.h b/plugins/check_load.d/config.h new file mode 100644 index 00000000..fd735455 --- /dev/null +++ b/plugins/check_load.d/config.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "output.h" | ||
| 4 | #include "thresholds.h" | ||
| 5 | typedef struct { | ||
| 6 | mp_thresholds th_load[3]; | ||
| 7 | |||
| 8 | bool take_into_account_cpus; | ||
| 9 | unsigned long n_procs_to_show; | ||
| 10 | |||
| 11 | mp_output_format output_format; | ||
| 12 | bool output_format_set; | ||
| 13 | } check_load_config; | ||
| 14 | |||
| 15 | check_load_config check_load_config_init() { | ||
| 16 | check_load_config tmp = { | ||
| 17 | .th_load = | ||
| 18 | { | ||
| 19 | mp_thresholds_init(), | ||
| 20 | mp_thresholds_init(), | ||
| 21 | mp_thresholds_init(), | ||
| 22 | }, | ||
| 23 | |||
| 24 | .take_into_account_cpus = false, | ||
| 25 | .n_procs_to_show = 0, | ||
| 26 | |||
| 27 | .output_format_set = false, | ||
| 28 | }; | ||
| 29 | return tmp; | ||
| 30 | } | ||
diff --git a/plugins/check_mrtg.c b/plugins/check_mrtg.c index 5bd276dc..cdc2a035 100644 --- a/plugins/check_mrtg.c +++ b/plugins/check_mrtg.c | |||
| @@ -29,14 +29,18 @@ | |||
| 29 | * | 29 | * |
| 30 | *****************************************************************************/ | 30 | *****************************************************************************/ |
| 31 | 31 | ||
| 32 | const char *progname = "check_mrtg"; | ||
| 33 | const char *copyright = "1999-2024"; | ||
| 34 | const char *email = "devel@monitoring-plugins.org"; | ||
| 35 | |||
| 36 | #include "common.h" | 32 | #include "common.h" |
| 33 | #include "output.h" | ||
| 34 | #include "perfdata.h" | ||
| 35 | #include "states.h" | ||
| 36 | #include "thresholds.h" | ||
| 37 | #include "utils.h" | 37 | #include "utils.h" |
| 38 | #include "check_mrtg.d/config.h" | 38 | #include "check_mrtg.d/config.h" |
| 39 | 39 | ||
| 40 | const char *progname = "check_mrtg"; | ||
| 41 | const char *copyright = "1999-2024"; | ||
| 42 | const char *email = "devel@monitoring-plugins.org"; | ||
| 43 | |||
| 40 | typedef struct { | 44 | typedef struct { |
| 41 | int errorcode; | 45 | int errorcode; |
| 42 | check_mrtg_config config; | 46 | check_mrtg_config config; |
| @@ -62,11 +66,24 @@ int main(int argc, char **argv) { | |||
| 62 | 66 | ||
| 63 | const check_mrtg_config config = tmp_config.config; | 67 | const check_mrtg_config config = tmp_config.config; |
| 64 | 68 | ||
| 69 | if (config.output_format_is_set) { | ||
| 70 | mp_set_format(config.output_format); | ||
| 71 | } | ||
| 72 | |||
| 73 | mp_check overall = mp_check_init(); | ||
| 74 | |||
| 65 | /* open the MRTG log file for reading */ | 75 | /* open the MRTG log file for reading */ |
| 76 | mp_subcheck sc_open_mrtg_log_file = mp_subcheck_init(); | ||
| 66 | FILE *mtrg_log_file = fopen(config.log_file, "r"); | 77 | FILE *mtrg_log_file = fopen(config.log_file, "r"); |
| 67 | if (mtrg_log_file == NULL) { | 78 | if (mtrg_log_file == NULL) { |
| 68 | printf(_("Unable to open MRTG log file\n")); | 79 | xasprintf(&sc_open_mrtg_log_file.output, "unable to open MRTG log file"); |
| 69 | return STATE_UNKNOWN; | 80 | sc_open_mrtg_log_file = mp_set_subcheck_state(sc_open_mrtg_log_file, STATE_UNKNOWN); |
| 81 | mp_add_subcheck_to_check(&overall, sc_open_mrtg_log_file); | ||
| 82 | mp_exit(overall); | ||
| 83 | } else { | ||
| 84 | xasprintf(&sc_open_mrtg_log_file.output, "opened MRTG log file"); | ||
| 85 | sc_open_mrtg_log_file = mp_set_subcheck_state(sc_open_mrtg_log_file, STATE_OK); | ||
| 86 | mp_add_subcheck_to_check(&overall, sc_open_mrtg_log_file); | ||
| 70 | } | 87 | } |
| 71 | 88 | ||
| 72 | time_t timestamp = 0; | 89 | time_t timestamp = 0; |
| @@ -120,17 +137,32 @@ int main(int argc, char **argv) { | |||
| 120 | fclose(mtrg_log_file); | 137 | fclose(mtrg_log_file); |
| 121 | 138 | ||
| 122 | /* if we couldn't read enough data, return an unknown error */ | 139 | /* if we couldn't read enough data, return an unknown error */ |
| 140 | mp_subcheck sc_process_mrtg_log_file = mp_subcheck_init(); | ||
| 123 | if (line <= 2) { | 141 | if (line <= 2) { |
| 124 | printf(_("Unable to process MRTG log file\n")); | 142 | xasprintf(&sc_process_mrtg_log_file.output, "unable to process MRTG log file"); |
| 125 | return STATE_UNKNOWN; | 143 | sc_process_mrtg_log_file = mp_set_subcheck_state(sc_process_mrtg_log_file, STATE_UNKNOWN); |
| 144 | mp_exit(overall); | ||
| 145 | } else { | ||
| 146 | xasprintf(&sc_process_mrtg_log_file.output, "processed MRTG log file"); | ||
| 147 | sc_process_mrtg_log_file = mp_set_subcheck_state(sc_process_mrtg_log_file, STATE_OK); | ||
| 148 | mp_add_subcheck_to_check(&overall, sc_process_mrtg_log_file); | ||
| 126 | } | 149 | } |
| 127 | 150 | ||
| 128 | /* make sure the MRTG data isn't too old */ | 151 | /* make sure the MRTG data isn't too old */ |
| 129 | time_t current_time; | 152 | time_t current_time; |
| 130 | time(¤t_time); | 153 | time(¤t_time); |
| 154 | mp_subcheck sc_data_expired = mp_subcheck_init(); | ||
| 131 | if (config.expire_minutes > 0 && (current_time - timestamp) > (config.expire_minutes * 60)) { | 155 | if (config.expire_minutes > 0 && (current_time - timestamp) > (config.expire_minutes * 60)) { |
| 132 | printf(_("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60)); | 156 | xasprintf(&sc_data_expired.output, "MRTG data has expired (%d minutes old)", |
| 133 | return STATE_WARNING; | 157 | (int)((current_time - timestamp) / 60)); |
| 158 | sc_data_expired = mp_set_subcheck_state(sc_data_expired, STATE_WARNING); | ||
| 159 | mp_add_subcheck_to_check(&overall, sc_data_expired); | ||
| 160 | mp_exit(overall); | ||
| 161 | } else { | ||
| 162 | xasprintf(&sc_data_expired.output, "MRTG data should be valid (%d minutes old)", | ||
| 163 | (int)((current_time - timestamp) / 60)); | ||
| 164 | sc_data_expired = mp_set_subcheck_state(sc_data_expired, STATE_OK); | ||
| 165 | mp_add_subcheck_to_check(&overall, sc_data_expired); | ||
| 134 | } | 166 | } |
| 135 | 167 | ||
| 136 | unsigned long rate = 0L; | 168 | unsigned long rate = 0L; |
| @@ -141,27 +173,40 @@ int main(int argc, char **argv) { | |||
| 141 | rate = maximum_value_rate; | 173 | rate = maximum_value_rate; |
| 142 | } | 174 | } |
| 143 | 175 | ||
| 144 | int result = STATE_OK; | 176 | mp_subcheck sc_values = mp_subcheck_init(); |
| 145 | if (config.value_critical_threshold_set && rate > config.value_critical_threshold) { | 177 | mp_perfdata pd_value = perfdata_init(); |
| 146 | result = STATE_CRITICAL; | 178 | pd_value = mp_set_pd_value(pd_value, rate); |
| 147 | } else if (config.value_warning_threshold_set && rate > config.value_warning_threshold) { | 179 | pd_value.label = config.label; |
| 148 | result = STATE_WARNING; | 180 | pd_value = mp_pd_set_thresholds(pd_value, config.values_threshold); |
| 149 | } | ||
| 150 | 181 | ||
| 151 | printf("%s. %s = %lu %s|%s\n", (config.use_average) ? _("Avg") : _("Max"), config.label, rate, config.units, | 182 | sc_values = mp_set_subcheck_state(sc_values, mp_get_pd_status(pd_value)); |
| 152 | perfdata(config.label, (long)rate, config.units, config.value_warning_threshold_set, (long)config.value_warning_threshold, | 183 | xasprintf(&sc_values.output, "%s. %s = %lu %s", (config.use_average) ? _("Avg") : _("Max"), |
| 153 | config.value_critical_threshold_set, (long)config.value_critical_threshold, 0, 0, 0, 0)); | 184 | config.label, rate, config.units); |
| 154 | 185 | ||
| 155 | return result; | 186 | mp_add_subcheck_to_check(&overall, sc_values); |
| 187 | |||
| 188 | mp_exit(overall); | ||
| 156 | } | 189 | } |
| 157 | 190 | ||
| 158 | /* process command-line arguments */ | 191 | /* process command-line arguments */ |
| 159 | check_mrtg_config_wrapper process_arguments(int argc, char **argv) { | 192 | check_mrtg_config_wrapper process_arguments(int argc, char **argv) { |
| 160 | static struct option longopts[] = { | 193 | enum { |
| 161 | {"logfile", required_argument, 0, 'F'}, {"expires", required_argument, 0, 'e'}, {"aggregation", required_argument, 0, 'a'}, | 194 | output_format_index, |
| 162 | {"variable", required_argument, 0, 'v'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, | 195 | }; |
| 163 | {"label", required_argument, 0, 'l'}, {"units", required_argument, 0, 'u'}, {"variable", required_argument, 0, 'v'}, | 196 | |
| 164 | {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; | 197 | static struct option longopts[] = {{"logfile", required_argument, 0, 'F'}, |
| 198 | {"expires", required_argument, 0, 'e'}, | ||
| 199 | {"aggregation", required_argument, 0, 'a'}, | ||
| 200 | {"variable", required_argument, 0, 'v'}, | ||
| 201 | {"critical", required_argument, 0, 'c'}, | ||
| 202 | {"warning", required_argument, 0, 'w'}, | ||
| 203 | {"label", required_argument, 0, 'l'}, | ||
| 204 | {"units", required_argument, 0, 'u'}, | ||
| 205 | {"variable", required_argument, 0, 'v'}, | ||
| 206 | {"version", no_argument, 0, 'V'}, | ||
| 207 | {"help", no_argument, 0, 'h'}, | ||
| 208 | {"output-format", required_argument, 0, output_format_index}, | ||
| 209 | {0, 0, 0, 0}}; | ||
| 165 | 210 | ||
| 166 | check_mrtg_config_wrapper result = { | 211 | check_mrtg_config_wrapper result = { |
| 167 | .errorcode = OK, | 212 | .errorcode = OK, |
| @@ -208,14 +253,22 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) { | |||
| 208 | usage4(_("Invalid variable number")); | 253 | usage4(_("Invalid variable number")); |
| 209 | } | 254 | } |
| 210 | break; | 255 | break; |
| 211 | case 'w': /* critical time threshold */ | 256 | case 'w': /* critical time threshold */ { |
| 212 | result.config.value_warning_threshold_set = true; | 257 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 213 | result.config.value_warning_threshold = strtoul(optarg, NULL, 10); | 258 | if (tmp.error != MP_PARSING_SUCCES) { |
| 214 | break; | 259 | die(STATE_UNKNOWN, "failed to parse warning threshold"); |
| 215 | case 'c': /* warning time threshold */ | 260 | } |
| 216 | result.config.value_critical_threshold_set = true; | 261 | result.config.values_threshold = |
| 217 | result.config.value_critical_threshold = strtoul(optarg, NULL, 10); | 262 | mp_thresholds_set_warn(result.config.values_threshold, tmp.range); |
| 218 | break; | 263 | } break; |
| 264 | case 'c': /* warning time threshold */ { | ||
| 265 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 266 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 267 | die(STATE_UNKNOWN, "failed to parse critical threshold"); | ||
| 268 | } | ||
| 269 | result.config.values_threshold = | ||
| 270 | mp_thresholds_set_crit(result.config.values_threshold, tmp.range); | ||
| 271 | } break; | ||
| 219 | case 'l': /* label */ | 272 | case 'l': /* label */ |
| 220 | result.config.label = optarg; | 273 | result.config.label = optarg; |
| 221 | break; | 274 | break; |
| @@ -230,6 +283,17 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) { | |||
| 230 | exit(STATE_UNKNOWN); | 283 | exit(STATE_UNKNOWN); |
| 231 | case '?': /* help */ | 284 | case '?': /* help */ |
| 232 | usage5(); | 285 | usage5(); |
| 286 | case output_format_index: { | ||
| 287 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 288 | if (!parser.parsing_success) { | ||
| 289 | printf("Invalid output format: %s\n", optarg); | ||
| 290 | exit(STATE_UNKNOWN); | ||
| 291 | } | ||
| 292 | |||
| 293 | result.config.output_format_is_set = true; | ||
| 294 | result.config.output_format = parser.output_format; | ||
| 295 | break; | ||
| 296 | } | ||
| 233 | } | 297 | } |
| 234 | } | 298 | } |
| 235 | 299 | ||
| @@ -242,7 +306,9 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) { | |||
| 242 | if (is_intpos(argv[option_char])) { | 306 | if (is_intpos(argv[option_char])) { |
| 243 | result.config.expire_minutes = atoi(argv[option_char++]); | 307 | result.config.expire_minutes = atoi(argv[option_char++]); |
| 244 | } else { | 308 | } else { |
| 245 | die(STATE_UNKNOWN, _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), argv[option_char], progname); | 309 | die(STATE_UNKNOWN, |
| 310 | _("%s is not a valid expiration time\nUse '%s -h' for additional help\n"), | ||
| 311 | argv[option_char], progname); | ||
| 246 | } | 312 | } |
| 247 | } | 313 | } |
| 248 | 314 | ||
| @@ -262,14 +328,22 @@ check_mrtg_config_wrapper process_arguments(int argc, char **argv) { | |||
| 262 | } | 328 | } |
| 263 | } | 329 | } |
| 264 | 330 | ||
| 265 | if (argc > option_char && !result.config.value_warning_threshold_set) { | 331 | if (argc > option_char && !result.config.values_threshold.warning_is_set) { |
| 266 | result.config.value_warning_threshold_set = true; | 332 | mp_range_parsed tmp = mp_parse_range_string(argv[option_char++]); |
| 267 | result.config.value_warning_threshold = strtoul(argv[option_char++], NULL, 10); | 333 | if (tmp.error != MP_PARSING_SUCCES) { |
| 334 | die(STATE_UNKNOWN, "failed to parse warning threshold"); | ||
| 335 | } | ||
| 336 | result.config.values_threshold = | ||
| 337 | mp_thresholds_set_warn(result.config.values_threshold, tmp.range); | ||
| 268 | } | 338 | } |
| 269 | 339 | ||
| 270 | if (argc > option_char && !result.config.value_critical_threshold_set) { | 340 | if (argc > option_char && !result.config.values_threshold.critical_is_set) { |
| 271 | result.config.value_critical_threshold_set = true; | 341 | mp_range_parsed tmp = mp_parse_range_string(argv[option_char++]); |
| 272 | result.config.value_critical_threshold = strtoul(argv[option_char++], NULL, 10); | 342 | if (tmp.error != MP_PARSING_SUCCES) { |
| 343 | die(STATE_UNKNOWN, "failed to parse critical threshold"); | ||
| 344 | } | ||
| 345 | result.config.values_threshold = | ||
| 346 | mp_thresholds_set_crit(result.config.values_threshold, tmp.range); | ||
| 273 | } | 347 | } |
| 274 | 348 | ||
| 275 | if (argc > option_char && strlen(result.config.label) == 0) { | 349 | if (argc > option_char && strlen(result.config.label) == 0) { |
| @@ -333,26 +407,35 @@ void print_help(void) { | |||
| 333 | printf(" %s\n", _("Option units label for data (Example: Packets/Sec, Errors/Sec,")); | 407 | printf(" %s\n", _("Option units label for data (Example: Packets/Sec, Errors/Sec,")); |
| 334 | printf(" %s\n", _("\"Bytes Per Second\", \"%% Utilization\")")); | 408 | printf(" %s\n", _("\"Bytes Per Second\", \"%% Utilization\")")); |
| 335 | 409 | ||
| 410 | printf(UT_OUTPUT_FORMAT); | ||
| 411 | |||
| 336 | printf("\n"); | 412 | printf("\n"); |
| 337 | printf(" %s\n", _("If the value exceeds the <vwl> threshold, a WARNING status is returned. If")); | 413 | printf(" %s\n", |
| 414 | _("If the value exceeds the <vwl> threshold, a WARNING status is returned. If")); | ||
| 338 | printf(" %s\n", _("the value exceeds the <vcl> threshold, a CRITICAL status is returned. If")); | 415 | printf(" %s\n", _("the value exceeds the <vcl> threshold, a CRITICAL status is returned. If")); |
| 339 | printf(" %s\n", _("the data in the log file is older than <expire_minutes> old, a WARNING")); | 416 | printf(" %s\n", _("the data in the log file is older than <expire_minutes> old, a WARNING")); |
| 340 | printf(" %s\n", _("status is returned and a warning message is printed.")); | 417 | printf(" %s\n", _("status is returned and a warning message is printed.")); |
| 341 | 418 | ||
| 342 | printf("\n"); | 419 | printf("\n"); |
| 343 | printf(" %s\n", _("This plugin is useful for monitoring MRTG data that does not correspond to")); | 420 | printf(" %s\n", |
| 344 | printf(" %s\n", _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).")); | 421 | _("This plugin is useful for monitoring MRTG data that does not correspond to")); |
| 345 | printf(" %s\n", _("It can be used to monitor any kind of data that MRTG is monitoring - errors,")); | 422 | printf(" %s\n", |
| 346 | printf(" %s\n", _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows")); | 423 | _("bandwidth usage. (Use the check_mrtgtraf plugin for monitoring bandwidth).")); |
| 424 | printf(" %s\n", | ||
| 425 | _("It can be used to monitor any kind of data that MRTG is monitoring - errors,")); | ||
| 426 | printf(" %s\n", | ||
| 427 | _("packets/sec, etc. I use MRTG in conjunction with the Novell NLM that allows")); | ||
| 347 | printf(" %s\n", _("me to track processor utilization, user connections, drive space, etc and")); | 428 | printf(" %s\n", _("me to track processor utilization, user connections, drive space, etc and")); |
| 348 | printf(" %s\n\n", _("this plugin works well for monitoring that kind of data as well.")); | 429 | printf(" %s\n\n", _("this plugin works well for monitoring that kind of data as well.")); |
| 349 | 430 | ||
| 350 | printf("%s\n", _("Notes:")); | 431 | printf("%s\n", _("Notes:")); |
| 351 | printf(" %s\n", _("- This plugin only monitors one of the two variables stored in the MRTG log")); | 432 | printf(" %s\n", |
| 433 | _("- This plugin only monitors one of the two variables stored in the MRTG log")); | ||
| 352 | printf(" %s\n", _("file. If you want to monitor both values you will have to define two")); | 434 | printf(" %s\n", _("file. If you want to monitor both values you will have to define two")); |
| 353 | printf(" %s\n", _("commands with different values for the <variable> argument. Of course,")); | 435 | printf(" %s\n", _("commands with different values for the <variable> argument. Of course,")); |
| 354 | printf(" %s\n", _("you can always hack the code to make this plugin work for you...")); | 436 | printf(" %s\n", _("you can always hack the code to make this plugin work for you...")); |
| 355 | printf(" %s\n", _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from")); | 437 | printf(" %s\n", |
| 438 | _("- MRTG stands for the Multi Router Traffic Grapher. It can be downloaded from")); | ||
| 356 | printf(" %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html"); | 439 | printf(" %s\n", "http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html"); |
| 357 | 440 | ||
| 358 | printf(UT_SUPPORT); | 441 | printf(UT_SUPPORT); |
diff --git a/plugins/check_mrtg.d/config.h b/plugins/check_mrtg.d/config.h index 96b849a2..4a5b5595 100644 --- a/plugins/check_mrtg.d/config.h +++ b/plugins/check_mrtg.d/config.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "output.h" | ||
| 5 | #include "thresholds.h" | ||
| 4 | #include <stddef.h> | 6 | #include <stddef.h> |
| 5 | #include <stdlib.h> | 7 | #include <stdlib.h> |
| 6 | 8 | ||
| @@ -12,10 +14,10 @@ typedef struct { | |||
| 12 | char *units; | 14 | char *units; |
| 13 | char *log_file; | 15 | char *log_file; |
| 14 | 16 | ||
| 15 | bool value_warning_threshold_set; | 17 | mp_thresholds values_threshold; |
| 16 | unsigned long value_warning_threshold; | 18 | |
| 17 | bool value_critical_threshold_set; | 19 | bool output_format_is_set; |
| 18 | unsigned long value_critical_threshold; | 20 | mp_output_format output_format; |
| 19 | } check_mrtg_config; | 21 | } check_mrtg_config; |
| 20 | 22 | ||
| 21 | check_mrtg_config check_mrtg_config_init() { | 23 | check_mrtg_config check_mrtg_config_init() { |
| @@ -27,10 +29,9 @@ check_mrtg_config check_mrtg_config_init() { | |||
| 27 | .units = NULL, | 29 | .units = NULL, |
| 28 | .log_file = NULL, | 30 | .log_file = NULL, |
| 29 | 31 | ||
| 30 | .value_warning_threshold_set = false, | 32 | .values_threshold = mp_thresholds_init(), |
| 31 | .value_warning_threshold = 0, | 33 | |
| 32 | .value_critical_threshold_set = false, | 34 | .output_format_is_set = false, |
| 33 | .value_critical_threshold = 0, | ||
| 34 | }; | 35 | }; |
| 35 | return tmp; | 36 | return tmp; |
| 36 | } | 37 | } |
diff --git a/plugins/check_mrtgtraf.c b/plugins/check_mrtgtraf.c index 8c7cf8aa..46b94f57 100644 --- a/plugins/check_mrtgtraf.c +++ b/plugins/check_mrtgtraf.c | |||
| @@ -29,14 +29,18 @@ | |||
| 29 | * | 29 | * |
| 30 | *****************************************************************************/ | 30 | *****************************************************************************/ |
| 31 | 31 | ||
| 32 | const char *progname = "check_mrtgtraf"; | ||
| 33 | const char *copyright = "1999-2024"; | ||
| 34 | const char *email = "devel@monitoring-plugins.org"; | ||
| 35 | |||
| 36 | #include "check_mrtgtraf.d/config.h" | 32 | #include "check_mrtgtraf.d/config.h" |
| 37 | #include "common.h" | 33 | #include "common.h" |
| 34 | #include "output.h" | ||
| 35 | #include "perfdata.h" | ||
| 36 | #include "states.h" | ||
| 37 | #include "thresholds.h" | ||
| 38 | #include "utils.h" | 38 | #include "utils.h" |
| 39 | 39 | ||
| 40 | const char *progname = "check_mrtgtraf"; | ||
| 41 | const char *copyright = "1999-2024"; | ||
| 42 | const char *email = "devel@monitoring-plugins.org"; | ||
| 43 | |||
| 40 | typedef struct { | 44 | typedef struct { |
| 41 | int errorcode; | 45 | int errorcode; |
| 42 | check_mrtgtraf_config config; | 46 | check_mrtgtraf_config config; |
| @@ -61,10 +65,24 @@ int main(int argc, char **argv) { | |||
| 61 | 65 | ||
| 62 | const check_mrtgtraf_config config = tmp_config.config; | 66 | const check_mrtgtraf_config config = tmp_config.config; |
| 63 | 67 | ||
| 68 | if (config.output_format_is_set) { | ||
| 69 | mp_set_format(config.output_format); | ||
| 70 | } | ||
| 71 | |||
| 72 | mp_check overall = mp_check_init(); | ||
| 73 | mp_subcheck sc_open_mrtg_log_file = mp_subcheck_init(); | ||
| 74 | |||
| 64 | /* open the MRTG log file for reading */ | 75 | /* open the MRTG log file for reading */ |
| 65 | FILE *mrtg_log_file_ptr = fopen(config.log_file, "r"); | 76 | FILE *mrtg_log_file_ptr = fopen(config.log_file, "r"); |
| 66 | if (mrtg_log_file_ptr == NULL) { | 77 | if (mrtg_log_file_ptr == NULL) { |
| 67 | usage4(_("Unable to open MRTG log file")); | 78 | sc_open_mrtg_log_file = mp_set_subcheck_state(sc_open_mrtg_log_file, STATE_UNKNOWN); |
| 79 | xasprintf(&sc_open_mrtg_log_file.output, "unable to open MRTG log file"); | ||
| 80 | mp_add_subcheck_to_check(&overall, sc_open_mrtg_log_file); | ||
| 81 | mp_exit(overall); | ||
| 82 | } else { | ||
| 83 | sc_open_mrtg_log_file = mp_set_subcheck_state(sc_open_mrtg_log_file, STATE_OK); | ||
| 84 | xasprintf(&sc_open_mrtg_log_file.output, "opened MRTG log file"); | ||
| 85 | mp_add_subcheck_to_check(&overall, sc_open_mrtg_log_file); | ||
| 68 | } | 86 | } |
| 69 | 87 | ||
| 70 | time_t timestamp = 0L; | 88 | time_t timestamp = 0L; |
| @@ -75,7 +93,6 @@ int main(int argc, char **argv) { | |||
| 75 | unsigned long maximum_outgoing_rate = 0L; | 93 | unsigned long maximum_outgoing_rate = 0L; |
| 76 | int line = 0; | 94 | int line = 0; |
| 77 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, mrtg_log_file_ptr)) { | 95 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, mrtg_log_file_ptr)) { |
| 78 | |||
| 79 | line++; | 96 | line++; |
| 80 | 97 | ||
| 81 | /* skip the first line of the log file */ | 98 | /* skip the first line of the log file */ |
| @@ -121,10 +138,20 @@ int main(int argc, char **argv) { | |||
| 121 | /* make sure the MRTG data isn't too old */ | 138 | /* make sure the MRTG data isn't too old */ |
| 122 | time_t current_time; | 139 | time_t current_time; |
| 123 | time(¤t_time); | 140 | time(¤t_time); |
| 141 | mp_subcheck sc_expired = mp_subcheck_init(); | ||
| 124 | if ((config.expire_minutes > 0) && (current_time - timestamp) > (config.expire_minutes * 60)) { | 142 | if ((config.expire_minutes > 0) && (current_time - timestamp) > (config.expire_minutes * 60)) { |
| 125 | die(STATE_WARNING, _("MRTG data has expired (%d minutes old)\n"), (int)((current_time - timestamp) / 60)); | 143 | xasprintf(&sc_expired.output, "MRTG data has expired (%d minutes old)", |
| 144 | (int)((current_time - timestamp) / 60)); | ||
| 145 | sc_expired = mp_set_subcheck_state(sc_expired, STATE_WARNING); | ||
| 146 | mp_add_subcheck_to_check(&overall, sc_expired); | ||
| 147 | mp_exit(overall); | ||
| 126 | } | 148 | } |
| 127 | 149 | ||
| 150 | xasprintf(&sc_expired.output, "MRTG data should be valid (%d minutes old)", | ||
| 151 | (int)((current_time - timestamp) / 60)); | ||
| 152 | sc_expired = mp_set_subcheck_state(sc_expired, STATE_WARNING); | ||
| 153 | mp_add_subcheck_to_check(&overall, sc_expired); | ||
| 154 | |||
| 128 | unsigned long incoming_rate = 0L; | 155 | unsigned long incoming_rate = 0L; |
| 129 | unsigned long outgoing_rate = 0L; | 156 | unsigned long outgoing_rate = 0L; |
| 130 | /* else check the incoming/outgoing rates */ | 157 | /* else check the incoming/outgoing rates */ |
| @@ -147,60 +174,72 @@ int main(int argc, char **argv) { | |||
| 147 | /* report incoming traffic in KBytes/sec */ | 174 | /* report incoming traffic in KBytes/sec */ |
| 148 | else if (incoming_rate < (1024 * 1024)) { | 175 | else if (incoming_rate < (1024 * 1024)) { |
| 149 | strcpy(incoming_speed_rating, "KB"); | 176 | strcpy(incoming_speed_rating, "KB"); |
| 150 | adjusted_incoming_rate = (double)(incoming_rate / 1024.0); | 177 | adjusted_incoming_rate = ((double)incoming_rate / 1024.0); |
| 151 | } | 178 | } |
| 152 | 179 | ||
| 153 | /* report incoming traffic in MBytes/sec */ | 180 | /* report incoming traffic in MBytes/sec */ |
| 154 | else { | 181 | else { |
| 155 | strcpy(incoming_speed_rating, "MB"); | 182 | strcpy(incoming_speed_rating, "MB"); |
| 156 | adjusted_incoming_rate = (double)(incoming_rate / 1024.0 / 1024.0); | 183 | adjusted_incoming_rate = ((double)incoming_rate / 1024.0 / 1024.0); |
| 157 | } | 184 | } |
| 158 | 185 | ||
| 159 | double adjusted_outgoing_rate = 0.0; | 186 | double adjusted_outgoing_rate = 0.0; |
| 160 | char outgoing_speed_rating[8]; | 187 | char outgoing_speed_rating[8]; |
| 161 | /* report outgoing traffic in Bytes/sec */ | ||
| 162 | if (outgoing_rate < 1024) { | 188 | if (outgoing_rate < 1024) { |
| 189 | /* report outgoing traffic in Bytes/sec */ | ||
| 163 | strcpy(outgoing_speed_rating, "B"); | 190 | strcpy(outgoing_speed_rating, "B"); |
| 164 | adjusted_outgoing_rate = (double)outgoing_rate; | 191 | adjusted_outgoing_rate = (double)outgoing_rate; |
| 165 | } | 192 | } else if (outgoing_rate < (1024 * 1024)) { |
| 166 | 193 | /* report outgoing traffic in KBytes/sec */ | |
| 167 | /* report outgoing traffic in KBytes/sec */ | ||
| 168 | else if (outgoing_rate < (1024 * 1024)) { | ||
| 169 | strcpy(outgoing_speed_rating, "KB"); | 194 | strcpy(outgoing_speed_rating, "KB"); |
| 170 | adjusted_outgoing_rate = (double)(outgoing_rate / 1024.0); | 195 | adjusted_outgoing_rate = ((double)outgoing_rate / 1024.0); |
| 171 | } | 196 | } else { |
| 172 | 197 | /* report outgoing traffic in MBytes/sec */ | |
| 173 | /* report outgoing traffic in MBytes/sec */ | ||
| 174 | else { | ||
| 175 | strcpy(outgoing_speed_rating, "MB"); | 198 | strcpy(outgoing_speed_rating, "MB"); |
| 176 | adjusted_outgoing_rate = (outgoing_rate / 1024.0 / 1024.0); | 199 | adjusted_outgoing_rate = ((double)outgoing_rate / 1024.0 / 1024.0); |
| 177 | } | ||
| 178 | |||
| 179 | int result = STATE_OK; | ||
| 180 | if (incoming_rate > config.incoming_critical_threshold || outgoing_rate > config.outgoing_critical_threshold) { | ||
| 181 | result = STATE_CRITICAL; | ||
| 182 | } else if (incoming_rate > config.incoming_warning_threshold || outgoing_rate > config.outgoing_warning_threshold) { | ||
| 183 | result = STATE_WARNING; | ||
| 184 | } | 200 | } |
| 185 | 201 | ||
| 186 | char *error_message; | 202 | mp_perfdata pd_rate_in = perfdata_init(); |
| 187 | xasprintf(&error_message, _("%s. In = %0.1f %s/s, %s. Out = %0.1f %s/s|%s %s\n"), (config.use_average) ? _("Avg") : _("Max"), | 203 | pd_rate_in.label = "in"; |
| 188 | adjusted_incoming_rate, incoming_speed_rating, (config.use_average) ? _("Avg") : _("Max"), adjusted_outgoing_rate, | 204 | pd_rate_in = mp_set_pd_value(pd_rate_in, incoming_rate); |
| 189 | outgoing_speed_rating, | 205 | pd_rate_in.uom = "B"; |
| 190 | fperfdata("in", adjusted_incoming_rate, incoming_speed_rating, (int)config.incoming_warning_threshold, | 206 | pd_rate_in = mp_pd_set_thresholds(pd_rate_in, config.incoming_thresholds); |
| 191 | config.incoming_warning_threshold, (int)config.incoming_critical_threshold, config.incoming_critical_threshold, | 207 | |
| 192 | true, 0, false, 0), | 208 | mp_perfdata pd_rate_out = perfdata_init(); |
| 193 | fperfdata("out", adjusted_outgoing_rate, outgoing_speed_rating, (int)config.outgoing_warning_threshold, | 209 | pd_rate_out.label = "out"; |
| 194 | config.outgoing_warning_threshold, (int)config.outgoing_critical_threshold, config.outgoing_critical_threshold, | 210 | pd_rate_out = mp_set_pd_value(pd_rate_out, outgoing_rate); |
| 195 | true, 0, false, 0)); | 211 | pd_rate_out.uom = "B"; |
| 196 | 212 | pd_rate_out = mp_pd_set_thresholds(pd_rate_out, config.outgoing_thresholds); | |
| 197 | printf(_("Traffic %s - %s\n"), state_text(result), error_message); | 213 | |
| 198 | 214 | mp_subcheck sc_rate_in = mp_subcheck_init(); | |
| 199 | return result; | 215 | sc_rate_in = mp_set_subcheck_state(sc_rate_in, mp_get_pd_status(pd_rate_in)); |
| 216 | mp_add_perfdata_to_subcheck(&sc_rate_in, pd_rate_in); | ||
| 217 | xasprintf(&sc_rate_in.output, "%s. In = %0.1f %s/s", (config.use_average) ? _("Avg") : _("Max"), | ||
| 218 | adjusted_incoming_rate, incoming_speed_rating); | ||
| 219 | |||
| 220 | mp_subcheck sc_rate_out = mp_subcheck_init(); | ||
| 221 | sc_rate_out = mp_set_subcheck_state(sc_rate_out, mp_get_pd_status(pd_rate_out)); | ||
| 222 | mp_add_perfdata_to_subcheck(&sc_rate_out, pd_rate_out); | ||
| 223 | xasprintf(&sc_rate_out.output, "%s. Out = %0.1f %s/s", | ||
| 224 | (config.use_average) ? _("Avg") : _("Max"), adjusted_outgoing_rate, | ||
| 225 | outgoing_speed_rating); | ||
| 226 | |||
| 227 | mp_subcheck sc_rate = mp_subcheck_init(); | ||
| 228 | xasprintf(&sc_rate.output, "Traffic"); | ||
| 229 | mp_add_subcheck_to_subcheck(&sc_rate, sc_rate_in); | ||
| 230 | mp_add_subcheck_to_subcheck(&sc_rate, sc_rate_out); | ||
| 231 | |||
| 232 | mp_add_subcheck_to_check(&overall, sc_rate); | ||
| 233 | |||
| 234 | mp_exit(overall); | ||
| 200 | } | 235 | } |
| 201 | 236 | ||
| 202 | /* process command-line arguments */ | 237 | /* process command-line arguments */ |
| 203 | check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { | 238 | check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { |
| 239 | enum { | ||
| 240 | output_format_index = CHAR_MAX + 1, | ||
| 241 | }; | ||
| 242 | |||
| 204 | static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, | 243 | static struct option longopts[] = {{"filename", required_argument, 0, 'F'}, |
| 205 | {"expires", required_argument, 0, 'e'}, | 244 | {"expires", required_argument, 0, 'e'}, |
| 206 | {"aggregation", required_argument, 0, 'a'}, | 245 | {"aggregation", required_argument, 0, 'a'}, |
| @@ -208,6 +247,7 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { | |||
| 208 | {"warning", required_argument, 0, 'w'}, | 247 | {"warning", required_argument, 0, 'w'}, |
| 209 | {"version", no_argument, 0, 'V'}, | 248 | {"version", no_argument, 0, 'V'}, |
| 210 | {"help", no_argument, 0, 'h'}, | 249 | {"help", no_argument, 0, 'h'}, |
| 250 | {"output-format", required_argument, 0, output_format_index}, | ||
| 211 | {0, 0, 0, 0}}; | 251 | {0, 0, 0, 0}}; |
| 212 | 252 | ||
| 213 | check_mrtgtraf_config_wrapper result = { | 253 | check_mrtgtraf_config_wrapper result = { |
| @@ -231,6 +271,14 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { | |||
| 231 | 271 | ||
| 232 | int option_char; | 272 | int option_char; |
| 233 | int option = 0; | 273 | int option = 0; |
| 274 | unsigned long incoming_warning_threshold = 0; | ||
| 275 | unsigned long incoming_critical_threshold = 0; | ||
| 276 | unsigned long outgoing_warning_threshold = 0; | ||
| 277 | unsigned long outgoing_critical_threshold = 0; | ||
| 278 | bool incoming_warning_set = false; | ||
| 279 | bool incoming_critical_set = false; | ||
| 280 | bool outgoing_warning_set = false; | ||
| 281 | bool outgoing_critical_set = false; | ||
| 234 | while (true) { | 282 | while (true) { |
| 235 | option_char = getopt_long(argc, argv, "hVF:e:a:c:w:", longopts, &option); | 283 | option_char = getopt_long(argc, argv, "hVF:e:a:c:w:", longopts, &option); |
| 236 | 284 | ||
| @@ -248,11 +296,15 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { | |||
| 248 | case 'a': /* aggregation (AVE or MAX) */ | 296 | case 'a': /* aggregation (AVE or MAX) */ |
| 249 | result.config.use_average = (bool)(strcmp(optarg, "MAX")); | 297 | result.config.use_average = (bool)(strcmp(optarg, "MAX")); |
| 250 | break; | 298 | break; |
| 251 | case 'c': /* warning threshold */ | 299 | case 'c': /* critical threshold */ |
| 252 | sscanf(optarg, "%lu,%lu", &result.config.incoming_critical_threshold, &result.config.outgoing_critical_threshold); | 300 | sscanf(optarg, "%lu,%lu", &incoming_critical_threshold, &outgoing_critical_threshold); |
| 301 | incoming_critical_set = true; | ||
| 302 | outgoing_critical_set = true; | ||
| 253 | break; | 303 | break; |
| 254 | case 'w': /* critical threshold */ | 304 | case 'w': /* warning threshold */ |
| 255 | sscanf(optarg, "%lu,%lu", &result.config.incoming_warning_threshold, &result.config.outgoing_warning_threshold); | 305 | sscanf(optarg, "%lu,%lu", &incoming_warning_threshold, &outgoing_warning_threshold); |
| 306 | incoming_warning_set = true; | ||
| 307 | incoming_critical_set = true; | ||
| 256 | break; | 308 | break; |
| 257 | case 'V': /* version */ | 309 | case 'V': /* version */ |
| 258 | print_revision(progname, NP_VERSION); | 310 | print_revision(progname, NP_VERSION); |
| @@ -262,6 +314,17 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { | |||
| 262 | exit(STATE_UNKNOWN); | 314 | exit(STATE_UNKNOWN); |
| 263 | case '?': /* help */ | 315 | case '?': /* help */ |
| 264 | usage5(); | 316 | usage5(); |
| 317 | case output_format_index: { | ||
| 318 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 319 | if (!parser.parsing_success) { | ||
| 320 | printf("Invalid output format: %s\n", optarg); | ||
| 321 | exit(STATE_UNKNOWN); | ||
| 322 | } | ||
| 323 | |||
| 324 | result.config.output_format_is_set = true; | ||
| 325 | result.config.output_format = parser.output_format; | ||
| 326 | break; | ||
| 327 | } | ||
| 265 | } | 328 | } |
| 266 | } | 329 | } |
| 267 | 330 | ||
| @@ -282,22 +345,62 @@ check_mrtgtraf_config_wrapper process_arguments(int argc, char **argv) { | |||
| 282 | option_char++; | 345 | option_char++; |
| 283 | } | 346 | } |
| 284 | 347 | ||
| 285 | if (argc > option_char && result.config.incoming_warning_threshold == 0) { | 348 | if (argc > option_char && incoming_warning_threshold == 0) { |
| 286 | result.config.incoming_warning_threshold = strtoul(argv[option_char++], NULL, 10); | 349 | incoming_warning_threshold = strtoul(argv[option_char++], NULL, 10); |
| 350 | incoming_warning_set = true; | ||
| 287 | } | 351 | } |
| 288 | 352 | ||
| 289 | if (argc > option_char && result.config.incoming_critical_threshold == 0) { | 353 | if (argc > option_char && incoming_critical_threshold == 0) { |
| 290 | result.config.incoming_critical_threshold = strtoul(argv[option_char++], NULL, 10); | 354 | incoming_critical_threshold = strtoul(argv[option_char++], NULL, 10); |
| 355 | incoming_critical_set = true; | ||
| 291 | } | 356 | } |
| 292 | 357 | ||
| 293 | if (argc > option_char && result.config.outgoing_warning_threshold == 0) { | 358 | if (argc > option_char && outgoing_warning_threshold == 0) { |
| 294 | result.config.outgoing_warning_threshold = strtoul(argv[option_char++], NULL, 10); | 359 | outgoing_warning_threshold = strtoul(argv[option_char++], NULL, 10); |
| 360 | outgoing_warning_set = true; | ||
| 295 | } | 361 | } |
| 296 | 362 | ||
| 297 | if (argc > option_char && result.config.outgoing_critical_threshold == 0) { | 363 | if (argc > option_char && outgoing_critical_threshold == 0) { |
| 298 | result.config.outgoing_critical_threshold = strtoul(argv[option_char++], NULL, 10); | 364 | outgoing_critical_threshold = strtoul(argv[option_char++], NULL, 10); |
| 365 | outgoing_critical_set = true; | ||
| 299 | } | 366 | } |
| 300 | 367 | ||
| 368 | mp_range incoming_warning = mp_range_init(); | ||
| 369 | if (incoming_warning_set) { | ||
| 370 | incoming_warning = | ||
| 371 | mp_range_set_end(incoming_warning, mp_create_pd_value(incoming_warning_threshold)); | ||
| 372 | } | ||
| 373 | |||
| 374 | result.config.incoming_thresholds = | ||
| 375 | mp_thresholds_set_warn(result.config.incoming_thresholds, incoming_warning); | ||
| 376 | |||
| 377 | mp_range incoming_critical = mp_range_init(); | ||
| 378 | if (incoming_critical_set) { | ||
| 379 | incoming_critical = | ||
| 380 | mp_range_set_end(incoming_critical, mp_create_pd_value(incoming_critical_threshold)); | ||
| 381 | } | ||
| 382 | |||
| 383 | result.config.incoming_thresholds = | ||
| 384 | mp_thresholds_set_crit(result.config.incoming_thresholds, incoming_critical); | ||
| 385 | |||
| 386 | mp_range outgoing_warning = mp_range_init(); | ||
| 387 | if (outgoing_warning_set) { | ||
| 388 | outgoing_warning = | ||
| 389 | mp_range_set_end(outgoing_warning, mp_create_pd_value(outgoing_warning_threshold)); | ||
| 390 | } | ||
| 391 | |||
| 392 | result.config.outgoing_thresholds = | ||
| 393 | mp_thresholds_set_warn(result.config.outgoing_thresholds, outgoing_warning); | ||
| 394 | |||
| 395 | mp_range outgoing_critical = mp_range_init(); | ||
| 396 | if (outgoing_critical_set) { | ||
| 397 | outgoing_critical = | ||
| 398 | mp_range_set_end(outgoing_critical, mp_create_pd_value(outgoing_critical_threshold)); | ||
| 399 | } | ||
| 400 | |||
| 401 | result.config.outgoing_thresholds = | ||
| 402 | mp_thresholds_set_crit(result.config.outgoing_thresholds, outgoing_critical); | ||
| 403 | |||
| 301 | return result; | 404 | return result; |
| 302 | } | 405 | } |
| 303 | 406 | ||
| @@ -332,6 +435,8 @@ void print_help(void) { | |||
| 332 | printf(" %s\n", "-c, --critical"); | 435 | printf(" %s\n", "-c, --critical"); |
| 333 | printf(" %s\n", _("Critical threshold pair <incoming>,<outgoing>")); | 436 | printf(" %s\n", _("Critical threshold pair <incoming>,<outgoing>")); |
| 334 | 437 | ||
| 438 | printf(UT_OUTPUT_FORMAT); | ||
| 439 | |||
| 335 | printf("\n"); | 440 | printf("\n"); |
| 336 | printf("%s\n", _("Notes:")); | 441 | printf("%s\n", _("Notes:")); |
| 337 | printf(" %s\n", _("- MRTG stands for Multi Router Traffic Grapher. It can be downloaded from")); | 442 | printf(" %s\n", _("- MRTG stands for Multi Router Traffic Grapher. It can be downloaded from")); |
diff --git a/plugins/check_mrtgtraf.d/config.h b/plugins/check_mrtgtraf.d/config.h index 94929ff7..d9737243 100644 --- a/plugins/check_mrtgtraf.d/config.h +++ b/plugins/check_mrtgtraf.d/config.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "output.h" | ||
| 5 | #include "thresholds.h" | ||
| 4 | #include <stddef.h> | 6 | #include <stddef.h> |
| 5 | #include <stdlib.h> | 7 | #include <stdlib.h> |
| 6 | 8 | ||
| @@ -8,11 +10,12 @@ typedef struct { | |||
| 8 | char *log_file; | 10 | char *log_file; |
| 9 | int expire_minutes; | 11 | int expire_minutes; |
| 10 | bool use_average; | 12 | bool use_average; |
| 11 | unsigned long incoming_warning_threshold; | ||
| 12 | unsigned long incoming_critical_threshold; | ||
| 13 | unsigned long outgoing_warning_threshold; | ||
| 14 | unsigned long outgoing_critical_threshold; | ||
| 15 | 13 | ||
| 14 | mp_thresholds incoming_thresholds; | ||
| 15 | mp_thresholds outgoing_thresholds; | ||
| 16 | |||
| 17 | bool output_format_is_set; | ||
| 18 | mp_output_format output_format; | ||
| 16 | } check_mrtgtraf_config; | 19 | } check_mrtgtraf_config; |
| 17 | 20 | ||
| 18 | check_mrtgtraf_config check_mrtgtraf_config_init() { | 21 | check_mrtgtraf_config check_mrtgtraf_config_init() { |
| @@ -21,10 +24,10 @@ check_mrtgtraf_config check_mrtgtraf_config_init() { | |||
| 21 | .expire_minutes = -1, | 24 | .expire_minutes = -1, |
| 22 | .use_average = true, | 25 | .use_average = true, |
| 23 | 26 | ||
| 24 | .incoming_warning_threshold = 0, | 27 | .incoming_thresholds = mp_thresholds_init(), |
| 25 | .incoming_critical_threshold = 0, | 28 | .outgoing_thresholds = mp_thresholds_init(), |
| 26 | .outgoing_warning_threshold = 0, | 29 | |
| 27 | .outgoing_critical_threshold = 0, | 30 | .output_format_is_set = false, |
| 28 | }; | 31 | }; |
| 29 | return tmp; | 32 | return tmp; |
| 30 | } | 33 | } |
diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c index ca3422b5..26730d4c 100644 --- a/plugins/check_mysql.c +++ b/plugins/check_mysql.c | |||
| @@ -30,13 +30,11 @@ | |||
| 30 | * | 30 | * |
| 31 | *****************************************************************************/ | 31 | *****************************************************************************/ |
| 32 | 32 | ||
| 33 | const char *progname = "check_mysql"; | ||
| 34 | const char *copyright = "1999-2024"; | ||
| 35 | const char *email = "devel@monitoring-plugins.org"; | ||
| 36 | |||
| 37 | #define REPLICA_RESULTSIZE 96 | ||
| 38 | |||
| 39 | #include "common.h" | 33 | #include "common.h" |
| 34 | #include "output.h" | ||
| 35 | #include "perfdata.h" | ||
| 36 | #include "states.h" | ||
| 37 | #include "thresholds.h" | ||
| 40 | #include "utils.h" | 38 | #include "utils.h" |
| 41 | #include "utils_base.h" | 39 | #include "utils_base.h" |
| 42 | #include "netutils.h" | 40 | #include "netutils.h" |
| @@ -46,19 +44,33 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 46 | #include <mysqld_error.h> | 44 | #include <mysqld_error.h> |
| 47 | #include <errmsg.h> | 45 | #include <errmsg.h> |
| 48 | 46 | ||
| 47 | const char *progname = "check_mysql"; | ||
| 48 | const char *copyright = "1999-2024"; | ||
| 49 | const char *email = "devel@monitoring-plugins.org"; | ||
| 50 | |||
| 49 | static int verbose = 0; | 51 | static int verbose = 0; |
| 50 | 52 | ||
| 53 | #define REPLICA_RESULTSIZE 96 | ||
| 54 | |||
| 51 | #define LENGTH_METRIC_UNIT 6 | 55 | #define LENGTH_METRIC_UNIT 6 |
| 52 | static const char *metric_unit[LENGTH_METRIC_UNIT] = { | 56 | static const char *metric_unit[LENGTH_METRIC_UNIT] = { |
| 53 | "Open_files", "Open_tables", "Qcache_free_memory", "Qcache_queries_in_cache", "Threads_connected", "Threads_running"}; | 57 | "Open_files", "Open_tables", "Qcache_free_memory", "Qcache_queries_in_cache", |
| 58 | "Threads_connected", "Threads_running"}; | ||
| 54 | 59 | ||
| 55 | #define LENGTH_METRIC_COUNTER 9 | 60 | #define LENGTH_METRIC_COUNTER 9 |
| 56 | static const char *metric_counter[LENGTH_METRIC_COUNTER] = { | 61 | static const char *metric_counter[LENGTH_METRIC_COUNTER] = {"Connections", |
| 57 | "Connections", "Qcache_hits", "Qcache_inserts", "Qcache_lowmem_prunes", "Qcache_not_cached", "Queries", | 62 | "Qcache_hits", |
| 58 | "Questions", "Table_locks_waited", "Uptime"}; | 63 | "Qcache_inserts", |
| 59 | 64 | "Qcache_lowmem_prunes", | |
| 60 | #define MYSQLDUMP_THREADS_QUERY \ | 65 | "Qcache_not_cached", |
| 61 | "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE 'SELECT /*!40001 SQL_NO_CACHE */%'" | 66 | "Queries", |
| 67 | "Questions", | ||
| 68 | "Table_locks_waited", | ||
| 69 | "Uptime"}; | ||
| 70 | |||
| 71 | #define MYSQLDUMP_THREADS_QUERY \ | ||
| 72 | "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE " \ | ||
| 73 | "'SELECT /*!40001 SQL_NO_CACHE */%'" | ||
| 62 | 74 | ||
| 63 | typedef struct { | 75 | typedef struct { |
| 64 | int errorcode; | 76 | int errorcode; |
| @@ -84,6 +96,10 @@ int main(int argc, char **argv) { | |||
| 84 | 96 | ||
| 85 | const check_mysql_config config = tmp_config.config; | 97 | const check_mysql_config config = tmp_config.config; |
| 86 | 98 | ||
| 99 | if (config.output_format_is_set) { | ||
| 100 | mp_set_format(config.output_format); | ||
| 101 | } | ||
| 102 | |||
| 87 | MYSQL mysql; | 103 | MYSQL mysql; |
| 88 | /* initialize mysql */ | 104 | /* initialize mysql */ |
| 89 | mysql_init(&mysql); | 105 | mysql_init(&mysql); |
| @@ -99,82 +115,130 @@ int main(int argc, char **argv) { | |||
| 99 | } | 115 | } |
| 100 | 116 | ||
| 101 | if (config.ssl) { | 117 | if (config.ssl) { |
| 102 | mysql_ssl_set(&mysql, config.key, config.cert, config.ca_cert, config.ca_dir, config.ciphers); | 118 | mysql_ssl_set(&mysql, config.key, config.cert, config.ca_cert, config.ca_dir, |
| 119 | config.ciphers); | ||
| 103 | } | 120 | } |
| 104 | /* establish a connection to the server and error checking */ | 121 | |
| 105 | if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, config.db_port, config.db_socket, 0)) { | 122 | mp_check overall = mp_check_init(); |
| 123 | |||
| 124 | mp_subcheck sc_connection = mp_subcheck_init(); | ||
| 125 | /* establish a connection to the server and check for errors */ | ||
| 126 | if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, | ||
| 127 | config.db_port, config.db_socket, 0)) { | ||
| 106 | /* Depending on internally-selected auth plugin MySQL might return */ | 128 | /* Depending on internally-selected auth plugin MySQL might return */ |
| 107 | /* ER_ACCESS_DENIED_NO_PASSWORD_ERROR or ER_ACCESS_DENIED_ERROR. */ | 129 | /* ER_ACCESS_DENIED_NO_PASSWORD_ERROR or ER_ACCESS_DENIED_ERROR. */ |
| 108 | /* Semantically these errors are the same. */ | 130 | /* Semantically these errors are the same. */ |
| 109 | if (config.ignore_auth && | 131 | if (config.ignore_auth && (mysql_errno(&mysql) == ER_ACCESS_DENIED_ERROR || |
| 110 | (mysql_errno(&mysql) == ER_ACCESS_DENIED_ERROR || mysql_errno(&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) { | 132 | mysql_errno(&mysql) == ER_ACCESS_DENIED_NO_PASSWORD_ERROR)) { |
| 111 | printf("MySQL OK - Version: %s (protocol %d)\n", mysql_get_server_info(&mysql), mysql_get_proto_info(&mysql)); | 133 | xasprintf(&sc_connection.output, "Version: %s (protocol %d)", |
| 112 | mysql_close(&mysql); | 134 | mysql_get_server_info(&mysql), mysql_get_proto_info(&mysql)); |
| 113 | return STATE_OK; | 135 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_OK); |
| 114 | } | ||
| 115 | 136 | ||
| 116 | if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { | 137 | mysql_close(&mysql); |
| 117 | die(STATE_WARNING, "%s\n", mysql_error(&mysql)); | ||
| 118 | } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { | ||
| 119 | die(STATE_WARNING, "%s\n", mysql_error(&mysql)); | ||
| 120 | } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) { | ||
| 121 | die(STATE_WARNING, "%s\n", mysql_error(&mysql)); | ||
| 122 | } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) { | ||
| 123 | die(STATE_WARNING, "%s\n", mysql_error(&mysql)); | ||
| 124 | } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) { | ||
| 125 | die(STATE_WARNING, "%s\n", mysql_error(&mysql)); | ||
| 126 | } else { | 138 | } else { |
| 127 | die(STATE_CRITICAL, "%s\n", mysql_error(&mysql)); | 139 | if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { |
| 140 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_WARNING); | ||
| 141 | xasprintf(&sc_connection.output, "%s", mysql_error(&mysql)); | ||
| 142 | } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { | ||
| 143 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_WARNING); | ||
| 144 | xasprintf(&sc_connection.output, "%s", mysql_error(&mysql)); | ||
| 145 | } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) { | ||
| 146 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_WARNING); | ||
| 147 | xasprintf(&sc_connection.output, "%s", mysql_error(&mysql)); | ||
| 148 | } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) { | ||
| 149 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_WARNING); | ||
| 150 | xasprintf(&sc_connection.output, "%s", mysql_error(&mysql)); | ||
| 151 | } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) { | ||
| 152 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_WARNING); | ||
| 153 | xasprintf(&sc_connection.output, "%s", mysql_error(&mysql)); | ||
| 154 | } else { | ||
| 155 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_CRITICAL); | ||
| 156 | xasprintf(&sc_connection.output, "%s", mysql_error(&mysql)); | ||
| 157 | } | ||
| 128 | } | 158 | } |
| 159 | |||
| 160 | mp_add_subcheck_to_check(&overall, sc_connection); | ||
| 161 | mp_exit(overall); | ||
| 162 | } else { | ||
| 163 | // successful connection | ||
| 164 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_OK); | ||
| 165 | xasprintf(&sc_connection.output, "Version: %s (protocol %d)", mysql_get_server_info(&mysql), | ||
| 166 | mysql_get_proto_info(&mysql)); | ||
| 167 | mp_add_subcheck_to_check(&overall, sc_connection); | ||
| 129 | } | 168 | } |
| 130 | 169 | ||
| 131 | /* get the server stats */ | 170 | /* get the server stats */ |
| 132 | char *result = strdup(mysql_stat(&mysql)); | 171 | char *mysql_stats = strdup(mysql_stat(&mysql)); |
| 172 | |||
| 173 | mp_subcheck sc_stats = mp_subcheck_init(); | ||
| 174 | sc_stats = mp_set_subcheck_default_state(sc_stats, STATE_OK); | ||
| 133 | 175 | ||
| 134 | /* error checking once more */ | 176 | /* error checking once more */ |
| 135 | if (mysql_error(&mysql)) { | 177 | if (mysql_errno(&mysql) != 0) { |
| 136 | if (mysql_errno(&mysql) == CR_SERVER_GONE_ERROR) { | 178 | if ((mysql_errno(&mysql) == CR_SERVER_GONE_ERROR) || |
| 137 | die(STATE_CRITICAL, "%s\n", mysql_error(&mysql)); | 179 | (mysql_errno(&mysql) == CR_SERVER_LOST) || (mysql_errno(&mysql) == CR_UNKNOWN_ERROR)) { |
| 138 | } else if (mysql_errno(&mysql) == CR_SERVER_LOST) { | 180 | sc_stats = mp_set_subcheck_state(sc_stats, STATE_CRITICAL); |
| 139 | die(STATE_CRITICAL, "%s\n", mysql_error(&mysql)); | 181 | xasprintf(&sc_stats.output, "Retrieving stats failed: %s", mysql_error(&mysql)); |
| 140 | } else if (mysql_errno(&mysql) == CR_UNKNOWN_ERROR) { | 182 | } else { |
| 141 | die(STATE_CRITICAL, "%s\n", mysql_error(&mysql)); | 183 | // not sure which error modes occur here, but mysql_error indicates an error |
| 184 | sc_stats = mp_set_subcheck_state(sc_stats, STATE_WARNING); | ||
| 185 | xasprintf(&sc_stats.output, "retrieving stats caused an error: %s", | ||
| 186 | mysql_error(&mysql)); | ||
| 142 | } | 187 | } |
| 188 | |||
| 189 | mp_add_subcheck_to_check(&overall, sc_stats); | ||
| 190 | mp_exit(overall); | ||
| 191 | } else { | ||
| 192 | xasprintf(&sc_stats.output, "retrieved stats: %s", mysql_stats); | ||
| 193 | sc_stats = mp_set_subcheck_state(sc_stats, STATE_OK); | ||
| 194 | mp_add_subcheck_to_check(&overall, sc_stats); | ||
| 143 | } | 195 | } |
| 144 | 196 | ||
| 145 | char *perf = strdup(""); | ||
| 146 | char *error = NULL; | ||
| 147 | MYSQL_RES *res; | 197 | MYSQL_RES *res; |
| 148 | MYSQL_ROW row; | 198 | MYSQL_ROW row; |
| 199 | mp_subcheck sc_query = mp_subcheck_init(); | ||
| 149 | /* try to fetch some perf data */ | 200 | /* try to fetch some perf data */ |
| 150 | if (mysql_query(&mysql, "show global status") == 0) { | 201 | if (mysql_query(&mysql, "show global status") == 0) { |
| 151 | if ((res = mysql_store_result(&mysql)) == NULL) { | 202 | if ((res = mysql_store_result(&mysql)) == NULL) { |
| 152 | error = strdup(mysql_error(&mysql)); | 203 | xasprintf(&sc_connection.output, "query failed - status store_result error: %s", |
| 204 | mysql_error(&mysql)); | ||
| 153 | mysql_close(&mysql); | 205 | mysql_close(&mysql); |
| 154 | die(STATE_CRITICAL, _("status store_result error: %s\n"), error); | 206 | |
| 207 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | ||
| 208 | mp_add_subcheck_to_check(&overall, sc_query); | ||
| 209 | mp_exit(overall); | ||
| 155 | } | 210 | } |
| 156 | 211 | ||
| 157 | while ((row = mysql_fetch_row(res)) != NULL) { | 212 | while ((row = mysql_fetch_row(res)) != NULL) { |
| 158 | for (int i = 0; i < LENGTH_METRIC_UNIT; i++) { | 213 | for (int i = 0; i < LENGTH_METRIC_UNIT; i++) { |
| 159 | if (strcmp(row[0], metric_unit[i]) == 0) { | 214 | if (strcmp(row[0], metric_unit[i]) == 0) { |
| 160 | xasprintf(&perf, "%s%s ", perf, perfdata(metric_unit[i], atol(row[1]), "", false, 0, false, 0, false, 0, false, 0)); | 215 | mp_perfdata pd_mysql_stat = perfdata_init(); |
| 216 | pd_mysql_stat.label = (char *)metric_unit[i]; | ||
| 217 | pd_mysql_stat.value = mp_create_pd_value(atol(row[1])); | ||
| 218 | mp_add_perfdata_to_subcheck(&sc_stats, pd_mysql_stat); | ||
| 161 | continue; | 219 | continue; |
| 162 | } | 220 | } |
| 163 | } | 221 | } |
| 222 | |||
| 164 | for (int i = 0; i < LENGTH_METRIC_COUNTER; i++) { | 223 | for (int i = 0; i < LENGTH_METRIC_COUNTER; i++) { |
| 165 | if (strcmp(row[0], metric_counter[i]) == 0) { | 224 | if (strcmp(row[0], metric_counter[i]) == 0) { |
| 166 | xasprintf(&perf, "%s%s ", perf, perfdata(metric_counter[i], atol(row[1]), "c", false, 0, false, 0, false, 0, false, 0)); | 225 | mp_perfdata pd_mysql_stat = perfdata_init(); |
| 226 | pd_mysql_stat.label = (char *)metric_counter[i]; | ||
| 227 | pd_mysql_stat.value = mp_create_pd_value(atol(row[1])); | ||
| 228 | pd_mysql_stat.uom = "c"; | ||
| 229 | mp_add_perfdata_to_subcheck(&sc_stats, pd_mysql_stat); | ||
| 167 | continue; | 230 | continue; |
| 168 | } | 231 | } |
| 169 | } | 232 | } |
| 170 | } | 233 | } |
| 171 | /* remove trailing space */ | 234 | } else { |
| 172 | if (strlen(perf) > 0) { | 235 | // Query failed! |
| 173 | perf[strlen(perf) - 1] = '\0'; | 236 | xasprintf(&sc_connection.output, "query failed"); |
| 174 | } | 237 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); |
| 238 | mp_add_subcheck_to_check(&overall, sc_query); | ||
| 239 | mp_exit(overall); | ||
| 175 | } | 240 | } |
| 176 | 241 | ||
| 177 | char replica_result[REPLICA_RESULTSIZE] = {0}; | ||
| 178 | if (config.check_replica) { | 242 | if (config.check_replica) { |
| 179 | // Detect which version we are, on older version | 243 | // Detect which version we are, on older version |
| 180 | // "show slave status" should work, on newer ones | 244 | // "show slave status" should work, on newer ones |
| @@ -188,9 +252,11 @@ int main(int argc, char **argv) { | |||
| 188 | unsigned long major_version = server_verion_int / 10000; | 252 | unsigned long major_version = server_verion_int / 10000; |
| 189 | unsigned long minor_version = (server_verion_int % 10000) / 100; | 253 | unsigned long minor_version = (server_verion_int % 10000) / 100; |
| 190 | unsigned long patch_version = (server_verion_int % 100); | 254 | unsigned long patch_version = (server_verion_int % 100); |
| 255 | |||
| 191 | if (verbose) { | 256 | if (verbose) { |
| 192 | printf("Found MariaDB: %s, main version: %lu, minor version: %lu, patch version: %lu\n", server_version, major_version, | 257 | printf("Found MariaDB/MySQL: %s, main version: %lu, minor version: %lu, patch version: " |
| 193 | minor_version, patch_version); | 258 | "%lu\n", |
| 259 | server_version, major_version, minor_version, patch_version); | ||
| 194 | } | 260 | } |
| 195 | 261 | ||
| 196 | if (strstr(server_version, "MariaDB") != NULL) { | 262 | if (strstr(server_version, "MariaDB") != NULL) { |
| @@ -204,16 +270,13 @@ int main(int argc, char **argv) { | |||
| 204 | use_deprecated_slave_status = true; | 270 | use_deprecated_slave_status = true; |
| 205 | } | 271 | } |
| 206 | } | 272 | } |
| 207 | } else if (strstr(server_version, "MySQL") != NULL) { | 273 | } else { |
| 208 | // Looks like MySQL | 274 | // Looks like MySQL or at least not like MariaDB |
| 209 | if (major_version < 8) { | 275 | if (major_version < 8) { |
| 210 | use_deprecated_slave_status = true; | 276 | use_deprecated_slave_status = true; |
| 211 | } else if (major_version == 10 && minor_version < 4) { | 277 | } else if (major_version == 10 && minor_version < 4) { |
| 212 | use_deprecated_slave_status = true; | 278 | use_deprecated_slave_status = true; |
| 213 | } | 279 | } |
| 214 | } else { | ||
| 215 | printf("Not a known sever implementation: %s\n", server_version); | ||
| 216 | exit(STATE_UNKNOWN); | ||
| 217 | } | 280 | } |
| 218 | 281 | ||
| 219 | char *replica_query = NULL; | 282 | char *replica_query = NULL; |
| @@ -223,62 +286,80 @@ int main(int argc, char **argv) { | |||
| 223 | replica_query = "show replica status"; | 286 | replica_query = "show replica status"; |
| 224 | } | 287 | } |
| 225 | 288 | ||
| 289 | mp_subcheck sc_replica = mp_subcheck_init(); | ||
| 290 | |||
| 226 | /* check the replica status */ | 291 | /* check the replica status */ |
| 227 | if (mysql_query(&mysql, replica_query) != 0) { | 292 | if (mysql_query(&mysql, replica_query) != 0) { |
| 228 | error = strdup(mysql_error(&mysql)); | 293 | xasprintf(&sc_replica.output, "replica query error: %s", mysql_error(&mysql)); |
| 229 | mysql_close(&mysql); | 294 | mysql_close(&mysql); |
| 230 | die(STATE_CRITICAL, _("replica query error: %s\n"), error); | 295 | |
| 296 | sc_replica = mp_set_subcheck_state(sc_replica, STATE_CRITICAL); | ||
| 297 | mp_add_subcheck_to_check(&overall, sc_replica); | ||
| 298 | mp_exit(overall); | ||
| 231 | } | 299 | } |
| 232 | 300 | ||
| 233 | /* store the result */ | 301 | /* store the result */ |
| 234 | if ((res = mysql_store_result(&mysql)) == NULL) { | 302 | if ((res = mysql_store_result(&mysql)) == NULL) { |
| 235 | error = strdup(mysql_error(&mysql)); | 303 | xasprintf(&sc_replica.output, "replica store_result error: %s", mysql_error(&mysql)); |
| 236 | mysql_close(&mysql); | 304 | mysql_close(&mysql); |
| 237 | die(STATE_CRITICAL, _("replica store_result error: %s\n"), error); | 305 | |
| 306 | sc_replica = mp_set_subcheck_state(sc_replica, STATE_CRITICAL); | ||
| 307 | mp_add_subcheck_to_check(&overall, sc_replica); | ||
| 308 | mp_exit(overall); | ||
| 238 | } | 309 | } |
| 239 | 310 | ||
| 240 | /* Check there is some data */ | 311 | /* Check there is some data */ |
| 241 | if (mysql_num_rows(res) == 0) { | 312 | if (mysql_num_rows(res) == 0) { |
| 242 | mysql_close(&mysql); | 313 | mysql_close(&mysql); |
| 243 | die(STATE_WARNING, "%s\n", _("No replicas defined")); | 314 | |
| 315 | xasprintf(&sc_replica.output, "no replicas defined"); | ||
| 316 | sc_replica = mp_set_subcheck_state(sc_replica, STATE_WARNING); | ||
| 317 | mp_add_subcheck_to_check(&overall, sc_replica); | ||
| 318 | mp_exit(overall); | ||
| 244 | } | 319 | } |
| 245 | 320 | ||
| 246 | /* fetch the first row */ | 321 | /* fetch the first row */ |
| 247 | if ((row = mysql_fetch_row(res)) == NULL) { | 322 | if ((row = mysql_fetch_row(res)) == NULL) { |
| 248 | error = strdup(mysql_error(&mysql)); | 323 | xasprintf(&sc_replica.output, "replica fetch row error: %s", mysql_error(&mysql)); |
| 249 | mysql_free_result(res); | 324 | mysql_free_result(res); |
| 250 | mysql_close(&mysql); | 325 | mysql_close(&mysql); |
| 251 | die(STATE_CRITICAL, _("replica fetch row error: %s\n"), error); | 326 | |
| 327 | sc_replica = mp_set_subcheck_state(sc_replica, STATE_CRITICAL); | ||
| 328 | mp_add_subcheck_to_check(&overall, sc_replica); | ||
| 329 | mp_exit(overall); | ||
| 252 | } | 330 | } |
| 253 | 331 | ||
| 254 | if (mysql_field_count(&mysql) == 12) { | 332 | if (mysql_field_count(&mysql) == 12) { |
| 255 | /* mysql 3.23.x */ | 333 | /* mysql 3.23.x */ |
| 256 | snprintf(replica_result, REPLICA_RESULTSIZE, _("Replica running: %s"), row[6]); | 334 | xasprintf(&sc_replica.output, "Replica running: %s", row[6]); |
| 257 | if (strcmp(row[6], "Yes") != 0) { | 335 | if (strcmp(row[6], "Yes") != 0) { |
| 258 | mysql_free_result(res); | 336 | mysql_free_result(res); |
| 259 | mysql_close(&mysql); | 337 | mysql_close(&mysql); |
| 260 | die(STATE_CRITICAL, "%s\n", replica_result); | ||
| 261 | } | ||
| 262 | 338 | ||
| 339 | sc_replica = mp_set_subcheck_state(sc_replica, STATE_CRITICAL); | ||
| 340 | mp_add_subcheck_to_check(&overall, sc_replica); | ||
| 341 | mp_exit(overall); | ||
| 342 | } | ||
| 263 | } else { | 343 | } else { |
| 264 | /* mysql 4.x.x and mysql 5.x.x */ | 344 | /* mysql 4.x.x and mysql 5.x.x */ |
| 265 | int replica_io_field = -1; | 345 | int replica_io_field = -1; |
| 266 | int replica_sql_field = -1; | 346 | int replica_sql_field = -1; |
| 267 | int seconds_behind_field = -1; | 347 | int seconds_behind_field = -1; |
| 268 | int num_fields; | 348 | unsigned int num_fields = mysql_num_fields(res); |
| 269 | MYSQL_FIELD *fields; | 349 | MYSQL_FIELD *fields = mysql_fetch_fields(res); |
| 270 | num_fields = mysql_num_fields(res); | 350 | for (int i = 0; i < (int)num_fields; i++) { |
| 271 | fields = mysql_fetch_fields(res); | 351 | if ((strcasecmp(fields[i].name, "Slave_IO_Running") == 0) || |
| 272 | for (int i = 0; i < num_fields; i++) { | 352 | (strcasecmp(fields[i].name, "Replica_IO_Running") == 0)) { |
| 273 | if (strcmp(fields[i].name, "Slave_IO_Running") == 0) { | ||
| 274 | replica_io_field = i; | 353 | replica_io_field = i; |
| 275 | continue; | 354 | continue; |
| 276 | } | 355 | } |
| 277 | if (strcmp(fields[i].name, "Slave_SQL_Running") == 0) { | 356 | if ((strcasecmp(fields[i].name, "Slave_SQL_Running") == 0) || |
| 357 | (strcasecmp(fields[i].name, "Replica_SQL_Running") == 0)) { | ||
| 278 | replica_sql_field = i; | 358 | replica_sql_field = i; |
| 279 | continue; | 359 | continue; |
| 280 | } | 360 | } |
| 281 | if (strcmp(fields[i].name, "Seconds_Behind_Master") == 0) { | 361 | if ((strcasecmp(fields[i].name, "Seconds_Behind_Master") == 0) || |
| 362 | (strcasecmp(fields[i].name, "Seconds_Behind_Source") == 0)) { | ||
| 282 | seconds_behind_field = i; | 363 | seconds_behind_field = i; |
| 283 | continue; | 364 | continue; |
| 284 | } | 365 | } |
| @@ -288,15 +369,23 @@ int main(int argc, char **argv) { | |||
| 288 | if ((replica_io_field < 0) || (replica_sql_field < 0) || (num_fields == 0)) { | 369 | if ((replica_io_field < 0) || (replica_sql_field < 0) || (num_fields == 0)) { |
| 289 | mysql_free_result(res); | 370 | mysql_free_result(res); |
| 290 | mysql_close(&mysql); | 371 | mysql_close(&mysql); |
| 291 | die(STATE_CRITICAL, "Replica status unavailable\n"); | 372 | |
| 373 | xasprintf(&sc_replica.output, "Replica status unavailable"); | ||
| 374 | sc_replica = mp_set_subcheck_state(sc_replica, STATE_CRITICAL); | ||
| 375 | mp_add_subcheck_to_check(&overall, sc_replica); | ||
| 376 | mp_exit(overall); | ||
| 292 | } | 377 | } |
| 293 | 378 | ||
| 294 | /* Save replica status in replica_result */ | 379 | /* Save replica status in replica_result */ |
| 295 | snprintf(replica_result, REPLICA_RESULTSIZE, "Replica IO: %s Replica SQL: %s Seconds Behind Master: %s", row[replica_io_field], | 380 | xasprintf(&sc_replica.output, |
| 296 | row[replica_sql_field], seconds_behind_field != -1 ? row[seconds_behind_field] : "Unknown"); | 381 | "Replica IO: %s Replica SQL: %s Seconds Behind Master: %s", |
| 297 | 382 | row[replica_io_field], row[replica_sql_field], | |
| 298 | /* Raise critical error if SQL THREAD or IO THREAD are stopped, but only if there are no mysqldump threads running */ | 383 | seconds_behind_field != -1 ? row[seconds_behind_field] : "Unknown"); |
| 299 | if (strcmp(row[replica_io_field], "Yes") != 0 || strcmp(row[replica_sql_field], "Yes") != 0) { | 384 | |
| 385 | /* Raise critical error if SQL THREAD or IO THREAD are stopped, but only if there are no | ||
| 386 | * mysqldump threads running */ | ||
| 387 | if (strcmp(row[replica_io_field], "Yes") != 0 || | ||
| 388 | strcmp(row[replica_sql_field], "Yes") != 0) { | ||
| 300 | MYSQL_RES *res_mysqldump; | 389 | MYSQL_RES *res_mysqldump; |
| 301 | MYSQL_ROW row_mysqldump; | 390 | MYSQL_ROW row_mysqldump; |
| 302 | unsigned int mysqldump_threads = 0; | 391 | unsigned int mysqldump_threads = 0; |
| @@ -314,10 +403,14 @@ int main(int argc, char **argv) { | |||
| 314 | } | 403 | } |
| 315 | mysql_close(&mysql); | 404 | mysql_close(&mysql); |
| 316 | } | 405 | } |
| 406 | |||
| 317 | if (mysqldump_threads == 0) { | 407 | if (mysqldump_threads == 0) { |
| 318 | die(STATE_CRITICAL, "%s\n", replica_result); | 408 | sc_replica = mp_set_subcheck_state(sc_replica, STATE_CRITICAL); |
| 409 | mp_add_subcheck_to_check(&overall, sc_replica); | ||
| 410 | mp_exit(overall); | ||
| 319 | } else { | 411 | } else { |
| 320 | strncat(replica_result, " Mysqldump: in progress", REPLICA_RESULTSIZE - 1); | 412 | xasprintf(&sc_replica.output, "%s %s", sc_replica.output, |
| 413 | " Mysqldump: in progress"); | ||
| 321 | } | 414 | } |
| 322 | } | 415 | } |
| 323 | 416 | ||
| @@ -325,27 +418,30 @@ int main(int argc, char **argv) { | |||
| 325 | if (seconds_behind_field == -1) { | 418 | if (seconds_behind_field == -1) { |
| 326 | printf("seconds_behind_field not found\n"); | 419 | printf("seconds_behind_field not found\n"); |
| 327 | } else { | 420 | } else { |
| 328 | printf("seconds_behind_field(index %d)=%s\n", seconds_behind_field, row[seconds_behind_field]); | 421 | printf("seconds_behind_field(index %d)=%s\n", seconds_behind_field, |
| 422 | row[seconds_behind_field]); | ||
| 329 | } | 423 | } |
| 330 | } | 424 | } |
| 331 | 425 | ||
| 332 | /* Check Seconds Behind against threshold */ | 426 | /* Check Seconds Behind against threshold */ |
| 333 | if ((seconds_behind_field != -1) && (row[seconds_behind_field] != NULL && strcmp(row[seconds_behind_field], "NULL") != 0)) { | 427 | if ((seconds_behind_field != -1) && (row[seconds_behind_field] != NULL && |
| 334 | double value = atof(row[seconds_behind_field]); | 428 | strcmp(row[seconds_behind_field], "NULL") != 0)) { |
| 335 | int status; | 429 | mp_perfdata pd_seconds_behind = perfdata_init(); |
| 336 | 430 | pd_seconds_behind.label = "seconds behind master"; | |
| 337 | status = get_status(value, config.my_threshold); | 431 | pd_seconds_behind.value = mp_create_pd_value(atof(row[seconds_behind_field])); |
| 338 | 432 | pd_seconds_behind = | |
| 339 | xasprintf(&perf, "%s %s", perf, | 433 | mp_pd_set_thresholds(pd_seconds_behind, config.replica_thresholds); |
| 340 | fperfdata("seconds behind master", value, "s", true, (double)config.warning_time, true, | 434 | pd_seconds_behind.uom = "s"; |
| 341 | (double)config.critical_time, false, 0, false, 0)); | 435 | mp_add_perfdata_to_subcheck(&sc_replica, pd_seconds_behind); |
| 342 | 436 | ||
| 343 | if (status == STATE_WARNING) { | 437 | mp_state_enum status = mp_get_pd_status(pd_seconds_behind); |
| 344 | printf("SLOW_REPLICA %s: %s|%s\n", _("WARNING"), replica_result, perf); | 438 | |
| 345 | exit(STATE_WARNING); | 439 | sc_replica = mp_set_subcheck_state(sc_replica, status); |
| 346 | } else if (status == STATE_CRITICAL) { | 440 | |
| 347 | printf("SLOW_REPLICA %s: %s|%s\n", _("CRITICAL"), replica_result, perf); | 441 | if (status != STATE_OK) { |
| 348 | exit(STATE_CRITICAL); | 442 | xasprintf(&sc_replica.output, "slow replica - %s", sc_replica.output); |
| 443 | mp_add_subcheck_to_check(&overall, sc_replica); | ||
| 444 | mp_exit(overall); | ||
| 349 | } | 445 | } |
| 350 | } | 446 | } |
| 351 | } | 447 | } |
| @@ -357,20 +453,17 @@ int main(int argc, char **argv) { | |||
| 357 | /* close the connection */ | 453 | /* close the connection */ |
| 358 | mysql_close(&mysql); | 454 | mysql_close(&mysql); |
| 359 | 455 | ||
| 360 | /* print out the result of stats */ | 456 | mp_exit(overall); |
| 361 | if (config.check_replica) { | ||
| 362 | printf("%s %s|%s\n", result, replica_result, perf); | ||
| 363 | } else { | ||
| 364 | printf("%s|%s\n", result, perf); | ||
| 365 | } | ||
| 366 | |||
| 367 | return STATE_OK; | ||
| 368 | } | 457 | } |
| 369 | 458 | ||
| 370 | #define CHECK_REPLICA_OPT CHAR_MAX + 1 | ||
| 371 | |||
| 372 | /* process command-line arguments */ | 459 | /* process command-line arguments */ |
| 373 | check_mysql_config_wrapper process_arguments(int argc, char **argv) { | 460 | check_mysql_config_wrapper process_arguments(int argc, char **argv) { |
| 461 | |||
| 462 | enum { | ||
| 463 | CHECK_REPLICA_OPT = CHAR_MAX + 1, | ||
| 464 | output_format_index, | ||
| 465 | }; | ||
| 466 | |||
| 374 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, | 467 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, |
| 375 | {"socket", required_argument, 0, 's'}, | 468 | {"socket", required_argument, 0, 's'}, |
| 376 | {"database", required_argument, 0, 'd'}, | 469 | {"database", required_argument, 0, 'd'}, |
| @@ -393,6 +486,7 @@ check_mysql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 393 | {"cert", required_argument, 0, 'a'}, | 486 | {"cert", required_argument, 0, 'a'}, |
| 394 | {"ca-dir", required_argument, 0, 'D'}, | 487 | {"ca-dir", required_argument, 0, 'D'}, |
| 395 | {"ciphers", required_argument, 0, 'L'}, | 488 | {"ciphers", required_argument, 0, 'L'}, |
| 489 | {"output-format", required_argument, 0, output_format_index}, | ||
| 396 | {0, 0, 0, 0}}; | 490 | {0, 0, 0, 0}}; |
| 397 | 491 | ||
| 398 | check_mysql_config_wrapper result = { | 492 | check_mysql_config_wrapper result = { |
| @@ -405,12 +499,10 @@ check_mysql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 405 | return result; | 499 | return result; |
| 406 | } | 500 | } |
| 407 | 501 | ||
| 408 | char *warning = NULL; | ||
| 409 | char *critical = NULL; | ||
| 410 | |||
| 411 | int option = 0; | 502 | int option = 0; |
| 412 | while (true) { | 503 | while (true) { |
| 413 | int option_index = getopt_long(argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); | 504 | int option_index = |
| 505 | getopt_long(argc, argv, "hlvVnSP:p:u:d:H:s:c:w:a:k:C:D:L:f:g:", longopts, &option); | ||
| 414 | 506 | ||
| 415 | if (option_index == -1 || option_index == EOF) { | 507 | if (option_index == -1 || option_index == EOF) { |
| 416 | break; | 508 | break; |
| @@ -478,14 +570,22 @@ check_mysql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 478 | case 'n': | 570 | case 'n': |
| 479 | result.config.ignore_auth = true; /* ignore-auth */ | 571 | result.config.ignore_auth = true; /* ignore-auth */ |
| 480 | break; | 572 | break; |
| 481 | case 'w': | 573 | case 'w': { |
| 482 | warning = optarg; | 574 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 483 | result.config.warning_time = strtod(warning, NULL); | 575 | if (tmp.error != MP_PARSING_SUCCES) { |
| 484 | break; | 576 | die(STATE_UNKNOWN, "failed to parse warning time threshold"); |
| 485 | case 'c': | 577 | } |
| 486 | critical = optarg; | 578 | result.config.replica_thresholds = |
| 487 | result.config.critical_time = strtod(critical, NULL); | 579 | mp_thresholds_set_warn(result.config.replica_thresholds, tmp.range); |
| 488 | break; | 580 | } break; |
| 581 | case 'c': { | ||
| 582 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 583 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 584 | die(STATE_UNKNOWN, "failed to parse critical time threshold"); | ||
| 585 | } | ||
| 586 | result.config.replica_thresholds = | ||
| 587 | mp_thresholds_set_crit(result.config.replica_thresholds, tmp.range); | ||
| 588 | } break; | ||
| 489 | case 'V': /* version */ | 589 | case 'V': /* version */ |
| 490 | print_revision(progname, NP_VERSION); | 590 | print_revision(progname, NP_VERSION); |
| 491 | exit(STATE_UNKNOWN); | 591 | exit(STATE_UNKNOWN); |
| @@ -497,13 +597,22 @@ check_mysql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 497 | break; | 597 | break; |
| 498 | case '?': /* help */ | 598 | case '?': /* help */ |
| 499 | usage5(); | 599 | usage5(); |
| 600 | case output_format_index: { | ||
| 601 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 602 | if (!parser.parsing_success) { | ||
| 603 | printf("Invalid output format: %s\n", optarg); | ||
| 604 | exit(STATE_UNKNOWN); | ||
| 605 | } | ||
| 606 | |||
| 607 | result.config.output_format_is_set = true; | ||
| 608 | result.config.output_format = parser.output_format; | ||
| 609 | break; | ||
| 610 | } | ||
| 500 | } | 611 | } |
| 501 | } | 612 | } |
| 502 | 613 | ||
| 503 | int index = optind; | 614 | int index = optind; |
| 504 | 615 | ||
| 505 | set_thresholds(&result.config.my_threshold, warning, critical); | ||
| 506 | |||
| 507 | while (argc > index) { | 616 | while (argc > index) { |
| 508 | if (result.config.db_host == NULL) { | 617 | if (result.config.db_host == NULL) { |
| 509 | if (is_host(argv[index])) { | 618 | if (is_host(argv[index])) { |
| @@ -580,15 +689,17 @@ void print_help(void) { | |||
| 580 | printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); | 689 | printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); |
| 581 | printf(" %s\n", _("Your clear-text password could be visible as a process table entry")); | 690 | printf(" %s\n", _("Your clear-text password could be visible as a process table entry")); |
| 582 | printf(" %s\n", "-S, --check-slave"); | 691 | printf(" %s\n", "-S, --check-slave"); |
| 583 | printf(" %s\n", | 692 | printf(" %s\n", _("Check if the slave thread is running properly. This option is deprecated " |
| 584 | _("Check if the slave thread is running properly. This option is deprecated in favour of check-replica, which does the same")); | 693 | "in favour of check-replica, which does the same")); |
| 585 | printf(" %s\n", "--check-replica"); | 694 | printf(" %s\n", "--check-replica"); |
| 586 | printf(" %s\n", _("Check if the replica thread is running properly.")); | 695 | printf(" %s\n", _("Check if the replica thread is running properly.")); |
| 587 | printf(" %s\n", "-w, --warning"); | 696 | printf(" %s\n", "-w, --warning"); |
| 588 | printf(" %s\n", _("Exit with WARNING status if replica server is more than INTEGER seconds")); | 697 | printf(" %s\n", |
| 698 | _("Exit with WARNING status if replica server is more than INTEGER seconds")); | ||
| 589 | printf(" %s\n", _("behind master")); | 699 | printf(" %s\n", _("behind master")); |
| 590 | printf(" %s\n", "-c, --critical"); | 700 | printf(" %s\n", "-c, --critical"); |
| 591 | printf(" %s\n", _("Exit with CRITICAL status if replica server is more then INTEGER seconds")); | 701 | printf(" %s\n", |
| 702 | _("Exit with CRITICAL status if replica server is more then INTEGER seconds")); | ||
| 592 | printf(" %s\n", _("behind master")); | 703 | printf(" %s\n", _("behind master")); |
| 593 | printf(" %s\n", "-l, --ssl"); | 704 | printf(" %s\n", "-l, --ssl"); |
| 594 | printf(" %s\n", _("Use ssl encryption")); | 705 | printf(" %s\n", _("Use ssl encryption")); |
| @@ -603,8 +714,11 @@ void print_help(void) { | |||
| 603 | printf(" %s\n", "-L, --ciphers=STRING"); | 714 | printf(" %s\n", "-L, --ciphers=STRING"); |
| 604 | printf(" %s\n", _("List of valid SSL ciphers")); | 715 | printf(" %s\n", _("List of valid SSL ciphers")); |
| 605 | 716 | ||
| 717 | printf(UT_OUTPUT_FORMAT); | ||
| 718 | |||
| 606 | printf("\n"); | 719 | printf("\n"); |
| 607 | printf(" %s\n", _("There are no required arguments. By default, the local database is checked")); | 720 | printf(" %s\n", |
| 721 | _("There are no required arguments. By default, the local database is checked")); | ||
| 608 | printf(" %s\n", _("using the default unix socket. You can force TCP on localhost by using an")); | 722 | printf(" %s\n", _("using the default unix socket. You can force TCP on localhost by using an")); |
| 609 | printf(" %s\n", _("IP address or FQDN ('localhost' will use the socket as well).")); | 723 | printf(" %s\n", _("IP address or FQDN ('localhost' will use the socket as well).")); |
| 610 | 724 | ||
diff --git a/plugins/check_mysql.d/config.h b/plugins/check_mysql.d/config.h index 71ddbe8d..1d8c82bb 100644 --- a/plugins/check_mysql.d/config.h +++ b/plugins/check_mysql.d/config.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "output.h" | ||
| 4 | #include "thresholds.h" | 5 | #include "thresholds.h" |
| 5 | #include <stddef.h> | 6 | #include <stddef.h> |
| 6 | #include <mysql.h> | 7 | #include <mysql.h> |
| @@ -24,10 +25,10 @@ typedef struct { | |||
| 24 | bool check_replica; | 25 | bool check_replica; |
| 25 | bool ignore_auth; | 26 | bool ignore_auth; |
| 26 | 27 | ||
| 27 | double warning_time; | 28 | mp_thresholds replica_thresholds; |
| 28 | double critical_time; | ||
| 29 | thresholds *my_threshold; | ||
| 30 | 29 | ||
| 30 | bool output_format_is_set; | ||
| 31 | mp_output_format output_format; | ||
| 31 | } check_mysql_config; | 32 | } check_mysql_config; |
| 32 | 33 | ||
| 33 | check_mysql_config check_mysql_config_init() { | 34 | check_mysql_config check_mysql_config_init() { |
| @@ -50,9 +51,9 @@ check_mysql_config check_mysql_config_init() { | |||
| 50 | .check_replica = false, | 51 | .check_replica = false, |
| 51 | .ignore_auth = false, | 52 | .ignore_auth = false, |
| 52 | 53 | ||
| 53 | .warning_time = 0, | 54 | .replica_thresholds = mp_thresholds_init(), |
| 54 | .critical_time = 0, | 55 | |
| 55 | .my_threshold = NULL, | 56 | .output_format_is_set = false, |
| 56 | }; | 57 | }; |
| 57 | return tmp; | 58 | return tmp; |
| 58 | } | 59 | } |
diff --git a/plugins/check_mysql_query.c b/plugins/check_mysql_query.c index 5e04a94b..ae6cc15d 100644 --- a/plugins/check_mysql_query.c +++ b/plugins/check_mysql_query.c | |||
| @@ -29,11 +29,11 @@ | |||
| 29 | * | 29 | * |
| 30 | *****************************************************************************/ | 30 | *****************************************************************************/ |
| 31 | 31 | ||
| 32 | const char *progname = "check_mysql_query"; | ||
| 33 | const char *copyright = "1999-2024"; | ||
| 34 | const char *email = "devel@monitoring-plugins.org"; | ||
| 35 | |||
| 36 | #include "common.h" | 32 | #include "common.h" |
| 33 | #include "output.h" | ||
| 34 | #include "perfdata.h" | ||
| 35 | #include "states.h" | ||
| 36 | #include "thresholds.h" | ||
| 37 | #include "utils.h" | 37 | #include "utils.h" |
| 38 | #include "utils_base.h" | 38 | #include "utils_base.h" |
| 39 | #include "netutils.h" | 39 | #include "netutils.h" |
| @@ -42,12 +42,17 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 42 | #include <mysql.h> | 42 | #include <mysql.h> |
| 43 | #include <errmsg.h> | 43 | #include <errmsg.h> |
| 44 | 44 | ||
| 45 | const char *progname = "check_mysql_query"; | ||
| 46 | const char *copyright = "1999-2024"; | ||
| 47 | const char *email = "devel@monitoring-plugins.org"; | ||
| 48 | |||
| 45 | typedef struct { | 49 | typedef struct { |
| 46 | int errorcode; | 50 | int errorcode; |
| 47 | check_mysql_query_config config; | 51 | check_mysql_query_config config; |
| 48 | } check_mysql_query_config_wrapper; | 52 | } check_mysql_query_config_wrapper; |
| 49 | static check_mysql_query_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | 53 | static check_mysql_query_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 50 | static check_mysql_query_config_wrapper validate_arguments(check_mysql_query_config_wrapper /*config_wrapper*/); | 54 | static check_mysql_query_config_wrapper |
| 55 | validate_arguments(check_mysql_query_config_wrapper /*config_wrapper*/); | ||
| 51 | static void print_help(void); | 56 | static void print_help(void); |
| 52 | void print_usage(void); | 57 | void print_usage(void); |
| 53 | 58 | ||
| @@ -68,6 +73,10 @@ int main(int argc, char **argv) { | |||
| 68 | 73 | ||
| 69 | const check_mysql_query_config config = tmp_config.config; | 74 | const check_mysql_query_config config = tmp_config.config; |
| 70 | 75 | ||
| 76 | if (config.output_format_is_set) { | ||
| 77 | mp_set_format(config.output_format); | ||
| 78 | } | ||
| 79 | |||
| 71 | MYSQL mysql; | 80 | MYSQL mysql; |
| 72 | /* initialize mysql */ | 81 | /* initialize mysql */ |
| 73 | mysql_init(&mysql); | 82 | mysql_init(&mysql); |
| @@ -82,26 +91,38 @@ int main(int argc, char **argv) { | |||
| 82 | mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); | 91 | mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, "client"); |
| 83 | } | 92 | } |
| 84 | 93 | ||
| 94 | mp_check overall = mp_check_init(); | ||
| 95 | mp_subcheck sc_connect = mp_subcheck_init(); | ||
| 96 | |||
| 85 | /* establish a connection to the server and error checking */ | 97 | /* establish a connection to the server and error checking */ |
| 86 | if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, config.db_port, config.db_socket, 0)) { | 98 | if (!mysql_real_connect(&mysql, config.db_host, config.db_user, config.db_pass, config.db, |
| 99 | config.db_port, config.db_socket, 0)) { | ||
| 100 | xasprintf(&sc_connect.output, "query failed: %s", mysql_error(&mysql)); | ||
| 101 | |||
| 87 | if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { | 102 | if (mysql_errno(&mysql) == CR_UNKNOWN_HOST) { |
| 88 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 103 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 89 | } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { | 104 | } else if (mysql_errno(&mysql) == CR_VERSION_ERROR) { |
| 90 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 105 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 91 | } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) { | 106 | } else if (mysql_errno(&mysql) == CR_OUT_OF_MEMORY) { |
| 92 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 107 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 93 | } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) { | 108 | } else if (mysql_errno(&mysql) == CR_IPSOCK_ERROR) { |
| 94 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 109 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 95 | } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) { | 110 | } else if (mysql_errno(&mysql) == CR_SOCKET_CREATE_ERROR) { |
| 96 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), mysql_error(&mysql)); | 111 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_WARNING); |
| 97 | } else { | 112 | } else { |
| 98 | die(STATE_CRITICAL, "QUERY %s: %s\n", _("CRITICAL"), mysql_error(&mysql)); | 113 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_CRITICAL); |
| 99 | } | 114 | } |
| 115 | |||
| 116 | mp_add_subcheck_to_check(&overall, sc_connect); | ||
| 117 | mp_exit(overall); | ||
| 100 | } | 118 | } |
| 101 | 119 | ||
| 102 | char *error = NULL; | 120 | sc_connect = mp_set_subcheck_state(sc_connect, STATE_OK); |
| 121 | xasprintf(&sc_connect.output, "query succeeded"); | ||
| 122 | mp_add_subcheck_to_check(&overall, sc_connect); | ||
| 123 | |||
| 103 | if (mysql_query(&mysql, config.sql_query) != 0) { | 124 | if (mysql_query(&mysql, config.sql_query) != 0) { |
| 104 | error = strdup(mysql_error(&mysql)); | 125 | char *error = strdup(mysql_error(&mysql)); |
| 105 | mysql_close(&mysql); | 126 | mysql_close(&mysql); |
| 106 | die(STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error); | 127 | die(STATE_CRITICAL, "QUERY %s: %s - %s\n", _("CRITICAL"), _("Error with query"), error); |
| 107 | } | 128 | } |
| @@ -109,7 +130,7 @@ int main(int argc, char **argv) { | |||
| 109 | MYSQL_RES *res; | 130 | MYSQL_RES *res; |
| 110 | /* store the result */ | 131 | /* store the result */ |
| 111 | if ((res = mysql_store_result(&mysql)) == NULL) { | 132 | if ((res = mysql_store_result(&mysql)) == NULL) { |
| 112 | error = strdup(mysql_error(&mysql)); | 133 | char *error = strdup(mysql_error(&mysql)); |
| 113 | mysql_close(&mysql); | 134 | mysql_close(&mysql); |
| 114 | die(STATE_CRITICAL, "QUERY %s: Error with store_result - %s\n", _("CRITICAL"), error); | 135 | die(STATE_CRITICAL, "QUERY %s: Error with store_result - %s\n", _("CRITICAL"), error); |
| 115 | } | 136 | } |
| @@ -120,17 +141,24 @@ int main(int argc, char **argv) { | |||
| 120 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned")); | 141 | die(STATE_WARNING, "QUERY %s: %s\n", _("WARNING"), _("No rows returned")); |
| 121 | } | 142 | } |
| 122 | 143 | ||
| 144 | mp_subcheck sc_value = mp_subcheck_init(); | ||
| 123 | MYSQL_ROW row; | 145 | MYSQL_ROW row; |
| 124 | /* fetch the first row */ | 146 | /* fetch the first row */ |
| 125 | if ((row = mysql_fetch_row(res)) == NULL) { | 147 | if ((row = mysql_fetch_row(res)) == NULL) { |
| 126 | error = strdup(mysql_error(&mysql)); | 148 | xasprintf(&sc_value.output, "fetch row error - %s", mysql_error(&mysql)); |
| 127 | mysql_free_result(res); | 149 | mysql_free_result(res); |
| 128 | mysql_close(&mysql); | 150 | mysql_close(&mysql); |
| 129 | die(STATE_CRITICAL, "QUERY %s: Fetch row error - %s\n", _("CRITICAL"), error); | 151 | |
| 152 | sc_value = mp_set_subcheck_state(sc_value, STATE_CRITICAL); | ||
| 153 | mp_add_subcheck_to_check(&overall, sc_value); | ||
| 154 | mp_exit(overall); | ||
| 130 | } | 155 | } |
| 131 | 156 | ||
| 132 | if (!is_numeric(row[0])) { | 157 | if (!is_numeric(row[0])) { |
| 133 | die(STATE_CRITICAL, "QUERY %s: %s - '%s'\n", _("CRITICAL"), _("Is not a numeric"), row[0]); | 158 | xasprintf(&sc_value.output, "query result is not numeric"); |
| 159 | sc_value = mp_set_subcheck_state(sc_value, STATE_CRITICAL); | ||
| 160 | mp_add_subcheck_to_check(&overall, sc_value); | ||
| 161 | mp_exit(overall); | ||
| 134 | } | 162 | } |
| 135 | 163 | ||
| 136 | double value = strtod(row[0], NULL); | 164 | double value = strtod(row[0], NULL); |
| @@ -145,31 +173,42 @@ int main(int argc, char **argv) { | |||
| 145 | printf("mysql result: %f\n", value); | 173 | printf("mysql result: %f\n", value); |
| 146 | } | 174 | } |
| 147 | 175 | ||
| 148 | int status = get_status(value, config.my_thresholds); | 176 | mp_perfdata pd_query_result = perfdata_init(); |
| 177 | pd_query_result = mp_set_pd_value(pd_query_result, value); | ||
| 178 | pd_query_result = mp_pd_set_thresholds(pd_query_result, config.thresholds); | ||
| 179 | pd_query_result.label = "result"; | ||
| 180 | mp_add_perfdata_to_subcheck(&sc_value, pd_query_result); | ||
| 149 | 181 | ||
| 150 | if (status == STATE_OK) { | 182 | sc_value = mp_set_subcheck_state(sc_value, mp_get_pd_status(pd_query_result)); |
| 151 | printf("QUERY %s: ", _("OK")); | 183 | xasprintf(&sc_value.output, "'%s' returned '%f'", config.sql_query, value); |
| 152 | } else if (status == STATE_WARNING) { | 184 | |
| 153 | printf("QUERY %s: ", _("WARNING")); | 185 | mp_add_subcheck_to_check(&overall, sc_value); |
| 154 | } else if (status == STATE_CRITICAL) { | ||
| 155 | printf("QUERY %s: ", _("CRITICAL")); | ||
| 156 | } | ||
| 157 | printf(_("'%s' returned %f | %s"), config.sql_query, value, | ||
| 158 | fperfdata("result", value, "", config.my_thresholds->warning, config.my_thresholds->warning ? config.my_thresholds->warning->end : 0, | ||
| 159 | config.my_thresholds->critical, config.my_thresholds->critical ? config.my_thresholds->critical->end : 0, false, 0, false, 0)); | ||
| 160 | printf("\n"); | ||
| 161 | 186 | ||
| 162 | return status; | 187 | mp_exit(overall); |
| 163 | } | 188 | } |
| 164 | 189 | ||
| 165 | /* process command-line arguments */ | 190 | /* process command-line arguments */ |
| 166 | check_mysql_query_config_wrapper process_arguments(int argc, char **argv) { | 191 | check_mysql_query_config_wrapper process_arguments(int argc, char **argv) { |
| 167 | static struct option longopts[] = { | 192 | enum { |
| 168 | {"hostname", required_argument, 0, 'H'}, {"socket", required_argument, 0, 's'}, {"database", required_argument, 0, 'd'}, | 193 | output_format_index = CHAR_MAX + 1, |
| 169 | {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, {"file", required_argument, 0, 'f'}, | 194 | }; |
| 170 | {"group", required_argument, 0, 'g'}, {"port", required_argument, 0, 'P'}, {"verbose", no_argument, 0, 'v'}, | 195 | |
| 171 | {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"query", required_argument, 0, 'q'}, | 196 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, |
| 172 | {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {0, 0, 0, 0}}; | 197 | {"socket", required_argument, 0, 's'}, |
| 198 | {"database", required_argument, 0, 'd'}, | ||
| 199 | {"username", required_argument, 0, 'u'}, | ||
| 200 | {"password", required_argument, 0, 'p'}, | ||
| 201 | {"file", required_argument, 0, 'f'}, | ||
| 202 | {"group", required_argument, 0, 'g'}, | ||
| 203 | {"port", required_argument, 0, 'P'}, | ||
| 204 | {"verbose", no_argument, 0, 'v'}, | ||
| 205 | {"version", no_argument, 0, 'V'}, | ||
| 206 | {"help", no_argument, 0, 'h'}, | ||
| 207 | {"query", required_argument, 0, 'q'}, | ||
| 208 | {"warning", required_argument, 0, 'w'}, | ||
| 209 | {"critical", required_argument, 0, 'c'}, | ||
| 210 | {"output-format", required_argument, 0, output_format_index}, | ||
| 211 | {0, 0, 0, 0}}; | ||
| 173 | 212 | ||
| 174 | check_mysql_query_config_wrapper result = { | 213 | check_mysql_query_config_wrapper result = { |
| 175 | .errorcode = OK, | 214 | .errorcode = OK, |
| @@ -181,9 +220,6 @@ check_mysql_query_config_wrapper process_arguments(int argc, char **argv) { | |||
| 181 | return result; | 220 | return result; |
| 182 | } | 221 | } |
| 183 | 222 | ||
| 184 | char *warning = NULL; | ||
| 185 | char *critical = NULL; | ||
| 186 | |||
| 187 | while (true) { | 223 | while (true) { |
| 188 | int option = 0; | 224 | int option = 0; |
| 189 | int option_char = getopt_long(argc, argv, "hvVP:p:u:d:H:s:q:w:c:f:g:", longopts, &option); | 225 | int option_char = getopt_long(argc, argv, "hvVP:p:u:d:H:s:q:w:c:f:g:", longopts, &option); |
| @@ -239,23 +275,41 @@ check_mysql_query_config_wrapper process_arguments(int argc, char **argv) { | |||
| 239 | case 'q': | 275 | case 'q': |
| 240 | xasprintf(&result.config.sql_query, "%s", optarg); | 276 | xasprintf(&result.config.sql_query, "%s", optarg); |
| 241 | break; | 277 | break; |
| 242 | case 'w': | 278 | case 'w': { |
| 243 | warning = optarg; | 279 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 244 | break; | 280 | if (tmp.error != MP_PARSING_SUCCES) { |
| 245 | case 'c': | 281 | die(STATE_UNKNOWN, "failed to parse warning threshold"); |
| 246 | critical = optarg; | 282 | } |
| 247 | break; | 283 | result.config.thresholds = mp_thresholds_set_warn(result.config.thresholds, tmp.range); |
| 284 | } break; | ||
| 285 | case 'c': { | ||
| 286 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 287 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 288 | die(STATE_UNKNOWN, "failed to parse critical threshold"); | ||
| 289 | } | ||
| 290 | result.config.thresholds = mp_thresholds_set_crit(result.config.thresholds, tmp.range); | ||
| 291 | } break; | ||
| 248 | case '?': /* help */ | 292 | case '?': /* help */ |
| 249 | usage5(); | 293 | usage5(); |
| 294 | case output_format_index: { | ||
| 295 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 296 | if (!parser.parsing_success) { | ||
| 297 | printf("Invalid output format: %s\n", optarg); | ||
| 298 | exit(STATE_UNKNOWN); | ||
| 299 | } | ||
| 300 | |||
| 301 | result.config.output_format_is_set = true; | ||
| 302 | result.config.output_format = parser.output_format; | ||
| 303 | break; | ||
| 304 | } | ||
| 250 | } | 305 | } |
| 251 | } | 306 | } |
| 252 | 307 | ||
| 253 | set_thresholds(&result.config.my_thresholds, warning, critical); | ||
| 254 | |||
| 255 | return validate_arguments(result); | 308 | return validate_arguments(result); |
| 256 | } | 309 | } |
| 257 | 310 | ||
| 258 | check_mysql_query_config_wrapper validate_arguments(check_mysql_query_config_wrapper config_wrapper) { | 311 | check_mysql_query_config_wrapper |
| 312 | validate_arguments(check_mysql_query_config_wrapper config_wrapper) { | ||
| 259 | if (config_wrapper.config.sql_query == NULL) { | 313 | if (config_wrapper.config.sql_query == NULL) { |
| 260 | usage("Must specify a SQL query to run"); | 314 | usage("Must specify a SQL query to run"); |
| 261 | } | 315 | } |
| @@ -310,6 +364,8 @@ void print_help(void) { | |||
| 310 | printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); | 364 | printf(" ==> %s <==\n", _("IMPORTANT: THIS FORM OF AUTHENTICATION IS NOT SECURE!!!")); |
| 311 | printf(" %s\n", _("Your clear-text password could be visible as a process table entry")); | 365 | printf(" %s\n", _("Your clear-text password could be visible as a process table entry")); |
| 312 | 366 | ||
| 367 | printf(UT_OUTPUT_FORMAT); | ||
| 368 | |||
| 313 | printf("\n"); | 369 | printf("\n"); |
| 314 | printf(" %s\n", _("A query is required. The result from the query should be numeric.")); | 370 | printf(" %s\n", _("A query is required. The result from the query should be numeric.")); |
| 315 | printf(" %s\n", _("For extra security, create a user with minimal access.")); | 371 | printf(" %s\n", _("For extra security, create a user with minimal access.")); |
diff --git a/plugins/check_mysql_query.d/config.h b/plugins/check_mysql_query.d/config.h index be019160..32ab455a 100644 --- a/plugins/check_mysql_query.d/config.h +++ b/plugins/check_mysql_query.d/config.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "output.h" | ||
| 4 | #include "thresholds.h" | 5 | #include "thresholds.h" |
| 5 | #include <mysql.h> | 6 | #include <mysql.h> |
| 6 | 7 | ||
| @@ -15,7 +16,10 @@ typedef struct { | |||
| 15 | unsigned int db_port; | 16 | unsigned int db_port; |
| 16 | 17 | ||
| 17 | char *sql_query; | 18 | char *sql_query; |
| 18 | thresholds *my_thresholds; | 19 | mp_thresholds thresholds; |
| 20 | |||
| 21 | bool output_format_is_set; | ||
| 22 | mp_output_format output_format; | ||
| 19 | } check_mysql_query_config; | 23 | } check_mysql_query_config; |
| 20 | 24 | ||
| 21 | check_mysql_query_config check_mysql_query_config_init() { | 25 | check_mysql_query_config check_mysql_query_config_init() { |
| @@ -30,7 +34,9 @@ check_mysql_query_config check_mysql_query_config_init() { | |||
| 30 | .db_port = MYSQL_PORT, | 34 | .db_port = MYSQL_PORT, |
| 31 | 35 | ||
| 32 | .sql_query = NULL, | 36 | .sql_query = NULL, |
| 33 | .my_thresholds = NULL, | 37 | .thresholds = mp_thresholds_init(), |
| 38 | |||
| 39 | .output_format_is_set = false, | ||
| 34 | }; | 40 | }; |
| 35 | return tmp; | 41 | return tmp; |
| 36 | } | 42 | } |
diff --git a/plugins/check_nt.c b/plugins/check_nt.c deleted file mode 100644 index 7dd23e5c..00000000 --- a/plugins/check_nt.c +++ /dev/null | |||
| @@ -1,756 +0,0 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Monitoring check_nt plugin | ||
| 4 | * | ||
| 5 | * License: GPL | ||
| 6 | * Copyright (c) 2000-2002 Yves Rubin (rubiyz@yahoo.com) | ||
| 7 | * Copyright (c) 2003-2024 Monitoring Plugins Development Team | ||
| 8 | * | ||
| 9 | * Description: | ||
| 10 | * | ||
| 11 | * This file contains the check_nt plugin | ||
| 12 | * | ||
| 13 | * This plugin collects data from the NSClient service running on a | ||
| 14 | * Windows NT/2000/XP/2003 server. | ||
| 15 | * This plugin requires NSClient software to run on NT | ||
| 16 | * (https://nsclient.org/) | ||
| 17 | * | ||
| 18 | * | ||
| 19 | * This program is free software: you can redistribute it and/or modify | ||
| 20 | * it under the terms of the GNU General Public License as published by | ||
| 21 | * the Free Software Foundation, either version 3 of the License, or | ||
| 22 | * (at your option) any later version. | ||
| 23 | * | ||
| 24 | * This program is distributed in the hope that it will be useful, | ||
| 25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 27 | * GNU General Public License for more details. | ||
| 28 | * | ||
| 29 | * You should have received a copy of the GNU General Public License | ||
| 30 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 31 | * | ||
| 32 | * | ||
| 33 | *****************************************************************************/ | ||
| 34 | |||
| 35 | const char *progname = "check_nt"; | ||
| 36 | const char *copyright = "2000-2024"; | ||
| 37 | const char *email = "devel@monitoring-plugins.org"; | ||
| 38 | |||
| 39 | #include "common.h" | ||
| 40 | #include "netutils.h" | ||
| 41 | #include "utils.h" | ||
| 42 | #include "check_nt.d/config.h" | ||
| 43 | |||
| 44 | enum { | ||
| 45 | MAX_VALUE_LIST = 30, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static char recv_buffer[MAX_INPUT_BUFFER]; | ||
| 49 | |||
| 50 | static void fetch_data(const char *address, int port, const char *sendb); | ||
| 51 | |||
| 52 | typedef struct { | ||
| 53 | int errorcode; | ||
| 54 | check_nt_config config; | ||
| 55 | } check_nt_config_wrapper; | ||
| 56 | static check_nt_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 57 | |||
| 58 | static void preparelist(char *string); | ||
| 59 | static bool strtoularray(unsigned long *array, char *string, const char *delim); | ||
| 60 | static void print_help(void); | ||
| 61 | void print_usage(void); | ||
| 62 | |||
| 63 | int main(int argc, char **argv) { | ||
| 64 | setlocale(LC_ALL, ""); | ||
| 65 | bindtextdomain(PACKAGE, LOCALEDIR); | ||
| 66 | textdomain(PACKAGE); | ||
| 67 | |||
| 68 | /* Parse extra opts if any */ | ||
| 69 | argv = np_extra_opts(&argc, argv, progname); | ||
| 70 | |||
| 71 | check_nt_config_wrapper tmp_config = process_arguments(argc, argv); | ||
| 72 | if (tmp_config.errorcode == ERROR) { | ||
| 73 | usage4(_("Could not parse arguments")); | ||
| 74 | } | ||
| 75 | |||
| 76 | const check_nt_config config = tmp_config.config; | ||
| 77 | |||
| 78 | /* initialize alarm signal handling */ | ||
| 79 | signal(SIGALRM, socket_timeout_alarm_handler); | ||
| 80 | |||
| 81 | /* set socket timeout */ | ||
| 82 | alarm(socket_timeout); | ||
| 83 | |||
| 84 | int return_code = STATE_UNKNOWN; | ||
| 85 | char *send_buffer = NULL; | ||
| 86 | char *output_message = NULL; | ||
| 87 | char *perfdata = NULL; | ||
| 88 | char *temp_string = NULL; | ||
| 89 | char *temp_string_perf = NULL; | ||
| 90 | char *description = NULL; | ||
| 91 | char *counter_unit = NULL; | ||
| 92 | char *errcvt = NULL; | ||
| 93 | unsigned long lvalue_list[MAX_VALUE_LIST]; | ||
| 94 | switch (config.vars_to_check) { | ||
| 95 | case CHECK_CLIENTVERSION: | ||
| 96 | xasprintf(&send_buffer, "%s&1", config.req_password); | ||
| 97 | fetch_data(config.server_address, config.server_port, send_buffer); | ||
| 98 | if (config.value_list != NULL && strcmp(recv_buffer, config.value_list) != 0) { | ||
| 99 | xasprintf(&output_message, _("Wrong client version - running: %s, required: %s"), recv_buffer, config.value_list); | ||
| 100 | return_code = STATE_WARNING; | ||
| 101 | } else { | ||
| 102 | xasprintf(&output_message, "%s", recv_buffer); | ||
| 103 | return_code = STATE_OK; | ||
| 104 | } | ||
| 105 | break; | ||
| 106 | case CHECK_CPULOAD: | ||
| 107 | if (config.value_list == NULL) { | ||
| 108 | output_message = strdup(_("missing -l parameters")); | ||
| 109 | } else if (!strtoularray(lvalue_list, config.value_list, ",")) { | ||
| 110 | output_message = strdup(_("wrong -l parameter.")); | ||
| 111 | } else { | ||
| 112 | /* -l parameters is present with only integers */ | ||
| 113 | return_code = STATE_OK; | ||
| 114 | temp_string = strdup(_("CPU Load")); | ||
| 115 | temp_string_perf = strdup(" "); | ||
| 116 | |||
| 117 | /* loop until one of the parameters is wrong or not present */ | ||
| 118 | int offset = 0; | ||
| 119 | while (lvalue_list[0 + offset] > (unsigned long)0 && lvalue_list[0 + offset] <= (unsigned long)17280 && | ||
| 120 | lvalue_list[1 + offset] > (unsigned long)0 && lvalue_list[1 + offset] <= (unsigned long)100 && | ||
| 121 | lvalue_list[2 + offset] > (unsigned long)0 && lvalue_list[2 + offset] <= (unsigned long)100) { | ||
| 122 | |||
| 123 | /* Send request and retrieve data */ | ||
| 124 | xasprintf(&send_buffer, "%s&2&%lu", config.req_password, lvalue_list[0 + offset]); | ||
| 125 | fetch_data(config.server_address, config.server_port, send_buffer); | ||
| 126 | |||
| 127 | unsigned long utilization = strtoul(recv_buffer, NULL, 10); | ||
| 128 | |||
| 129 | /* Check if any of the request is in a warning or critical state */ | ||
| 130 | if (utilization >= lvalue_list[2 + offset]) { | ||
| 131 | return_code = STATE_CRITICAL; | ||
| 132 | } else if (utilization >= lvalue_list[1 + offset] && return_code < STATE_WARNING) { | ||
| 133 | return_code = STATE_WARNING; | ||
| 134 | } | ||
| 135 | |||
| 136 | xasprintf(&output_message, _(" %lu%% (%lu min average)"), utilization, lvalue_list[0 + offset]); | ||
| 137 | xasprintf(&temp_string, "%s%s", temp_string, output_message); | ||
| 138 | xasprintf(&perfdata, _(" '%lu min avg Load'=%lu%%;%lu;%lu;0;100"), lvalue_list[0 + offset], utilization, | ||
| 139 | lvalue_list[1 + offset], lvalue_list[2 + offset]); | ||
| 140 | xasprintf(&temp_string_perf, "%s%s", temp_string_perf, perfdata); | ||
| 141 | offset += 3; /* move across the array */ | ||
| 142 | } | ||
| 143 | |||
| 144 | if (strlen(temp_string) > 10) { /* we had at least one loop */ | ||
| 145 | output_message = strdup(temp_string); | ||
| 146 | perfdata = temp_string_perf; | ||
| 147 | } else { | ||
| 148 | output_message = strdup(_("not enough values for -l parameters")); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | break; | ||
| 152 | case CHECK_UPTIME: { | ||
| 153 | char *tmp_value_list = config.value_list; | ||
| 154 | if (config.value_list == NULL) { | ||
| 155 | tmp_value_list = "minutes"; | ||
| 156 | } | ||
| 157 | if (strncmp(tmp_value_list, "seconds", strlen("seconds") + 1) && strncmp(tmp_value_list, "minutes", strlen("minutes") + 1) && | ||
| 158 | strncmp(config.value_list, "hours", strlen("hours") + 1) && strncmp(tmp_value_list, "days", strlen("days") + 1)) { | ||
| 159 | |||
| 160 | output_message = strdup(_("wrong -l argument")); | ||
| 161 | } else { | ||
| 162 | xasprintf(&send_buffer, "%s&3", config.req_password); | ||
| 163 | fetch_data(config.server_address, config.server_port, send_buffer); | ||
| 164 | unsigned long uptime = strtoul(recv_buffer, NULL, 10); | ||
| 165 | int updays = uptime / 86400; | ||
| 166 | int uphours = (uptime % 86400) / 3600; | ||
| 167 | int upminutes = ((uptime % 86400) % 3600) / 60; | ||
| 168 | |||
| 169 | if (!strncmp(tmp_value_list, "minutes", strlen("minutes"))) { | ||
| 170 | uptime = uptime / 60; | ||
| 171 | } else if (!strncmp(tmp_value_list, "hours", strlen("hours"))) { | ||
| 172 | uptime = uptime / 3600; | ||
| 173 | } else if (!strncmp(tmp_value_list, "days", strlen("days"))) { | ||
| 174 | uptime = uptime / 86400; | ||
| 175 | } | ||
| 176 | /* else uptime in seconds, nothing to do */ | ||
| 177 | |||
| 178 | xasprintf(&output_message, _("System Uptime - %u day(s) %u hour(s) %u minute(s) |uptime=%lu"), updays, uphours, upminutes, | ||
| 179 | uptime); | ||
| 180 | |||
| 181 | if (config.check_critical_value && uptime <= config.critical_value) { | ||
| 182 | return_code = STATE_CRITICAL; | ||
| 183 | } else if (config.check_warning_value && uptime <= config.warning_value) { | ||
| 184 | return_code = STATE_WARNING; | ||
| 185 | } else { | ||
| 186 | return_code = STATE_OK; | ||
| 187 | } | ||
| 188 | } | ||
| 189 | } break; | ||
| 190 | case CHECK_USEDDISKSPACE: | ||
| 191 | if (config.value_list == NULL) { | ||
| 192 | output_message = strdup(_("missing -l parameters")); | ||
| 193 | } else if (strlen(config.value_list) != 1) { | ||
| 194 | output_message = strdup(_("wrong -l argument")); | ||
| 195 | } else { | ||
| 196 | xasprintf(&send_buffer, "%s&4&%s", config.req_password, config.value_list); | ||
| 197 | fetch_data(config.server_address, config.server_port, send_buffer); | ||
| 198 | char *fds = strtok(recv_buffer, "&"); | ||
| 199 | char *tds = strtok(NULL, "&"); | ||
| 200 | double total_disk_space = 0; | ||
| 201 | double free_disk_space = 0; | ||
| 202 | if (fds != NULL) { | ||
| 203 | free_disk_space = atof(fds); | ||
| 204 | } | ||
| 205 | if (tds != NULL) { | ||
| 206 | total_disk_space = atof(tds); | ||
| 207 | } | ||
| 208 | |||
| 209 | if (total_disk_space > 0 && free_disk_space >= 0) { | ||
| 210 | double percent_used_space = ((total_disk_space - free_disk_space) / total_disk_space) * 100; | ||
| 211 | double warning_used_space = ((float)config.warning_value / 100) * total_disk_space; | ||
| 212 | double critical_used_space = ((float)config.critical_value / 100) * total_disk_space; | ||
| 213 | |||
| 214 | xasprintf(&temp_string, _("%s:\\ - total: %.2f Gb - used: %.2f Gb (%.0f%%) - free %.2f Gb (%.0f%%)"), config.value_list, | ||
| 215 | total_disk_space / 1073741824, (total_disk_space - free_disk_space) / 1073741824, percent_used_space, | ||
| 216 | free_disk_space / 1073741824, (free_disk_space / total_disk_space) * 100); | ||
| 217 | xasprintf(&temp_string_perf, _("'%s:\\ Used Space'=%.2fGb;%.2f;%.2f;0.00;%.2f"), config.value_list, | ||
| 218 | (total_disk_space - free_disk_space) / 1073741824, warning_used_space / 1073741824, | ||
| 219 | critical_used_space / 1073741824, total_disk_space / 1073741824); | ||
| 220 | |||
| 221 | if (config.check_critical_value && percent_used_space >= config.critical_value) { | ||
| 222 | return_code = STATE_CRITICAL; | ||
| 223 | } else if (config.check_warning_value && percent_used_space >= config.warning_value) { | ||
| 224 | return_code = STATE_WARNING; | ||
| 225 | } else { | ||
| 226 | return_code = STATE_OK; | ||
| 227 | } | ||
| 228 | |||
| 229 | output_message = strdup(temp_string); | ||
| 230 | perfdata = temp_string_perf; | ||
| 231 | } else { | ||
| 232 | output_message = strdup(_("Free disk space : Invalid drive")); | ||
| 233 | return_code = STATE_UNKNOWN; | ||
| 234 | } | ||
| 235 | } | ||
| 236 | break; | ||
| 237 | case CHECK_SERVICESTATE: | ||
| 238 | case CHECK_PROCSTATE: | ||
| 239 | if (config.value_list == NULL) { | ||
| 240 | output_message = strdup(_("No service/process specified")); | ||
| 241 | } else { | ||
| 242 | preparelist(config.value_list); /* replace , between services with & to send the request */ | ||
| 243 | xasprintf(&send_buffer, "%s&%u&%s&%s", config.req_password, (config.vars_to_check == CHECK_SERVICESTATE) ? 5 : 6, | ||
| 244 | (config.show_all) ? "ShowAll" : "ShowFail", config.value_list); | ||
| 245 | fetch_data(config.server_address, config.server_port, send_buffer); | ||
| 246 | char *numstr = strtok(recv_buffer, "&"); | ||
| 247 | if (numstr == NULL) { | ||
| 248 | die(STATE_UNKNOWN, _("could not fetch information from server\n")); | ||
| 249 | } | ||
| 250 | return_code = atoi(numstr); | ||
| 251 | temp_string = strtok(NULL, "&"); | ||
| 252 | output_message = strdup(temp_string); | ||
| 253 | } | ||
| 254 | break; | ||
| 255 | case CHECK_MEMUSE: | ||
| 256 | xasprintf(&send_buffer, "%s&7", config.req_password); | ||
| 257 | fetch_data(config.server_address, config.server_port, send_buffer); | ||
| 258 | char *numstr = strtok(recv_buffer, "&"); | ||
| 259 | if (numstr == NULL) { | ||
| 260 | die(STATE_UNKNOWN, _("could not fetch information from server\n")); | ||
| 261 | } | ||
| 262 | double mem_commitLimit = atof(numstr); | ||
| 263 | numstr = strtok(NULL, "&"); | ||
| 264 | if (numstr == NULL) { | ||
| 265 | die(STATE_UNKNOWN, _("could not fetch information from server\n")); | ||
| 266 | } | ||
| 267 | double mem_commitByte = atof(numstr); | ||
| 268 | double percent_used_space = (mem_commitByte / mem_commitLimit) * 100; | ||
| 269 | double warning_used_space = ((float)config.warning_value / 100) * mem_commitLimit; | ||
| 270 | double critical_used_space = ((float)config.critical_value / 100) * mem_commitLimit; | ||
| 271 | |||
| 272 | /* Divisor should be 1048567, not 3044515, as we are measuring "Commit Charge" here, | ||
| 273 | which equals RAM + Pagefiles. */ | ||
| 274 | xasprintf(&output_message, _("Memory usage: total:%.2f MB - used: %.2f MB (%.0f%%) - free: %.2f MB (%.0f%%)"), | ||
| 275 | mem_commitLimit / 1048567, mem_commitByte / 1048567, percent_used_space, (mem_commitLimit - mem_commitByte) / 1048567, | ||
| 276 | (mem_commitLimit - mem_commitByte) / mem_commitLimit * 100); | ||
| 277 | xasprintf(&perfdata, _("'Memory usage'=%.2fMB;%.2f;%.2f;0.00;%.2f"), mem_commitByte / 1048567, warning_used_space / 1048567, | ||
| 278 | critical_used_space / 1048567, mem_commitLimit / 1048567); | ||
| 279 | |||
| 280 | return_code = STATE_OK; | ||
| 281 | if (config.check_critical_value && percent_used_space >= config.critical_value) { | ||
| 282 | return_code = STATE_CRITICAL; | ||
| 283 | } else if (config.check_warning_value && percent_used_space >= config.warning_value) { | ||
| 284 | return_code = STATE_WARNING; | ||
| 285 | } | ||
| 286 | |||
| 287 | break; | ||
| 288 | case CHECK_COUNTER: { | ||
| 289 | /* | ||
| 290 | CHECK_COUNTER has been modified to provide extensive perfdata information. | ||
| 291 | In order to do this, some modifications have been done to the code | ||
| 292 | and some constraints have been introduced. | ||
| 293 | |||
| 294 | 1) For the sake of simplicity of the code, perfdata information will only be | ||
| 295 | provided when the "description" field is added. | ||
| 296 | |||
| 297 | 2) If the counter you're going to measure is percent-based, the code will detect | ||
| 298 | the percent sign in its name and will attribute minimum (0%) and maximum (100%) | ||
| 299 | values automagically, as well the "%" sign to graph units. | ||
| 300 | |||
| 301 | 3) OTOH, if the counter is "absolute", you'll have to provide the following | ||
| 302 | the counter unit - that is, the dimensions of the counter you're getting. Examples: | ||
| 303 | pages/s, packets transferred, etc. | ||
| 304 | |||
| 305 | 4) If you want, you may provide the minimum and maximum values to expect. They aren't mandatory, | ||
| 306 | but once specified they MUST have the same order of magnitude and units of -w and -c; otherwise. | ||
| 307 | strange things will happen when you make graphs of your data. | ||
| 308 | */ | ||
| 309 | |||
| 310 | double counter_value = 0.0; | ||
| 311 | if (config.value_list == NULL) { | ||
| 312 | output_message = strdup(_("No counter specified")); | ||
| 313 | } else { | ||
| 314 | preparelist(config.value_list); /* replace , between services with & to send the request */ | ||
| 315 | bool isPercent = (strchr(config.value_list, '%') != NULL); | ||
| 316 | |||
| 317 | strtok(config.value_list, "&"); /* burn the first parameters */ | ||
| 318 | description = strtok(NULL, "&"); | ||
| 319 | counter_unit = strtok(NULL, "&"); | ||
| 320 | xasprintf(&send_buffer, "%s&8&%s", config.req_password, config.value_list); | ||
| 321 | fetch_data(config.server_address, config.server_port, send_buffer); | ||
| 322 | counter_value = atof(recv_buffer); | ||
| 323 | |||
| 324 | bool allRight = false; | ||
| 325 | if (description == NULL) { | ||
| 326 | xasprintf(&output_message, "%.f", counter_value); | ||
| 327 | } else if (isPercent) { | ||
| 328 | counter_unit = strdup("%"); | ||
| 329 | allRight = true; | ||
| 330 | } | ||
| 331 | |||
| 332 | char *minval = NULL; | ||
| 333 | char *maxval = NULL; | ||
| 334 | double fminval = 0; | ||
| 335 | double fmaxval = 0; | ||
| 336 | if ((counter_unit != NULL) && (!allRight)) { | ||
| 337 | minval = strtok(NULL, "&"); | ||
| 338 | maxval = strtok(NULL, "&"); | ||
| 339 | |||
| 340 | /* All parameters specified. Let's check the numbers */ | ||
| 341 | |||
| 342 | fminval = (minval != NULL) ? strtod(minval, &errcvt) : -1; | ||
| 343 | fmaxval = (minval != NULL) ? strtod(maxval, &errcvt) : -1; | ||
| 344 | |||
| 345 | if ((fminval == 0) && (minval == errcvt)) { | ||
| 346 | output_message = strdup(_("Minimum value contains non-numbers")); | ||
| 347 | } else { | ||
| 348 | if ((fmaxval == 0) && (maxval == errcvt)) { | ||
| 349 | output_message = strdup(_("Maximum value contains non-numbers")); | ||
| 350 | } else { | ||
| 351 | allRight = true; /* Everything is OK. */ | ||
| 352 | } | ||
| 353 | } | ||
| 354 | } else if ((counter_unit == NULL) && (description != NULL)) { | ||
| 355 | output_message = strdup(_("No unit counter specified")); | ||
| 356 | } | ||
| 357 | |||
| 358 | if (allRight) { | ||
| 359 | /* Let's format the output string, finally... */ | ||
| 360 | if (strstr(description, "%") == NULL) { | ||
| 361 | xasprintf(&output_message, "%s = %.2f %s", description, counter_value, counter_unit); | ||
| 362 | } else { | ||
| 363 | /* has formatting, will segv if wrong */ | ||
| 364 | xasprintf(&output_message, description, counter_value); | ||
| 365 | } | ||
| 366 | xasprintf(&output_message, "%s |", output_message); | ||
| 367 | xasprintf(&output_message, "%s %s", output_message, | ||
| 368 | fperfdata(description, counter_value, counter_unit, 1, config.warning_value, 1, config.critical_value, | ||
| 369 | (!(isPercent) && (minval != NULL)), fminval, (!(isPercent) && (minval != NULL)), fmaxval)); | ||
| 370 | } | ||
| 371 | } | ||
| 372 | |||
| 373 | if (config.critical_value > config.warning_value) { /* Normal thresholds */ | ||
| 374 | if (config.check_critical_value && counter_value >= config.critical_value) { | ||
| 375 | return_code = STATE_CRITICAL; | ||
| 376 | } else if (config.check_warning_value && counter_value >= config.warning_value) { | ||
| 377 | return_code = STATE_WARNING; | ||
| 378 | } else { | ||
| 379 | return_code = STATE_OK; | ||
| 380 | } | ||
| 381 | } else { /* inverse thresholds */ | ||
| 382 | return_code = STATE_OK; | ||
| 383 | if (config.check_critical_value && counter_value <= config.critical_value) { | ||
| 384 | return_code = STATE_CRITICAL; | ||
| 385 | } else if (config.check_warning_value && counter_value <= config.warning_value) { | ||
| 386 | return_code = STATE_WARNING; | ||
| 387 | } | ||
| 388 | } | ||
| 389 | } break; | ||
| 390 | case CHECK_FILEAGE: | ||
| 391 | if (config.value_list == NULL) { | ||
| 392 | output_message = strdup(_("No counter specified")); | ||
| 393 | } else { | ||
| 394 | preparelist(config.value_list); /* replace , between services with & to send the request */ | ||
| 395 | xasprintf(&send_buffer, "%s&9&%s", config.req_password, config.value_list); | ||
| 396 | fetch_data(config.server_address, config.server_port, send_buffer); | ||
| 397 | unsigned long age_in_minutes = atoi(strtok(recv_buffer, "&")); | ||
| 398 | description = strtok(NULL, "&"); | ||
| 399 | output_message = strdup(description); | ||
| 400 | |||
| 401 | if (config.critical_value > config.warning_value) { /* Normal thresholds */ | ||
| 402 | if (config.check_critical_value && age_in_minutes >= config.critical_value) { | ||
| 403 | return_code = STATE_CRITICAL; | ||
| 404 | } else if (config.check_warning_value && age_in_minutes >= config.warning_value) { | ||
| 405 | return_code = STATE_WARNING; | ||
| 406 | } else { | ||
| 407 | return_code = STATE_OK; | ||
| 408 | } | ||
| 409 | } else { /* inverse thresholds */ | ||
| 410 | if (config.check_critical_value && age_in_minutes <= config.critical_value) { | ||
| 411 | return_code = STATE_CRITICAL; | ||
| 412 | } else if (config.check_warning_value && age_in_minutes <= config.warning_value) { | ||
| 413 | return_code = STATE_WARNING; | ||
| 414 | } else { | ||
| 415 | return_code = STATE_OK; | ||
| 416 | } | ||
| 417 | } | ||
| 418 | } | ||
| 419 | break; | ||
| 420 | |||
| 421 | case CHECK_INSTANCES: | ||
| 422 | if (config.value_list == NULL) { | ||
| 423 | output_message = strdup(_("No counter specified")); | ||
| 424 | } else { | ||
| 425 | xasprintf(&send_buffer, "%s&10&%s", config.req_password, config.value_list); | ||
| 426 | fetch_data(config.server_address, config.server_port, send_buffer); | ||
| 427 | if (!strncmp(recv_buffer, "ERROR", 5)) { | ||
| 428 | printf("NSClient - %s\n", recv_buffer); | ||
| 429 | exit(STATE_UNKNOWN); | ||
| 430 | } | ||
| 431 | xasprintf(&output_message, "%s", recv_buffer); | ||
| 432 | return_code = STATE_OK; | ||
| 433 | } | ||
| 434 | break; | ||
| 435 | |||
| 436 | case CHECK_NONE: | ||
| 437 | default: | ||
| 438 | usage4(_("Please specify a variable to check")); | ||
| 439 | break; | ||
| 440 | } | ||
| 441 | |||
| 442 | /* reset timeout */ | ||
| 443 | alarm(0); | ||
| 444 | |||
| 445 | if (perfdata == NULL) { | ||
| 446 | printf("%s\n", output_message); | ||
| 447 | } else { | ||
| 448 | printf("%s | %s\n", output_message, perfdata); | ||
| 449 | } | ||
| 450 | return return_code; | ||
| 451 | } | ||
| 452 | |||
| 453 | /* process command-line arguments */ | ||
| 454 | check_nt_config_wrapper process_arguments(int argc, char **argv) { | ||
| 455 | static struct option longopts[] = {{"port", required_argument, 0, 'p'}, | ||
| 456 | {"timeout", required_argument, 0, 't'}, | ||
| 457 | {"critical", required_argument, 0, 'c'}, | ||
| 458 | {"warning", required_argument, 0, 'w'}, | ||
| 459 | {"variable", required_argument, 0, 'v'}, | ||
| 460 | {"hostname", required_argument, 0, 'H'}, | ||
| 461 | {"params", required_argument, 0, 'l'}, | ||
| 462 | {"secret", required_argument, 0, 's'}, | ||
| 463 | {"display", required_argument, 0, 'd'}, | ||
| 464 | {"unknown-timeout", no_argument, 0, 'u'}, | ||
| 465 | {"version", no_argument, 0, 'V'}, | ||
| 466 | {"help", no_argument, 0, 'h'}, | ||
| 467 | {0, 0, 0, 0}}; | ||
| 468 | |||
| 469 | check_nt_config_wrapper result = { | ||
| 470 | .errorcode = OK, | ||
| 471 | .config = check_nt_config_init(), | ||
| 472 | }; | ||
| 473 | |||
| 474 | /* no options were supplied */ | ||
| 475 | if (argc < 2) { | ||
| 476 | result.errorcode = ERROR; | ||
| 477 | return result; | ||
| 478 | } | ||
| 479 | |||
| 480 | /* backwards compatibility */ | ||
| 481 | if (!is_option(argv[1])) { | ||
| 482 | result.config.server_address = strdup(argv[1]); | ||
| 483 | argv[1] = argv[0]; | ||
| 484 | argv = &argv[1]; | ||
| 485 | argc--; | ||
| 486 | } | ||
| 487 | |||
| 488 | for (int index = 1; index < argc; index++) { | ||
| 489 | if (strcmp("-to", argv[index]) == 0) { | ||
| 490 | strcpy(argv[index], "-t"); | ||
| 491 | } else if (strcmp("-wv", argv[index]) == 0) { | ||
| 492 | strcpy(argv[index], "-w"); | ||
| 493 | } else if (strcmp("-cv", argv[index]) == 0) { | ||
| 494 | strcpy(argv[index], "-c"); | ||
| 495 | } | ||
| 496 | } | ||
| 497 | |||
| 498 | int option = 0; | ||
| 499 | while (true) { | ||
| 500 | int option_index = getopt_long(argc, argv, "+hVH:t:c:w:p:v:l:s:d:u", longopts, &option); | ||
| 501 | |||
| 502 | if (option_index == -1 || option_index == EOF || option_index == 1) { | ||
| 503 | break; | ||
| 504 | } | ||
| 505 | |||
| 506 | switch (option_index) { | ||
| 507 | case '?': /* print short usage statement if args not parsable */ | ||
| 508 | usage5(); | ||
| 509 | case 'h': /* help */ | ||
| 510 | print_help(); | ||
| 511 | exit(STATE_UNKNOWN); | ||
| 512 | case 'V': /* version */ | ||
| 513 | print_revision(progname, NP_VERSION); | ||
| 514 | exit(STATE_UNKNOWN); | ||
| 515 | case 'H': /* hostname */ | ||
| 516 | result.config.server_address = optarg; | ||
| 517 | break; | ||
| 518 | case 's': /* password */ | ||
| 519 | result.config.req_password = optarg; | ||
| 520 | break; | ||
| 521 | case 'p': /* port */ | ||
| 522 | if (is_intnonneg(optarg)) { | ||
| 523 | result.config.server_port = atoi(optarg); | ||
| 524 | } else { | ||
| 525 | die(STATE_UNKNOWN, _("Server port must be an integer\n")); | ||
| 526 | } | ||
| 527 | break; | ||
| 528 | case 'v': | ||
| 529 | if (strlen(optarg) < 4) { | ||
| 530 | result.errorcode = ERROR; | ||
| 531 | return result; | ||
| 532 | } | ||
| 533 | if (!strcmp(optarg, "CLIENTVERSION")) { | ||
| 534 | result.config.vars_to_check = CHECK_CLIENTVERSION; | ||
| 535 | } else if (!strcmp(optarg, "CPULOAD")) { | ||
| 536 | result.config.vars_to_check = CHECK_CPULOAD; | ||
| 537 | } else if (!strcmp(optarg, "UPTIME")) { | ||
| 538 | result.config.vars_to_check = CHECK_UPTIME; | ||
| 539 | } else if (!strcmp(optarg, "USEDDISKSPACE")) { | ||
| 540 | result.config.vars_to_check = CHECK_USEDDISKSPACE; | ||
| 541 | } else if (!strcmp(optarg, "SERVICESTATE")) { | ||
| 542 | result.config.vars_to_check = CHECK_SERVICESTATE; | ||
| 543 | } else if (!strcmp(optarg, "PROCSTATE")) { | ||
| 544 | result.config.vars_to_check = CHECK_PROCSTATE; | ||
| 545 | } else if (!strcmp(optarg, "MEMUSE")) { | ||
| 546 | result.config.vars_to_check = CHECK_MEMUSE; | ||
| 547 | } else if (!strcmp(optarg, "COUNTER")) { | ||
| 548 | result.config.vars_to_check = CHECK_COUNTER; | ||
| 549 | } else if (!strcmp(optarg, "FILEAGE")) { | ||
| 550 | result.config.vars_to_check = CHECK_FILEAGE; | ||
| 551 | } else if (!strcmp(optarg, "INSTANCES")) { | ||
| 552 | result.config.vars_to_check = CHECK_INSTANCES; | ||
| 553 | } else { | ||
| 554 | result.errorcode = ERROR; | ||
| 555 | return result; | ||
| 556 | } | ||
| 557 | break; | ||
| 558 | case 'l': /* value list */ | ||
| 559 | result.config.value_list = optarg; | ||
| 560 | break; | ||
| 561 | case 'w': /* warning threshold */ | ||
| 562 | result.config.warning_value = strtoul(optarg, NULL, 10); | ||
| 563 | result.config.check_warning_value = true; | ||
| 564 | break; | ||
| 565 | case 'c': /* critical threshold */ | ||
| 566 | result.config.critical_value = strtoul(optarg, NULL, 10); | ||
| 567 | result.config.check_critical_value = true; | ||
| 568 | break; | ||
| 569 | case 'd': /* Display select for services */ | ||
| 570 | if (!strcmp(optarg, "SHOWALL")) { | ||
| 571 | result.config.show_all = true; | ||
| 572 | } | ||
| 573 | break; | ||
| 574 | case 'u': | ||
| 575 | socket_timeout_state = STATE_UNKNOWN; | ||
| 576 | break; | ||
| 577 | case 't': /* timeout */ | ||
| 578 | socket_timeout = atoi(optarg); | ||
| 579 | if (socket_timeout <= 0) { | ||
| 580 | result.errorcode = ERROR; | ||
| 581 | return result; | ||
| 582 | } | ||
| 583 | } | ||
| 584 | } | ||
| 585 | if (result.config.server_address == NULL) { | ||
| 586 | usage4(_("You must provide a server address or host name")); | ||
| 587 | } | ||
| 588 | |||
| 589 | if (result.config.vars_to_check == CHECK_NONE) { | ||
| 590 | result.errorcode = ERROR; | ||
| 591 | return result; | ||
| 592 | } | ||
| 593 | |||
| 594 | if (result.config.req_password == NULL) { | ||
| 595 | result.config.req_password = strdup(_("None")); | ||
| 596 | } | ||
| 597 | |||
| 598 | return result; | ||
| 599 | } | ||
| 600 | |||
| 601 | void fetch_data(const char *address, int port, const char *sendb) { | ||
| 602 | int result = process_tcp_request(address, port, sendb, recv_buffer, sizeof(recv_buffer)); | ||
| 603 | |||
| 604 | if (result != STATE_OK) { | ||
| 605 | die(result, _("could not fetch information from server\n")); | ||
| 606 | } | ||
| 607 | |||
| 608 | if (!strncmp(recv_buffer, "ERROR", 5)) { | ||
| 609 | die(STATE_UNKNOWN, "NSClient - %s\n", recv_buffer); | ||
| 610 | } | ||
| 611 | } | ||
| 612 | |||
| 613 | bool strtoularray(unsigned long *array, char *string, const char *delim) { | ||
| 614 | /* split a <delim> delimited string into a long array */ | ||
| 615 | for (int idx = 0; idx < MAX_VALUE_LIST; idx++) { | ||
| 616 | array[idx] = 0; | ||
| 617 | } | ||
| 618 | |||
| 619 | int idx = 0; | ||
| 620 | for (char *t1 = strtok(string, delim); t1 != NULL; t1 = strtok(NULL, delim)) { | ||
| 621 | if (is_numeric(t1) && idx < MAX_VALUE_LIST) { | ||
| 622 | array[idx] = strtoul(t1, NULL, 10); | ||
| 623 | idx++; | ||
| 624 | } else { | ||
| 625 | return false; | ||
| 626 | } | ||
| 627 | } | ||
| 628 | return true; | ||
| 629 | } | ||
| 630 | |||
| 631 | void preparelist(char *string) { | ||
| 632 | /* Replace all , with & which is the delimiter for the request */ | ||
| 633 | for (int i = 0; (size_t)i < strlen(string); i++) { | ||
| 634 | if (string[i] == ',') { | ||
| 635 | string[i] = '&'; | ||
| 636 | } | ||
| 637 | } | ||
| 638 | } | ||
| 639 | |||
| 640 | void print_help(void) { | ||
| 641 | print_revision(progname, NP_VERSION); | ||
| 642 | |||
| 643 | printf("Copyright (c) 2000 Yves Rubin (rubiyz@yahoo.com)\n"); | ||
| 644 | printf(COPYRIGHT, copyright, email); | ||
| 645 | |||
| 646 | printf("%s\n", _("This plugin collects data from the NSClient service running on a")); | ||
| 647 | printf("%s\n", _("Windows NT/2000/XP/2003 server.")); | ||
| 648 | |||
| 649 | printf("\n\n"); | ||
| 650 | |||
| 651 | print_usage(); | ||
| 652 | |||
| 653 | printf(UT_HELP_VRSN); | ||
| 654 | printf(UT_EXTRA_OPTS); | ||
| 655 | |||
| 656 | printf("%s\n", _("Options:")); | ||
| 657 | printf(" %s\n", "-H, --hostname=HOST"); | ||
| 658 | printf(" %s\n", _("Name of the host to check")); | ||
| 659 | printf(" %s\n", "-p, --port=INTEGER"); | ||
| 660 | printf(" %s", _("Optional port number (default: ")); | ||
| 661 | printf("%d)\n", PORT); | ||
| 662 | printf(" %s\n", "-s, --secret=<password>"); | ||
| 663 | printf(" %s\n", _("Password needed for the request")); | ||
| 664 | printf(" %s\n", "-w, --warning=INTEGER"); | ||
| 665 | printf(" %s\n", _("Threshold which will result in a warning status")); | ||
| 666 | printf(" %s\n", "-c, --critical=INTEGER"); | ||
| 667 | printf(" %s\n", _("Threshold which will result in a critical status")); | ||
| 668 | printf(" %s\n", "-t, --timeout=INTEGER"); | ||
| 669 | printf(" %s", _("Seconds before connection attempt times out (default: ")); | ||
| 670 | printf(" %s\n", "-l, --params=<parameters>"); | ||
| 671 | printf(" %s", _("Parameters passed to specified check (see below)")); | ||
| 672 | printf(" %s\n", "-d, --display={SHOWALL}"); | ||
| 673 | printf(" %s", _("Display options (currently only SHOWALL works)")); | ||
| 674 | printf(" %s\n", "-u, --unknown-timeout"); | ||
| 675 | printf(" %s", _("Return UNKNOWN on timeouts")); | ||
| 676 | printf("%d)\n", DEFAULT_SOCKET_TIMEOUT); | ||
| 677 | printf(" %s\n", "-h, --help"); | ||
| 678 | printf(" %s\n", _("Print this help screen")); | ||
| 679 | printf(" %s\n", "-V, --version"); | ||
| 680 | printf(" %s\n", _("Print version information")); | ||
| 681 | printf(" %s\n", "-v, --variable=STRING"); | ||
| 682 | printf(" %s\n\n", _("Variable to check")); | ||
| 683 | printf("%s\n", _("Valid variables are:")); | ||
| 684 | printf(" %s", "CLIENTVERSION ="); | ||
| 685 | printf(" %s\n", _("Get the NSClient version")); | ||
| 686 | printf(" %s\n", _("If -l <version> is specified, will return warning if versions differ.")); | ||
| 687 | printf(" %s\n", "CPULOAD ="); | ||
| 688 | printf(" %s\n", _("Average CPU load on last x minutes.")); | ||
| 689 | printf(" %s\n", _("Request a -l parameter with the following syntax:")); | ||
| 690 | printf(" %s\n", _("-l <minutes range>,<warning threshold>,<critical threshold>.")); | ||
| 691 | printf(" %s\n", _("<minute range> should be less than 24*60.")); | ||
| 692 | printf(" %s\n", _("Thresholds are percentage and up to 10 requests can be done in one shot.")); | ||
| 693 | printf(" %s\n", "ie: -l 60,90,95,120,90,95"); | ||
| 694 | printf(" %s\n", "UPTIME ="); | ||
| 695 | printf(" %s\n", _("Get the uptime of the machine.")); | ||
| 696 | printf(" %s\n", _("-l <unit> ")); | ||
| 697 | printf(" %s\n", _("<unit> = seconds, minutes, hours, or days. (default: minutes)")); | ||
| 698 | printf(" %s\n", _("Thresholds will use the unit specified above.")); | ||
| 699 | printf(" %s\n", "USEDDISKSPACE ="); | ||
| 700 | printf(" %s\n", _("Size and percentage of disk use.")); | ||
| 701 | printf(" %s\n", _("Request a -l parameter containing the drive letter only.")); | ||
| 702 | printf(" %s\n", _("Warning and critical thresholds can be specified with -w and -c.")); | ||
| 703 | printf(" %s\n", "MEMUSE ="); | ||
| 704 | printf(" %s\n", _("Memory use.")); | ||
| 705 | printf(" %s\n", _("Warning and critical thresholds can be specified with -w and -c.")); | ||
| 706 | printf(" %s\n", "SERVICESTATE ="); | ||
| 707 | printf(" %s\n", _("Check the state of one or several services.")); | ||
| 708 | printf(" %s\n", _("Request a -l parameters with the following syntax:")); | ||
| 709 | printf(" %s\n", _("-l <service1>,<service2>,<service3>,...")); | ||
| 710 | printf(" %s\n", _("You can specify -d SHOWALL in case you want to see working services")); | ||
| 711 | printf(" %s\n", _("in the returned string.")); | ||
| 712 | printf(" %s\n", "PROCSTATE ="); | ||
| 713 | printf(" %s\n", _("Check if one or several process are running.")); | ||
| 714 | printf(" %s\n", _("Same syntax as SERVICESTATE.")); | ||
| 715 | printf(" %s\n", "COUNTER ="); | ||
| 716 | printf(" %s\n", _("Check any performance counter of Windows NT/2000.")); | ||
| 717 | printf(" %s\n", _("Request a -l parameters with the following syntax:")); | ||
| 718 | printf(" %s\n", _("-l \"\\\\<performance object>\\\\counter\",\"<description>")); | ||
| 719 | printf(" %s\n", _("The <description> parameter is optional and is given to a printf ")); | ||
| 720 | printf(" %s\n", _("output command which requires a float parameter.")); | ||
| 721 | printf(" %s\n", _("If <description> does not include \"%%\", it is used as a label.")); | ||
| 722 | printf(" %s\n", _("Some examples:")); | ||
| 723 | printf(" %s\n", "\"Paging file usage is %%.2f %%%%\""); | ||
| 724 | printf(" %s\n", "\"%%.f %%%% paging file used.\""); | ||
| 725 | printf(" %s\n", "INSTANCES ="); | ||
| 726 | printf(" %s\n", _("Check any performance counter object of Windows NT/2000.")); | ||
| 727 | printf(" %s\n", _("Syntax: check_nt -H <hostname> -p <port> -v INSTANCES -l <counter object>")); | ||
| 728 | printf(" %s\n", _("<counter object> is a Windows Perfmon Counter object (eg. Process),")); | ||
| 729 | printf(" %s\n", _("if it is two words, it should be enclosed in quotes")); | ||
| 730 | printf(" %s\n", _("The returned results will be a comma-separated list of instances on ")); | ||
| 731 | printf(" %s\n", _(" the selected computer for that object.")); | ||
| 732 | printf(" %s\n", _("The purpose of this is to be run from command line to determine what instances")); | ||
| 733 | printf(" %s\n", _(" are available for monitoring without having to log onto the Windows server")); | ||
| 734 | printf(" %s\n", _(" to run Perfmon directly.")); | ||
| 735 | printf(" %s\n", _("It can also be used in scripts that automatically create the monitoring service")); | ||
| 736 | printf(" %s\n", _(" configuration files.")); | ||
| 737 | printf(" %s\n", _("Some examples:")); | ||
| 738 | printf(" %s\n\n", _("check_nt -H 192.168.1.1 -p 1248 -v INSTANCES -l Process")); | ||
| 739 | |||
| 740 | printf("%s\n", _("Notes:")); | ||
| 741 | printf(" %s\n", _("- The NSClient service should be running on the server to get any information")); | ||
| 742 | printf(" %s\n", "(http://nsclient.ready2run.nl)."); | ||
| 743 | printf(" %s\n", _("- Critical thresholds should be lower than warning thresholds")); | ||
| 744 | printf(" %s\n", _("- Default port 1248 is sometimes in use by other services. The error")); | ||
| 745 | printf(" %s\n", _("output when this happens contains \"Cannot map xxxxx to protocol number\".")); | ||
| 746 | printf(" %s\n", _("One fix for this is to change the port to something else on check_nt ")); | ||
| 747 | printf(" %s\n", _("and on the client service it\'s connecting to.")); | ||
| 748 | |||
| 749 | printf(UT_SUPPORT); | ||
| 750 | } | ||
| 751 | |||
| 752 | void print_usage(void) { | ||
| 753 | printf("%s\n", _("Usage:")); | ||
| 754 | printf("%s -H host -v variable [-p port] [-w warning] [-c critical]\n", progname); | ||
| 755 | printf("[-l params] [-d SHOWALL] [-u] [-t timeout]\n"); | ||
| 756 | } | ||
diff --git a/plugins/check_nt.d/config.h b/plugins/check_nt.d/config.h deleted file mode 100644 index 431889cb..00000000 --- a/plugins/check_nt.d/config.h +++ /dev/null | |||
| @@ -1,53 +0,0 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include <stddef.h> | ||
| 5 | |||
| 6 | enum { | ||
| 7 | PORT = 1248, | ||
| 8 | }; | ||
| 9 | |||
| 10 | enum checkvars { | ||
| 11 | CHECK_NONE, | ||
| 12 | CHECK_CLIENTVERSION, | ||
| 13 | CHECK_CPULOAD, | ||
| 14 | CHECK_UPTIME, | ||
| 15 | CHECK_USEDDISKSPACE, | ||
| 16 | CHECK_SERVICESTATE, | ||
| 17 | CHECK_PROCSTATE, | ||
| 18 | CHECK_MEMUSE, | ||
| 19 | CHECK_COUNTER, | ||
| 20 | CHECK_FILEAGE, | ||
| 21 | CHECK_INSTANCES | ||
| 22 | }; | ||
| 23 | |||
| 24 | typedef struct { | ||
| 25 | char *server_address; | ||
| 26 | int server_port; | ||
| 27 | char *req_password; | ||
| 28 | enum checkvars vars_to_check; | ||
| 29 | bool show_all; | ||
| 30 | char *value_list; | ||
| 31 | bool check_warning_value; | ||
| 32 | unsigned long warning_value; | ||
| 33 | bool check_critical_value; | ||
| 34 | unsigned long critical_value; | ||
| 35 | } check_nt_config; | ||
| 36 | |||
| 37 | check_nt_config check_nt_config_init() { | ||
| 38 | check_nt_config tmp = { | ||
| 39 | .server_address = NULL, | ||
| 40 | .server_port = PORT, | ||
| 41 | .req_password = NULL, | ||
| 42 | |||
| 43 | .vars_to_check = CHECK_NONE, | ||
| 44 | .show_all = false, | ||
| 45 | .value_list = NULL, | ||
| 46 | |||
| 47 | .check_warning_value = false, | ||
| 48 | .warning_value = 0, | ||
| 49 | .check_critical_value = false, | ||
| 50 | .critical_value = 0, | ||
| 51 | }; | ||
| 52 | return tmp; | ||
| 53 | } | ||
diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c deleted file mode 100644 index d33f8786..00000000 --- a/plugins/check_ntp.c +++ /dev/null | |||
| @@ -1,901 +0,0 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Monitoring check_ntp plugin | ||
| 4 | * | ||
| 5 | * License: GPL | ||
| 6 | * Copyright (c) 2006 Sean Finney <seanius@seanius.net> | ||
| 7 | * Copyright (c) 2006-2024 Monitoring Plugins Development Team | ||
| 8 | * | ||
| 9 | * Description: | ||
| 10 | * | ||
| 11 | * This file contains the check_ntp plugin | ||
| 12 | * | ||
| 13 | * This plugin to check ntp servers independent of any commandline | ||
| 14 | * programs or external libraries. | ||
| 15 | * | ||
| 16 | * | ||
| 17 | * This program is free software: you can redistribute it and/or modify | ||
| 18 | * it under the terms of the GNU General Public License as published by | ||
| 19 | * the Free Software Foundation, either version 3 of the License, or | ||
| 20 | * (at your option) any later version. | ||
| 21 | * | ||
| 22 | * This program is distributed in the hope that it will be useful, | ||
| 23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 25 | * GNU General Public License for more details. | ||
| 26 | * | ||
| 27 | * You should have received a copy of the GNU General Public License | ||
| 28 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 29 | * | ||
| 30 | * | ||
| 31 | *****************************************************************************/ | ||
| 32 | |||
| 33 | const char *progname = "check_ntp"; | ||
| 34 | const char *copyright = "2006-2024"; | ||
| 35 | const char *email = "devel@monitoring-plugins.org"; | ||
| 36 | |||
| 37 | #include "common.h" | ||
| 38 | #include "netutils.h" | ||
| 39 | #include "utils.h" | ||
| 40 | |||
| 41 | static char *server_address=NULL; | ||
| 42 | static int verbose=0; | ||
| 43 | static bool do_offset = false; | ||
| 44 | static char *owarn="60"; | ||
| 45 | static char *ocrit="120"; | ||
| 46 | static bool do_jitter = false; | ||
| 47 | static char *jwarn="5000"; | ||
| 48 | static char *jcrit="10000"; | ||
| 49 | |||
| 50 | static int process_arguments (int /*argc*/, char ** /*argv*/); | ||
| 51 | static thresholds *offset_thresholds = NULL; | ||
| 52 | static thresholds *jitter_thresholds = NULL; | ||
| 53 | static void print_help (void); | ||
| 54 | void print_usage (void); | ||
| 55 | |||
| 56 | /* number of times to perform each request to get a good average. */ | ||
| 57 | #ifndef AVG_NUM | ||
| 58 | #define AVG_NUM 4 | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* max size of control message data */ | ||
| 62 | #define MAX_CM_SIZE 468 | ||
| 63 | |||
| 64 | /* this structure holds everything in an ntp request/response as per rfc1305 */ | ||
| 65 | typedef struct { | ||
| 66 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ | ||
| 67 | uint8_t stratum; /* clock stratum */ | ||
| 68 | int8_t poll; /* polling interval */ | ||
| 69 | int8_t precision; /* precision of the local clock */ | ||
| 70 | int32_t rtdelay; /* total rt delay, as a fixed point num. see macros */ | ||
| 71 | uint32_t rtdisp; /* like above, but for max err to primary src */ | ||
| 72 | uint32_t refid; /* ref clock identifier */ | ||
| 73 | uint64_t refts; /* reference timestamp. local time local clock */ | ||
| 74 | uint64_t origts; /* time at which request departed client */ | ||
| 75 | uint64_t rxts; /* time at which request arrived at server */ | ||
| 76 | uint64_t txts; /* time at which request departed server */ | ||
| 77 | } ntp_message; | ||
| 78 | |||
| 79 | /* this structure holds data about results from querying offset from a peer */ | ||
| 80 | typedef struct { | ||
| 81 | time_t waiting; /* ts set when we started waiting for a response */ | ||
| 82 | int num_responses; /* number of successfully received responses */ | ||
| 83 | uint8_t stratum; /* copied verbatim from the ntp_message */ | ||
| 84 | double rtdelay; /* converted from the ntp_message */ | ||
| 85 | double rtdisp; /* converted from the ntp_message */ | ||
| 86 | double offset[AVG_NUM]; /* offsets from each response */ | ||
| 87 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ | ||
| 88 | } ntp_server_results; | ||
| 89 | |||
| 90 | /* this structure holds everything in an ntp control message as per rfc1305 */ | ||
| 91 | typedef struct { | ||
| 92 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ | ||
| 93 | uint8_t op; /* R,E,M bits and Opcode */ | ||
| 94 | uint16_t seq; /* Packet sequence */ | ||
| 95 | uint16_t status; /* Clock status */ | ||
| 96 | uint16_t assoc; /* Association */ | ||
| 97 | uint16_t offset; /* Similar to TCP sequence # */ | ||
| 98 | uint16_t count; /* # bytes of data */ | ||
| 99 | char data[MAX_CM_SIZE]; /* ASCII data of the request */ | ||
| 100 | /* NB: not necessarily NULL terminated! */ | ||
| 101 | } ntp_control_message; | ||
| 102 | |||
| 103 | /* this is an association/status-word pair found in control packet responses */ | ||
| 104 | typedef struct { | ||
| 105 | uint16_t assoc; | ||
| 106 | uint16_t status; | ||
| 107 | } ntp_assoc_status_pair; | ||
| 108 | |||
| 109 | /* bits 1,2 are the leap indicator */ | ||
| 110 | #define LI_MASK 0xc0 | ||
| 111 | #define LI(x) ((x&LI_MASK)>>6) | ||
| 112 | #define LI_SET(x,y) do{ x |= ((y<<6)&LI_MASK); }while(0) | ||
| 113 | /* and these are the values of the leap indicator */ | ||
| 114 | #define LI_NOWARNING 0x00 | ||
| 115 | #define LI_EXTRASEC 0x01 | ||
| 116 | #define LI_MISSINGSEC 0x02 | ||
| 117 | #define LI_ALARM 0x03 | ||
| 118 | /* bits 3,4,5 are the ntp version */ | ||
| 119 | #define VN_MASK 0x38 | ||
| 120 | #define VN(x) ((x&VN_MASK)>>3) | ||
| 121 | #define VN_SET(x,y) do{ x |= ((y<<3)&VN_MASK); }while(0) | ||
| 122 | #define VN_RESERVED 0x02 | ||
| 123 | /* bits 6,7,8 are the ntp mode */ | ||
| 124 | #define MODE_MASK 0x07 | ||
| 125 | #define MODE(x) (x&MODE_MASK) | ||
| 126 | #define MODE_SET(x,y) do{ x |= (y&MODE_MASK); }while(0) | ||
| 127 | /* here are some values */ | ||
| 128 | #define MODE_CLIENT 0x03 | ||
| 129 | #define MODE_CONTROLMSG 0x06 | ||
| 130 | /* In control message, bits 8-10 are R,E,M bits */ | ||
| 131 | #define REM_MASK 0xe0 | ||
| 132 | #define REM_RESP 0x80 | ||
| 133 | #define REM_ERROR 0x40 | ||
| 134 | #define REM_MORE 0x20 | ||
| 135 | /* In control message, bits 11 - 15 are opcode */ | ||
| 136 | #define OP_MASK 0x1f | ||
| 137 | #define OP_SET(x,y) do{ x |= (y&OP_MASK); }while(0) | ||
| 138 | #define OP_READSTAT 0x01 | ||
| 139 | #define OP_READVAR 0x02 | ||
| 140 | /* In peer status bytes, bits 6,7,8 determine clock selection status */ | ||
| 141 | #define PEER_SEL(x) ((ntohs(x)>>8)&0x07) | ||
| 142 | #define PEER_INCLUDED 0x04 | ||
| 143 | #define PEER_SYNCSOURCE 0x06 | ||
| 144 | |||
| 145 | /** | ||
| 146 | ** a note about the 32-bit "fixed point" numbers: | ||
| 147 | ** | ||
| 148 | they are divided into halves, each being a 16-bit int in network byte order: | ||
| 149 | - the first 16 bits are an int on the left side of a decimal point. | ||
| 150 | - the second 16 bits represent a fraction n/(2^16) | ||
| 151 | likewise for the 64-bit "fixed point" numbers with everything doubled :) | ||
| 152 | **/ | ||
| 153 | |||
| 154 | /* macros to access the left/right 16 bits of a 32-bit ntp "fixed point" | ||
| 155 | number. note that these can be used as lvalues too */ | ||
| 156 | #define L16(x) (((uint16_t*)&x)[0]) | ||
| 157 | #define R16(x) (((uint16_t*)&x)[1]) | ||
| 158 | /* macros to access the left/right 32 bits of a 64-bit ntp "fixed point" | ||
| 159 | number. these too can be used as lvalues */ | ||
| 160 | #define L32(x) (((uint32_t*)&x)[0]) | ||
| 161 | #define R32(x) (((uint32_t*)&x)[1]) | ||
| 162 | |||
| 163 | /* ntp wants seconds since 1/1/00, epoch is 1/1/70. this is the difference */ | ||
| 164 | #define EPOCHDIFF 0x83aa7e80UL | ||
| 165 | |||
| 166 | /* extract a 32-bit ntp fixed point number into a double */ | ||
| 167 | #define NTP32asDOUBLE(x) (ntohs(L16(x)) + (double)ntohs(R16(x))/65536.0) | ||
| 168 | |||
| 169 | /* likewise for a 64-bit ntp fp number */ | ||
| 170 | #define NTP64asDOUBLE(n) (double)(((uint64_t)n)?\ | ||
| 171 | (ntohl(L32(n))-EPOCHDIFF) + \ | ||
| 172 | (.00000001*(0.5+(double)(ntohl(R32(n))/42.94967296))):\ | ||
| 173 | 0) | ||
| 174 | |||
| 175 | /* convert a struct timeval to a double */ | ||
| 176 | #define TVasDOUBLE(x) (double)(x.tv_sec+(0.000001*x.tv_usec)) | ||
| 177 | |||
| 178 | /* convert an ntp 64-bit fp number to a struct timeval */ | ||
| 179 | #define NTP64toTV(n,t) \ | ||
| 180 | do{ if(!n) t.tv_sec = t.tv_usec = 0; \ | ||
| 181 | else { \ | ||
| 182 | t.tv_sec=ntohl(L32(n))-EPOCHDIFF; \ | ||
| 183 | t.tv_usec=(int)(0.5+(double)(ntohl(R32(n))/4294.967296)); \ | ||
| 184 | } \ | ||
| 185 | }while(0) | ||
| 186 | |||
| 187 | /* convert a struct timeval to an ntp 64-bit fp number */ | ||
| 188 | #define TVtoNTP64(t,n) \ | ||
| 189 | do{ if(!t.tv_usec && !t.tv_sec) n=0x0UL; \ | ||
| 190 | else { \ | ||
| 191 | L32(n)=htonl(t.tv_sec + EPOCHDIFF); \ | ||
| 192 | R32(n)=htonl((uint64_t)((4294.967296*t.tv_usec)+.5)); \ | ||
| 193 | } \ | ||
| 194 | } while(0) | ||
| 195 | |||
| 196 | /* NTP control message header is 12 bytes, plus any data in the data | ||
| 197 | * field, plus null padding to the nearest 32-bit boundary per rfc. | ||
| 198 | */ | ||
| 199 | #define SIZEOF_NTPCM(m) (12+ntohs(m.count)+((ntohs(m.count)%4)?4-(ntohs(m.count)%4):0)) | ||
| 200 | |||
| 201 | /* finally, a little helper or two for debugging: */ | ||
| 202 | #define DBG(x) do{if(verbose>1){ x; }}while(0); | ||
| 203 | #define PRINTSOCKADDR(x) \ | ||
| 204 | do{ \ | ||
| 205 | printf("%u.%u.%u.%u", (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff);\ | ||
| 206 | }while(0); | ||
| 207 | |||
| 208 | /* calculate the offset of the local clock */ | ||
| 209 | static inline double calc_offset(const ntp_message *m, const struct timeval *t){ | ||
| 210 | double client_tx, peer_rx, peer_tx, client_rx; | ||
| 211 | client_tx = NTP64asDOUBLE(m->origts); | ||
| 212 | peer_rx = NTP64asDOUBLE(m->rxts); | ||
| 213 | peer_tx = NTP64asDOUBLE(m->txts); | ||
| 214 | client_rx=TVasDOUBLE((*t)); | ||
| 215 | return (.5*((peer_tx-client_rx)+(peer_rx-client_tx))); | ||
| 216 | } | ||
| 217 | |||
| 218 | /* print out a ntp packet in human readable/debuggable format */ | ||
| 219 | void print_ntp_message(const ntp_message *p){ | ||
| 220 | struct timeval ref, orig, rx, tx; | ||
| 221 | |||
| 222 | NTP64toTV(p->refts,ref); | ||
| 223 | NTP64toTV(p->origts,orig); | ||
| 224 | NTP64toTV(p->rxts,rx); | ||
| 225 | NTP64toTV(p->txts,tx); | ||
| 226 | |||
| 227 | printf("packet contents:\n"); | ||
| 228 | printf("\tflags: 0x%.2x\n", p->flags); | ||
| 229 | printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags&LI_MASK); | ||
| 230 | printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags&VN_MASK); | ||
| 231 | printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags&MODE_MASK); | ||
| 232 | printf("\tstratum = %d\n", p->stratum); | ||
| 233 | printf("\tpoll = %g\n", pow(2, p->poll)); | ||
| 234 | printf("\tprecision = %g\n", pow(2, p->precision)); | ||
| 235 | printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(p->rtdelay)); | ||
| 236 | printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(p->rtdisp)); | ||
| 237 | printf("\trefid = %x\n", p->refid); | ||
| 238 | printf("\trefts = %-.16g\n", NTP64asDOUBLE(p->refts)); | ||
| 239 | printf("\torigts = %-.16g\n", NTP64asDOUBLE(p->origts)); | ||
| 240 | printf("\trxts = %-.16g\n", NTP64asDOUBLE(p->rxts)); | ||
| 241 | printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts)); | ||
| 242 | } | ||
| 243 | |||
| 244 | void print_ntp_control_message(const ntp_control_message *p){ | ||
| 245 | int i=0, numpeers=0; | ||
| 246 | const ntp_assoc_status_pair *peer=NULL; | ||
| 247 | |||
| 248 | printf("control packet contents:\n"); | ||
| 249 | printf("\tflags: 0x%.2x , 0x%.2x\n", p->flags, p->op); | ||
| 250 | printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags&LI_MASK); | ||
| 251 | printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags&VN_MASK); | ||
| 252 | printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags&MODE_MASK); | ||
| 253 | printf("\t response=%d (0x%.2x)\n", (p->op&REM_RESP)>0, p->op&REM_RESP); | ||
| 254 | printf("\t more=%d (0x%.2x)\n", (p->op&REM_MORE)>0, p->op&REM_MORE); | ||
| 255 | printf("\t error=%d (0x%.2x)\n", (p->op&REM_ERROR)>0, p->op&REM_ERROR); | ||
| 256 | printf("\t op=%d (0x%.2x)\n", p->op&OP_MASK, p->op&OP_MASK); | ||
| 257 | printf("\tsequence: %d (0x%.2x)\n", ntohs(p->seq), ntohs(p->seq)); | ||
| 258 | printf("\tstatus: %d (0x%.2x)\n", ntohs(p->status), ntohs(p->status)); | ||
| 259 | printf("\tassoc: %d (0x%.2x)\n", ntohs(p->assoc), ntohs(p->assoc)); | ||
| 260 | printf("\toffset: %d (0x%.2x)\n", ntohs(p->offset), ntohs(p->offset)); | ||
| 261 | printf("\tcount: %d (0x%.2x)\n", ntohs(p->count), ntohs(p->count)); | ||
| 262 | numpeers=ntohs(p->count)/(sizeof(ntp_assoc_status_pair)); | ||
| 263 | if(p->op&REM_RESP && p->op&OP_READSTAT){ | ||
| 264 | peer=(ntp_assoc_status_pair*)p->data; | ||
| 265 | for(i=0;i<numpeers;i++){ | ||
| 266 | printf("\tpeer id %.2x status %.2x", | ||
| 267 | ntohs(peer[i].assoc), ntohs(peer[i].status)); | ||
| 268 | if (PEER_SEL(peer[i].status) >= PEER_INCLUDED){ | ||
| 269 | if(PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE){ | ||
| 270 | printf(" <-- current sync source"); | ||
| 271 | } else { | ||
| 272 | printf(" <-- current sync candidate"); | ||
| 273 | } | ||
| 274 | } | ||
| 275 | printf("\n"); | ||
| 276 | } | ||
| 277 | } | ||
| 278 | } | ||
| 279 | |||
| 280 | void setup_request(ntp_message *p){ | ||
| 281 | struct timeval t; | ||
| 282 | |||
| 283 | memset(p, 0, sizeof(ntp_message)); | ||
| 284 | LI_SET(p->flags, LI_ALARM); | ||
| 285 | VN_SET(p->flags, 4); | ||
| 286 | MODE_SET(p->flags, MODE_CLIENT); | ||
| 287 | p->poll=4; | ||
| 288 | p->precision=(int8_t)0xfa; | ||
| 289 | L16(p->rtdelay)=htons(1); | ||
| 290 | L16(p->rtdisp)=htons(1); | ||
| 291 | |||
| 292 | gettimeofday(&t, NULL); | ||
| 293 | TVtoNTP64(t,p->txts); | ||
| 294 | } | ||
| 295 | |||
| 296 | /* select the "best" server from a list of servers, and return its index. | ||
| 297 | * this is done by filtering servers based on stratum, dispersion, and | ||
| 298 | * finally round-trip delay. */ | ||
| 299 | int best_offset_server(const ntp_server_results *slist, int nservers){ | ||
| 300 | int cserver=0, best_server=-1; | ||
| 301 | |||
| 302 | /* for each server */ | ||
| 303 | for(cserver=0; cserver<nservers; cserver++){ | ||
| 304 | /* We don't want any servers that fails these tests */ | ||
| 305 | /* Sort out servers that didn't respond or responede with a 0 stratum; | ||
| 306 | * stratum 0 is for reference clocks so no NTP server should ever report | ||
| 307 | * a stratum 0 */ | ||
| 308 | if ( slist[cserver].stratum == 0){ | ||
| 309 | if (verbose) printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum); | ||
| 310 | continue; | ||
| 311 | } | ||
| 312 | /* Sort out servers with error flags */ | ||
| 313 | if ( LI(slist[cserver].flags) == LI_ALARM ){ | ||
| 314 | if (verbose) printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags)); | ||
| 315 | continue; | ||
| 316 | } | ||
| 317 | |||
| 318 | /* If we don't have a server yet, use the first one */ | ||
| 319 | if (best_server == -1) { | ||
| 320 | best_server = cserver; | ||
| 321 | DBG(printf("using peer %d as our first candidate\n", best_server)); | ||
| 322 | continue; | ||
| 323 | } | ||
| 324 | |||
| 325 | /* compare the server to the best one we've seen so far */ | ||
| 326 | /* does it have an equal or better stratum? */ | ||
| 327 | DBG(printf("comparing peer %d with peer %d\n", cserver, best_server)); | ||
| 328 | if(slist[cserver].stratum <= slist[best_server].stratum){ | ||
| 329 | DBG(printf("stratum for peer %d <= peer %d\n", cserver, best_server)); | ||
| 330 | /* does it have an equal or better dispersion? */ | ||
| 331 | if(slist[cserver].rtdisp <= slist[best_server].rtdisp){ | ||
| 332 | DBG(printf("dispersion for peer %d <= peer %d\n", cserver, best_server)); | ||
| 333 | /* does it have a better rtdelay? */ | ||
| 334 | if(slist[cserver].rtdelay < slist[best_server].rtdelay){ | ||
| 335 | DBG(printf("rtdelay for peer %d < peer %d\n", cserver, best_server)); | ||
| 336 | best_server = cserver; | ||
| 337 | DBG(printf("peer %d is now our best candidate\n", best_server)); | ||
| 338 | } | ||
| 339 | } | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | if(best_server >= 0) { | ||
| 344 | DBG(printf("best server selected: peer %d\n", best_server)); | ||
| 345 | return best_server; | ||
| 346 | } else { | ||
| 347 | DBG(printf("no peers meeting synchronization criteria :(\n")); | ||
| 348 | return -1; | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 352 | /* do everything we need to get the total average offset | ||
| 353 | * - we use a certain amount of parallelization with poll() to ensure | ||
| 354 | * we don't waste time sitting around waiting for single packets. | ||
| 355 | * - we also "manually" handle resolving host names and connecting, because | ||
| 356 | * we have to do it in a way that our lazy macros don't handle currently :( */ | ||
| 357 | double offset_request(const char *host, int *status){ | ||
| 358 | int i=0, ga_result=0, num_hosts=0, *socklist=NULL, respnum=0; | ||
| 359 | int servers_completed=0, one_read=0, servers_readable=0, best_index=-1; | ||
| 360 | time_t now_time=0, start_ts=0; | ||
| 361 | ntp_message *req=NULL; | ||
| 362 | double avg_offset=0.; | ||
| 363 | struct timeval recv_time; | ||
| 364 | struct addrinfo *ai=NULL, *ai_tmp=NULL, hints; | ||
| 365 | struct pollfd *ufds=NULL; | ||
| 366 | ntp_server_results *servers=NULL; | ||
| 367 | |||
| 368 | /* setup hints to only return results from getaddrinfo that we'd like */ | ||
| 369 | memset(&hints, 0, sizeof(struct addrinfo)); | ||
| 370 | hints.ai_family = address_family; | ||
| 371 | hints.ai_protocol = IPPROTO_UDP; | ||
| 372 | hints.ai_socktype = SOCK_DGRAM; | ||
| 373 | |||
| 374 | /* fill in ai with the list of hosts resolved by the host name */ | ||
| 375 | ga_result = getaddrinfo(host, "123", &hints, &ai); | ||
| 376 | if(ga_result!=0){ | ||
| 377 | die(STATE_UNKNOWN, "error getting address for %s: %s\n", | ||
| 378 | host, gai_strerror(ga_result)); | ||
| 379 | } | ||
| 380 | |||
| 381 | /* count the number of returned hosts, and allocate stuff accordingly */ | ||
| 382 | for(ai_tmp=ai; ai_tmp!=NULL; ai_tmp=ai_tmp->ai_next){ num_hosts++; } | ||
| 383 | req=(ntp_message*)malloc(sizeof(ntp_message)*num_hosts); | ||
| 384 | if(req==NULL) die(STATE_UNKNOWN, "can not allocate ntp message array"); | ||
| 385 | socklist=(int*)malloc(sizeof(int)*num_hosts); | ||
| 386 | if(socklist==NULL) die(STATE_UNKNOWN, "can not allocate socket array"); | ||
| 387 | ufds=(struct pollfd*)malloc(sizeof(struct pollfd)*num_hosts); | ||
| 388 | if(ufds==NULL) die(STATE_UNKNOWN, "can not allocate socket array"); | ||
| 389 | servers=(ntp_server_results*)malloc(sizeof(ntp_server_results)*num_hosts); | ||
| 390 | if(servers==NULL) die(STATE_UNKNOWN, "can not allocate server array"); | ||
| 391 | memset(servers, 0, sizeof(ntp_server_results)*num_hosts); | ||
| 392 | DBG(printf("Found %d peers to check\n", num_hosts)); | ||
| 393 | |||
| 394 | /* setup each socket for writing, and the corresponding struct pollfd */ | ||
| 395 | ai_tmp=ai; | ||
| 396 | for(i=0;ai_tmp;i++){ | ||
| 397 | socklist[i]=socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); | ||
| 398 | if(socklist[i] == -1) { | ||
| 399 | perror(NULL); | ||
| 400 | die(STATE_UNKNOWN, "can not create new socket"); | ||
| 401 | } | ||
| 402 | if(connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)){ | ||
| 403 | /* don't die here, because it is enough if there is one server | ||
| 404 | answering in time. This also would break for dual ipv4/6 stacked | ||
| 405 | ntp servers when the client only supports on of them. | ||
| 406 | */ | ||
| 407 | DBG(printf("can't create socket connection on peer %i: %s\n", i, strerror(errno))); | ||
| 408 | } else { | ||
| 409 | ufds[i].fd=socklist[i]; | ||
| 410 | ufds[i].events=POLLIN; | ||
| 411 | ufds[i].revents=0; | ||
| 412 | } | ||
| 413 | ai_tmp = ai_tmp->ai_next; | ||
| 414 | } | ||
| 415 | |||
| 416 | /* now do AVG_NUM checks to each host. we stop before timeout/2 seconds | ||
| 417 | * have passed in order to ensure post-processing and jitter time. */ | ||
| 418 | now_time=start_ts=time(NULL); | ||
| 419 | while(servers_completed<num_hosts && now_time-start_ts <= socket_timeout/2){ | ||
| 420 | /* loop through each server and find each one which hasn't | ||
| 421 | * been touched in the past second or so and is still lacking | ||
| 422 | * some responses. for each of these servers, send a new request, | ||
| 423 | * and update the "waiting" timestamp with the current time. */ | ||
| 424 | now_time=time(NULL); | ||
| 425 | |||
| 426 | for(i=0; i<num_hosts; i++){ | ||
| 427 | if(servers[i].waiting<now_time && servers[i].num_responses<AVG_NUM){ | ||
| 428 | if(verbose && servers[i].waiting != 0) printf("re-"); | ||
| 429 | if(verbose) printf("sending request to peer %d\n", i); | ||
| 430 | setup_request(&req[i]); | ||
| 431 | write(socklist[i], &req[i], sizeof(ntp_message)); | ||
| 432 | servers[i].waiting=now_time; | ||
| 433 | break; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | /* quickly poll for any sockets with pending data */ | ||
| 438 | servers_readable=poll(ufds, num_hosts, 100); | ||
| 439 | if(servers_readable==-1){ | ||
| 440 | perror("polling ntp sockets"); | ||
| 441 | die(STATE_UNKNOWN, "communication errors"); | ||
| 442 | } | ||
| 443 | |||
| 444 | /* read from any sockets with pending data */ | ||
| 445 | for(i=0; servers_readable && i<num_hosts; i++){ | ||
| 446 | if(ufds[i].revents&POLLIN && servers[i].num_responses < AVG_NUM){ | ||
| 447 | if(verbose) { | ||
| 448 | printf("response from peer %d: ", i); | ||
| 449 | } | ||
| 450 | |||
| 451 | read(ufds[i].fd, &req[i], sizeof(ntp_message)); | ||
| 452 | gettimeofday(&recv_time, NULL); | ||
| 453 | DBG(print_ntp_message(&req[i])); | ||
| 454 | respnum=servers[i].num_responses++; | ||
| 455 | servers[i].offset[respnum]=calc_offset(&req[i], &recv_time); | ||
| 456 | if(verbose) { | ||
| 457 | printf("offset %.10g\n", servers[i].offset[respnum]); | ||
| 458 | } | ||
| 459 | servers[i].stratum=req[i].stratum; | ||
| 460 | servers[i].rtdisp=NTP32asDOUBLE(req[i].rtdisp); | ||
| 461 | servers[i].rtdelay=NTP32asDOUBLE(req[i].rtdelay); | ||
| 462 | servers[i].waiting=0; | ||
| 463 | servers[i].flags=req[i].flags; | ||
| 464 | servers_readable--; | ||
| 465 | one_read = 1; | ||
| 466 | if(servers[i].num_responses==AVG_NUM) servers_completed++; | ||
| 467 | } | ||
| 468 | } | ||
| 469 | /* lather, rinse, repeat. */ | ||
| 470 | } | ||
| 471 | |||
| 472 | if (one_read == 0) { | ||
| 473 | die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); | ||
| 474 | } | ||
| 475 | |||
| 476 | /* now, pick the best server from the list */ | ||
| 477 | best_index=best_offset_server(servers, num_hosts); | ||
| 478 | if(best_index < 0){ | ||
| 479 | *status=STATE_UNKNOWN; | ||
| 480 | } else { | ||
| 481 | /* finally, calculate the average offset */ | ||
| 482 | for(i=0; i<servers[best_index].num_responses;i++){ | ||
| 483 | avg_offset+=servers[best_index].offset[i]; | ||
| 484 | } | ||
| 485 | avg_offset/=servers[best_index].num_responses; | ||
| 486 | } | ||
| 487 | |||
| 488 | /* cleanup */ | ||
| 489 | /* FIXME: Not closing the socket to avoid reuse of the local port | ||
| 490 | * which can cause old NTP packets to be read instead of NTP control | ||
| 491 | * packets in jitter_request(). THERE MUST BE ANOTHER WAY... | ||
| 492 | * for(j=0; j<num_hosts; j++){ close(socklist[j]); } */ | ||
| 493 | free(socklist); | ||
| 494 | free(ufds); | ||
| 495 | free(servers); | ||
| 496 | free(req); | ||
| 497 | freeaddrinfo(ai); | ||
| 498 | |||
| 499 | if(verbose) printf("overall average offset: %.10g\n", avg_offset); | ||
| 500 | return avg_offset; | ||
| 501 | } | ||
| 502 | |||
| 503 | void | ||
| 504 | setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq){ | ||
| 505 | memset(p, 0, sizeof(ntp_control_message)); | ||
| 506 | LI_SET(p->flags, LI_NOWARNING); | ||
| 507 | VN_SET(p->flags, VN_RESERVED); | ||
| 508 | MODE_SET(p->flags, MODE_CONTROLMSG); | ||
| 509 | OP_SET(p->op, opcode); | ||
| 510 | p->seq = htons(seq); | ||
| 511 | /* Remaining fields are zero for requests */ | ||
| 512 | } | ||
| 513 | |||
| 514 | /* XXX handle responses with the error bit set */ | ||
| 515 | double jitter_request(int *status){ | ||
| 516 | int conn=-1, i, npeers=0, num_candidates=0; | ||
| 517 | bool syncsource_found = false; | ||
| 518 | int run=0, min_peer_sel=PEER_INCLUDED, num_selected=0, num_valid=0; | ||
| 519 | int peers_size=0, peer_offset=0; | ||
| 520 | ntp_assoc_status_pair *peers=NULL; | ||
| 521 | ntp_control_message req; | ||
| 522 | const char *getvar = "jitter"; | ||
| 523 | double rval = 0.0, jitter = -1.0; | ||
| 524 | char *startofvalue=NULL, *nptr=NULL; | ||
| 525 | void *tmp; | ||
| 526 | |||
| 527 | /* Long-winded explanation: | ||
| 528 | * Getting the jitter requires a number of steps: | ||
| 529 | * 1) Send a READSTAT request. | ||
| 530 | * 2) Interpret the READSTAT reply | ||
| 531 | * a) The data section contains a list of peer identifiers (16 bits) | ||
| 532 | * and associated status words (16 bits) | ||
| 533 | * b) We want the value of 0x06 in the SEL (peer selection) value, | ||
| 534 | * which means "current synchronizatin source". If that's missing, | ||
| 535 | * we take anything better than 0x04 (see the rfc for details) but | ||
| 536 | * set a minimum of warning. | ||
| 537 | * 3) Send a READVAR request for information on each peer identified | ||
| 538 | * in 2b greater than the minimum selection value. | ||
| 539 | * 4) Extract the jitter value from the data[] (it's ASCII) | ||
| 540 | */ | ||
| 541 | my_udp_connect(server_address, 123, &conn); | ||
| 542 | |||
| 543 | /* keep sending requests until the server stops setting the | ||
| 544 | * REM_MORE bit, though usually this is only 1 packet. */ | ||
| 545 | do{ | ||
| 546 | setup_control_request(&req, OP_READSTAT, 1); | ||
| 547 | DBG(printf("sending READSTAT request")); | ||
| 548 | write(conn, &req, SIZEOF_NTPCM(req)); | ||
| 549 | DBG(print_ntp_control_message(&req)); | ||
| 550 | /* Attempt to read the largest size packet possible */ | ||
| 551 | req.count=htons(MAX_CM_SIZE); | ||
| 552 | DBG(printf("receiving READSTAT response")) | ||
| 553 | read(conn, &req, SIZEOF_NTPCM(req)); | ||
| 554 | DBG(print_ntp_control_message(&req)); | ||
| 555 | /* Each peer identifier is 4 bytes in the data section, which | ||
| 556 | * we represent as a ntp_assoc_status_pair datatype. | ||
| 557 | */ | ||
| 558 | peers_size+=ntohs(req.count); | ||
| 559 | if((tmp=realloc(peers, peers_size)) == NULL) | ||
| 560 | free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n"); | ||
| 561 | peers=tmp; | ||
| 562 | memcpy((void*)((ptrdiff_t)peers+peer_offset), (void*)req.data, ntohs(req.count)); | ||
| 563 | npeers=peers_size/sizeof(ntp_assoc_status_pair); | ||
| 564 | peer_offset+=ntohs(req.count); | ||
| 565 | } while(req.op&REM_MORE); | ||
| 566 | |||
| 567 | /* first, let's find out if we have a sync source, or if there are | ||
| 568 | * at least some candidates. in the case of the latter we'll issue | ||
| 569 | * a warning but go ahead with the check on them. */ | ||
| 570 | for (i = 0; i < npeers; i++){ | ||
| 571 | if (PEER_SEL(peers[i].status) >= PEER_INCLUDED){ | ||
| 572 | num_candidates++; | ||
| 573 | if(PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE){ | ||
| 574 | syncsource_found = true; | ||
| 575 | min_peer_sel=PEER_SYNCSOURCE; | ||
| 576 | } | ||
| 577 | } | ||
| 578 | } | ||
| 579 | if(verbose) printf("%d candidate peers available\n", num_candidates); | ||
| 580 | if(verbose && syncsource_found) printf("synchronization source found\n"); | ||
| 581 | if(! syncsource_found){ | ||
| 582 | *status = STATE_UNKNOWN; | ||
| 583 | if(verbose) printf("warning: no synchronization source found\n"); | ||
| 584 | } | ||
| 585 | |||
| 586 | |||
| 587 | for (run=0; run<AVG_NUM; run++){ | ||
| 588 | if(verbose) printf("jitter run %d of %d\n", run+1, AVG_NUM); | ||
| 589 | for (i = 0; i < npeers; i++){ | ||
| 590 | /* Only query this server if it is the current sync source */ | ||
| 591 | if (PEER_SEL(peers[i].status) >= min_peer_sel){ | ||
| 592 | char jitter_data[MAX_CM_SIZE+1]; | ||
| 593 | size_t jitter_data_count; | ||
| 594 | |||
| 595 | num_selected++; | ||
| 596 | setup_control_request(&req, OP_READVAR, 2); | ||
| 597 | req.assoc = peers[i].assoc; | ||
| 598 | /* By spec, putting the variable name "jitter" in the request | ||
| 599 | * should cause the server to provide _only_ the jitter value. | ||
| 600 | * thus reducing net traffic, guaranteeing us only a single | ||
| 601 | * datagram in reply, and making interpretation much simpler | ||
| 602 | */ | ||
| 603 | /* Older servers doesn't know what jitter is, so if we get an | ||
| 604 | * error on the first pass we redo it with "dispersion" */ | ||
| 605 | strncpy(req.data, getvar, MAX_CM_SIZE-1); | ||
| 606 | req.count = htons(strlen(getvar)); | ||
| 607 | DBG(printf("sending READVAR request...\n")); | ||
| 608 | write(conn, &req, SIZEOF_NTPCM(req)); | ||
| 609 | DBG(print_ntp_control_message(&req)); | ||
| 610 | |||
| 611 | req.count = htons(MAX_CM_SIZE); | ||
| 612 | DBG(printf("receiving READVAR response...\n")); | ||
| 613 | read(conn, &req, SIZEOF_NTPCM(req)); | ||
| 614 | DBG(print_ntp_control_message(&req)); | ||
| 615 | |||
| 616 | if(req.op&REM_ERROR && strstr(getvar, "jitter")) { | ||
| 617 | if(verbose) printf("The 'jitter' command failed (old ntp server?)\nRestarting with 'dispersion'...\n"); | ||
| 618 | getvar = "dispersion"; | ||
| 619 | num_selected--; | ||
| 620 | i--; | ||
| 621 | continue; | ||
| 622 | } | ||
| 623 | |||
| 624 | /* get to the float value */ | ||
| 625 | if(verbose) { | ||
| 626 | printf("parsing jitter from peer %.2x: ", ntohs(peers[i].assoc)); | ||
| 627 | } | ||
| 628 | if((jitter_data_count = ntohs(req.count)) >= sizeof(jitter_data)){ | ||
| 629 | die(STATE_UNKNOWN, | ||
| 630 | _("jitter response too large (%lu bytes)\n"), | ||
| 631 | (unsigned long)jitter_data_count); | ||
| 632 | } | ||
| 633 | memcpy(jitter_data, req.data, jitter_data_count); | ||
| 634 | jitter_data[jitter_data_count] = '\0'; | ||
| 635 | startofvalue = strchr(jitter_data, '='); | ||
| 636 | if(startofvalue != NULL) { | ||
| 637 | startofvalue++; | ||
| 638 | jitter = strtod(startofvalue, &nptr); | ||
| 639 | } | ||
| 640 | if(startofvalue == NULL || startofvalue==nptr){ | ||
| 641 | printf("warning: unable to read server jitter response.\n"); | ||
| 642 | *status = STATE_UNKNOWN; | ||
| 643 | } else { | ||
| 644 | if(verbose) printf("%g\n", jitter); | ||
| 645 | num_valid++; | ||
| 646 | rval += jitter; | ||
| 647 | } | ||
| 648 | } | ||
| 649 | } | ||
| 650 | if(verbose){ | ||
| 651 | printf("jitter parsed from %d/%d peers\n", num_valid, num_selected); | ||
| 652 | } | ||
| 653 | } | ||
| 654 | |||
| 655 | rval = num_valid ? rval / num_valid : -1.0; | ||
| 656 | |||
| 657 | close(conn); | ||
| 658 | if(peers!=NULL) free(peers); | ||
| 659 | /* If we return -1.0, it means no synchronization source was found */ | ||
| 660 | return rval; | ||
| 661 | } | ||
| 662 | |||
| 663 | int process_arguments(int argc, char **argv){ | ||
| 664 | int c; | ||
| 665 | int option=0; | ||
| 666 | static struct option longopts[] = { | ||
| 667 | {"version", no_argument, 0, 'V'}, | ||
| 668 | {"help", no_argument, 0, 'h'}, | ||
| 669 | {"verbose", no_argument, 0, 'v'}, | ||
| 670 | {"use-ipv4", no_argument, 0, '4'}, | ||
| 671 | {"use-ipv6", no_argument, 0, '6'}, | ||
| 672 | {"warning", required_argument, 0, 'w'}, | ||
| 673 | {"critical", required_argument, 0, 'c'}, | ||
| 674 | {"jwarn", required_argument, 0, 'j'}, | ||
| 675 | {"jcrit", required_argument, 0, 'k'}, | ||
| 676 | {"timeout", required_argument, 0, 't'}, | ||
| 677 | {"hostname", required_argument, 0, 'H'}, | ||
| 678 | {0, 0, 0, 0} | ||
| 679 | }; | ||
| 680 | |||
| 681 | |||
| 682 | if (argc < 2) | ||
| 683 | usage ("\n"); | ||
| 684 | |||
| 685 | while (1) { | ||
| 686 | c = getopt_long (argc, argv, "Vhv46w:c:j:k:t:H:", longopts, &option); | ||
| 687 | if (c == -1 || c == EOF || c == 1) | ||
| 688 | break; | ||
| 689 | |||
| 690 | switch (c) { | ||
| 691 | case 'h': | ||
| 692 | print_help(); | ||
| 693 | exit(STATE_UNKNOWN); | ||
| 694 | break; | ||
| 695 | case 'V': | ||
| 696 | print_revision(progname, NP_VERSION); | ||
| 697 | exit(STATE_UNKNOWN); | ||
| 698 | break; | ||
| 699 | case 'v': | ||
| 700 | verbose++; | ||
| 701 | break; | ||
| 702 | case 'w': | ||
| 703 | do_offset = true; | ||
| 704 | owarn = optarg; | ||
| 705 | break; | ||
| 706 | case 'c': | ||
| 707 | do_offset = true; | ||
| 708 | ocrit = optarg; | ||
| 709 | break; | ||
| 710 | case 'j': | ||
| 711 | do_jitter = true; | ||
| 712 | jwarn = optarg; | ||
| 713 | break; | ||
| 714 | case 'k': | ||
| 715 | do_jitter = true; | ||
| 716 | jcrit = optarg; | ||
| 717 | break; | ||
| 718 | case 'H': | ||
| 719 | if(!is_host(optarg)) | ||
| 720 | usage2(_("Invalid hostname/address"), optarg); | ||
| 721 | server_address = strdup(optarg); | ||
| 722 | break; | ||
| 723 | case 't': | ||
| 724 | socket_timeout=atoi(optarg); | ||
| 725 | break; | ||
| 726 | case '4': | ||
| 727 | address_family = AF_INET; | ||
| 728 | break; | ||
| 729 | case '6': | ||
| 730 | #ifdef USE_IPV6 | ||
| 731 | address_family = AF_INET6; | ||
| 732 | #else | ||
| 733 | usage4 (_("IPv6 support not available")); | ||
| 734 | #endif | ||
| 735 | break; | ||
| 736 | case '?': | ||
| 737 | /* print short usage statement if args not parsable */ | ||
| 738 | usage5 (); | ||
| 739 | break; | ||
| 740 | } | ||
| 741 | } | ||
| 742 | |||
| 743 | if(server_address == NULL){ | ||
| 744 | usage4(_("Hostname was not supplied")); | ||
| 745 | } | ||
| 746 | |||
| 747 | return 0; | ||
| 748 | } | ||
| 749 | |||
| 750 | char *perfd_offset (double offset) | ||
| 751 | { | ||
| 752 | return fperfdata ("offset", offset, "s", | ||
| 753 | true, offset_thresholds->warning->end, | ||
| 754 | true, offset_thresholds->critical->end, | ||
| 755 | false, 0, false, 0); | ||
| 756 | } | ||
| 757 | |||
| 758 | char *perfd_jitter (double jitter) | ||
| 759 | { | ||
| 760 | return fperfdata ("jitter", jitter, "s", | ||
| 761 | do_jitter, jitter_thresholds->warning->end, | ||
| 762 | do_jitter, jitter_thresholds->critical->end, | ||
| 763 | true, 0, false, 0); | ||
| 764 | } | ||
| 765 | |||
| 766 | int main(int argc, char *argv[]){ | ||
| 767 | int result, offset_result, jitter_result; | ||
| 768 | double offset=0, jitter=0; | ||
| 769 | char *result_line, *perfdata_line; | ||
| 770 | |||
| 771 | setlocale (LC_ALL, ""); | ||
| 772 | bindtextdomain (PACKAGE, LOCALEDIR); | ||
| 773 | textdomain (PACKAGE); | ||
| 774 | |||
| 775 | result = offset_result = jitter_result = STATE_OK; | ||
| 776 | |||
| 777 | /* Parse extra opts if any */ | ||
| 778 | argv=np_extra_opts (&argc, argv, progname); | ||
| 779 | |||
| 780 | if (process_arguments (argc, argv) == ERROR) | ||
| 781 | usage4 (_("Could not parse arguments")); | ||
| 782 | |||
| 783 | set_thresholds(&offset_thresholds, owarn, ocrit); | ||
| 784 | set_thresholds(&jitter_thresholds, jwarn, jcrit); | ||
| 785 | |||
| 786 | /* initialize alarm signal handling */ | ||
| 787 | signal (SIGALRM, socket_timeout_alarm_handler); | ||
| 788 | |||
| 789 | /* set socket timeout */ | ||
| 790 | alarm (socket_timeout); | ||
| 791 | |||
| 792 | offset = offset_request(server_address, &offset_result); | ||
| 793 | /* check_ntp used to always return CRITICAL if offset_result == STATE_UNKNOWN. | ||
| 794 | * Now we'll only do that is the offset thresholds were set */ | ||
| 795 | if (do_offset && offset_result == STATE_UNKNOWN) { | ||
| 796 | result = STATE_CRITICAL; | ||
| 797 | } else { | ||
| 798 | result = get_status(fabs(offset), offset_thresholds); | ||
| 799 | } | ||
| 800 | |||
| 801 | /* If not told to check the jitter, we don't even send packets. | ||
| 802 | * jitter is checked using NTP control packets, which not all | ||
| 803 | * servers recognize. Trying to check the jitter on OpenNTPD | ||
| 804 | * (for example) will result in an error | ||
| 805 | */ | ||
| 806 | if(do_jitter){ | ||
| 807 | jitter=jitter_request(&jitter_result); | ||
| 808 | result = max_state_alt(result, get_status(jitter, jitter_thresholds)); | ||
| 809 | /* -1 indicates that we couldn't calculate the jitter | ||
| 810 | * Only overrides STATE_OK from the offset */ | ||
| 811 | if(jitter == -1.0 && result == STATE_OK) | ||
| 812 | result = STATE_UNKNOWN; | ||
| 813 | } | ||
| 814 | result = max_state_alt(result, jitter_result); | ||
| 815 | |||
| 816 | switch (result) { | ||
| 817 | case STATE_CRITICAL : | ||
| 818 | xasprintf(&result_line, _("NTP CRITICAL:")); | ||
| 819 | break; | ||
| 820 | case STATE_WARNING : | ||
| 821 | xasprintf(&result_line, _("NTP WARNING:")); | ||
| 822 | break; | ||
| 823 | case STATE_OK : | ||
| 824 | xasprintf(&result_line, _("NTP OK:")); | ||
| 825 | break; | ||
| 826 | default : | ||
| 827 | xasprintf(&result_line, _("NTP UNKNOWN:")); | ||
| 828 | break; | ||
| 829 | } | ||
| 830 | if(offset_result == STATE_UNKNOWN){ | ||
| 831 | xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); | ||
| 832 | xasprintf(&perfdata_line, ""); | ||
| 833 | } else { | ||
| 834 | xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset); | ||
| 835 | xasprintf(&perfdata_line, "%s", perfd_offset(offset)); | ||
| 836 | } | ||
| 837 | if (do_jitter) { | ||
| 838 | xasprintf(&result_line, "%s, jitter=%f", result_line, jitter); | ||
| 839 | xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter)); | ||
| 840 | } | ||
| 841 | printf("%s|%s\n", result_line, perfdata_line); | ||
| 842 | |||
| 843 | if(server_address!=NULL) free(server_address); | ||
| 844 | return result; | ||
| 845 | } | ||
| 846 | |||
| 847 | |||
| 848 | |||
| 849 | void print_help(void){ | ||
| 850 | print_revision(progname, NP_VERSION); | ||
| 851 | |||
| 852 | printf ("Copyright (c) 2006 Sean Finney\n"); | ||
| 853 | printf (COPYRIGHT, copyright, email); | ||
| 854 | |||
| 855 | printf ("%s\n", _("This plugin checks the selected ntp server")); | ||
| 856 | |||
| 857 | printf ("\n\n"); | ||
| 858 | |||
| 859 | print_usage(); | ||
| 860 | printf (UT_HELP_VRSN); | ||
| 861 | printf (UT_EXTRA_OPTS); | ||
| 862 | printf (UT_HOST_PORT, 'p', "123"); | ||
| 863 | printf (UT_IPv46); | ||
| 864 | printf (" %s\n", "-w, --warning=THRESHOLD"); | ||
| 865 | printf (" %s\n", _("Offset to result in warning status (seconds)")); | ||
| 866 | printf (" %s\n", "-c, --critical=THRESHOLD"); | ||
| 867 | printf (" %s\n", _("Offset to result in critical status (seconds)")); | ||
| 868 | printf (" %s\n", "-j, --jwarn=THRESHOLD"); | ||
| 869 | printf (" %s\n", _("Warning threshold for jitter")); | ||
| 870 | printf (" %s\n", "-k, --jcrit=THRESHOLD"); | ||
| 871 | printf (" %s\n", _("Critical threshold for jitter")); | ||
| 872 | printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | ||
| 873 | printf (UT_VERBOSE); | ||
| 874 | |||
| 875 | printf("\n"); | ||
| 876 | printf("%s\n", _("Notes:")); | ||
| 877 | printf(UT_THRESHOLDS_NOTES); | ||
| 878 | |||
| 879 | printf("\n"); | ||
| 880 | printf("%s\n", _("Examples:")); | ||
| 881 | printf(" %s\n", _("Normal offset check:")); | ||
| 882 | printf(" %s\n", ("./check_ntp -H ntpserv -w 0.5 -c 1")); | ||
| 883 | printf("\n"); | ||
| 884 | printf(" %s\n", _("Check jitter too, avoiding critical notifications if jitter isn't available")); | ||
| 885 | printf(" %s\n", _("(See Notes above for more details on thresholds formats):")); | ||
| 886 | printf(" %s\n", ("./check_ntp -H ntpserv -w 0.5 -c 1 -j -1:100 -k -1:200")); | ||
| 887 | |||
| 888 | printf (UT_SUPPORT); | ||
| 889 | |||
| 890 | printf ("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); | ||
| 891 | printf ("%s\n\n", _("check_ntp_time instead.")); | ||
| 892 | } | ||
| 893 | |||
| 894 | void | ||
| 895 | print_usage(void) | ||
| 896 | { | ||
| 897 | printf ("%s\n", _("WARNING: check_ntp is deprecated. Please use check_ntp_peer or")); | ||
| 898 | printf ("%s\n\n", _("check_ntp_time instead.")); | ||
| 899 | printf ("%s\n", _("Usage:")); | ||
| 900 | printf(" %s -H <host> [-w <warn>] [-c <crit>] [-j <warn>] [-k <crit>] [-4|-6] [-v verbose]\n", progname); | ||
| 901 | } | ||
diff --git a/plugins/check_ntp_peer.c b/plugins/check_ntp_peer.c index f99e5032..26f74286 100644 --- a/plugins/check_ntp_peer.c +++ b/plugins/check_ntp_peer.c | |||
| @@ -39,33 +39,23 @@ const char *progname = "check_ntp_peer"; | |||
| 39 | const char *copyright = "2006-2024"; | 39 | const char *copyright = "2006-2024"; |
| 40 | const char *email = "devel@monitoring-plugins.org"; | 40 | const char *email = "devel@monitoring-plugins.org"; |
| 41 | 41 | ||
| 42 | #include "output.h" | ||
| 43 | #include "perfdata.h" | ||
| 44 | #include <openssl/x509.h> | ||
| 45 | #include "thresholds.h" | ||
| 42 | #include "common.h" | 46 | #include "common.h" |
| 43 | #include "netutils.h" | 47 | #include "netutils.h" |
| 44 | #include "utils.h" | 48 | #include "utils.h" |
| 49 | #include "../lib/states.h" | ||
| 50 | #include "check_ntp_peer.d/config.h" | ||
| 45 | 51 | ||
| 46 | static char *server_address = NULL; | ||
| 47 | static int port = 123; | ||
| 48 | static int verbose = 0; | 52 | static int verbose = 0; |
| 49 | static bool quiet = false; | 53 | |
| 50 | static char *owarn = "60"; | 54 | typedef struct { |
| 51 | static char *ocrit = "120"; | 55 | int errorcode; |
| 52 | static bool do_stratum = false; | 56 | check_ntp_peer_config config; |
| 53 | static char *swarn = "-1:16"; | 57 | } check_ntp_peer_config_wrapper; |
| 54 | static char *scrit = "-1:16"; | 58 | static check_ntp_peer_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 55 | static bool do_jitter = false; | ||
| 56 | static char *jwarn = "-1:5000"; | ||
| 57 | static char *jcrit = "-1:10000"; | ||
| 58 | static bool do_truechimers = false; | ||
| 59 | static char *twarn = "0:"; | ||
| 60 | static char *tcrit = "0:"; | ||
| 61 | static bool syncsource_found = false; | ||
| 62 | static bool li_alarm = false; | ||
| 63 | |||
| 64 | static int process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 65 | static thresholds *offset_thresholds = NULL; | ||
| 66 | static thresholds *jitter_thresholds = NULL; | ||
| 67 | static thresholds *stratum_thresholds = NULL; | ||
| 68 | static thresholds *truechimer_thresholds = NULL; | ||
| 69 | static void print_help(void); | 59 | static void print_help(void); |
| 70 | void print_usage(void); | 60 | void print_usage(void); |
| 71 | 61 | ||
| @@ -94,9 +84,9 @@ typedef struct { | |||
| 94 | /* bits 1,2 are the leap indicator */ | 84 | /* bits 1,2 are the leap indicator */ |
| 95 | #define LI_MASK 0xc0 | 85 | #define LI_MASK 0xc0 |
| 96 | #define LI(x) ((x & LI_MASK) >> 6) | 86 | #define LI(x) ((x & LI_MASK) >> 6) |
| 97 | #define LI_SET(x, y) \ | 87 | #define LI_SET(x, y) \ |
| 98 | do { \ | 88 | do { \ |
| 99 | x |= ((y << 6) & LI_MASK); \ | 89 | x |= ((y << 6) & LI_MASK); \ |
| 100 | } while (0) | 90 | } while (0) |
| 101 | /* and these are the values of the leap indicator */ | 91 | /* and these are the values of the leap indicator */ |
| 102 | #define LI_NOWARNING 0x00 | 92 | #define LI_NOWARNING 0x00 |
| @@ -106,17 +96,17 @@ typedef struct { | |||
| 106 | /* bits 3,4,5 are the ntp version */ | 96 | /* bits 3,4,5 are the ntp version */ |
| 107 | #define VN_MASK 0x38 | 97 | #define VN_MASK 0x38 |
| 108 | #define VN(x) ((x & VN_MASK) >> 3) | 98 | #define VN(x) ((x & VN_MASK) >> 3) |
| 109 | #define VN_SET(x, y) \ | 99 | #define VN_SET(x, y) \ |
| 110 | do { \ | 100 | do { \ |
| 111 | x |= ((y << 3) & VN_MASK); \ | 101 | x |= ((y << 3) & VN_MASK); \ |
| 112 | } while (0) | 102 | } while (0) |
| 113 | #define VN_RESERVED 0x02 | 103 | #define VN_RESERVED 0x02 |
| 114 | /* bits 6,7,8 are the ntp mode */ | 104 | /* bits 6,7,8 are the ntp mode */ |
| 115 | #define MODE_MASK 0x07 | 105 | #define MODE_MASK 0x07 |
| 116 | #define MODE(x) (x & MODE_MASK) | 106 | #define MODE(x) (x & MODE_MASK) |
| 117 | #define MODE_SET(x, y) \ | 107 | #define MODE_SET(x, y) \ |
| 118 | do { \ | 108 | do { \ |
| 119 | x |= (y & MODE_MASK); \ | 109 | x |= (y & MODE_MASK); \ |
| 120 | } while (0) | 110 | } while (0) |
| 121 | /* here are some values */ | 111 | /* here are some values */ |
| 122 | #define MODE_CLIENT 0x03 | 112 | #define MODE_CLIENT 0x03 |
| @@ -128,9 +118,9 @@ typedef struct { | |||
| 128 | #define REM_MORE 0x20 | 118 | #define REM_MORE 0x20 |
| 129 | /* In control message, bits 11 - 15 are opcode */ | 119 | /* In control message, bits 11 - 15 are opcode */ |
| 130 | #define OP_MASK 0x1f | 120 | #define OP_MASK 0x1f |
| 131 | #define OP_SET(x, y) \ | 121 | #define OP_SET(x, y) \ |
| 132 | do { \ | 122 | do { \ |
| 133 | x |= (y & OP_MASK); \ | 123 | x |= (y & OP_MASK); \ |
| 134 | } while (0) | 124 | } while (0) |
| 135 | #define OP_READSTAT 0x01 | 125 | #define OP_READSTAT 0x01 |
| 136 | #define OP_READVAR 0x02 | 126 | #define OP_READVAR 0x02 |
| @@ -143,39 +133,40 @@ typedef struct { | |||
| 143 | /* NTP control message header is 12 bytes, plus any data in the data | 133 | /* NTP control message header is 12 bytes, plus any data in the data |
| 144 | * field, plus null padding to the nearest 32-bit boundary per rfc. | 134 | * field, plus null padding to the nearest 32-bit boundary per rfc. |
| 145 | */ | 135 | */ |
| 146 | #define SIZEOF_NTPCM(m) (12 + ntohs(m.count) + ((ntohs(m.count) % 4) ? 4 - (ntohs(m.count) % 4) : 0)) | 136 | #define SIZEOF_NTPCM(m) \ |
| 137 | (12 + ntohs(m.count) + ((ntohs(m.count) % 4) ? 4 - (ntohs(m.count) % 4) : 0)) | ||
| 147 | 138 | ||
| 148 | /* finally, a little helper or two for debugging: */ | 139 | /* finally, a little helper or two for debugging: */ |
| 149 | #define DBG(x) \ | 140 | #define DBG(x) \ |
| 150 | do { \ | 141 | do { \ |
| 151 | if (verbose > 1) { \ | 142 | if (verbose > 1) { \ |
| 152 | x; \ | 143 | x; \ |
| 153 | } \ | 144 | } \ |
| 154 | } while (0); | 145 | } while (0); |
| 155 | #define PRINTSOCKADDR(x) \ | 146 | #define PRINTSOCKADDR(x) \ |
| 156 | do { \ | 147 | do { \ |
| 157 | printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ | 148 | printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ |
| 158 | } while (0); | 149 | } while (0); |
| 159 | 150 | ||
| 160 | void print_ntp_control_message(const ntp_control_message *p) { | 151 | void print_ntp_control_message(const ntp_control_message *message) { |
| 161 | printf("control packet contents:\n"); | 152 | printf("control packet contents:\n"); |
| 162 | printf("\tflags: 0x%.2x , 0x%.2x\n", p->flags, p->op); | 153 | printf("\tflags: 0x%.2x , 0x%.2x\n", message->flags, message->op); |
| 163 | printf("\t li=%d (0x%.2x)\n", LI(p->flags), p->flags & LI_MASK); | 154 | printf("\t li=%d (0x%.2x)\n", LI(message->flags), message->flags & LI_MASK); |
| 164 | printf("\t vn=%d (0x%.2x)\n", VN(p->flags), p->flags & VN_MASK); | 155 | printf("\t vn=%d (0x%.2x)\n", VN(message->flags), message->flags & VN_MASK); |
| 165 | printf("\t mode=%d (0x%.2x)\n", MODE(p->flags), p->flags & MODE_MASK); | 156 | printf("\t mode=%d (0x%.2x)\n", MODE(message->flags), message->flags & MODE_MASK); |
| 166 | printf("\t response=%d (0x%.2x)\n", (p->op & REM_RESP) > 0, p->op & REM_RESP); | 157 | printf("\t response=%d (0x%.2x)\n", (message->op & REM_RESP) > 0, message->op & REM_RESP); |
| 167 | printf("\t more=%d (0x%.2x)\n", (p->op & REM_MORE) > 0, p->op & REM_MORE); | 158 | printf("\t more=%d (0x%.2x)\n", (message->op & REM_MORE) > 0, message->op & REM_MORE); |
| 168 | printf("\t error=%d (0x%.2x)\n", (p->op & REM_ERROR) > 0, p->op & REM_ERROR); | 159 | printf("\t error=%d (0x%.2x)\n", (message->op & REM_ERROR) > 0, message->op & REM_ERROR); |
| 169 | printf("\t op=%d (0x%.2x)\n", p->op & OP_MASK, p->op & OP_MASK); | 160 | printf("\t op=%d (0x%.2x)\n", message->op & OP_MASK, message->op & OP_MASK); |
| 170 | printf("\tsequence: %d (0x%.2x)\n", ntohs(p->seq), ntohs(p->seq)); | 161 | printf("\tsequence: %d (0x%.2x)\n", ntohs(message->seq), ntohs(message->seq)); |
| 171 | printf("\tstatus: %d (0x%.2x)\n", ntohs(p->status), ntohs(p->status)); | 162 | printf("\tstatus: %d (0x%.2x)\n", ntohs(message->status), ntohs(message->status)); |
| 172 | printf("\tassoc: %d (0x%.2x)\n", ntohs(p->assoc), ntohs(p->assoc)); | 163 | printf("\tassoc: %d (0x%.2x)\n", ntohs(message->assoc), ntohs(message->assoc)); |
| 173 | printf("\toffset: %d (0x%.2x)\n", ntohs(p->offset), ntohs(p->offset)); | 164 | printf("\toffset: %d (0x%.2x)\n", ntohs(message->offset), ntohs(message->offset)); |
| 174 | printf("\tcount: %d (0x%.2x)\n", ntohs(p->count), ntohs(p->count)); | 165 | printf("\tcount: %d (0x%.2x)\n", ntohs(message->count), ntohs(message->count)); |
| 175 | 166 | ||
| 176 | int numpeers = ntohs(p->count) / (sizeof(ntp_assoc_status_pair)); | 167 | int numpeers = ntohs(message->count) / (sizeof(ntp_assoc_status_pair)); |
| 177 | if (p->op & REM_RESP && p->op & OP_READSTAT) { | 168 | if (message->op & REM_RESP && message->op & OP_READSTAT) { |
| 178 | const ntp_assoc_status_pair *peer = (ntp_assoc_status_pair *)p->data; | 169 | const ntp_assoc_status_pair *peer = (ntp_assoc_status_pair *)message->data; |
| 179 | for (int i = 0; i < numpeers; i++) { | 170 | for (int i = 0; i < numpeers; i++) { |
| 180 | printf("\tpeer id %.2x status %.2x", ntohs(peer[i].assoc), ntohs(peer[i].status)); | 171 | printf("\tpeer id %.2x status %.2x", ntohs(peer[i].assoc), ntohs(peer[i].status)); |
| 181 | if (PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE) { | 172 | if (PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE) { |
| @@ -190,13 +181,13 @@ void print_ntp_control_message(const ntp_control_message *p) { | |||
| 190 | } | 181 | } |
| 191 | } | 182 | } |
| 192 | 183 | ||
| 193 | void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq) { | 184 | void setup_control_request(ntp_control_message *message, uint8_t opcode, uint16_t seq) { |
| 194 | memset(p, 0, sizeof(ntp_control_message)); | 185 | memset(message, 0, sizeof(ntp_control_message)); |
| 195 | LI_SET(p->flags, LI_NOWARNING); | 186 | LI_SET(message->flags, LI_NOWARNING); |
| 196 | VN_SET(p->flags, VN_RESERVED); | 187 | VN_SET(message->flags, VN_RESERVED); |
| 197 | MODE_SET(p->flags, MODE_CONTROLMSG); | 188 | MODE_SET(message->flags, MODE_CONTROLMSG); |
| 198 | OP_SET(p->op, opcode); | 189 | OP_SET(message->op, opcode); |
| 199 | p->seq = htons(seq); | 190 | message->seq = htons(seq); |
| 200 | /* Remaining fields are zero for requests */ | 191 | /* Remaining fields are zero for requests */ |
| 201 | } | 192 | } |
| 202 | 193 | ||
| @@ -208,13 +199,28 @@ void setup_control_request(ntp_control_message *p, uint8_t opcode, uint16_t seq) | |||
| 208 | * positive value means a success retrieving the value. | 199 | * positive value means a success retrieving the value. |
| 209 | * - status is set to WARNING if there's no sync.peer (otherwise OK) and is | 200 | * - status is set to WARNING if there's no sync.peer (otherwise OK) and is |
| 210 | * the return value of the function. | 201 | * the return value of the function. |
| 211 | * status is pretty much useless as syncsource_found is a global variable | 202 | */ |
| 212 | * used later in main to check is the server was synchronized. It works | 203 | typedef struct { |
| 213 | * so I left it alone */ | 204 | mp_state_enum state; |
| 214 | int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum, int *num_truechimers) { | 205 | mp_state_enum offset_result; |
| 215 | *offset_result = STATE_UNKNOWN; | 206 | double offset; |
| 216 | *jitter = *stratum = -1; | 207 | double jitter; |
| 217 | *num_truechimers = 0; | 208 | long stratum; |
| 209 | int num_truechimers; | ||
| 210 | bool syncsource_found; | ||
| 211 | bool li_alarm; | ||
| 212 | } ntp_request_result; | ||
| 213 | ntp_request_result ntp_request(const check_ntp_peer_config config) { | ||
| 214 | |||
| 215 | ntp_request_result result = { | ||
| 216 | .state = STATE_OK, | ||
| 217 | .offset_result = STATE_UNKNOWN, | ||
| 218 | .jitter = -1, | ||
| 219 | .stratum = -1, | ||
| 220 | .num_truechimers = 0, | ||
| 221 | .syncsource_found = false, | ||
| 222 | .li_alarm = false, | ||
| 223 | }; | ||
| 218 | 224 | ||
| 219 | /* Long-winded explanation: | 225 | /* Long-winded explanation: |
| 220 | * Getting the sync peer offset, jitter and stratum requires a number of | 226 | * Getting the sync peer offset, jitter and stratum requires a number of |
| @@ -232,19 +238,16 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 232 | * 4) Extract the offset, jitter and stratum value from the data[] | 238 | * 4) Extract the offset, jitter and stratum value from the data[] |
| 233 | * (it's ASCII) | 239 | * (it's ASCII) |
| 234 | */ | 240 | */ |
| 235 | int min_peer_sel = PEER_INCLUDED; | ||
| 236 | int num_candidates = 0; | ||
| 237 | void *tmp; | ||
| 238 | ntp_assoc_status_pair *peers = NULL; | ||
| 239 | int peer_offset = 0; | ||
| 240 | int peers_size = 0; | ||
| 241 | int npeers = 0; | ||
| 242 | int conn = -1; | 241 | int conn = -1; |
| 243 | my_udp_connect(server_address, port, &conn); | 242 | my_udp_connect(config.server_address, config.port, &conn); |
| 244 | 243 | ||
| 245 | /* keep sending requests until the server stops setting the | 244 | /* keep sending requests until the server stops setting the |
| 246 | * REM_MORE bit, though usually this is only 1 packet. */ | 245 | * REM_MORE bit, though usually this is only 1 packet. */ |
| 247 | ntp_control_message req; | 246 | ntp_control_message req; |
| 247 | ntp_assoc_status_pair *peers = NULL; | ||
| 248 | int peer_offset = 0; | ||
| 249 | size_t peers_size = 0; | ||
| 250 | size_t npeers = 0; | ||
| 248 | do { | 251 | do { |
| 249 | setup_control_request(&req, OP_READSTAT, 1); | 252 | setup_control_request(&req, OP_READSTAT, 1); |
| 250 | DBG(printf("sending READSTAT request")); | 253 | DBG(printf("sending READSTAT request")); |
| @@ -255,24 +258,29 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 255 | /* Attempt to read the largest size packet possible */ | 258 | /* Attempt to read the largest size packet possible */ |
| 256 | req.count = htons(MAX_CM_SIZE); | 259 | req.count = htons(MAX_CM_SIZE); |
| 257 | DBG(printf("receiving READSTAT response")) | 260 | DBG(printf("receiving READSTAT response")) |
| 258 | if (read(conn, &req, SIZEOF_NTPCM(req)) == -1) | 261 | if (read(conn, &req, SIZEOF_NTPCM(req)) == -1) { |
| 259 | die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); | 262 | die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); |
| 263 | } | ||
| 260 | DBG(print_ntp_control_message(&req)); | 264 | DBG(print_ntp_control_message(&req)); |
| 261 | /* discard obviously invalid packets */ | 265 | /* discard obviously invalid packets */ |
| 262 | if (ntohs(req.count) > MAX_CM_SIZE) | 266 | if (ntohs(req.count) > MAX_CM_SIZE) { |
| 263 | die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n"); | 267 | die(STATE_CRITICAL, "NTP CRITICAL: Invalid packet received from NTP server\n"); |
| 268 | } | ||
| 264 | } while (!(req.op & OP_READSTAT && ntohs(req.seq) == 1)); | 269 | } while (!(req.op & OP_READSTAT && ntohs(req.seq) == 1)); |
| 265 | 270 | ||
| 266 | if (LI(req.flags) == LI_ALARM) | 271 | if (LI(req.flags) == LI_ALARM) { |
| 267 | li_alarm = true; | 272 | result.li_alarm = true; |
| 273 | } | ||
| 268 | /* Each peer identifier is 4 bytes in the data section, which | 274 | /* Each peer identifier is 4 bytes in the data section, which |
| 269 | * we represent as a ntp_assoc_status_pair datatype. | 275 | * we represent as a ntp_assoc_status_pair datatype. |
| 270 | */ | 276 | */ |
| 271 | peers_size += ntohs(req.count); | 277 | peers_size += ntohs(req.count); |
| 272 | if ((tmp = realloc(peers, peers_size)) == NULL) | 278 | void *tmp; |
| 279 | if ((tmp = realloc(peers, peers_size)) == NULL) { | ||
| 273 | free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n"); | 280 | free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n"); |
| 281 | } | ||
| 274 | peers = tmp; | 282 | peers = tmp; |
| 275 | memcpy((void *)((ptrdiff_t)peers + peer_offset), (void *)req.data, ntohs(req.count)); | 283 | memcpy((peers + peer_offset), (void *)req.data, ntohs(req.count)); |
| 276 | npeers = peers_size / sizeof(ntp_assoc_status_pair); | 284 | npeers = peers_size / sizeof(ntp_assoc_status_pair); |
| 277 | peer_offset += ntohs(req.count); | 285 | peer_offset += ntohs(req.count); |
| 278 | } while (req.op & REM_MORE); | 286 | } while (req.op & REM_MORE); |
| @@ -280,45 +288,51 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 280 | /* first, let's find out if we have a sync source, or if there are | 288 | /* first, let's find out if we have a sync source, or if there are |
| 281 | * at least some candidates. In the latter case we'll issue | 289 | * at least some candidates. In the latter case we'll issue |
| 282 | * a warning but go ahead with the check on them. */ | 290 | * a warning but go ahead with the check on them. */ |
| 283 | for (int i = 0; i < npeers; i++) { | 291 | int min_peer_sel = PEER_INCLUDED; |
| 292 | int num_candidates = 0; | ||
| 293 | for (size_t i = 0; i < npeers; i++) { | ||
| 284 | if (PEER_SEL(peers[i].status) >= PEER_TRUECHIMER) { | 294 | if (PEER_SEL(peers[i].status) >= PEER_TRUECHIMER) { |
| 285 | (*num_truechimers)++; | 295 | result.num_truechimers++; |
| 286 | if (PEER_SEL(peers[i].status) >= PEER_INCLUDED) { | 296 | if (PEER_SEL(peers[i].status) >= PEER_INCLUDED) { |
| 287 | num_candidates++; | 297 | num_candidates++; |
| 288 | if (PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE) { | 298 | if (PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE) { |
| 289 | syncsource_found = true; | 299 | result.syncsource_found = true; |
| 290 | min_peer_sel = PEER_SYNCSOURCE; | 300 | min_peer_sel = PEER_SYNCSOURCE; |
| 291 | } | 301 | } |
| 292 | } | 302 | } |
| 293 | } | 303 | } |
| 294 | } | 304 | } |
| 295 | 305 | ||
| 296 | if (verbose) | 306 | if (verbose) { |
| 297 | printf("%d candidate peers available\n", num_candidates); | 307 | printf("%d candidate peers available\n", num_candidates); |
| 298 | if (verbose && syncsource_found) | 308 | if (result.syncsource_found) { |
| 299 | printf("synchronization source found\n"); | 309 | printf("synchronization source found\n"); |
| 310 | } | ||
| 311 | } | ||
| 300 | 312 | ||
| 301 | int status = STATE_OK; | 313 | if (!result.syncsource_found) { |
| 302 | if (!syncsource_found) { | 314 | result.state = STATE_WARNING; |
| 303 | status = STATE_WARNING; | 315 | if (verbose) { |
| 304 | if (verbose) | ||
| 305 | printf("warning: no synchronization source found\n"); | 316 | printf("warning: no synchronization source found\n"); |
| 317 | } | ||
| 306 | } | 318 | } |
| 307 | if (li_alarm) { | 319 | if (result.li_alarm) { |
| 308 | status = STATE_WARNING; | 320 | result.state = STATE_WARNING; |
| 309 | if (verbose) | 321 | if (verbose) { |
| 310 | printf("warning: LI_ALARM bit is set\n"); | 322 | printf("warning: LI_ALARM bit is set\n"); |
| 323 | } | ||
| 311 | } | 324 | } |
| 312 | 325 | ||
| 313 | const char *getvar = "stratum,offset,jitter"; | 326 | const char *getvar = "stratum,offset,jitter"; |
| 314 | char *data; | 327 | char *data; |
| 315 | for (int i = 0; i < npeers; i++) { | 328 | for (size_t i = 0; i < npeers; i++) { |
| 316 | /* Only query this server if it is the current sync source */ | 329 | /* Only query this server if it is the current sync source */ |
| 317 | /* If there's no sync.peer, query all candidates and use the best one */ | 330 | /* If there's no sync.peer, query all candidates and use the best one */ |
| 318 | if (PEER_SEL(peers[i].status) >= min_peer_sel) { | 331 | if (PEER_SEL(peers[i].status) >= min_peer_sel) { |
| 319 | if (verbose) | 332 | if (verbose) { |
| 320 | printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc)); | 333 | printf("Getting offset, jitter and stratum for peer %.2x\n", ntohs(peers[i].assoc)); |
| 321 | xasprintf(&data, ""); | 334 | } |
| 335 | data = strdup(""); | ||
| 322 | do { | 336 | do { |
| 323 | setup_control_request(&req, OP_READVAR, 2); | 337 | setup_control_request(&req, OP_READVAR, 2); |
| 324 | req.assoc = peers[i].assoc; | 338 | req.assoc = peers[i].assoc; |
| @@ -342,81 +356,95 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 342 | DBG(print_ntp_control_message(&req)); | 356 | DBG(print_ntp_control_message(&req)); |
| 343 | } while (!(req.op & OP_READVAR && ntohs(req.seq) == 2)); | 357 | } while (!(req.op & OP_READVAR && ntohs(req.seq) == 2)); |
| 344 | 358 | ||
| 345 | if (!(req.op & REM_ERROR)) | 359 | if (!(req.op & REM_ERROR)) { |
| 346 | xasprintf(&data, "%s%s", data, req.data); | 360 | xasprintf(&data, "%s%s", data, req.data); |
| 361 | } | ||
| 347 | } while (req.op & REM_MORE); | 362 | } while (req.op & REM_MORE); |
| 348 | 363 | ||
| 349 | if (req.op & REM_ERROR) { | 364 | if (req.op & REM_ERROR) { |
| 350 | if (strstr(getvar, "jitter")) { | 365 | if (strstr(getvar, "jitter")) { |
| 351 | if (verbose) | 366 | if (verbose) { |
| 352 | printf("The command failed. This is usually caused by servers refusing the 'jitter'\nvariable. Restarting with " | 367 | printf("The command failed. This is usually caused by servers refusing the " |
| 368 | "'jitter'\nvariable. Restarting with " | ||
| 353 | "'dispersion'...\n"); | 369 | "'dispersion'...\n"); |
| 370 | } | ||
| 354 | getvar = "stratum,offset,dispersion"; | 371 | getvar = "stratum,offset,dispersion"; |
| 355 | i--; | 372 | i--; |
| 356 | continue; | 373 | continue; |
| 357 | } | 374 | } |
| 358 | if (strlen(getvar)) { | 375 | if (strlen(getvar)) { |
| 359 | if (verbose) | 376 | if (verbose) { |
| 360 | printf("Server didn't like dispersion either; will retrieve everything\n"); | 377 | printf("Server didn't like dispersion either; will retrieve everything\n"); |
| 378 | } | ||
| 361 | getvar = ""; | 379 | getvar = ""; |
| 362 | i--; | 380 | i--; |
| 363 | continue; | 381 | continue; |
| 364 | } | 382 | } |
| 365 | } | 383 | } |
| 366 | 384 | ||
| 367 | if (verbose > 1) | 385 | if (verbose > 1) { |
| 368 | printf("Server responded: >>>%s<<<\n", data); | 386 | printf("Server responded: >>>%s<<<\n", data); |
| 387 | } | ||
| 369 | 388 | ||
| 370 | double tmp_offset = 0; | 389 | double tmp_offset = 0; |
| 371 | char *value; | 390 | char *value; |
| 372 | char *nptr; | 391 | char *nptr; |
| 373 | /* get the offset */ | 392 | /* get the offset */ |
| 374 | if (verbose) | 393 | if (verbose) { |
| 375 | printf("parsing offset from peer %.2x: ", ntohs(peers[i].assoc)); | 394 | printf("parsing offset from peer %.2x: ", ntohs(peers[i].assoc)); |
| 395 | } | ||
| 376 | 396 | ||
| 377 | value = np_extract_ntpvar(data, "offset"); | 397 | value = np_extract_ntpvar(data, "offset"); |
| 378 | nptr = NULL; | 398 | nptr = NULL; |
| 379 | /* Convert the value if we have one */ | 399 | /* Convert the value if we have one */ |
| 380 | if (value != NULL) | 400 | if (value != NULL) { |
| 381 | tmp_offset = strtod(value, &nptr) / 1000; | 401 | tmp_offset = strtod(value, &nptr) / 1000; |
| 402 | } | ||
| 382 | /* If value is null or no conversion was performed */ | 403 | /* If value is null or no conversion was performed */ |
| 383 | if (value == NULL || value == nptr) { | 404 | if (value == NULL || value == nptr) { |
| 384 | if (verbose) | 405 | if (verbose) { |
| 385 | printf("error: unable to read server offset response.\n"); | 406 | printf("error: unable to read server offset response.\n"); |
| 407 | } | ||
| 386 | } else { | 408 | } else { |
| 387 | if (verbose) | 409 | if (verbose) { |
| 388 | printf("%.10g\n", tmp_offset); | 410 | printf("%.10g\n", tmp_offset); |
| 389 | if (*offset_result == STATE_UNKNOWN || fabs(tmp_offset) < fabs(*offset)) { | 411 | } |
| 390 | *offset = tmp_offset; | 412 | if (result.offset_result == STATE_UNKNOWN || |
| 391 | *offset_result = STATE_OK; | 413 | fabs(tmp_offset) < fabs(result.offset)) { |
| 414 | result.offset = tmp_offset; | ||
| 415 | result.offset_result = STATE_OK; | ||
| 392 | } else { | 416 | } else { |
| 393 | /* Skip this one; move to the next */ | 417 | /* Skip this one; move to the next */ |
| 394 | continue; | 418 | continue; |
| 395 | } | 419 | } |
| 396 | } | 420 | } |
| 397 | 421 | ||
| 398 | if (do_jitter) { | 422 | if (config.do_jitter) { |
| 399 | /* get the jitter */ | 423 | /* get the jitter */ |
| 400 | if (verbose) { | 424 | if (verbose) { |
| 401 | printf("parsing %s from peer %.2x: ", strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter", | 425 | printf("parsing %s from peer %.2x: ", |
| 426 | strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter", | ||
| 402 | ntohs(peers[i].assoc)); | 427 | ntohs(peers[i].assoc)); |
| 403 | } | 428 | } |
| 404 | value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" : "jitter"); | 429 | value = np_extract_ntpvar(data, strstr(getvar, "dispersion") != NULL ? "dispersion" |
| 430 | : "jitter"); | ||
| 405 | nptr = NULL; | 431 | nptr = NULL; |
| 406 | /* Convert the value if we have one */ | 432 | /* Convert the value if we have one */ |
| 407 | if (value != NULL) | 433 | if (value != NULL) { |
| 408 | *jitter = strtod(value, &nptr); | 434 | result.jitter = strtod(value, &nptr); |
| 435 | } | ||
| 409 | /* If value is null or no conversion was performed */ | 436 | /* If value is null or no conversion was performed */ |
| 410 | if (value == NULL || value == nptr) { | 437 | if (value == NULL || value == nptr) { |
| 411 | if (verbose) | 438 | if (verbose) { |
| 412 | printf("error: unable to read server jitter/dispersion response.\n"); | 439 | printf("error: unable to read server jitter/dispersion response.\n"); |
| 413 | *jitter = -1; | 440 | } |
| 441 | result.jitter = -1; | ||
| 414 | } else if (verbose) { | 442 | } else if (verbose) { |
| 415 | printf("%.10g\n", *jitter); | 443 | printf("%.10g\n", result.jitter); |
| 416 | } | 444 | } |
| 417 | } | 445 | } |
| 418 | 446 | ||
| 419 | if (do_stratum) { | 447 | if (config.do_stratum) { |
| 420 | /* get the stratum */ | 448 | /* get the stratum */ |
| 421 | if (verbose) { | 449 | if (verbose) { |
| 422 | printf("parsing stratum from peer %.2x: ", ntohs(peers[i].assoc)); | 450 | printf("parsing stratum from peer %.2x: ", ntohs(peers[i].assoc)); |
| @@ -424,46 +452,86 @@ int ntp_request(double *offset, int *offset_result, double *jitter, int *stratum | |||
| 424 | value = np_extract_ntpvar(data, "stratum"); | 452 | value = np_extract_ntpvar(data, "stratum"); |
| 425 | nptr = NULL; | 453 | nptr = NULL; |
| 426 | /* Convert the value if we have one */ | 454 | /* Convert the value if we have one */ |
| 427 | if (value != NULL) | 455 | if (value != NULL) { |
| 428 | *stratum = strtol(value, &nptr, 10); | 456 | result.stratum = strtol(value, &nptr, 10); |
| 457 | } | ||
| 429 | if (value == NULL || value == nptr) { | 458 | if (value == NULL || value == nptr) { |
| 430 | if (verbose) | 459 | if (verbose) { |
| 431 | printf("error: unable to read server stratum response.\n"); | 460 | printf("error: unable to read server stratum response.\n"); |
| 432 | *stratum = -1; | 461 | } |
| 462 | result.stratum = -1; | ||
| 433 | } else { | 463 | } else { |
| 434 | if (verbose) | 464 | if (verbose) { |
| 435 | printf("%i\n", *stratum); | 465 | printf("%li\n", result.stratum); |
| 466 | } | ||
| 436 | } | 467 | } |
| 437 | } | 468 | } |
| 438 | } /* if (PEER_SEL(peers[i].status) >= min_peer_sel) */ | 469 | } /* if (PEER_SEL(peers[i].status) >= min_peer_sel) */ |
| 439 | } /* for (i = 0; i < npeers; i++) */ | 470 | } /* for (i = 0; i < npeers; i++) */ |
| 440 | 471 | ||
| 441 | close(conn); | 472 | close(conn); |
| 442 | if (peers != NULL) | 473 | if (peers != NULL) { |
| 443 | free(peers); | 474 | free(peers); |
| 475 | } | ||
| 444 | 476 | ||
| 445 | return status; | 477 | return result; |
| 446 | } | 478 | } |
| 447 | 479 | ||
| 448 | int process_arguments(int argc, char **argv) { | 480 | check_ntp_peer_config_wrapper process_arguments(int argc, char **argv) { |
| 449 | static struct option longopts[] = { | 481 | |
| 450 | {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, | 482 | enum { |
| 451 | {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"quiet", no_argument, 0, 'q'}, | 483 | output_format_index = CHAR_MAX + 1, |
| 452 | {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, {"swarn", required_argument, 0, 'W'}, | 484 | }; |
| 453 | {"scrit", required_argument, 0, 'C'}, {"jwarn", required_argument, 0, 'j'}, {"jcrit", required_argument, 0, 'k'}, | 485 | |
| 454 | {"twarn", required_argument, 0, 'm'}, {"tcrit", required_argument, 0, 'n'}, {"timeout", required_argument, 0, 't'}, | 486 | static struct option longopts[] = {{"version", no_argument, 0, 'V'}, |
| 455 | {"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}}; | 487 | {"help", no_argument, 0, 'h'}, |
| 456 | 488 | {"verbose", no_argument, 0, 'v'}, | |
| 457 | if (argc < 2) | 489 | {"use-ipv4", no_argument, 0, '4'}, |
| 490 | {"use-ipv6", no_argument, 0, '6'}, | ||
| 491 | {"quiet", no_argument, 0, 'q'}, | ||
| 492 | {"warning", required_argument, 0, 'w'}, | ||
| 493 | {"critical", required_argument, 0, 'c'}, | ||
| 494 | {"swarn", required_argument, 0, 'W'}, | ||
| 495 | {"scrit", required_argument, 0, 'C'}, | ||
| 496 | {"jwarn", required_argument, 0, 'j'}, | ||
| 497 | {"jcrit", required_argument, 0, 'k'}, | ||
| 498 | {"twarn", required_argument, 0, 'm'}, | ||
| 499 | {"tcrit", required_argument, 0, 'n'}, | ||
| 500 | {"timeout", required_argument, 0, 't'}, | ||
| 501 | {"hostname", required_argument, 0, 'H'}, | ||
| 502 | {"port", required_argument, 0, 'p'}, | ||
| 503 | {"output-format", required_argument, 0, output_format_index}, | ||
| 504 | {0, 0, 0, 0}}; | ||
| 505 | |||
| 506 | if (argc < 2) { | ||
| 458 | usage("\n"); | 507 | usage("\n"); |
| 508 | } | ||
| 509 | |||
| 510 | check_ntp_peer_config_wrapper result = { | ||
| 511 | .errorcode = OK, | ||
| 512 | .config = check_ntp_peer_config_init(), | ||
| 513 | }; | ||
| 459 | 514 | ||
| 460 | while (true) { | 515 | while (true) { |
| 461 | int option = 0; | 516 | int option = 0; |
| 462 | int option_char = getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option); | 517 | int option_char = |
| 463 | if (option_char == -1 || option_char == EOF || option_char == 1) | 518 | getopt_long(argc, argv, "Vhv46qw:c:W:C:j:k:m:n:t:H:p:", longopts, &option); |
| 519 | if (option_char == -1 || option_char == EOF || option_char == 1) { | ||
| 464 | break; | 520 | break; |
| 521 | } | ||
| 465 | 522 | ||
| 466 | switch (option_char) { | 523 | switch (option_char) { |
| 524 | case output_format_index: { | ||
| 525 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 526 | if (!parser.parsing_success) { | ||
| 527 | printf("Invalid output format: %s\n", optarg); | ||
| 528 | exit(STATE_UNKNOWN); | ||
| 529 | } | ||
| 530 | |||
| 531 | result.config.output_format_is_set = true; | ||
| 532 | result.config.output_format = parser.output_format; | ||
| 533 | break; | ||
| 534 | } | ||
| 467 | case 'h': | 535 | case 'h': |
| 468 | print_help(); | 536 | print_help(); |
| 469 | exit(STATE_UNKNOWN); | 537 | exit(STATE_UNKNOWN); |
| @@ -476,45 +544,94 @@ int process_arguments(int argc, char **argv) { | |||
| 476 | verbose++; | 544 | verbose++; |
| 477 | break; | 545 | break; |
| 478 | case 'q': | 546 | case 'q': |
| 479 | quiet = true; | 547 | result.config.quiet = true; |
| 480 | break; | ||
| 481 | case 'w': | ||
| 482 | owarn = optarg; | ||
| 483 | break; | ||
| 484 | case 'c': | ||
| 485 | ocrit = optarg; | ||
| 486 | break; | ||
| 487 | case 'W': | ||
| 488 | do_stratum = true; | ||
| 489 | swarn = optarg; | ||
| 490 | break; | ||
| 491 | case 'C': | ||
| 492 | do_stratum = true; | ||
| 493 | scrit = optarg; | ||
| 494 | break; | ||
| 495 | case 'j': | ||
| 496 | do_jitter = true; | ||
| 497 | jwarn = optarg; | ||
| 498 | break; | ||
| 499 | case 'k': | ||
| 500 | do_jitter = true; | ||
| 501 | jcrit = optarg; | ||
| 502 | break; | ||
| 503 | case 'm': | ||
| 504 | do_truechimers = true; | ||
| 505 | twarn = optarg; | ||
| 506 | break; | ||
| 507 | case 'n': | ||
| 508 | do_truechimers = true; | ||
| 509 | tcrit = optarg; | ||
| 510 | break; | 548 | break; |
| 549 | case 'w': { | ||
| 550 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 551 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 552 | die(STATE_UNKNOWN, "failed to parse warning offset threshold"); | ||
| 553 | } | ||
| 554 | |||
| 555 | result.config.offset_thresholds = | ||
| 556 | mp_thresholds_set_warn(result.config.offset_thresholds, tmp.range); | ||
| 557 | } break; | ||
| 558 | case 'c': { | ||
| 559 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 560 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 561 | die(STATE_UNKNOWN, "failed to parse critical offset threshold"); | ||
| 562 | } | ||
| 563 | |||
| 564 | result.config.offset_thresholds = | ||
| 565 | mp_thresholds_set_crit(result.config.offset_thresholds, tmp.range); | ||
| 566 | } break; | ||
| 567 | case 'W': { | ||
| 568 | result.config.do_stratum = true; | ||
| 569 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 570 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 571 | die(STATE_UNKNOWN, "failed to parse warning stratum threshold"); | ||
| 572 | } | ||
| 573 | |||
| 574 | result.config.stratum_thresholds = | ||
| 575 | mp_thresholds_set_warn(result.config.stratum_thresholds, tmp.range); | ||
| 576 | } break; | ||
| 577 | case 'C': { | ||
| 578 | result.config.do_stratum = true; | ||
| 579 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 580 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 581 | die(STATE_UNKNOWN, "failed to parse critical stratum threshold"); | ||
| 582 | } | ||
| 583 | |||
| 584 | result.config.stratum_thresholds = | ||
| 585 | mp_thresholds_set_crit(result.config.stratum_thresholds, tmp.range); | ||
| 586 | } break; | ||
| 587 | case 'j': { | ||
| 588 | result.config.do_jitter = true; | ||
| 589 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 590 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 591 | die(STATE_UNKNOWN, "failed to parse warning jitter threshold"); | ||
| 592 | } | ||
| 593 | |||
| 594 | result.config.jitter_thresholds = | ||
| 595 | mp_thresholds_set_warn(result.config.jitter_thresholds, tmp.range); | ||
| 596 | } break; | ||
| 597 | case 'k': { | ||
| 598 | result.config.do_jitter = true; | ||
| 599 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 600 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 601 | die(STATE_UNKNOWN, "failed to parse critical jitter threshold"); | ||
| 602 | } | ||
| 603 | |||
| 604 | result.config.jitter_thresholds = | ||
| 605 | mp_thresholds_set_crit(result.config.jitter_thresholds, tmp.range); | ||
| 606 | } break; | ||
| 607 | case 'm': { | ||
| 608 | result.config.do_truechimers = true; | ||
| 609 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 610 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 611 | die(STATE_UNKNOWN, "failed to parse warning truechimer threshold"); | ||
| 612 | } | ||
| 613 | |||
| 614 | result.config.truechimer_thresholds = | ||
| 615 | mp_thresholds_set_warn(result.config.truechimer_thresholds, tmp.range); | ||
| 616 | } break; | ||
| 617 | case 'n': { | ||
| 618 | result.config.do_truechimers = true; | ||
| 619 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 620 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 621 | die(STATE_UNKNOWN, "failed to parse critical truechimer threshold"); | ||
| 622 | } | ||
| 623 | |||
| 624 | result.config.truechimer_thresholds = | ||
| 625 | mp_thresholds_set_crit(result.config.truechimer_thresholds, tmp.range); | ||
| 626 | } break; | ||
| 511 | case 'H': | 627 | case 'H': |
| 512 | if (!is_host(optarg)) | 628 | if (!is_host(optarg) && (optarg[0] != '/')) { |
| 513 | usage2(_("Invalid hostname/address"), optarg); | 629 | usage2(_("Invalid hostname/address"), optarg); |
| 514 | server_address = strdup(optarg); | 630 | } |
| 631 | result.config.server_address = strdup(optarg); | ||
| 515 | break; | 632 | break; |
| 516 | case 'p': | 633 | case 'p': |
| 517 | port = atoi(optarg); | 634 | result.config.port = atoi(optarg); |
| 518 | break; | 635 | break; |
| 519 | case 't': | 636 | case 't': |
| 520 | socket_timeout = atoi(optarg); | 637 | socket_timeout = atoi(optarg); |
| @@ -536,30 +653,32 @@ int process_arguments(int argc, char **argv) { | |||
| 536 | } | 653 | } |
| 537 | } | 654 | } |
| 538 | 655 | ||
| 539 | if (server_address == NULL) { | 656 | if (result.config.server_address == NULL) { |
| 540 | usage4(_("Hostname was not supplied")); | 657 | usage4(_("Hostname was not supplied")); |
| 541 | } | 658 | } |
| 542 | 659 | ||
| 543 | return 0; | 660 | return result; |
| 544 | } | 661 | } |
| 545 | 662 | ||
| 546 | char *perfd_offset(double offset) { | 663 | char *perfd_offset(double offset, thresholds *offset_thresholds) { |
| 547 | return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false, | 664 | return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, |
| 548 | 0); | 665 | offset_thresholds->critical->end, false, 0, false, 0); |
| 549 | } | 666 | } |
| 550 | 667 | ||
| 551 | char *perfd_jitter(double jitter) { | 668 | char *perfd_jitter(double jitter, bool do_jitter, thresholds *jitter_thresholds) { |
| 552 | return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter, jitter_thresholds->critical->end, true, 0, | 669 | return fperfdata("jitter", jitter, "", do_jitter, jitter_thresholds->warning->end, do_jitter, |
| 553 | false, 0); | 670 | jitter_thresholds->critical->end, true, 0, false, 0); |
| 554 | } | 671 | } |
| 555 | 672 | ||
| 556 | char *perfd_stratum(int stratum) { | 673 | char *perfd_stratum(int stratum, bool do_stratum, thresholds *stratum_thresholds) { |
| 557 | return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end, do_stratum, | 674 | return perfdata("stratum", stratum, "", do_stratum, (int)stratum_thresholds->warning->end, |
| 558 | (int)stratum_thresholds->critical->end, true, 0, true, 16); | 675 | do_stratum, (int)stratum_thresholds->critical->end, true, 0, true, 16); |
| 559 | } | 676 | } |
| 560 | 677 | ||
| 561 | char *perfd_truechimers(int num_truechimers) { | 678 | char *perfd_truechimers(int num_truechimers, const bool do_truechimers, |
| 562 | return perfdata("truechimers", num_truechimers, "", do_truechimers, (int)truechimer_thresholds->warning->end, do_truechimers, | 679 | thresholds *truechimer_thresholds) { |
| 680 | return perfdata("truechimers", num_truechimers, "", do_truechimers, | ||
| 681 | (int)truechimer_thresholds->warning->end, do_truechimers, | ||
| 563 | (int)truechimer_thresholds->critical->end, true, 0, false, 0); | 682 | (int)truechimer_thresholds->critical->end, true, 0, false, 0); |
| 564 | } | 683 | } |
| 565 | 684 | ||
| @@ -571,13 +690,17 @@ int main(int argc, char *argv[]) { | |||
| 571 | /* Parse extra opts if any */ | 690 | /* Parse extra opts if any */ |
| 572 | argv = np_extra_opts(&argc, argv, progname); | 691 | argv = np_extra_opts(&argc, argv, progname); |
| 573 | 692 | ||
| 574 | if (process_arguments(argc, argv) == ERROR) | 693 | check_ntp_peer_config_wrapper tmp_config = process_arguments(argc, argv); |
| 694 | |||
| 695 | if (tmp_config.errorcode == ERROR) { | ||
| 575 | usage4(_("Could not parse arguments")); | 696 | usage4(_("Could not parse arguments")); |
| 697 | } | ||
| 698 | |||
| 699 | const check_ntp_peer_config config = tmp_config.config; | ||
| 576 | 700 | ||
| 577 | set_thresholds(&offset_thresholds, owarn, ocrit); | 701 | if (config.output_format_is_set) { |
| 578 | set_thresholds(&jitter_thresholds, jwarn, jcrit); | 702 | mp_set_format(config.output_format); |
| 579 | set_thresholds(&stratum_thresholds, swarn, scrit); | 703 | } |
| 580 | set_thresholds(&truechimer_thresholds, twarn, tcrit); | ||
| 581 | 704 | ||
| 582 | /* initialize alarm signal handling */ | 705 | /* initialize alarm signal handling */ |
| 583 | signal(SIGALRM, socket_timeout_alarm_handler); | 706 | signal(SIGALRM, socket_timeout_alarm_handler); |
| @@ -585,115 +708,114 @@ int main(int argc, char *argv[]) { | |||
| 585 | /* set socket timeout */ | 708 | /* set socket timeout */ |
| 586 | alarm(socket_timeout); | 709 | alarm(socket_timeout); |
| 587 | 710 | ||
| 588 | int offset_result; | ||
| 589 | int stratum; | ||
| 590 | int num_truechimers; | ||
| 591 | double offset = 0; | ||
| 592 | double jitter = 0; | ||
| 593 | /* This returns either OK or WARNING (See comment preceding ntp_request) */ | 711 | /* This returns either OK or WARNING (See comment preceding ntp_request) */ |
| 594 | int result = ntp_request(&offset, &offset_result, &jitter, &stratum, &num_truechimers); | 712 | const ntp_request_result ntp_res = ntp_request(config); |
| 713 | mp_check overall = mp_check_init(); | ||
| 595 | 714 | ||
| 596 | if (offset_result == STATE_UNKNOWN) { | 715 | mp_subcheck sc_offset = mp_subcheck_init(); |
| 716 | xasprintf(&sc_offset.output, "offset"); | ||
| 717 | if (ntp_res.offset_result == STATE_UNKNOWN) { | ||
| 597 | /* if there's no sync peer (this overrides ntp_request output): */ | 718 | /* if there's no sync peer (this overrides ntp_request output): */ |
| 598 | result = (quiet ? STATE_UNKNOWN : STATE_CRITICAL); | 719 | sc_offset = |
| 720 | mp_set_subcheck_state(sc_offset, (config.quiet ? STATE_UNKNOWN : STATE_CRITICAL)); | ||
| 721 | xasprintf(&sc_offset.output, "%s unknown", sc_offset.output); | ||
| 599 | } else { | 722 | } else { |
| 600 | /* Be quiet if there's no candidates either */ | 723 | /* Be quiet if there's no candidates either */ |
| 601 | if (quiet && result == STATE_WARNING) | 724 | mp_state_enum tmp = STATE_OK; |
| 602 | result = STATE_UNKNOWN; | 725 | if (config.quiet && ntp_res.state == STATE_WARNING) { |
| 603 | result = max_state_alt(result, get_status(fabs(offset), offset_thresholds)); | 726 | tmp = STATE_UNKNOWN; |
| 604 | } | 727 | } |
| 605 | 728 | ||
| 606 | int oresult = result; | 729 | xasprintf(&sc_offset.output, "%s: %.6fs", sc_offset.output, ntp_res.offset); |
| 607 | 730 | ||
| 608 | int tresult = STATE_UNKNOWN; | 731 | mp_perfdata pd_offset = perfdata_init(); |
| 732 | pd_offset.value = mp_create_pd_value(fabs(ntp_res.offset)); | ||
| 733 | pd_offset = mp_pd_set_thresholds(pd_offset, config.offset_thresholds); | ||
| 734 | pd_offset.label = "offset"; | ||
| 735 | pd_offset.uom = "s"; | ||
| 736 | mp_add_perfdata_to_subcheck(&sc_offset, pd_offset); | ||
| 609 | 737 | ||
| 610 | if (do_truechimers) { | 738 | tmp = max_state_alt(tmp, mp_get_pd_status(pd_offset)); |
| 611 | tresult = get_status(num_truechimers, truechimer_thresholds); | 739 | sc_offset = mp_set_subcheck_state(sc_offset, tmp); |
| 612 | result = max_state_alt(result, tresult); | ||
| 613 | } | 740 | } |
| 614 | 741 | ||
| 615 | int sresult = STATE_UNKNOWN; | 742 | mp_add_subcheck_to_check(&overall, sc_offset); |
| 616 | 743 | ||
| 617 | if (do_stratum) { | 744 | // truechimers |
| 618 | sresult = get_status(stratum, stratum_thresholds); | 745 | if (config.do_truechimers) { |
| 619 | result = max_state_alt(result, sresult); | 746 | mp_subcheck sc_truechimers = mp_subcheck_init(); |
| 620 | } | 747 | xasprintf(&sc_truechimers.output, "truechimers: %i", ntp_res.num_truechimers); |
| 748 | |||
| 749 | mp_perfdata pd_truechimers = perfdata_init(); | ||
| 750 | pd_truechimers.value = mp_create_pd_value(ntp_res.num_truechimers); | ||
| 751 | pd_truechimers.label = "truechimers"; | ||
| 752 | pd_truechimers = mp_pd_set_thresholds(pd_truechimers, config.truechimer_thresholds); | ||
| 753 | |||
| 754 | mp_add_perfdata_to_subcheck(&sc_truechimers, pd_truechimers); | ||
| 621 | 755 | ||
| 622 | int jresult = STATE_UNKNOWN; | 756 | sc_truechimers = mp_set_subcheck_state(sc_truechimers, mp_get_pd_status(pd_truechimers)); |
| 623 | 757 | ||
| 624 | if (do_jitter) { | 758 | mp_add_subcheck_to_check(&overall, sc_truechimers); |
| 625 | jresult = get_status(jitter, jitter_thresholds); | ||
| 626 | result = max_state_alt(result, jresult); | ||
| 627 | } | 759 | } |
| 628 | 760 | ||
| 629 | char *result_line; | 761 | if (config.do_stratum) { |
| 630 | switch (result) { | 762 | mp_subcheck sc_stratum = mp_subcheck_init(); |
| 631 | case STATE_CRITICAL: | 763 | xasprintf(&sc_stratum.output, "stratum: %li", ntp_res.stratum); |
| 632 | xasprintf(&result_line, _("NTP CRITICAL:")); | 764 | |
| 633 | break; | 765 | mp_perfdata pd_stratum = perfdata_init(); |
| 634 | case STATE_WARNING: | 766 | pd_stratum.value = mp_create_pd_value(ntp_res.stratum); |
| 635 | xasprintf(&result_line, _("NTP WARNING:")); | 767 | pd_stratum = mp_pd_set_thresholds(pd_stratum, config.stratum_thresholds); |
| 636 | break; | 768 | pd_stratum.label = "stratum"; |
| 637 | case STATE_OK: | 769 | |
| 638 | xasprintf(&result_line, _("NTP OK:")); | 770 | mp_add_perfdata_to_subcheck(&sc_stratum, pd_stratum); |
| 639 | break; | 771 | |
| 640 | default: | 772 | sc_stratum = mp_set_subcheck_state(sc_stratum, mp_get_pd_status(pd_stratum)); |
| 641 | xasprintf(&result_line, _("NTP UNKNOWN:")); | 773 | |
| 642 | break; | 774 | mp_add_subcheck_to_check(&overall, sc_stratum); |
| 643 | } | 775 | } |
| 644 | if (!syncsource_found) | 776 | |
| 645 | xasprintf(&result_line, "%s %s,", result_line, _("Server not synchronized")); | 777 | if (config.do_jitter) { |
| 646 | else if (li_alarm) | 778 | mp_subcheck sc_jitter = mp_subcheck_init(); |
| 647 | xasprintf(&result_line, "%s %s,", result_line, _("Server has the LI_ALARM bit set")); | 779 | xasprintf(&sc_jitter.output, "jitter: %f", ntp_res.jitter); |
| 648 | 780 | ||
| 649 | char *perfdata_line; | 781 | mp_perfdata pd_jitter = perfdata_init(); |
| 650 | if (offset_result == STATE_UNKNOWN) { | 782 | pd_jitter.value = mp_create_pd_value(ntp_res.jitter); |
| 651 | xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); | 783 | pd_jitter = mp_pd_set_thresholds(pd_jitter, config.jitter_thresholds); |
| 652 | xasprintf(&perfdata_line, ""); | 784 | pd_jitter.label = "jitter"; |
| 653 | } else if (oresult == STATE_WARNING) { | 785 | |
| 654 | xasprintf(&result_line, "%s %s %.10g secs (WARNING)", result_line, _("Offset"), offset); | 786 | mp_add_perfdata_to_subcheck(&sc_jitter, pd_jitter); |
| 655 | } else if (oresult == STATE_CRITICAL) { | 787 | |
| 656 | xasprintf(&result_line, "%s %s %.10g secs (CRITICAL)", result_line, _("Offset"), offset); | 788 | sc_jitter = mp_set_subcheck_state(sc_jitter, mp_get_pd_status(pd_jitter)); |
| 657 | } else { | 789 | mp_add_subcheck_to_check(&overall, sc_jitter); |
| 658 | xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset); | ||
| 659 | } | 790 | } |
| 660 | xasprintf(&perfdata_line, "%s", perfd_offset(offset)); | 791 | |
| 661 | 792 | mp_subcheck sc_other_info = mp_subcheck_init(); | |
| 662 | if (do_jitter) { | 793 | sc_other_info = mp_set_subcheck_default_state(sc_other_info, STATE_OK); |
| 663 | if (jresult == STATE_WARNING) { | 794 | if (!ntp_res.syncsource_found) { |
| 664 | xasprintf(&result_line, "%s, jitter=%f (WARNING)", result_line, jitter); | 795 | xasprintf(&sc_other_info.output, "%s", _("Server not synchronized")); |
| 665 | } else if (jresult == STATE_CRITICAL) { | 796 | mp_add_subcheck_to_check(&overall, sc_other_info); |
| 666 | xasprintf(&result_line, "%s, jitter=%f (CRITICAL)", result_line, jitter); | 797 | } else if (ntp_res.li_alarm) { |
| 667 | } else { | 798 | xasprintf(&sc_other_info.output, "%s", _("Server has the LI_ALARM bit set")); |
| 668 | xasprintf(&result_line, "%s, jitter=%f", result_line, jitter); | 799 | mp_add_subcheck_to_check(&overall, sc_other_info); |
| 669 | } | ||
| 670 | xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_jitter(jitter)); | ||
| 671 | } | 800 | } |
| 672 | if (do_stratum) { | 801 | |
| 673 | if (sresult == STATE_WARNING) { | 802 | { |
| 674 | xasprintf(&result_line, "%s, stratum=%i (WARNING)", result_line, stratum); | 803 | mp_subcheck sc_offset = mp_subcheck_init(); |
| 675 | } else if (sresult == STATE_CRITICAL) { | 804 | sc_offset = mp_set_subcheck_default_state(sc_offset, STATE_OK); |
| 676 | xasprintf(&result_line, "%s, stratum=%i (CRITICAL)", result_line, stratum); | 805 | xasprintf(&sc_offset.output, "offset: %.10gs", ntp_res.offset); |
| 677 | } else { | 806 | |
| 678 | xasprintf(&result_line, "%s, stratum=%i", result_line, stratum); | 807 | mp_perfdata pd_offset = perfdata_init(); |
| 679 | } | 808 | pd_offset.value = mp_create_pd_value(ntp_res.offset); |
| 680 | xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_stratum(stratum)); | 809 | pd_offset = mp_pd_set_thresholds(pd_offset, config.offset_thresholds); |
| 810 | |||
| 811 | sc_offset = mp_set_subcheck_state(sc_offset, ntp_res.offset_result); | ||
| 681 | } | 812 | } |
| 682 | if (do_truechimers) { | 813 | |
| 683 | if (tresult == STATE_WARNING) { | 814 | if (config.server_address != NULL) { |
| 684 | xasprintf(&result_line, "%s, truechimers=%i (WARNING)", result_line, num_truechimers); | 815 | free(config.server_address); |
| 685 | } else if (tresult == STATE_CRITICAL) { | ||
| 686 | xasprintf(&result_line, "%s, truechimers=%i (CRITICAL)", result_line, num_truechimers); | ||
| 687 | } else { | ||
| 688 | xasprintf(&result_line, "%s, truechimers=%i", result_line, num_truechimers); | ||
| 689 | } | ||
| 690 | xasprintf(&perfdata_line, "%s %s", perfdata_line, perfd_truechimers(num_truechimers)); | ||
| 691 | } | 816 | } |
| 692 | printf("%s|%s\n", result_line, perfdata_line); | ||
| 693 | 817 | ||
| 694 | if (server_address != NULL) | 818 | mp_exit(overall); |
| 695 | free(server_address); | ||
| 696 | return result; | ||
| 697 | } | 819 | } |
| 698 | 820 | ||
| 699 | void print_help(void) { | 821 | void print_help(void) { |
| @@ -712,7 +834,8 @@ void print_help(void) { | |||
| 712 | printf(UT_IPv46); | 834 | printf(UT_IPv46); |
| 713 | printf(UT_HOST_PORT, 'p', "123"); | 835 | printf(UT_HOST_PORT, 'p', "123"); |
| 714 | printf(" %s\n", "-q, --quiet"); | 836 | printf(" %s\n", "-q, --quiet"); |
| 715 | printf(" %s\n", _("Returns UNKNOWN instead of CRITICAL or WARNING if server isn't synchronized")); | 837 | printf(" %s\n", |
| 838 | _("Returns UNKNOWN instead of CRITICAL or WARNING if server isn't synchronized")); | ||
| 716 | printf(" %s\n", "-w, --warning=THRESHOLD"); | 839 | printf(" %s\n", "-w, --warning=THRESHOLD"); |
| 717 | printf(" %s\n", _("Offset to result in warning status (seconds)")); | 840 | printf(" %s\n", _("Offset to result in warning status (seconds)")); |
| 718 | printf(" %s\n", "-c, --critical=THRESHOLD"); | 841 | printf(" %s\n", "-c, --critical=THRESHOLD"); |
| @@ -731,6 +854,7 @@ void print_help(void) { | |||
| 731 | printf(" %s\n", _("Critical threshold for number of usable time sources (\"truechimers\")")); | 854 | printf(" %s\n", _("Critical threshold for number of usable time sources (\"truechimers\")")); |
| 732 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 855 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 733 | printf(UT_VERBOSE); | 856 | printf(UT_VERBOSE); |
| 857 | printf(UT_OUTPUT_FORMAT); | ||
| 734 | 858 | ||
| 735 | printf("\n"); | 859 | printf("\n"); |
| 736 | printf("%s\n", _("This plugin checks an NTP server independent of any commandline")); | 860 | printf("%s\n", _("This plugin checks an NTP server independent of any commandline")); |
| @@ -749,7 +873,8 @@ void print_help(void) { | |||
| 749 | printf(" %s\n", _("Simple NTP server check:")); | 873 | printf(" %s\n", _("Simple NTP server check:")); |
| 750 | printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1")); | 874 | printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1")); |
| 751 | printf("\n"); | 875 | printf("\n"); |
| 752 | printf(" %s\n", _("Check jitter too, avoiding critical notifications if jitter isn't available")); | 876 | printf(" %s\n", |
| 877 | _("Check jitter too, avoiding critical notifications if jitter isn't available")); | ||
| 753 | printf(" %s\n", _("(See Notes above for more details on thresholds formats):")); | 878 | printf(" %s\n", _("(See Notes above for more details on thresholds formats):")); |
| 754 | printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1 -j -1:100 -k -1:200")); | 879 | printf(" %s\n", ("./check_ntp_peer -H ntpserv -w 0.5 -c 1 -j -1:100 -k -1:200")); |
| 755 | printf("\n"); | 880 | printf("\n"); |
diff --git a/plugins/check_ntp_peer.d/config.h b/plugins/check_ntp_peer.d/config.h new file mode 100644 index 00000000..488d936c --- /dev/null +++ b/plugins/check_ntp_peer.d/config.h | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include "output.h" | ||
| 5 | #include "perfdata.h" | ||
| 6 | #include "thresholds.h" | ||
| 7 | #include <stddef.h> | ||
| 8 | |||
| 9 | enum { | ||
| 10 | DEFAULT_NTP_PORT = 123, | ||
| 11 | }; | ||
| 12 | |||
| 13 | typedef struct { | ||
| 14 | char *server_address; | ||
| 15 | int port; | ||
| 16 | |||
| 17 | bool quiet; | ||
| 18 | |||
| 19 | // truechimer stuff | ||
| 20 | bool do_truechimers; | ||
| 21 | mp_thresholds truechimer_thresholds; | ||
| 22 | |||
| 23 | // offset thresholds | ||
| 24 | mp_thresholds offset_thresholds; | ||
| 25 | |||
| 26 | // stratum stuff | ||
| 27 | bool do_stratum; | ||
| 28 | mp_thresholds stratum_thresholds; | ||
| 29 | |||
| 30 | // jitter stuff | ||
| 31 | bool do_jitter; | ||
| 32 | mp_thresholds jitter_thresholds; | ||
| 33 | |||
| 34 | bool output_format_is_set; | ||
| 35 | mp_output_format output_format; | ||
| 36 | } check_ntp_peer_config; | ||
| 37 | |||
| 38 | check_ntp_peer_config check_ntp_peer_config_init() { | ||
| 39 | check_ntp_peer_config tmp = { | ||
| 40 | .server_address = NULL, | ||
| 41 | .port = DEFAULT_NTP_PORT, | ||
| 42 | |||
| 43 | .quiet = false, | ||
| 44 | .do_truechimers = false, | ||
| 45 | .truechimer_thresholds = mp_thresholds_init(), | ||
| 46 | |||
| 47 | .offset_thresholds = mp_thresholds_init(), | ||
| 48 | |||
| 49 | .do_stratum = false, | ||
| 50 | .stratum_thresholds = mp_thresholds_init(), | ||
| 51 | |||
| 52 | .do_jitter = false, | ||
| 53 | .jitter_thresholds = mp_thresholds_init(), | ||
| 54 | |||
| 55 | .output_format_is_set = false, | ||
| 56 | }; | ||
| 57 | |||
| 58 | mp_range stratum_default = mp_range_init(); | ||
| 59 | stratum_default = mp_range_set_start(stratum_default, mp_create_pd_value(-1)); | ||
| 60 | stratum_default = mp_range_set_end(stratum_default, mp_create_pd_value(16)); | ||
| 61 | tmp.stratum_thresholds = mp_thresholds_set_warn(tmp.stratum_thresholds, stratum_default); | ||
| 62 | tmp.stratum_thresholds = mp_thresholds_set_crit(tmp.stratum_thresholds, stratum_default); | ||
| 63 | |||
| 64 | mp_range jitter_w_default = mp_range_init(); | ||
| 65 | jitter_w_default = mp_range_set_start(jitter_w_default, mp_create_pd_value(-1)); | ||
| 66 | jitter_w_default = mp_range_set_end(jitter_w_default, mp_create_pd_value(5000)); | ||
| 67 | tmp.jitter_thresholds = mp_thresholds_set_warn(tmp.jitter_thresholds, jitter_w_default); | ||
| 68 | |||
| 69 | mp_range jitter_c_default = mp_range_init(); | ||
| 70 | jitter_c_default = mp_range_set_start(jitter_c_default, mp_create_pd_value(-1)); | ||
| 71 | jitter_c_default = mp_range_set_end(jitter_c_default, mp_create_pd_value(10000)); | ||
| 72 | tmp.jitter_thresholds = mp_thresholds_set_crit(tmp.jitter_thresholds, jitter_c_default); | ||
| 73 | |||
| 74 | mp_range offset_w_default = mp_range_init(); | ||
| 75 | offset_w_default = mp_range_set_end(offset_w_default, mp_create_pd_value(60)); | ||
| 76 | tmp.offset_thresholds = mp_thresholds_set_warn(tmp.offset_thresholds, offset_w_default); | ||
| 77 | |||
| 78 | mp_range offset_c_default = mp_range_init(); | ||
| 79 | offset_c_default = mp_range_set_end(offset_c_default, mp_create_pd_value(120)); | ||
| 80 | tmp.offset_thresholds = mp_thresholds_set_crit(tmp.offset_thresholds, offset_c_default); | ||
| 81 | return tmp; | ||
| 82 | } | ||
diff --git a/plugins/check_ntp_time.c b/plugins/check_ntp_time.c index 31162883..9e0beb9c 100644 --- a/plugins/check_ntp_time.c +++ b/plugins/check_ntp_time.c | |||
| @@ -34,19 +34,23 @@ | |||
| 34 | * | 34 | * |
| 35 | *****************************************************************************/ | 35 | *****************************************************************************/ |
| 36 | 36 | ||
| 37 | const char *progname = "check_ntp_time"; | 37 | #include "output.h" |
| 38 | const char *copyright = "2006-2024"; | ||
| 39 | const char *email = "devel@monitoring-plugins.org"; | ||
| 40 | |||
| 41 | #include "common.h" | 38 | #include "common.h" |
| 42 | #include "netutils.h" | 39 | #include "netutils.h" |
| 40 | #include "perfdata.h" | ||
| 43 | #include "utils.h" | 41 | #include "utils.h" |
| 44 | #include "states.h" | 42 | #include "states.h" |
| 45 | #include "thresholds.h" | 43 | #include "thresholds.h" |
| 46 | #include "check_ntp_time.d/config.h" | 44 | #include "check_ntp_time.d/config.h" |
| 45 | #include <netinet/in.h> | ||
| 46 | #include <sys/socket.h> | ||
| 47 | 47 | ||
| 48 | static int verbose = 0; | 48 | static int verbose = 0; |
| 49 | 49 | ||
| 50 | const char *progname = "check_ntp_time"; | ||
| 51 | const char *copyright = "2006-2024"; | ||
| 52 | const char *email = "devel@monitoring-plugins.org"; | ||
| 53 | |||
| 50 | typedef struct { | 54 | typedef struct { |
| 51 | int errorcode; | 55 | int errorcode; |
| 52 | check_ntp_time_config config; | 56 | check_ntp_time_config config; |
| @@ -61,9 +65,6 @@ void print_usage(void); | |||
| 61 | # define AVG_NUM 4 | 65 | # define AVG_NUM 4 |
| 62 | #endif | 66 | #endif |
| 63 | 67 | ||
| 64 | /* max size of control message data */ | ||
| 65 | #define MAX_CM_SIZE 468 | ||
| 66 | |||
| 67 | /* this structure holds everything in an ntp request/response as per rfc1305 */ | 68 | /* this structure holds everything in an ntp request/response as per rfc1305 */ |
| 68 | typedef struct { | 69 | typedef struct { |
| 69 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ | 70 | uint8_t flags; /* byte with leapindicator,vers,mode. see macros */ |
| @@ -93,9 +94,9 @@ typedef struct { | |||
| 93 | /* bits 1,2 are the leap indicator */ | 94 | /* bits 1,2 are the leap indicator */ |
| 94 | #define LI_MASK 0xc0 | 95 | #define LI_MASK 0xc0 |
| 95 | #define LI(x) ((x & LI_MASK) >> 6) | 96 | #define LI(x) ((x & LI_MASK) >> 6) |
| 96 | #define LI_SET(x, y) \ | 97 | #define LI_SET(x, y) \ |
| 97 | do { \ | 98 | do { \ |
| 98 | x |= ((y << 6) & LI_MASK); \ | 99 | x |= ((y << 6) & LI_MASK); \ |
| 99 | } while (0) | 100 | } while (0) |
| 100 | /* and these are the values of the leap indicator */ | 101 | /* and these are the values of the leap indicator */ |
| 101 | #define LI_NOWARNING 0x00 | 102 | #define LI_NOWARNING 0x00 |
| @@ -105,17 +106,17 @@ typedef struct { | |||
| 105 | /* bits 3,4,5 are the ntp version */ | 106 | /* bits 3,4,5 are the ntp version */ |
| 106 | #define VN_MASK 0x38 | 107 | #define VN_MASK 0x38 |
| 107 | #define VN(x) ((x & VN_MASK) >> 3) | 108 | #define VN(x) ((x & VN_MASK) >> 3) |
| 108 | #define VN_SET(x, y) \ | 109 | #define VN_SET(x, y) \ |
| 109 | do { \ | 110 | do { \ |
| 110 | x |= ((y << 3) & VN_MASK); \ | 111 | x |= ((y << 3) & VN_MASK); \ |
| 111 | } while (0) | 112 | } while (0) |
| 112 | #define VN_RESERVED 0x02 | 113 | #define VN_RESERVED 0x02 |
| 113 | /* bits 6,7,8 are the ntp mode */ | 114 | /* bits 6,7,8 are the ntp mode */ |
| 114 | #define MODE_MASK 0x07 | 115 | #define MODE_MASK 0x07 |
| 115 | #define MODE(x) (x & MODE_MASK) | 116 | #define MODE(x) (x & MODE_MASK) |
| 116 | #define MODE_SET(x, y) \ | 117 | #define MODE_SET(x, y) \ |
| 117 | do { \ | 118 | do { \ |
| 118 | x |= (y & MODE_MASK); \ | 119 | x |= (y & MODE_MASK); \ |
| 119 | } while (0) | 120 | } while (0) |
| 120 | /* here are some values */ | 121 | /* here are some values */ |
| 121 | #define MODE_CLIENT 0x03 | 122 | #define MODE_CLIENT 0x03 |
| @@ -127,9 +128,9 @@ typedef struct { | |||
| 127 | #define REM_MORE 0x20 | 128 | #define REM_MORE 0x20 |
| 128 | /* In control message, bits 11 - 15 are opcode */ | 129 | /* In control message, bits 11 - 15 are opcode */ |
| 129 | #define OP_MASK 0x1f | 130 | #define OP_MASK 0x1f |
| 130 | #define OP_SET(x, y) \ | 131 | #define OP_SET(x, y) \ |
| 131 | do { \ | 132 | do { \ |
| 132 | x |= (y & OP_MASK); \ | 133 | x |= (y & OP_MASK); \ |
| 133 | } while (0) | 134 | } while (0) |
| 134 | #define OP_READSTAT 0x01 | 135 | #define OP_READSTAT 0x01 |
| 135 | #define OP_READVAR 0x02 | 136 | #define OP_READVAR 0x02 |
| @@ -163,32 +164,36 @@ typedef struct { | |||
| 163 | #define NTP32asDOUBLE(x) (ntohs(L16(x)) + ((double)ntohs(R16(x)) / 65536.0)) | 164 | #define NTP32asDOUBLE(x) (ntohs(L16(x)) + ((double)ntohs(R16(x)) / 65536.0)) |
| 164 | 165 | ||
| 165 | /* likewise for a 64-bit ntp fp number */ | 166 | /* likewise for a 64-bit ntp fp number */ |
| 166 | #define NTP64asDOUBLE(n) \ | 167 | #define NTP64asDOUBLE(n) \ |
| 167 | (double)(((uint64_t)n) ? (ntohl(L32(n)) - EPOCHDIFF) + (.00000001 * (0.5 + (double)(ntohl(R32(n)) / 42.94967296))) : 0) | 168 | (double)(((uint64_t)n) ? (ntohl(L32(n)) - EPOCHDIFF) + \ |
| 169 | (.00000001 * (0.5 + (double)(ntohl(R32(n)) / 42.94967296))) \ | ||
| 170 | : 0) | ||
| 168 | 171 | ||
| 169 | /* convert a struct timeval to a double */ | 172 | /* convert a struct timeval to a double */ |
| 170 | #define TVasDOUBLE(x) (double)(x.tv_sec + (0.000001 * x.tv_usec)) | 173 | static double TVasDOUBLE(struct timeval time) { |
| 174 | return ((double)time.tv_sec + (0.000001 * (double)time.tv_usec)); | ||
| 175 | } | ||
| 171 | 176 | ||
| 172 | /* convert an ntp 64-bit fp number to a struct timeval */ | 177 | /* convert an ntp 64-bit fp number to a struct timeval */ |
| 173 | #define NTP64toTV(n, t) \ | 178 | #define NTP64toTV(n, t) \ |
| 174 | do { \ | 179 | do { \ |
| 175 | if (!n) \ | 180 | if (!n) \ |
| 176 | t.tv_sec = t.tv_usec = 0; \ | 181 | t.tv_sec = t.tv_usec = 0; \ |
| 177 | else { \ | 182 | else { \ |
| 178 | t.tv_sec = ntohl(L32(n)) - EPOCHDIFF; \ | 183 | t.tv_sec = ntohl(L32(n)) - EPOCHDIFF; \ |
| 179 | t.tv_usec = (int)(0.5 + (double)(ntohl(R32(n)) / 4294.967296)); \ | 184 | t.tv_usec = (int)(0.5 + (double)(ntohl(R32(n)) / 4294.967296)); \ |
| 180 | } \ | 185 | } \ |
| 181 | } while (0) | 186 | } while (0) |
| 182 | 187 | ||
| 183 | /* convert a struct timeval to an ntp 64-bit fp number */ | 188 | /* convert a struct timeval to an ntp 64-bit fp number */ |
| 184 | #define TVtoNTP64(t, n) \ | 189 | #define TVtoNTP64(t, n) \ |
| 185 | do { \ | 190 | do { \ |
| 186 | if (!t.tv_usec && !t.tv_sec) \ | 191 | if (!t.tv_usec && !t.tv_sec) \ |
| 187 | n = 0x0UL; \ | 192 | n = 0x0UL; \ |
| 188 | else { \ | 193 | else { \ |
| 189 | L32(n) = htonl(t.tv_sec + EPOCHDIFF); \ | 194 | L32(n) = htonl(t.tv_sec + EPOCHDIFF); \ |
| 190 | R32(n) = htonl((uint64_t)((4294.967296 * t.tv_usec) + .5)); \ | 195 | R32(n) = htonl((uint64_t)((4294.967296 * t.tv_usec) + .5)); \ |
| 191 | } \ | 196 | } \ |
| 192 | } while (0) | 197 | } while (0) |
| 193 | 198 | ||
| 194 | /* NTP control message header is 12 bytes, plus any data in the data | 199 | /* NTP control message header is 12 bytes, plus any data in the data |
| @@ -197,15 +202,15 @@ typedef struct { | |||
| 197 | #define SIZEOF_NTPCM(m) (12 + ntohs(m.count) + ((m.count) ? 4 - (ntohs(m.count) % 4) : 0)) | 202 | #define SIZEOF_NTPCM(m) (12 + ntohs(m.count) + ((m.count) ? 4 - (ntohs(m.count) % 4) : 0)) |
| 198 | 203 | ||
| 199 | /* finally, a little helper or two for debugging: */ | 204 | /* finally, a little helper or two for debugging: */ |
| 200 | #define DBG(x) \ | 205 | #define DBG(x) \ |
| 201 | do { \ | 206 | do { \ |
| 202 | if (verbose > 1) { \ | 207 | if (verbose > 1) { \ |
| 203 | x; \ | 208 | x; \ |
| 204 | } \ | 209 | } \ |
| 205 | } while (0); | 210 | } while (0); |
| 206 | #define PRINTSOCKADDR(x) \ | 211 | #define PRINTSOCKADDR(x) \ |
| 207 | do { \ | 212 | do { \ |
| 208 | printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ | 213 | printf("%u.%u.%u.%u", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff); \ |
| 209 | } while (0); | 214 | } while (0); |
| 210 | 215 | ||
| 211 | /* calculate the offset of the local clock */ | 216 | /* calculate the offset of the local clock */ |
| @@ -260,8 +265,8 @@ void setup_request(ntp_message *message) { | |||
| 260 | /* select the "best" server from a list of servers, and return its index. | 265 | /* select the "best" server from a list of servers, and return its index. |
| 261 | * this is done by filtering servers based on stratum, dispersion, and | 266 | * this is done by filtering servers based on stratum, dispersion, and |
| 262 | * finally round-trip delay. */ | 267 | * finally round-trip delay. */ |
| 263 | int best_offset_server(const ntp_server_results *slist, int nservers) { | 268 | static int best_offset_server(const ntp_server_results *slist, int nservers) { |
| 264 | int best_server = -1; | 269 | int best_server_index = -1; |
| 265 | 270 | ||
| 266 | /* for each server */ | 271 | /* for each server */ |
| 267 | for (int cserver = 0; cserver < nservers; cserver++) { | 272 | for (int cserver = 0; cserver < nservers; cserver++) { |
| @@ -284,33 +289,33 @@ int best_offset_server(const ntp_server_results *slist, int nservers) { | |||
| 284 | } | 289 | } |
| 285 | 290 | ||
| 286 | /* If we don't have a server yet, use the first one */ | 291 | /* If we don't have a server yet, use the first one */ |
| 287 | if (best_server == -1) { | 292 | if (best_server_index == -1) { |
| 288 | best_server = cserver; | 293 | best_server_index = cserver; |
| 289 | DBG(printf("using peer %d as our first candidate\n", best_server)); | 294 | DBG(printf("using peer %d as our first candidate\n", best_server_index)); |
| 290 | continue; | 295 | continue; |
| 291 | } | 296 | } |
| 292 | 297 | ||
| 293 | /* compare the server to the best one we've seen so far */ | 298 | /* compare the server to the best one we've seen so far */ |
| 294 | /* does it have an equal or better stratum? */ | 299 | /* does it have an equal or better stratum? */ |
| 295 | DBG(printf("comparing peer %d with peer %d\n", cserver, best_server)); | 300 | DBG(printf("comparing peer %d with peer %d\n", cserver, best_server_index)); |
| 296 | if (slist[cserver].stratum <= slist[best_server].stratum) { | 301 | if (slist[cserver].stratum <= slist[best_server_index].stratum) { |
| 297 | DBG(printf("stratum for peer %d <= peer %d\n", cserver, best_server)); | 302 | DBG(printf("stratum for peer %d <= peer %d\n", cserver, best_server_index)); |
| 298 | /* does it have an equal or better dispersion? */ | 303 | /* does it have an equal or better dispersion? */ |
| 299 | if (slist[cserver].rtdisp <= slist[best_server].rtdisp) { | 304 | if (slist[cserver].rtdisp <= slist[best_server_index].rtdisp) { |
| 300 | DBG(printf("dispersion for peer %d <= peer %d\n", cserver, best_server)); | 305 | DBG(printf("dispersion for peer %d <= peer %d\n", cserver, best_server_index)); |
| 301 | /* does it have a better rtdelay? */ | 306 | /* does it have a better rtdelay? */ |
| 302 | if (slist[cserver].rtdelay < slist[best_server].rtdelay) { | 307 | if (slist[cserver].rtdelay < slist[best_server_index].rtdelay) { |
| 303 | DBG(printf("rtdelay for peer %d < peer %d\n", cserver, best_server)); | 308 | DBG(printf("rtdelay for peer %d < peer %d\n", cserver, best_server_index)); |
| 304 | best_server = cserver; | 309 | best_server_index = cserver; |
| 305 | DBG(printf("peer %d is now our best candidate\n", best_server)); | 310 | DBG(printf("peer %d is now our best candidate\n", best_server_index)); |
| 306 | } | 311 | } |
| 307 | } | 312 | } |
| 308 | } | 313 | } |
| 309 | } | 314 | } |
| 310 | 315 | ||
| 311 | if (best_server >= 0) { | 316 | if (best_server_index >= 0) { |
| 312 | DBG(printf("best server selected: peer %d\n", best_server)); | 317 | DBG(printf("best server selected: peer %d\n", best_server_index)); |
| 313 | return best_server; | 318 | return best_server_index; |
| 314 | } | 319 | } |
| 315 | DBG(printf("no peers meeting synchronization criteria :(\n")); | 320 | DBG(printf("no peers meeting synchronization criteria :(\n")); |
| 316 | return -1; | 321 | return -1; |
| @@ -321,7 +326,11 @@ int best_offset_server(const ntp_server_results *slist, int nservers) { | |||
| 321 | * we don't waste time sitting around waiting for single packets. | 326 | * we don't waste time sitting around waiting for single packets. |
| 322 | * - we also "manually" handle resolving host names and connecting, because | 327 | * - we also "manually" handle resolving host names and connecting, because |
| 323 | * we have to do it in a way that our lazy macros don't handle currently :( */ | 328 | * we have to do it in a way that our lazy macros don't handle currently :( */ |
| 324 | double offset_request(const char *host, const char *port, mp_state_enum *status, int time_offset) { | 329 | typedef struct { |
| 330 | mp_state_enum offset_result; | ||
| 331 | double offset; | ||
| 332 | } offset_request_wrapper; | ||
| 333 | static offset_request_wrapper offset_request(const char *host, const char *port, int time_offset) { | ||
| 325 | /* setup hints to only return results from getaddrinfo that we'd like */ | 334 | /* setup hints to only return results from getaddrinfo that we'd like */ |
| 326 | struct addrinfo hints; | 335 | struct addrinfo hints; |
| 327 | memset(&hints, 0, sizeof(struct addrinfo)); | 336 | memset(&hints, 0, sizeof(struct addrinfo)); |
| @@ -329,17 +338,25 @@ double offset_request(const char *host, const char *port, mp_state_enum *status, | |||
| 329 | hints.ai_protocol = IPPROTO_UDP; | 338 | hints.ai_protocol = IPPROTO_UDP; |
| 330 | hints.ai_socktype = SOCK_DGRAM; | 339 | hints.ai_socktype = SOCK_DGRAM; |
| 331 | 340 | ||
| 332 | /* fill in ai with the list of hosts resolved by the host name */ | 341 | bool is_socket; |
| 333 | struct addrinfo *addresses = NULL; | 342 | struct addrinfo *addresses = NULL; |
| 334 | int ga_result = getaddrinfo(host, port, &hints, &addresses); | ||
| 335 | if (ga_result != 0) { | ||
| 336 | die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result)); | ||
| 337 | } | ||
| 338 | |||
| 339 | /* count the number of returned hosts, and allocate stuff accordingly */ | ||
| 340 | size_t num_hosts = 0; | 343 | size_t num_hosts = 0; |
| 341 | for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { | 344 | if (host[0] == '/') { |
| 342 | num_hosts++; | 345 | num_hosts = 1; |
| 346 | is_socket = true; | ||
| 347 | } else { | ||
| 348 | is_socket = false; | ||
| 349 | |||
| 350 | /* fill in ai with the list of hosts resolved by the host name */ | ||
| 351 | int ga_result = getaddrinfo(host, port, &hints, &addresses); | ||
| 352 | if (ga_result != 0) { | ||
| 353 | die(STATE_UNKNOWN, "error getting address for %s: %s\n", host, gai_strerror(ga_result)); | ||
| 354 | } | ||
| 355 | |||
| 356 | /* count the number of returned hosts, and allocate stuff accordingly */ | ||
| 357 | for (struct addrinfo *ai_tmp = addresses; ai_tmp != NULL; ai_tmp = ai_tmp->ai_next) { | ||
| 358 | num_hosts++; | ||
| 359 | } | ||
| 343 | } | 360 | } |
| 344 | 361 | ||
| 345 | ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts); | 362 | ntp_message *req = (ntp_message *)malloc(sizeof(ntp_message) * num_hosts); |
| @@ -358,7 +375,8 @@ double offset_request(const char *host, const char *port, mp_state_enum *status, | |||
| 358 | die(STATE_UNKNOWN, "can not allocate socket array"); | 375 | die(STATE_UNKNOWN, "can not allocate socket array"); |
| 359 | } | 376 | } |
| 360 | 377 | ||
| 361 | ntp_server_results *servers = (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts); | 378 | ntp_server_results *servers = |
| 379 | (ntp_server_results *)malloc(sizeof(ntp_server_results) * num_hosts); | ||
| 362 | if (servers == NULL) { | 380 | if (servers == NULL) { |
| 363 | die(STATE_UNKNOWN, "can not allocate server array"); | 381 | die(STATE_UNKNOWN, "can not allocate server array"); |
| 364 | } | 382 | } |
| @@ -366,25 +384,51 @@ double offset_request(const char *host, const char *port, mp_state_enum *status, | |||
| 366 | DBG(printf("Found %zu peers to check\n", num_hosts)); | 384 | DBG(printf("Found %zu peers to check\n", num_hosts)); |
| 367 | 385 | ||
| 368 | /* setup each socket for writing, and the corresponding struct pollfd */ | 386 | /* setup each socket for writing, and the corresponding struct pollfd */ |
| 369 | struct addrinfo *ai_tmp = addresses; | 387 | if (is_socket) { |
| 370 | for (int i = 0; ai_tmp; i++) { | 388 | socklist[0] = socket(AF_UNIX, SOCK_STREAM, 0); |
| 371 | socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); | 389 | if (socklist[0] == -1) { |
| 372 | if (socklist[i] == -1) { | 390 | DBG(printf("can't create socket: %s\n", strerror(errno))); |
| 373 | perror(NULL); | 391 | die(STATE_UNKNOWN, "can not create new socket\n"); |
| 374 | die(STATE_UNKNOWN, "can not create new socket"); | ||
| 375 | } | 392 | } |
| 376 | if (connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)) { | 393 | |
| 394 | struct sockaddr_un unix_socket = { | ||
| 395 | .sun_family = AF_UNIX, | ||
| 396 | }; | ||
| 397 | |||
| 398 | strncpy(unix_socket.sun_path, host, strlen(host)); | ||
| 399 | |||
| 400 | if (connect(socklist[0], &unix_socket, sizeof(unix_socket))) { | ||
| 377 | /* don't die here, because it is enough if there is one server | 401 | /* don't die here, because it is enough if there is one server |
| 378 | answering in time. This also would break for dual ipv4/6 stacked | 402 | answering in time. This also would break for dual ipv4/6 stacked |
| 379 | ntp servers when the client only supports on of them. | 403 | ntp servers when the client only supports on of them. |
| 380 | */ | 404 | */ |
| 381 | DBG(printf("can't create socket connection on peer %i: %s\n", i, strerror(errno))); | 405 | DBG(printf("can't create socket connection on peer %i: %s\n", 0, strerror(errno))); |
| 382 | } else { | 406 | } else { |
| 383 | ufds[i].fd = socklist[i]; | 407 | ufds[0].fd = socklist[0]; |
| 384 | ufds[i].events = POLLIN; | 408 | ufds[0].events = POLLIN; |
| 385 | ufds[i].revents = 0; | 409 | ufds[0].revents = 0; |
| 410 | } | ||
| 411 | } else { | ||
| 412 | struct addrinfo *ai_tmp = addresses; | ||
| 413 | for (int i = 0; ai_tmp; i++) { | ||
| 414 | socklist[i] = socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP); | ||
| 415 | if (socklist[i] == -1) { | ||
| 416 | perror(NULL); | ||
| 417 | die(STATE_UNKNOWN, "can not create new socket"); | ||
| 418 | } | ||
| 419 | if (connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)) { | ||
| 420 | /* don't die here, because it is enough if there is one server | ||
| 421 | answering in time. This also would break for dual ipv4/6 stacked | ||
| 422 | ntp servers when the client only supports on of them. | ||
| 423 | */ | ||
| 424 | DBG(printf("can't create socket connection on peer %i: %s\n", i, strerror(errno))); | ||
| 425 | } else { | ||
| 426 | ufds[i].fd = socklist[i]; | ||
| 427 | ufds[i].events = POLLIN; | ||
| 428 | ufds[i].revents = 0; | ||
| 429 | } | ||
| 430 | ai_tmp = ai_tmp->ai_next; | ||
| 386 | } | 431 | } |
| 387 | ai_tmp = ai_tmp->ai_next; | ||
| 388 | } | 432 | } |
| 389 | 433 | ||
| 390 | /* now do AVG_NUM checks to each host. We stop before timeout/2 seconds | 434 | /* now do AVG_NUM checks to each host. We stop before timeout/2 seconds |
| @@ -459,12 +503,18 @@ double offset_request(const char *host, const char *port, mp_state_enum *status, | |||
| 459 | die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); | 503 | die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n"); |
| 460 | } | 504 | } |
| 461 | 505 | ||
| 506 | offset_request_wrapper result = { | ||
| 507 | .offset = 0, | ||
| 508 | .offset_result = STATE_UNKNOWN, | ||
| 509 | }; | ||
| 510 | |||
| 462 | /* now, pick the best server from the list */ | 511 | /* now, pick the best server from the list */ |
| 463 | double avg_offset = 0.; | 512 | double avg_offset = 0.; |
| 464 | int best_index = best_offset_server(servers, num_hosts); | 513 | int best_index = best_offset_server(servers, num_hosts); |
| 465 | if (best_index < 0) { | 514 | if (best_index < 0) { |
| 466 | *status = STATE_UNKNOWN; | 515 | result.offset_result = STATE_UNKNOWN; |
| 467 | } else { | 516 | } else { |
| 517 | result.offset_result = STATE_OK; | ||
| 468 | /* finally, calculate the average offset */ | 518 | /* finally, calculate the average offset */ |
| 469 | for (int i = 0; i < servers[best_index].num_responses; i++) { | 519 | for (int i = 0; i < servers[best_index].num_responses; i++) { |
| 470 | avg_offset += servers[best_index].offset[i]; | 520 | avg_offset += servers[best_index].offset[i]; |
| @@ -485,22 +535,30 @@ double offset_request(const char *host, const char *port, mp_state_enum *status, | |||
| 485 | if (verbose) { | 535 | if (verbose) { |
| 486 | printf("overall average offset: %.10g\n", avg_offset); | 536 | printf("overall average offset: %.10g\n", avg_offset); |
| 487 | } | 537 | } |
| 488 | return avg_offset; | 538 | |
| 539 | result.offset = avg_offset; | ||
| 540 | return result; | ||
| 489 | } | 541 | } |
| 490 | 542 | ||
| 491 | check_ntp_time_config_wrapper process_arguments(int argc, char **argv) { | 543 | static check_ntp_time_config_wrapper process_arguments(int argc, char **argv) { |
| 544 | |||
| 545 | enum { | ||
| 546 | output_format_index = CHAR_MAX + 1, | ||
| 547 | }; | ||
| 548 | |||
| 492 | static struct option longopts[] = {{"version", no_argument, 0, 'V'}, | 549 | static struct option longopts[] = {{"version", no_argument, 0, 'V'}, |
| 493 | {"help", no_argument, 0, 'h'}, | 550 | {"help", no_argument, 0, 'h'}, |
| 494 | {"verbose", no_argument, 0, 'v'}, | 551 | {"verbose", no_argument, 0, 'v'}, |
| 495 | {"use-ipv4", no_argument, 0, '4'}, | 552 | {"use-ipv4", no_argument, 0, '4'}, |
| 496 | {"use-ipv6", no_argument, 0, '6'}, | 553 | {"use-ipv6", no_argument, 0, '6'}, |
| 497 | {"quiet", no_argument, 0, 'q'}, | 554 | {"quiet", no_argument, 0, 'q'}, |
| 498 | {"time-offset", optional_argument, 0, 'o'}, | 555 | {"time-offset", required_argument, 0, 'o'}, |
| 499 | {"warning", required_argument, 0, 'w'}, | 556 | {"warning", required_argument, 0, 'w'}, |
| 500 | {"critical", required_argument, 0, 'c'}, | 557 | {"critical", required_argument, 0, 'c'}, |
| 501 | {"timeout", required_argument, 0, 't'}, | 558 | {"timeout", required_argument, 0, 't'}, |
| 502 | {"hostname", required_argument, 0, 'H'}, | 559 | {"hostname", required_argument, 0, 'H'}, |
| 503 | {"port", required_argument, 0, 'p'}, | 560 | {"port", required_argument, 0, 'p'}, |
| 561 | {"output-format", required_argument, 0, output_format_index}, | ||
| 504 | {0, 0, 0, 0}}; | 562 | {0, 0, 0, 0}}; |
| 505 | 563 | ||
| 506 | if (argc < 2) { | 564 | if (argc < 2) { |
| @@ -512,9 +570,6 @@ check_ntp_time_config_wrapper process_arguments(int argc, char **argv) { | |||
| 512 | .config = check_ntp_time_config_init(), | 570 | .config = check_ntp_time_config_init(), |
| 513 | }; | 571 | }; |
| 514 | 572 | ||
| 515 | char *owarn = "60"; | ||
| 516 | char *ocrit = "120"; | ||
| 517 | |||
| 518 | while (true) { | 573 | while (true) { |
| 519 | int option = 0; | 574 | int option = 0; |
| 520 | int option_char = getopt_long(argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option); | 575 | int option_char = getopt_long(argc, argv, "Vhv46qw:c:t:H:p:o:", longopts, &option); |
| @@ -523,6 +578,17 @@ check_ntp_time_config_wrapper process_arguments(int argc, char **argv) { | |||
| 523 | } | 578 | } |
| 524 | 579 | ||
| 525 | switch (option_char) { | 580 | switch (option_char) { |
| 581 | case output_format_index: { | ||
| 582 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 583 | if (!parser.parsing_success) { | ||
| 584 | printf("Invalid output format: %s\n", optarg); | ||
| 585 | exit(STATE_UNKNOWN); | ||
| 586 | } | ||
| 587 | |||
| 588 | result.config.output_format_is_set = true; | ||
| 589 | result.config.output_format = parser.output_format; | ||
| 590 | break; | ||
| 591 | } | ||
| 526 | case 'h': | 592 | case 'h': |
| 527 | print_help(); | 593 | print_help(); |
| 528 | exit(STATE_UNKNOWN); | 594 | exit(STATE_UNKNOWN); |
| @@ -537,14 +603,26 @@ check_ntp_time_config_wrapper process_arguments(int argc, char **argv) { | |||
| 537 | case 'q': | 603 | case 'q': |
| 538 | result.config.quiet = true; | 604 | result.config.quiet = true; |
| 539 | break; | 605 | break; |
| 540 | case 'w': | 606 | case 'w': { |
| 541 | owarn = optarg; | 607 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 542 | break; | 608 | if (tmp.error != MP_PARSING_SUCCES) { |
| 543 | case 'c': | 609 | die(STATE_UNKNOWN, "failed to parse warning threshold"); |
| 544 | ocrit = optarg; | 610 | } |
| 545 | break; | 611 | |
| 612 | result.config.offset_thresholds = | ||
| 613 | mp_thresholds_set_warn(result.config.offset_thresholds, tmp.range); | ||
| 614 | } break; | ||
| 615 | case 'c': { | ||
| 616 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 617 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 618 | die(STATE_UNKNOWN, "failed to parse crit threshold"); | ||
| 619 | } | ||
| 620 | |||
| 621 | result.config.offset_thresholds = | ||
| 622 | mp_thresholds_set_crit(result.config.offset_thresholds, tmp.range); | ||
| 623 | } break; | ||
| 546 | case 'H': | 624 | case 'H': |
| 547 | if (!is_host(optarg)) { | 625 | if (!is_host(optarg) && (optarg[0] != '/')) { |
| 548 | usage2(_("Invalid hostname/address"), optarg); | 626 | usage2(_("Invalid hostname/address"), optarg); |
| 549 | } | 627 | } |
| 550 | result.config.server_address = strdup(optarg); | 628 | result.config.server_address = strdup(optarg); |
| @@ -579,16 +657,9 @@ check_ntp_time_config_wrapper process_arguments(int argc, char **argv) { | |||
| 579 | usage4(_("Hostname was not supplied")); | 657 | usage4(_("Hostname was not supplied")); |
| 580 | } | 658 | } |
| 581 | 659 | ||
| 582 | set_thresholds(&result.config.offset_thresholds, owarn, ocrit); | ||
| 583 | |||
| 584 | return result; | 660 | return result; |
| 585 | } | 661 | } |
| 586 | 662 | ||
| 587 | char *perfd_offset(double offset, thresholds *offset_thresholds) { | ||
| 588 | return fperfdata("offset", offset, "s", true, offset_thresholds->warning->end, true, offset_thresholds->critical->end, false, 0, false, | ||
| 589 | 0); | ||
| 590 | } | ||
| 591 | |||
| 592 | int main(int argc, char *argv[]) { | 663 | int main(int argc, char *argv[]) { |
| 593 | setlocale(LC_ALL, ""); | 664 | setlocale(LC_ALL, ""); |
| 594 | bindtextdomain(PACKAGE, LOCALEDIR); | 665 | bindtextdomain(PACKAGE, LOCALEDIR); |
| @@ -605,51 +676,47 @@ int main(int argc, char *argv[]) { | |||
| 605 | 676 | ||
| 606 | const check_ntp_time_config config = tmp_config.config; | 677 | const check_ntp_time_config config = tmp_config.config; |
| 607 | 678 | ||
| 679 | if (config.output_format_is_set) { | ||
| 680 | mp_set_format(config.output_format); | ||
| 681 | } | ||
| 682 | |||
| 608 | /* initialize alarm signal handling */ | 683 | /* initialize alarm signal handling */ |
| 609 | signal(SIGALRM, socket_timeout_alarm_handler); | 684 | signal(SIGALRM, socket_timeout_alarm_handler); |
| 610 | 685 | ||
| 611 | /* set socket timeout */ | 686 | /* set socket timeout */ |
| 612 | alarm(socket_timeout); | 687 | alarm(socket_timeout); |
| 613 | 688 | ||
| 614 | mp_state_enum offset_result = STATE_OK; | 689 | mp_check overall = mp_check_init(); |
| 615 | mp_state_enum result = STATE_OK; | ||
| 616 | double offset = offset_request(config.server_address, config.port, &offset_result, config.time_offset); | ||
| 617 | if (offset_result == STATE_UNKNOWN) { | ||
| 618 | result = ((!config.quiet) ? STATE_UNKNOWN : STATE_CRITICAL); | ||
| 619 | } else { | ||
| 620 | result = get_status(fabs(offset), config.offset_thresholds); | ||
| 621 | } | ||
| 622 | 690 | ||
| 623 | char *result_line; | 691 | mp_subcheck sc_offset = mp_subcheck_init(); |
| 624 | switch (result) { | 692 | offset_request_wrapper offset_result = |
| 625 | case STATE_CRITICAL: | 693 | offset_request(config.server_address, config.port, config.time_offset); |
| 626 | xasprintf(&result_line, _("NTP CRITICAL:")); | ||
| 627 | break; | ||
| 628 | case STATE_WARNING: | ||
| 629 | xasprintf(&result_line, _("NTP WARNING:")); | ||
| 630 | break; | ||
| 631 | case STATE_OK: | ||
| 632 | xasprintf(&result_line, _("NTP OK:")); | ||
| 633 | break; | ||
| 634 | default: | ||
| 635 | xasprintf(&result_line, _("NTP UNKNOWN:")); | ||
| 636 | break; | ||
| 637 | } | ||
| 638 | 694 | ||
| 639 | char *perfdata_line; | 695 | if (offset_result.offset_result == STATE_UNKNOWN) { |
| 640 | if (offset_result == STATE_UNKNOWN) { | 696 | sc_offset = |
| 641 | xasprintf(&result_line, "%s %s", result_line, _("Offset unknown")); | 697 | mp_set_subcheck_state(sc_offset, (!config.quiet) ? STATE_UNKNOWN : STATE_CRITICAL); |
| 642 | xasprintf(&perfdata_line, ""); | 698 | xasprintf(&sc_offset.output, "Offset unknown"); |
| 643 | } else { | 699 | mp_add_subcheck_to_check(&overall, sc_offset); |
| 644 | xasprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset); | 700 | mp_exit(overall); |
| 645 | xasprintf(&perfdata_line, "%s", perfd_offset(offset, config.offset_thresholds)); | ||
| 646 | } | 701 | } |
| 647 | printf("%s|%s\n", result_line, perfdata_line); | 702 | |
| 703 | xasprintf(&sc_offset.output, "Offset: %.6fs", offset_result.offset); | ||
| 704 | |||
| 705 | mp_perfdata pd_offset = perfdata_init(); | ||
| 706 | pd_offset = mp_set_pd_value(pd_offset, fabs(offset_result.offset)); | ||
| 707 | pd_offset.label = "offset"; | ||
| 708 | pd_offset.uom = "s"; | ||
| 709 | pd_offset = mp_pd_set_thresholds(pd_offset, config.offset_thresholds); | ||
| 710 | |||
| 711 | sc_offset = mp_set_subcheck_state(sc_offset, mp_get_pd_status(pd_offset)); | ||
| 712 | |||
| 713 | mp_add_perfdata_to_subcheck(&sc_offset, pd_offset); | ||
| 714 | mp_add_subcheck_to_check(&overall, sc_offset); | ||
| 648 | 715 | ||
| 649 | if (config.server_address != NULL) { | 716 | if (config.server_address != NULL) { |
| 650 | free(config.server_address); | 717 | free(config.server_address); |
| 651 | } | 718 | } |
| 652 | exit(result); | 719 | mp_exit(overall); |
| 653 | } | 720 | } |
| 654 | 721 | ||
| 655 | void print_help(void) { | 722 | void print_help(void) { |
| @@ -673,10 +740,11 @@ void print_help(void) { | |||
| 673 | printf(" %s\n", _("Offset to result in warning status (seconds)")); | 740 | printf(" %s\n", _("Offset to result in warning status (seconds)")); |
| 674 | printf(" %s\n", "-c, --critical=THRESHOLD"); | 741 | printf(" %s\n", "-c, --critical=THRESHOLD"); |
| 675 | printf(" %s\n", _("Offset to result in critical status (seconds)")); | 742 | printf(" %s\n", _("Offset to result in critical status (seconds)")); |
| 676 | printf(" %s\n", "-o, --time_offset=INTEGER"); | 743 | printf(" %s\n", "-o, --time-offset=INTEGER"); |
| 677 | printf(" %s\n", _("Expected offset of the ntp server relative to local server (seconds)")); | 744 | printf(" %s\n", _("Expected offset of the ntp server relative to local server (seconds)")); |
| 678 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 745 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 679 | printf(UT_VERBOSE); | 746 | printf(UT_VERBOSE); |
| 747 | printf(UT_OUTPUT_FORMAT); | ||
| 680 | 748 | ||
| 681 | printf("\n"); | 749 | printf("\n"); |
| 682 | printf("%s\n", _("This plugin checks the clock offset between the local host and a")); | 750 | printf("%s\n", _("This plugin checks the clock offset between the local host and a")); |
| @@ -701,5 +769,6 @@ void print_help(void) { | |||
| 701 | 769 | ||
| 702 | void print_usage(void) { | 770 | void print_usage(void) { |
| 703 | printf("%s\n", _("Usage:")); | 771 | printf("%s\n", _("Usage:")); |
| 704 | printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [-v verbose] [-o <time offset>]\n", progname); | 772 | printf(" %s -H <host> [-4|-6] [-w <warn>] [-c <crit>] [-v verbose] [-o <time offset>]\n", |
| 773 | progname); | ||
| 705 | } | 774 | } |
diff --git a/plugins/check_ntp_time.d/config.h b/plugins/check_ntp_time.d/config.h index 99dabbbd..9bbd82aa 100644 --- a/plugins/check_ntp_time.d/config.h +++ b/plugins/check_ntp_time.d/config.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "output.h" | ||
| 4 | #include "thresholds.h" | 5 | #include "thresholds.h" |
| 5 | #include <stddef.h> | 6 | #include <stddef.h> |
| 6 | 7 | ||
| @@ -11,7 +12,10 @@ typedef struct { | |||
| 11 | bool quiet; | 12 | bool quiet; |
| 12 | int time_offset; | 13 | int time_offset; |
| 13 | 14 | ||
| 14 | thresholds *offset_thresholds; | 15 | mp_thresholds offset_thresholds; |
| 16 | |||
| 17 | bool output_format_is_set; | ||
| 18 | mp_output_format output_format; | ||
| 15 | } check_ntp_time_config; | 19 | } check_ntp_time_config; |
| 16 | 20 | ||
| 17 | check_ntp_time_config check_ntp_time_config_init() { | 21 | check_ntp_time_config check_ntp_time_config_init() { |
| @@ -22,7 +26,18 @@ check_ntp_time_config check_ntp_time_config_init() { | |||
| 22 | .quiet = false, | 26 | .quiet = false, |
| 23 | .time_offset = 0, | 27 | .time_offset = 0, |
| 24 | 28 | ||
| 25 | .offset_thresholds = NULL, | 29 | .offset_thresholds = mp_thresholds_init(), |
| 30 | |||
| 31 | .output_format_is_set = false, | ||
| 26 | }; | 32 | }; |
| 33 | |||
| 34 | mp_range warning = mp_range_init(); | ||
| 35 | warning = mp_range_set_end(warning, mp_create_pd_value(60)); | ||
| 36 | tmp.offset_thresholds = mp_thresholds_set_warn(tmp.offset_thresholds, warning); | ||
| 37 | |||
| 38 | mp_range critical = mp_range_init(); | ||
| 39 | critical = mp_range_set_end(warning, mp_create_pd_value(120)); | ||
| 40 | tmp.offset_thresholds = mp_thresholds_set_crit(tmp.offset_thresholds, critical); | ||
| 41 | |||
| 27 | return tmp; | 42 | return tmp; |
| 28 | } | 43 | } |
diff --git a/plugins/check_nwstat.c b/plugins/check_nwstat.c deleted file mode 100644 index 176dfbc8..00000000 --- a/plugins/check_nwstat.c +++ /dev/null | |||
| @@ -1,1527 +0,0 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Monitoring check_nwstat plugin | ||
| 4 | * | ||
| 5 | * License: GPL | ||
| 6 | * Copyright (c) 2000-2024 Monitoring Plugins Development Team | ||
| 7 | * | ||
| 8 | * Description: | ||
| 9 | * | ||
| 10 | * This file contains the check_nwstat plugin | ||
| 11 | * | ||
| 12 | * This plugin attempts to contact the MRTGEXT NLM running on a | ||
| 13 | * Novell server to gather the requested system information. | ||
| 14 | * | ||
| 15 | * | ||
| 16 | * This program is free software: you can redistribute it and/or modify | ||
| 17 | * it under the terms of the GNU General Public License as published by | ||
| 18 | * the Free Software Foundation, either version 3 of the License, or | ||
| 19 | * (at your option) any later version. | ||
| 20 | * | ||
| 21 | * This program is distributed in the hope that it will be useful, | ||
| 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 24 | * GNU General Public License for more details. | ||
| 25 | * | ||
| 26 | * You should have received a copy of the GNU General Public License | ||
| 27 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 28 | * | ||
| 29 | * | ||
| 30 | *****************************************************************************/ | ||
| 31 | |||
| 32 | const char *progname = "check_nwstat"; | ||
| 33 | const char *copyright = "2000-2024"; | ||
| 34 | const char *email = "devel@monitoring-plugins.org"; | ||
| 35 | |||
| 36 | #include "common.h" | ||
| 37 | #include "netutils.h" | ||
| 38 | #include "utils.h" | ||
| 39 | |||
| 40 | enum checkvar { | ||
| 41 | NONE, | ||
| 42 | LOAD1, /* check 1 minute CPU load */ | ||
| 43 | LOAD5, /* check 5 minute CPU load */ | ||
| 44 | LOAD15, /* check 15 minute CPU load */ | ||
| 45 | CONNS, /* check number of connections */ | ||
| 46 | VPF, /* check % free space on volume */ | ||
| 47 | VMF, /* check MB free space on volume */ | ||
| 48 | VMU, /* check MB used space on volume */ | ||
| 49 | VPU, /* check % used space on volume */ | ||
| 50 | VMP, /* check MB purgeable space on volume */ | ||
| 51 | VKF, /* check KB free space on volume */ | ||
| 52 | LTCH, /* check long-term cache hit percentage */ | ||
| 53 | CBUFF, /* check total cache buffers */ | ||
| 54 | CDBUFF, /* check dirty cache buffers */ | ||
| 55 | LRUM, /* check LRU sitting time in minutes */ | ||
| 56 | DSDB, /* check to see if DS Database is open */ | ||
| 57 | LOGINS, /* check to see if logins are enabled */ | ||
| 58 | NRMH, /* check to see NRM Health Status */ | ||
| 59 | PUPRB, /* check % of used packet receive buffers */ | ||
| 60 | UPRB, /* check used packet receive buffers */ | ||
| 61 | SAPENTRIES, /* check SAP entries */ | ||
| 62 | OFILES, /* check number of open files */ | ||
| 63 | VKP, /* check KB purgeable space on volume */ | ||
| 64 | VPP, /* check % purgeable space on volume */ | ||
| 65 | VKNP, /* check KB not yet purgeable space on volume */ | ||
| 66 | VPNP, /* check % not yet purgeable space on volume */ | ||
| 67 | ABENDS, /* check abended thread count */ | ||
| 68 | CSPROCS, /* check number of current service processes */ | ||
| 69 | TSYNC, /* check timesync status 0=no 1=yes in sync to the network */ | ||
| 70 | LRUS, /* check LRU sitting time in seconds */ | ||
| 71 | DCB, /* check dirty cache buffers as a percentage of the total */ | ||
| 72 | TCB, /* check total cache buffers as a percentage of the original */ | ||
| 73 | DSVER, /* check NDS version */ | ||
| 74 | UPTIME, /* check server uptime */ | ||
| 75 | NLM, /* check NLM loaded */ | ||
| 76 | NRMP, /* check NRM Process Values */ | ||
| 77 | NRMM, /* check NRM Memory Values */ | ||
| 78 | NRMS, /* check NRM Values */ | ||
| 79 | NSS1, /* check Statistics from _Admin:Manage_NSS\GeneralStats.xml */ | ||
| 80 | NSS2, /* check Statistics from _Admin:Manage_NSS\BufferCache.xml */ | ||
| 81 | NSS3, /* check statistics from _Admin:Manage_NSS\NameCache.xml */ | ||
| 82 | NSS4, /* check statistics from _Admin:Manage_NSS\FileStats.xml */ | ||
| 83 | NSS5, /* check statistics from _Admin:Manage_NSS\ObjectCache.xml */ | ||
| 84 | NSS6, /* check statistics from _Admin:Manage_NSS\Thread.xml */ | ||
| 85 | NSS7 /* check statistics from _Admin:Manage_NSS\AuthorizationCache.xml */ | ||
| 86 | }; | ||
| 87 | |||
| 88 | enum { | ||
| 89 | PORT = 9999 | ||
| 90 | }; | ||
| 91 | |||
| 92 | static char *server_address = NULL; | ||
| 93 | static char *volume_name = NULL; | ||
| 94 | static char *nlm_name = NULL; | ||
| 95 | static char *nrmp_name = NULL; | ||
| 96 | static char *nrmm_name = NULL; | ||
| 97 | static char *nrms_name = NULL; | ||
| 98 | static char *nss1_name = NULL; | ||
| 99 | static char *nss2_name = NULL; | ||
| 100 | static char *nss3_name = NULL; | ||
| 101 | static char *nss4_name = NULL; | ||
| 102 | static char *nss5_name = NULL; | ||
| 103 | static char *nss6_name = NULL; | ||
| 104 | static char *nss7_name = NULL; | ||
| 105 | static int server_port = PORT; | ||
| 106 | static unsigned long warning_value = 0L; | ||
| 107 | static unsigned long critical_value = 0L; | ||
| 108 | static bool check_warning_value = false; | ||
| 109 | static bool check_critical_value = false; | ||
| 110 | static bool check_netware_version = false; | ||
| 111 | static enum checkvar vars_to_check = NONE; | ||
| 112 | static int sap_number = -1; | ||
| 113 | |||
| 114 | static int process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 115 | static void print_help(void); | ||
| 116 | void print_usage(void); | ||
| 117 | |||
| 118 | int main(int argc, char **argv) { | ||
| 119 | int result = STATE_UNKNOWN; | ||
| 120 | int sd; | ||
| 121 | char *send_buffer = NULL; | ||
| 122 | char recv_buffer[MAX_INPUT_BUFFER]; | ||
| 123 | char *output_message = NULL; | ||
| 124 | char *temp_buffer = NULL; | ||
| 125 | char *netware_version = NULL; | ||
| 126 | |||
| 127 | int time_sync_status = 0; | ||
| 128 | int nrm_health_status = 0; | ||
| 129 | unsigned long total_cache_buffers = 0; | ||
| 130 | unsigned long dirty_cache_buffers = 0; | ||
| 131 | unsigned long open_files = 0; | ||
| 132 | unsigned long abended_threads = 0; | ||
| 133 | unsigned long max_service_processes = 0; | ||
| 134 | unsigned long current_service_processes = 0; | ||
| 135 | unsigned long free_disk_space = 0L; | ||
| 136 | unsigned long nrmp_value = 0L; | ||
| 137 | unsigned long nrmm_value = 0L; | ||
| 138 | unsigned long nrms_value = 0L; | ||
| 139 | unsigned long nss1_value = 0L; | ||
| 140 | unsigned long nss2_value = 0L; | ||
| 141 | unsigned long nss3_value = 0L; | ||
| 142 | unsigned long nss4_value = 0L; | ||
| 143 | unsigned long nss5_value = 0L; | ||
| 144 | unsigned long nss6_value = 0L; | ||
| 145 | unsigned long nss7_value = 0L; | ||
| 146 | unsigned long total_disk_space = 0L; | ||
| 147 | unsigned long used_disk_space = 0L; | ||
| 148 | unsigned long percent_used_disk_space = 0L; | ||
| 149 | unsigned long purgeable_disk_space = 0L; | ||
| 150 | unsigned long non_purgeable_disk_space = 0L; | ||
| 151 | unsigned long percent_free_space = 0; | ||
| 152 | unsigned long percent_purgeable_space = 0; | ||
| 153 | unsigned long percent_non_purgeable_space = 0; | ||
| 154 | unsigned long current_connections = 0L; | ||
| 155 | unsigned long utilization = 0L; | ||
| 156 | unsigned long cache_hits = 0; | ||
| 157 | unsigned long cache_buffers = 0L; | ||
| 158 | unsigned long lru_time = 0L; | ||
| 159 | unsigned long max_packet_receive_buffers = 0; | ||
| 160 | unsigned long used_packet_receive_buffers = 0; | ||
| 161 | unsigned long percent_used_packet_receive_buffers = 0L; | ||
| 162 | unsigned long sap_entries = 0; | ||
| 163 | char uptime[MAX_INPUT_BUFFER]; | ||
| 164 | |||
| 165 | setlocale(LC_ALL, ""); | ||
| 166 | bindtextdomain(PACKAGE, LOCALEDIR); | ||
| 167 | textdomain(PACKAGE); | ||
| 168 | |||
| 169 | /* Parse extra opts if any */ | ||
| 170 | argv = np_extra_opts(&argc, argv, progname); | ||
| 171 | |||
| 172 | if (process_arguments(argc, argv) == ERROR) | ||
| 173 | usage4(_("Could not parse arguments")); | ||
| 174 | |||
| 175 | /* initialize alarm signal handling */ | ||
| 176 | signal(SIGALRM, socket_timeout_alarm_handler); | ||
| 177 | |||
| 178 | /* set socket timeout */ | ||
| 179 | alarm(socket_timeout); | ||
| 180 | |||
| 181 | /* open connection */ | ||
| 182 | my_tcp_connect(server_address, server_port, &sd); | ||
| 183 | |||
| 184 | /* get OS version string */ | ||
| 185 | if (check_netware_version) { | ||
| 186 | send_buffer = strdup("S19\r\n"); | ||
| 187 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 188 | if (result != STATE_OK) | ||
| 189 | return result; | ||
| 190 | if (!strcmp(recv_buffer, "-1\n")) | ||
| 191 | netware_version = strdup(""); | ||
| 192 | else { | ||
| 193 | recv_buffer[strlen(recv_buffer) - 1] = 0; | ||
| 194 | xasprintf(&netware_version, _("NetWare %s: "), recv_buffer); | ||
| 195 | } | ||
| 196 | } else | ||
| 197 | netware_version = strdup(""); | ||
| 198 | |||
| 199 | /* check CPU load */ | ||
| 200 | if (vars_to_check == LOAD1 || vars_to_check == LOAD5 || vars_to_check == LOAD15) { | ||
| 201 | |||
| 202 | switch (vars_to_check) { | ||
| 203 | case LOAD1: | ||
| 204 | temp_buffer = strdup("1"); | ||
| 205 | break; | ||
| 206 | case LOAD5: | ||
| 207 | temp_buffer = strdup("5"); | ||
| 208 | break; | ||
| 209 | default: | ||
| 210 | temp_buffer = strdup("15"); | ||
| 211 | break; | ||
| 212 | } | ||
| 213 | |||
| 214 | close(sd); | ||
| 215 | my_tcp_connect(server_address, server_port, &sd); | ||
| 216 | |||
| 217 | xasprintf(&send_buffer, "UTIL%s\r\n", temp_buffer); | ||
| 218 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 219 | if (result != STATE_OK) | ||
| 220 | return result; | ||
| 221 | utilization = strtoul(recv_buffer, NULL, 10); | ||
| 222 | |||
| 223 | close(sd); | ||
| 224 | my_tcp_connect(server_address, server_port, &sd); | ||
| 225 | |||
| 226 | send_buffer = strdup("UPTIME\r\n"); | ||
| 227 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 228 | if (result != STATE_OK) | ||
| 229 | return result; | ||
| 230 | recv_buffer[strlen(recv_buffer) - 1] = 0; | ||
| 231 | sprintf(uptime, _("Up %s,"), recv_buffer); | ||
| 232 | |||
| 233 | if (check_critical_value && utilization >= critical_value) | ||
| 234 | result = STATE_CRITICAL; | ||
| 235 | else if (check_warning_value && utilization >= warning_value) | ||
| 236 | result = STATE_WARNING; | ||
| 237 | |||
| 238 | xasprintf(&output_message, _("Load %s - %s %s-min load average = %lu%%|load%s=%lu;%lu;%lu;0;100"), state_text(result), uptime, | ||
| 239 | temp_buffer, utilization, temp_buffer, utilization, warning_value, critical_value); | ||
| 240 | |||
| 241 | /* check number of user connections */ | ||
| 242 | } else if (vars_to_check == CONNS) { | ||
| 243 | |||
| 244 | close(sd); | ||
| 245 | my_tcp_connect(server_address, server_port, &sd); | ||
| 246 | |||
| 247 | send_buffer = strdup("CONNECT\r\n"); | ||
| 248 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 249 | if (result != STATE_OK) | ||
| 250 | return result; | ||
| 251 | current_connections = strtoul(recv_buffer, NULL, 10); | ||
| 252 | |||
| 253 | if (check_critical_value && current_connections >= critical_value) | ||
| 254 | result = STATE_CRITICAL; | ||
| 255 | else if (check_warning_value && current_connections >= warning_value) | ||
| 256 | result = STATE_WARNING; | ||
| 257 | |||
| 258 | xasprintf(&output_message, _("Conns %s - %lu current connections|Conns=%lu;%lu;%lu;;"), state_text(result), current_connections, | ||
| 259 | current_connections, warning_value, critical_value); | ||
| 260 | |||
| 261 | /* check % long term cache hits */ | ||
| 262 | } else if (vars_to_check == LTCH) { | ||
| 263 | |||
| 264 | close(sd); | ||
| 265 | my_tcp_connect(server_address, server_port, &sd); | ||
| 266 | |||
| 267 | send_buffer = strdup("S1\r\n"); | ||
| 268 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 269 | if (result != STATE_OK) | ||
| 270 | return result; | ||
| 271 | cache_hits = atoi(recv_buffer); | ||
| 272 | |||
| 273 | if (check_critical_value && cache_hits <= critical_value) | ||
| 274 | result = STATE_CRITICAL; | ||
| 275 | else if (check_warning_value && cache_hits <= warning_value) | ||
| 276 | result = STATE_WARNING; | ||
| 277 | |||
| 278 | xasprintf(&output_message, _("%s: Long term cache hits = %lu%%"), state_text(result), cache_hits); | ||
| 279 | |||
| 280 | /* check cache buffers */ | ||
| 281 | } else if (vars_to_check == CBUFF) { | ||
| 282 | |||
| 283 | close(sd); | ||
| 284 | my_tcp_connect(server_address, server_port, &sd); | ||
| 285 | |||
| 286 | send_buffer = strdup("S2\r\n"); | ||
| 287 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 288 | if (result != STATE_OK) | ||
| 289 | return result; | ||
| 290 | cache_buffers = strtoul(recv_buffer, NULL, 10); | ||
| 291 | |||
| 292 | if (check_critical_value && cache_buffers <= critical_value) | ||
| 293 | result = STATE_CRITICAL; | ||
| 294 | else if (check_warning_value && cache_buffers <= warning_value) | ||
| 295 | result = STATE_WARNING; | ||
| 296 | |||
| 297 | xasprintf(&output_message, _("%s: Total cache buffers = %lu|Cachebuffers=%lu;%lu;%lu;;"), state_text(result), cache_buffers, | ||
| 298 | cache_buffers, warning_value, critical_value); | ||
| 299 | |||
| 300 | /* check dirty cache buffers */ | ||
| 301 | } else if (vars_to_check == CDBUFF) { | ||
| 302 | |||
| 303 | close(sd); | ||
| 304 | my_tcp_connect(server_address, server_port, &sd); | ||
| 305 | |||
| 306 | send_buffer = strdup("S3\r\n"); | ||
| 307 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 308 | if (result != STATE_OK) | ||
| 309 | return result; | ||
| 310 | cache_buffers = strtoul(recv_buffer, NULL, 10); | ||
| 311 | |||
| 312 | if (check_critical_value && cache_buffers >= critical_value) | ||
| 313 | result = STATE_CRITICAL; | ||
| 314 | else if (check_warning_value && cache_buffers >= warning_value) | ||
| 315 | result = STATE_WARNING; | ||
| 316 | |||
| 317 | xasprintf(&output_message, _("%s: Dirty cache buffers = %lu|Dirty-Cache-Buffers=%lu;%lu;%lu;;"), state_text(result), cache_buffers, | ||
| 318 | cache_buffers, warning_value, critical_value); | ||
| 319 | |||
| 320 | /* check LRU sitting time in minutes */ | ||
| 321 | } else if (vars_to_check == LRUM) { | ||
| 322 | |||
| 323 | close(sd); | ||
| 324 | my_tcp_connect(server_address, server_port, &sd); | ||
| 325 | |||
| 326 | send_buffer = strdup("S5\r\n"); | ||
| 327 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 328 | if (result != STATE_OK) | ||
| 329 | return result; | ||
| 330 | lru_time = strtoul(recv_buffer, NULL, 10); | ||
| 331 | |||
| 332 | if (check_critical_value && lru_time <= critical_value) | ||
| 333 | result = STATE_CRITICAL; | ||
| 334 | else if (check_warning_value && lru_time <= warning_value) | ||
| 335 | result = STATE_WARNING; | ||
| 336 | |||
| 337 | xasprintf(&output_message, _("%s: LRU sitting time = %lu minutes"), state_text(result), lru_time); | ||
| 338 | |||
| 339 | /* check KB free space on volume */ | ||
| 340 | } else if (vars_to_check == VKF) { | ||
| 341 | |||
| 342 | close(sd); | ||
| 343 | my_tcp_connect(server_address, server_port, &sd); | ||
| 344 | |||
| 345 | xasprintf(&send_buffer, "VKF%s\r\n", volume_name); | ||
| 346 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 347 | if (result != STATE_OK) | ||
| 348 | return result; | ||
| 349 | |||
| 350 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 351 | xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 352 | result = STATE_CRITICAL; | ||
| 353 | } else { | ||
| 354 | free_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 355 | if (check_critical_value && free_disk_space <= critical_value) | ||
| 356 | result = STATE_CRITICAL; | ||
| 357 | else if (check_warning_value && free_disk_space <= warning_value) | ||
| 358 | result = STATE_WARNING; | ||
| 359 | xasprintf(&output_message, _("%s%lu KB free on volume %s|KBFree%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), | ||
| 360 | free_disk_space, volume_name, volume_name, free_disk_space, warning_value, critical_value); | ||
| 361 | } | ||
| 362 | |||
| 363 | /* check MB free space on volume */ | ||
| 364 | } else if (vars_to_check == VMF) { | ||
| 365 | |||
| 366 | xasprintf(&send_buffer, "VMF%s\r\n", volume_name); | ||
| 367 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 368 | if (result != STATE_OK) | ||
| 369 | return result; | ||
| 370 | |||
| 371 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 372 | xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 373 | result = STATE_CRITICAL; | ||
| 374 | } else { | ||
| 375 | free_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 376 | if (check_critical_value && free_disk_space <= critical_value) | ||
| 377 | result = STATE_CRITICAL; | ||
| 378 | else if (check_warning_value && free_disk_space <= warning_value) | ||
| 379 | result = STATE_WARNING; | ||
| 380 | xasprintf(&output_message, _("%s%lu MB free on volume %s|MBFree%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), | ||
| 381 | free_disk_space, volume_name, volume_name, free_disk_space, warning_value, critical_value); | ||
| 382 | } | ||
| 383 | /* check MB used space on volume */ | ||
| 384 | } else if (vars_to_check == VMU) { | ||
| 385 | |||
| 386 | xasprintf(&send_buffer, "VMU%s\r\n", volume_name); | ||
| 387 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 388 | if (result != STATE_OK) | ||
| 389 | return result; | ||
| 390 | |||
| 391 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 392 | xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 393 | result = STATE_CRITICAL; | ||
| 394 | } else { | ||
| 395 | free_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 396 | if (check_critical_value && free_disk_space <= critical_value) | ||
| 397 | result = STATE_CRITICAL; | ||
| 398 | else if (check_warning_value && free_disk_space <= warning_value) | ||
| 399 | result = STATE_WARNING; | ||
| 400 | xasprintf(&output_message, _("%s%lu MB used on volume %s|MBUsed%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), | ||
| 401 | free_disk_space, volume_name, volume_name, free_disk_space, warning_value, critical_value); | ||
| 402 | } | ||
| 403 | /* check % used space on volume */ | ||
| 404 | } else if (vars_to_check == VPU) { | ||
| 405 | close(sd); | ||
| 406 | my_tcp_connect(server_address, server_port, &sd); | ||
| 407 | |||
| 408 | asprintf(&send_buffer, "VMU%s\r\n", volume_name); | ||
| 409 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 410 | |||
| 411 | if (result != STATE_OK) | ||
| 412 | return result; | ||
| 413 | |||
| 414 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 415 | asprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 416 | result = STATE_CRITICAL; | ||
| 417 | |||
| 418 | } else { | ||
| 419 | used_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 420 | close(sd); | ||
| 421 | my_tcp_connect(server_address, server_port, &sd); | ||
| 422 | /* get total volume in MB */ | ||
| 423 | asprintf(&send_buffer, "VMS%s\r\n", volume_name); | ||
| 424 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 425 | if (result != STATE_OK) | ||
| 426 | return result; | ||
| 427 | total_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 428 | /* calculate percent used on volume */ | ||
| 429 | percent_used_disk_space = (unsigned long)(((double)used_disk_space / (double)total_disk_space) * 100.0); | ||
| 430 | |||
| 431 | if (check_critical_value && percent_used_disk_space >= critical_value) | ||
| 432 | result = STATE_CRITICAL; | ||
| 433 | else if (check_warning_value && percent_used_disk_space >= warning_value) | ||
| 434 | result = STATE_WARNING; | ||
| 435 | |||
| 436 | asprintf(&output_message, _("%lu MB (%lu%%) used on volume %s - total %lu MB|Used space in percent on %s=%lu;%lu;%lu;0;100"), | ||
| 437 | used_disk_space, percent_used_disk_space, volume_name, total_disk_space, volume_name, percent_used_disk_space, | ||
| 438 | warning_value, critical_value); | ||
| 439 | } | ||
| 440 | |||
| 441 | /* check % free space on volume */ | ||
| 442 | } else if (vars_to_check == VPF) { | ||
| 443 | |||
| 444 | close(sd); | ||
| 445 | my_tcp_connect(server_address, server_port, &sd); | ||
| 446 | |||
| 447 | xasprintf(&send_buffer, "VKF%s\r\n", volume_name); | ||
| 448 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 449 | if (result != STATE_OK) | ||
| 450 | return result; | ||
| 451 | |||
| 452 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 453 | |||
| 454 | xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 455 | result = STATE_CRITICAL; | ||
| 456 | |||
| 457 | } else { | ||
| 458 | |||
| 459 | free_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 460 | |||
| 461 | close(sd); | ||
| 462 | my_tcp_connect(server_address, server_port, &sd); | ||
| 463 | |||
| 464 | xasprintf(&send_buffer, "VKS%s\r\n", volume_name); | ||
| 465 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 466 | if (result != STATE_OK) | ||
| 467 | return result; | ||
| 468 | total_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 469 | |||
| 470 | percent_free_space = (unsigned long)(((double)free_disk_space / (double)total_disk_space) * 100.0); | ||
| 471 | |||
| 472 | if (check_critical_value && percent_free_space <= critical_value) | ||
| 473 | result = STATE_CRITICAL; | ||
| 474 | else if (check_warning_value && percent_free_space <= warning_value) | ||
| 475 | result = STATE_WARNING; | ||
| 476 | free_disk_space /= 1024; | ||
| 477 | total_disk_space /= 1024; | ||
| 478 | xasprintf(&output_message, _("%lu MB (%lu%%) free on volume %s - total %lu MB|FreeMB%s=%lu;%lu;%lu;0;100"), free_disk_space, | ||
| 479 | percent_free_space, volume_name, total_disk_space, volume_name, percent_free_space, warning_value, critical_value); | ||
| 480 | } | ||
| 481 | |||
| 482 | /* check to see if DS Database is open or closed */ | ||
| 483 | } else if (vars_to_check == DSDB) { | ||
| 484 | |||
| 485 | close(sd); | ||
| 486 | my_tcp_connect(server_address, server_port, &sd); | ||
| 487 | |||
| 488 | send_buffer = strdup("S11\r\n"); | ||
| 489 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 490 | if (result != STATE_OK) | ||
| 491 | return result; | ||
| 492 | if (atoi(recv_buffer) == 1) | ||
| 493 | result = STATE_OK; | ||
| 494 | else | ||
| 495 | result = STATE_WARNING; | ||
| 496 | |||
| 497 | close(sd); | ||
| 498 | my_tcp_connect(server_address, server_port, &sd); | ||
| 499 | |||
| 500 | send_buffer = strdup("S13\r\n"); | ||
| 501 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 502 | temp_buffer = strtok(recv_buffer, "\r\n"); | ||
| 503 | |||
| 504 | xasprintf(&output_message, _("Directory Services Database is %s (DS version %s)"), (result == STATE_OK) ? "open" : "closed", | ||
| 505 | temp_buffer); | ||
| 506 | |||
| 507 | /* check to see if logins are enabled */ | ||
| 508 | } else if (vars_to_check == LOGINS) { | ||
| 509 | |||
| 510 | close(sd); | ||
| 511 | my_tcp_connect(server_address, server_port, &sd); | ||
| 512 | |||
| 513 | send_buffer = strdup("S12\r\n"); | ||
| 514 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 515 | if (result != STATE_OK) | ||
| 516 | return result; | ||
| 517 | if (atoi(recv_buffer) == 1) | ||
| 518 | result = STATE_OK; | ||
| 519 | else | ||
| 520 | result = STATE_WARNING; | ||
| 521 | |||
| 522 | xasprintf(&output_message, _("Logins are %s"), (result == STATE_OK) ? _("enabled") : _("disabled")); | ||
| 523 | |||
| 524 | /* check NRM Health Status Summary*/ | ||
| 525 | } else if (vars_to_check == NRMH) { | ||
| 526 | |||
| 527 | xasprintf(&send_buffer, "NRMH\r\n"); | ||
| 528 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 529 | if (result != STATE_OK) | ||
| 530 | return result; | ||
| 531 | |||
| 532 | nrm_health_status = atoi(recv_buffer); | ||
| 533 | |||
| 534 | if (nrm_health_status == 2) { | ||
| 535 | result = STATE_OK; | ||
| 536 | xasprintf(&output_message, _("CRITICAL - NRM Status is bad!")); | ||
| 537 | } else { | ||
| 538 | if (nrm_health_status == 1) { | ||
| 539 | result = STATE_WARNING; | ||
| 540 | xasprintf(&output_message, _("Warning - NRM Status is suspect!")); | ||
| 541 | } | ||
| 542 | |||
| 543 | xasprintf(&output_message, _("OK - NRM Status is good!")); | ||
| 544 | } | ||
| 545 | |||
| 546 | /* check packet receive buffers */ | ||
| 547 | } else if (vars_to_check == UPRB || vars_to_check == PUPRB) { | ||
| 548 | |||
| 549 | close(sd); | ||
| 550 | my_tcp_connect(server_address, server_port, &sd); | ||
| 551 | |||
| 552 | xasprintf(&send_buffer, "S15\r\n"); | ||
| 553 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 554 | if (result != STATE_OK) | ||
| 555 | return result; | ||
| 556 | |||
| 557 | used_packet_receive_buffers = atoi(recv_buffer); | ||
| 558 | |||
| 559 | close(sd); | ||
| 560 | my_tcp_connect(server_address, server_port, &sd); | ||
| 561 | |||
| 562 | xasprintf(&send_buffer, "S16\r\n"); | ||
| 563 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 564 | if (result != STATE_OK) | ||
| 565 | return result; | ||
| 566 | |||
| 567 | max_packet_receive_buffers = atoi(recv_buffer); | ||
| 568 | |||
| 569 | percent_used_packet_receive_buffers = | ||
| 570 | (unsigned long)(((double)used_packet_receive_buffers / (double)max_packet_receive_buffers) * 100.0); | ||
| 571 | |||
| 572 | if (vars_to_check == UPRB) { | ||
| 573 | if (check_critical_value && used_packet_receive_buffers >= critical_value) | ||
| 574 | result = STATE_CRITICAL; | ||
| 575 | else if (check_warning_value && used_packet_receive_buffers >= warning_value) | ||
| 576 | result = STATE_WARNING; | ||
| 577 | } else { | ||
| 578 | if (check_critical_value && percent_used_packet_receive_buffers >= critical_value) | ||
| 579 | result = STATE_CRITICAL; | ||
| 580 | else if (check_warning_value && percent_used_packet_receive_buffers >= warning_value) | ||
| 581 | result = STATE_WARNING; | ||
| 582 | } | ||
| 583 | |||
| 584 | xasprintf(&output_message, _("%lu of %lu (%lu%%) packet receive buffers used"), used_packet_receive_buffers, | ||
| 585 | max_packet_receive_buffers, percent_used_packet_receive_buffers); | ||
| 586 | |||
| 587 | /* check SAP table entries */ | ||
| 588 | } else if (vars_to_check == SAPENTRIES) { | ||
| 589 | |||
| 590 | close(sd); | ||
| 591 | my_tcp_connect(server_address, server_port, &sd); | ||
| 592 | |||
| 593 | if (sap_number == -1) | ||
| 594 | xasprintf(&send_buffer, "S9\r\n"); | ||
| 595 | else | ||
| 596 | xasprintf(&send_buffer, "S9.%d\r\n", sap_number); | ||
| 597 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 598 | if (result != STATE_OK) | ||
| 599 | return result; | ||
| 600 | |||
| 601 | sap_entries = atoi(recv_buffer); | ||
| 602 | |||
| 603 | if (check_critical_value && sap_entries >= critical_value) | ||
| 604 | result = STATE_CRITICAL; | ||
| 605 | else if (check_warning_value && sap_entries >= warning_value) | ||
| 606 | result = STATE_WARNING; | ||
| 607 | |||
| 608 | if (sap_number == -1) | ||
| 609 | xasprintf(&output_message, _("%lu entries in SAP table"), sap_entries); | ||
| 610 | else | ||
| 611 | xasprintf(&output_message, _("%lu entries in SAP table for SAP type %d"), sap_entries, sap_number); | ||
| 612 | |||
| 613 | /* check KB purgeable space on volume */ | ||
| 614 | } else if (vars_to_check == VKP) { | ||
| 615 | |||
| 616 | close(sd); | ||
| 617 | my_tcp_connect(server_address, server_port, &sd); | ||
| 618 | |||
| 619 | xasprintf(&send_buffer, "VKP%s\r\n", volume_name); | ||
| 620 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 621 | if (result != STATE_OK) | ||
| 622 | return result; | ||
| 623 | |||
| 624 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 625 | xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 626 | result = STATE_CRITICAL; | ||
| 627 | } else { | ||
| 628 | purgeable_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 629 | if (check_critical_value && purgeable_disk_space >= critical_value) | ||
| 630 | result = STATE_CRITICAL; | ||
| 631 | else if (check_warning_value && purgeable_disk_space >= warning_value) | ||
| 632 | result = STATE_WARNING; | ||
| 633 | xasprintf(&output_message, _("%s%lu KB purgeable on volume %s|Purge%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), | ||
| 634 | purgeable_disk_space, volume_name, volume_name, purgeable_disk_space, warning_value, critical_value); | ||
| 635 | } | ||
| 636 | /* check MB purgeable space on volume */ | ||
| 637 | } else if (vars_to_check == VMP) { | ||
| 638 | |||
| 639 | xasprintf(&send_buffer, "VMP%s\r\n", volume_name); | ||
| 640 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 641 | if (result != STATE_OK) | ||
| 642 | return result; | ||
| 643 | |||
| 644 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 645 | xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 646 | result = STATE_CRITICAL; | ||
| 647 | } else { | ||
| 648 | purgeable_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 649 | if (check_critical_value && purgeable_disk_space >= critical_value) | ||
| 650 | result = STATE_CRITICAL; | ||
| 651 | else if (check_warning_value && purgeable_disk_space >= warning_value) | ||
| 652 | result = STATE_WARNING; | ||
| 653 | xasprintf(&output_message, _("%s%lu MB purgeable on volume %s|Purge%s=%lu;%lu;%lu;;"), (result == STATE_OK) ? "" : _("Only "), | ||
| 654 | purgeable_disk_space, volume_name, volume_name, purgeable_disk_space, warning_value, critical_value); | ||
| 655 | } | ||
| 656 | |||
| 657 | /* check % purgeable space on volume */ | ||
| 658 | } else if (vars_to_check == VPP) { | ||
| 659 | |||
| 660 | close(sd); | ||
| 661 | my_tcp_connect(server_address, server_port, &sd); | ||
| 662 | |||
| 663 | xasprintf(&send_buffer, "VKP%s\r\n", volume_name); | ||
| 664 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 665 | if (result != STATE_OK) | ||
| 666 | return result; | ||
| 667 | |||
| 668 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 669 | |||
| 670 | xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 671 | result = STATE_CRITICAL; | ||
| 672 | |||
| 673 | } else { | ||
| 674 | |||
| 675 | purgeable_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 676 | |||
| 677 | close(sd); | ||
| 678 | my_tcp_connect(server_address, server_port, &sd); | ||
| 679 | |||
| 680 | xasprintf(&send_buffer, "VKS%s\r\n", volume_name); | ||
| 681 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 682 | if (result != STATE_OK) | ||
| 683 | return result; | ||
| 684 | total_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 685 | |||
| 686 | percent_purgeable_space = (unsigned long)(((double)purgeable_disk_space / (double)total_disk_space) * 100.0); | ||
| 687 | |||
| 688 | if (check_critical_value && percent_purgeable_space >= critical_value) | ||
| 689 | result = STATE_CRITICAL; | ||
| 690 | else if (check_warning_value && percent_purgeable_space >= warning_value) | ||
| 691 | result = STATE_WARNING; | ||
| 692 | purgeable_disk_space /= 1024; | ||
| 693 | xasprintf(&output_message, _("%lu MB (%lu%%) purgeable on volume %s|Purgeable%s=%lu;%lu;%lu;0;100"), purgeable_disk_space, | ||
| 694 | percent_purgeable_space, volume_name, volume_name, percent_purgeable_space, warning_value, critical_value); | ||
| 695 | } | ||
| 696 | |||
| 697 | /* check KB not yet purgeable space on volume */ | ||
| 698 | } else if (vars_to_check == VKNP) { | ||
| 699 | |||
| 700 | close(sd); | ||
| 701 | my_tcp_connect(server_address, server_port, &sd); | ||
| 702 | |||
| 703 | xasprintf(&send_buffer, "VKNP%s\r\n", volume_name); | ||
| 704 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 705 | if (result != STATE_OK) | ||
| 706 | return result; | ||
| 707 | |||
| 708 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 709 | xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 710 | result = STATE_CRITICAL; | ||
| 711 | } else { | ||
| 712 | non_purgeable_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 713 | if (check_critical_value && non_purgeable_disk_space >= critical_value) | ||
| 714 | result = STATE_CRITICAL; | ||
| 715 | else if (check_warning_value && non_purgeable_disk_space >= warning_value) | ||
| 716 | result = STATE_WARNING; | ||
| 717 | xasprintf(&output_message, _("%s%lu KB not yet purgeable on volume %s"), (result == STATE_OK) ? "" : _("Only "), | ||
| 718 | non_purgeable_disk_space, volume_name); | ||
| 719 | } | ||
| 720 | |||
| 721 | /* check % not yet purgeable space on volume */ | ||
| 722 | } else if (vars_to_check == VPNP) { | ||
| 723 | |||
| 724 | close(sd); | ||
| 725 | my_tcp_connect(server_address, server_port, &sd); | ||
| 726 | |||
| 727 | xasprintf(&send_buffer, "VKNP%s\r\n", volume_name); | ||
| 728 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 729 | if (result != STATE_OK) | ||
| 730 | return result; | ||
| 731 | |||
| 732 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 733 | |||
| 734 | xasprintf(&output_message, _("CRITICAL - Volume '%s' does not exist!"), volume_name); | ||
| 735 | result = STATE_CRITICAL; | ||
| 736 | |||
| 737 | } else { | ||
| 738 | |||
| 739 | non_purgeable_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 740 | |||
| 741 | close(sd); | ||
| 742 | my_tcp_connect(server_address, server_port, &sd); | ||
| 743 | |||
| 744 | xasprintf(&send_buffer, "VKS%s\r\n", volume_name); | ||
| 745 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 746 | if (result != STATE_OK) | ||
| 747 | return result; | ||
| 748 | total_disk_space = strtoul(recv_buffer, NULL, 10); | ||
| 749 | |||
| 750 | percent_non_purgeable_space = (unsigned long)(((double)non_purgeable_disk_space / (double)total_disk_space) * 100.0); | ||
| 751 | |||
| 752 | if (check_critical_value && percent_non_purgeable_space >= critical_value) | ||
| 753 | result = STATE_CRITICAL; | ||
| 754 | else if (check_warning_value && percent_non_purgeable_space >= warning_value) | ||
| 755 | result = STATE_WARNING; | ||
| 756 | purgeable_disk_space /= 1024; | ||
| 757 | xasprintf(&output_message, _("%lu MB (%lu%%) not yet purgeable on volume %s"), non_purgeable_disk_space, | ||
| 758 | percent_non_purgeable_space, volume_name); | ||
| 759 | } | ||
| 760 | |||
| 761 | /* check # of open files */ | ||
| 762 | } else if (vars_to_check == OFILES) { | ||
| 763 | |||
| 764 | close(sd); | ||
| 765 | my_tcp_connect(server_address, server_port, &sd); | ||
| 766 | |||
| 767 | xasprintf(&send_buffer, "S18\r\n"); | ||
| 768 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 769 | if (result != STATE_OK) | ||
| 770 | return result; | ||
| 771 | |||
| 772 | open_files = atoi(recv_buffer); | ||
| 773 | |||
| 774 | if (check_critical_value && open_files >= critical_value) | ||
| 775 | result = STATE_CRITICAL; | ||
| 776 | else if (check_warning_value && open_files >= warning_value) | ||
| 777 | result = STATE_WARNING; | ||
| 778 | |||
| 779 | xasprintf(&output_message, _("%lu open files|Openfiles=%lu;%lu;%lu;0,0"), open_files, open_files, warning_value, critical_value); | ||
| 780 | |||
| 781 | /* check # of abended threads (Netware > 5.x only) */ | ||
| 782 | } else if (vars_to_check == ABENDS) { | ||
| 783 | |||
| 784 | close(sd); | ||
| 785 | my_tcp_connect(server_address, server_port, &sd); | ||
| 786 | |||
| 787 | xasprintf(&send_buffer, "S17\r\n"); | ||
| 788 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 789 | if (result != STATE_OK) | ||
| 790 | return result; | ||
| 791 | |||
| 792 | abended_threads = atoi(recv_buffer); | ||
| 793 | |||
| 794 | if (check_critical_value && abended_threads >= critical_value) | ||
| 795 | result = STATE_CRITICAL; | ||
| 796 | else if (check_warning_value && abended_threads >= warning_value) | ||
| 797 | result = STATE_WARNING; | ||
| 798 | |||
| 799 | xasprintf(&output_message, _("%lu abended threads|Abends=%lu;%lu;%lu;;"), abended_threads, abended_threads, warning_value, | ||
| 800 | critical_value); | ||
| 801 | |||
| 802 | /* check # of current service processes (Netware 5.x only) */ | ||
| 803 | } else if (vars_to_check == CSPROCS) { | ||
| 804 | |||
| 805 | close(sd); | ||
| 806 | my_tcp_connect(server_address, server_port, &sd); | ||
| 807 | |||
| 808 | xasprintf(&send_buffer, "S20\r\n"); | ||
| 809 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 810 | if (result != STATE_OK) | ||
| 811 | return result; | ||
| 812 | |||
| 813 | max_service_processes = atoi(recv_buffer); | ||
| 814 | |||
| 815 | close(sd); | ||
| 816 | my_tcp_connect(server_address, server_port, &sd); | ||
| 817 | |||
| 818 | xasprintf(&send_buffer, "S21\r\n"); | ||
| 819 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 820 | if (result != STATE_OK) | ||
| 821 | return result; | ||
| 822 | |||
| 823 | current_service_processes = atoi(recv_buffer); | ||
| 824 | |||
| 825 | if (check_critical_value && current_service_processes >= critical_value) | ||
| 826 | result = STATE_CRITICAL; | ||
| 827 | else if (check_warning_value && current_service_processes >= warning_value) | ||
| 828 | result = STATE_WARNING; | ||
| 829 | |||
| 830 | xasprintf(&output_message, _("%lu current service processes (%lu max)|Processes=%lu;%lu;%lu;0;%lu"), current_service_processes, | ||
| 831 | max_service_processes, current_service_processes, warning_value, critical_value, max_service_processes); | ||
| 832 | |||
| 833 | /* check # Timesync Status */ | ||
| 834 | } else if (vars_to_check == TSYNC) { | ||
| 835 | |||
| 836 | close(sd); | ||
| 837 | my_tcp_connect(server_address, server_port, &sd); | ||
| 838 | |||
| 839 | xasprintf(&send_buffer, "S22\r\n"); | ||
| 840 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 841 | if (result != STATE_OK) | ||
| 842 | return result; | ||
| 843 | |||
| 844 | time_sync_status = atoi(recv_buffer); | ||
| 845 | |||
| 846 | if (time_sync_status == 0) { | ||
| 847 | result = STATE_CRITICAL; | ||
| 848 | xasprintf(&output_message, _("CRITICAL - Time not in sync with network!")); | ||
| 849 | } else { | ||
| 850 | xasprintf(&output_message, _("OK - Time in sync with network!")); | ||
| 851 | } | ||
| 852 | |||
| 853 | /* check LRU sitting time in secondss */ | ||
| 854 | } else if (vars_to_check == LRUS) { | ||
| 855 | |||
| 856 | close(sd); | ||
| 857 | my_tcp_connect(server_address, server_port, &sd); | ||
| 858 | |||
| 859 | send_buffer = strdup("S4\r\n"); | ||
| 860 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 861 | if (result != STATE_OK) | ||
| 862 | return result; | ||
| 863 | lru_time = strtoul(recv_buffer, NULL, 10); | ||
| 864 | |||
| 865 | if (check_critical_value && lru_time <= critical_value) | ||
| 866 | result = STATE_CRITICAL; | ||
| 867 | else if (check_warning_value && lru_time <= warning_value) | ||
| 868 | result = STATE_WARNING; | ||
| 869 | xasprintf(&output_message, _("LRU sitting time = %lu seconds"), lru_time); | ||
| 870 | |||
| 871 | /* check % dirty cacheobuffers as a percentage of the total*/ | ||
| 872 | } else if (vars_to_check == DCB) { | ||
| 873 | |||
| 874 | close(sd); | ||
| 875 | my_tcp_connect(server_address, server_port, &sd); | ||
| 876 | |||
| 877 | send_buffer = strdup("S6\r\n"); | ||
| 878 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 879 | if (result != STATE_OK) | ||
| 880 | return result; | ||
| 881 | dirty_cache_buffers = atoi(recv_buffer); | ||
| 882 | |||
| 883 | if (check_critical_value && dirty_cache_buffers <= critical_value) | ||
| 884 | result = STATE_CRITICAL; | ||
| 885 | else if (check_warning_value && dirty_cache_buffers <= warning_value) | ||
| 886 | result = STATE_WARNING; | ||
| 887 | xasprintf(&output_message, _("Dirty cache buffers = %lu%% of the total|DCB=%lu;%lu;%lu;0;100"), dirty_cache_buffers, | ||
| 888 | dirty_cache_buffers, warning_value, critical_value); | ||
| 889 | |||
| 890 | /* check % total cache buffers as a percentage of the original*/ | ||
| 891 | } else if (vars_to_check == TCB) { | ||
| 892 | |||
| 893 | close(sd); | ||
| 894 | my_tcp_connect(server_address, server_port, &sd); | ||
| 895 | |||
| 896 | send_buffer = strdup("S7\r\n"); | ||
| 897 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 898 | if (result != STATE_OK) | ||
| 899 | return result; | ||
| 900 | total_cache_buffers = atoi(recv_buffer); | ||
| 901 | |||
| 902 | if (check_critical_value && total_cache_buffers <= critical_value) | ||
| 903 | result = STATE_CRITICAL; | ||
| 904 | else if (check_warning_value && total_cache_buffers <= warning_value) | ||
| 905 | result = STATE_WARNING; | ||
| 906 | xasprintf(&output_message, _("Total cache buffers = %lu%% of the original|TCB=%lu;%lu;%lu;0;100"), total_cache_buffers, | ||
| 907 | total_cache_buffers, warning_value, critical_value); | ||
| 908 | |||
| 909 | } else if (vars_to_check == DSVER) { | ||
| 910 | |||
| 911 | close(sd); | ||
| 912 | my_tcp_connect(server_address, server_port, &sd); | ||
| 913 | |||
| 914 | xasprintf(&send_buffer, "S13\r\n"); | ||
| 915 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 916 | if (result != STATE_OK) | ||
| 917 | return result; | ||
| 918 | |||
| 919 | recv_buffer[strlen(recv_buffer) - 1] = 0; | ||
| 920 | |||
| 921 | xasprintf(&output_message, _("NDS Version %s"), recv_buffer); | ||
| 922 | |||
| 923 | } else if (vars_to_check == UPTIME) { | ||
| 924 | |||
| 925 | close(sd); | ||
| 926 | my_tcp_connect(server_address, server_port, &sd); | ||
| 927 | |||
| 928 | xasprintf(&send_buffer, "UPTIME\r\n"); | ||
| 929 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 930 | if (result != STATE_OK) | ||
| 931 | return result; | ||
| 932 | |||
| 933 | recv_buffer[sizeof(recv_buffer) - 1] = 0; | ||
| 934 | recv_buffer[strlen(recv_buffer) - 1] = 0; | ||
| 935 | |||
| 936 | xasprintf(&output_message, _("Up %s"), recv_buffer); | ||
| 937 | |||
| 938 | } else if (vars_to_check == NLM) { | ||
| 939 | |||
| 940 | close(sd); | ||
| 941 | my_tcp_connect(server_address, server_port, &sd); | ||
| 942 | |||
| 943 | xasprintf(&send_buffer, "S24:%s\r\n", nlm_name); | ||
| 944 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 945 | if (result != STATE_OK) | ||
| 946 | return result; | ||
| 947 | |||
| 948 | recv_buffer[strlen(recv_buffer) - 1] = 0; | ||
| 949 | if (strcmp(recv_buffer, "-1")) { | ||
| 950 | xasprintf(&output_message, _("Module %s version %s is loaded"), nlm_name, recv_buffer); | ||
| 951 | } else { | ||
| 952 | result = STATE_CRITICAL; | ||
| 953 | xasprintf(&output_message, _("Module %s is not loaded"), nlm_name); | ||
| 954 | } | ||
| 955 | } else if (vars_to_check == NRMP) { | ||
| 956 | |||
| 957 | xasprintf(&send_buffer, "NRMP:%s\r\n", nrmp_name); | ||
| 958 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 959 | if (result != STATE_OK) | ||
| 960 | return result; | ||
| 961 | |||
| 962 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 963 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nrmp_name); | ||
| 964 | result = STATE_CRITICAL; | ||
| 965 | } else { | ||
| 966 | nrmp_value = strtoul(recv_buffer, NULL, 10); | ||
| 967 | if (check_critical_value && nrmp_value <= critical_value) | ||
| 968 | result = STATE_CRITICAL; | ||
| 969 | else if (check_warning_value && nrmp_value <= warning_value) | ||
| 970 | result = STATE_WARNING; | ||
| 971 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nrmp_name, nrmp_value, nrmp_name, nrmp_value, warning_value, | ||
| 972 | critical_value); | ||
| 973 | } | ||
| 974 | |||
| 975 | } else if (vars_to_check == NRMM) { | ||
| 976 | |||
| 977 | xasprintf(&send_buffer, "NRMM:%s\r\n", nrmm_name); | ||
| 978 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 979 | if (result != STATE_OK) | ||
| 980 | return result; | ||
| 981 | |||
| 982 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 983 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nrmm_name); | ||
| 984 | result = STATE_CRITICAL; | ||
| 985 | } else { | ||
| 986 | nrmm_value = strtoul(recv_buffer, NULL, 10); | ||
| 987 | if (check_critical_value && nrmm_value <= critical_value) | ||
| 988 | result = STATE_CRITICAL; | ||
| 989 | else if (check_warning_value && nrmm_value <= warning_value) | ||
| 990 | result = STATE_WARNING; | ||
| 991 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nrmm_name, nrmm_value, nrmm_name, nrmm_value, warning_value, | ||
| 992 | critical_value); | ||
| 993 | } | ||
| 994 | |||
| 995 | } else if (vars_to_check == NRMS) { | ||
| 996 | |||
| 997 | xasprintf(&send_buffer, "NRMS:%s\r\n", nrms_name); | ||
| 998 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 999 | if (result != STATE_OK) | ||
| 1000 | return result; | ||
| 1001 | |||
| 1002 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 1003 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nrms_name); | ||
| 1004 | result = STATE_CRITICAL; | ||
| 1005 | } else { | ||
| 1006 | nrms_value = strtoul(recv_buffer, NULL, 10); | ||
| 1007 | if (check_critical_value && nrms_value >= critical_value) | ||
| 1008 | result = STATE_CRITICAL; | ||
| 1009 | else if (check_warning_value && nrms_value >= warning_value) | ||
| 1010 | result = STATE_WARNING; | ||
| 1011 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nrms_name, nrms_value, nrms_name, nrms_value, warning_value, | ||
| 1012 | critical_value); | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | } else if (vars_to_check == NSS1) { | ||
| 1016 | |||
| 1017 | xasprintf(&send_buffer, "NSS1:%s\r\n", nss1_name); | ||
| 1018 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 1019 | if (result != STATE_OK) | ||
| 1020 | return result; | ||
| 1021 | |||
| 1022 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 1023 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss1_name); | ||
| 1024 | result = STATE_CRITICAL; | ||
| 1025 | } else { | ||
| 1026 | nss1_value = strtoul(recv_buffer, NULL, 10); | ||
| 1027 | if (check_critical_value && nss1_value >= critical_value) | ||
| 1028 | result = STATE_CRITICAL; | ||
| 1029 | else if (check_warning_value && nss1_value >= warning_value) | ||
| 1030 | result = STATE_WARNING; | ||
| 1031 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss1_name, nss1_value, nss1_name, nss1_value, warning_value, | ||
| 1032 | critical_value); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | } else if (vars_to_check == NSS2) { | ||
| 1036 | |||
| 1037 | xasprintf(&send_buffer, "NSS2:%s\r\n", nss2_name); | ||
| 1038 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 1039 | if (result != STATE_OK) | ||
| 1040 | return result; | ||
| 1041 | |||
| 1042 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 1043 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss2_name); | ||
| 1044 | result = STATE_CRITICAL; | ||
| 1045 | } else { | ||
| 1046 | nss2_value = strtoul(recv_buffer, NULL, 10); | ||
| 1047 | if (check_critical_value && nss2_value >= critical_value) | ||
| 1048 | result = STATE_CRITICAL; | ||
| 1049 | else if (check_warning_value && nss2_value >= warning_value) | ||
| 1050 | result = STATE_WARNING; | ||
| 1051 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss2_name, nss2_value, nss2_name, nss2_value, warning_value, | ||
| 1052 | critical_value); | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | } else if (vars_to_check == NSS3) { | ||
| 1056 | |||
| 1057 | xasprintf(&send_buffer, "NSS3:%s\r\n", nss3_name); | ||
| 1058 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 1059 | if (result != STATE_OK) | ||
| 1060 | return result; | ||
| 1061 | |||
| 1062 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 1063 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss3_name); | ||
| 1064 | result = STATE_CRITICAL; | ||
| 1065 | } else { | ||
| 1066 | nss3_value = strtoul(recv_buffer, NULL, 10); | ||
| 1067 | if (check_critical_value && nss3_value >= critical_value) | ||
| 1068 | result = STATE_CRITICAL; | ||
| 1069 | else if (check_warning_value && nss3_value >= warning_value) | ||
| 1070 | result = STATE_WARNING; | ||
| 1071 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss3_name, nss3_value, nss3_name, nss3_value, warning_value, | ||
| 1072 | critical_value); | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | } else if (vars_to_check == NSS4) { | ||
| 1076 | |||
| 1077 | xasprintf(&send_buffer, "NSS4:%s\r\n", nss4_name); | ||
| 1078 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 1079 | if (result != STATE_OK) | ||
| 1080 | return result; | ||
| 1081 | |||
| 1082 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 1083 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss4_name); | ||
| 1084 | result = STATE_CRITICAL; | ||
| 1085 | } else { | ||
| 1086 | nss4_value = strtoul(recv_buffer, NULL, 10); | ||
| 1087 | if (check_critical_value && nss4_value >= critical_value) | ||
| 1088 | result = STATE_CRITICAL; | ||
| 1089 | else if (check_warning_value && nss4_value >= warning_value) | ||
| 1090 | result = STATE_WARNING; | ||
| 1091 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss4_name, nss4_value, nss4_name, nss4_value, warning_value, | ||
| 1092 | critical_value); | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | } else if (vars_to_check == NSS5) { | ||
| 1096 | |||
| 1097 | xasprintf(&send_buffer, "NSS5:%s\r\n", nss5_name); | ||
| 1098 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 1099 | if (result != STATE_OK) | ||
| 1100 | return result; | ||
| 1101 | |||
| 1102 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 1103 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss5_name); | ||
| 1104 | result = STATE_CRITICAL; | ||
| 1105 | } else { | ||
| 1106 | nss5_value = strtoul(recv_buffer, NULL, 10); | ||
| 1107 | if (check_critical_value && nss5_value >= critical_value) | ||
| 1108 | result = STATE_CRITICAL; | ||
| 1109 | else if (check_warning_value && nss5_value >= warning_value) | ||
| 1110 | result = STATE_WARNING; | ||
| 1111 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss5_name, nss5_value, nss5_name, nss5_value, warning_value, | ||
| 1112 | critical_value); | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | } else if (vars_to_check == NSS6) { | ||
| 1116 | |||
| 1117 | xasprintf(&send_buffer, "NSS6:%s\r\n", nss6_name); | ||
| 1118 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 1119 | if (result != STATE_OK) | ||
| 1120 | return result; | ||
| 1121 | |||
| 1122 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 1123 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss6_name); | ||
| 1124 | result = STATE_CRITICAL; | ||
| 1125 | } else { | ||
| 1126 | nss6_value = strtoul(recv_buffer, NULL, 10); | ||
| 1127 | if (check_critical_value && nss6_value >= critical_value) | ||
| 1128 | result = STATE_CRITICAL; | ||
| 1129 | else if (check_warning_value && nss6_value >= warning_value) | ||
| 1130 | result = STATE_WARNING; | ||
| 1131 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss6_name, nss6_value, nss6_name, nss6_value, warning_value, | ||
| 1132 | critical_value); | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | } else if (vars_to_check == NSS7) { | ||
| 1136 | |||
| 1137 | xasprintf(&send_buffer, "NSS7:%s\r\n", nss7_name); | ||
| 1138 | result = send_tcp_request(sd, send_buffer, recv_buffer, sizeof(recv_buffer)); | ||
| 1139 | if (result != STATE_OK) | ||
| 1140 | return result; | ||
| 1141 | |||
| 1142 | if (!strcmp(recv_buffer, "-1\n")) { | ||
| 1143 | xasprintf(&output_message, _("CRITICAL - Value '%s' does not exist!"), nss7_name); | ||
| 1144 | result = STATE_CRITICAL; | ||
| 1145 | } else { | ||
| 1146 | nss7_value = strtoul(recv_buffer, NULL, 10); | ||
| 1147 | if (check_critical_value && nss7_value >= critical_value) | ||
| 1148 | result = STATE_CRITICAL; | ||
| 1149 | else if (check_warning_value && nss7_value >= warning_value) | ||
| 1150 | result = STATE_WARNING; | ||
| 1151 | xasprintf(&output_message, _("%s is %lu|%s=%lu;%lu;%lu;;"), nss7_name, nss7_value, nss7_name, nss7_value, warning_value, | ||
| 1152 | critical_value); | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | } else { | ||
| 1156 | |||
| 1157 | output_message = strdup(_("Nothing to check!\n")); | ||
| 1158 | result = STATE_UNKNOWN; | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | close(sd); | ||
| 1162 | |||
| 1163 | /* reset timeout */ | ||
| 1164 | alarm(0); | ||
| 1165 | |||
| 1166 | printf("%s%s\n", netware_version, output_message); | ||
| 1167 | |||
| 1168 | return result; | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | /* process command-line arguments */ | ||
| 1172 | int process_arguments(int argc, char **argv) { | ||
| 1173 | int c; | ||
| 1174 | |||
| 1175 | int option = 0; | ||
| 1176 | static struct option longopts[] = {{"port", required_argument, 0, 'p'}, {"timeout", required_argument, 0, 't'}, | ||
| 1177 | {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, | ||
| 1178 | {"variable", required_argument, 0, 'v'}, {"hostname", required_argument, 0, 'H'}, | ||
| 1179 | {"osversion", no_argument, 0, 'o'}, {"version", no_argument, 0, 'V'}, | ||
| 1180 | {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; | ||
| 1181 | |||
| 1182 | /* no options were supplied */ | ||
| 1183 | if (argc < 2) | ||
| 1184 | return ERROR; | ||
| 1185 | |||
| 1186 | /* backwards compatibility */ | ||
| 1187 | if (!is_option(argv[1])) { | ||
| 1188 | server_address = argv[1]; | ||
| 1189 | argv[1] = argv[0]; | ||
| 1190 | argv = &argv[1]; | ||
| 1191 | argc--; | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | for (c = 1; c < argc; c++) { | ||
| 1195 | if (strcmp("-to", argv[c]) == 0) | ||
| 1196 | strcpy(argv[c], "-t"); | ||
| 1197 | else if (strcmp("-wv", argv[c]) == 0) | ||
| 1198 | strcpy(argv[c], "-w"); | ||
| 1199 | else if (strcmp("-cv", argv[c]) == 0) | ||
| 1200 | strcpy(argv[c], "-c"); | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | while (1) { | ||
| 1204 | c = getopt_long(argc, argv, "+hoVH:t:c:w:p:v:", longopts, &option); | ||
| 1205 | |||
| 1206 | if (c == -1 || c == EOF || c == 1) | ||
| 1207 | break; | ||
| 1208 | |||
| 1209 | switch (c) { | ||
| 1210 | case '?': /* print short usage statement if args not parsable */ | ||
| 1211 | usage5(); | ||
| 1212 | case 'h': /* help */ | ||
| 1213 | print_help(); | ||
| 1214 | exit(STATE_UNKNOWN); | ||
| 1215 | case 'V': /* version */ | ||
| 1216 | print_revision(progname, NP_VERSION); | ||
| 1217 | exit(STATE_UNKNOWN); | ||
| 1218 | case 'H': /* hostname */ | ||
| 1219 | server_address = optarg; | ||
| 1220 | break; | ||
| 1221 | case 'o': /* display nos version */ | ||
| 1222 | check_netware_version = true; | ||
| 1223 | break; | ||
| 1224 | case 'p': /* port */ | ||
| 1225 | if (is_intnonneg(optarg)) | ||
| 1226 | server_port = atoi(optarg); | ||
| 1227 | else | ||
| 1228 | die(STATE_UNKNOWN, _("Server port an integer\n")); | ||
| 1229 | break; | ||
| 1230 | case 'v': | ||
| 1231 | if (strlen(optarg) < 3) | ||
| 1232 | return ERROR; | ||
| 1233 | if (!strcmp(optarg, "LOAD1")) | ||
| 1234 | vars_to_check = LOAD1; | ||
| 1235 | else if (!strcmp(optarg, "LOAD5")) | ||
| 1236 | vars_to_check = LOAD5; | ||
| 1237 | else if (!strcmp(optarg, "LOAD15")) | ||
| 1238 | vars_to_check = LOAD15; | ||
| 1239 | else if (!strcmp(optarg, "CONNS")) | ||
| 1240 | vars_to_check = CONNS; | ||
| 1241 | else if (!strcmp(optarg, "LTCH")) | ||
| 1242 | vars_to_check = LTCH; | ||
| 1243 | else if (!strcmp(optarg, "DCB")) | ||
| 1244 | vars_to_check = DCB; | ||
| 1245 | else if (!strcmp(optarg, "TCB")) | ||
| 1246 | vars_to_check = TCB; | ||
| 1247 | else if (!strcmp(optarg, "CBUFF")) | ||
| 1248 | vars_to_check = CBUFF; | ||
| 1249 | else if (!strcmp(optarg, "CDBUFF")) | ||
| 1250 | vars_to_check = CDBUFF; | ||
| 1251 | else if (!strcmp(optarg, "LRUM")) | ||
| 1252 | vars_to_check = LRUM; | ||
| 1253 | else if (!strcmp(optarg, "LRUS")) | ||
| 1254 | vars_to_check = LRUS; | ||
| 1255 | else if (strncmp(optarg, "VPF", 3) == 0) { | ||
| 1256 | vars_to_check = VPF; | ||
| 1257 | volume_name = strdup(optarg + 3); | ||
| 1258 | if (!strcmp(volume_name, "")) | ||
| 1259 | volume_name = strdup("SYS"); | ||
| 1260 | } else if (strncmp(optarg, "VKF", 3) == 0) { | ||
| 1261 | vars_to_check = VKF; | ||
| 1262 | volume_name = strdup(optarg + 3); | ||
| 1263 | if (!strcmp(volume_name, "")) | ||
| 1264 | volume_name = strdup("SYS"); | ||
| 1265 | } else if (strncmp(optarg, "VMF", 3) == 0) { | ||
| 1266 | vars_to_check = VMF; | ||
| 1267 | volume_name = strdup(optarg + 3); | ||
| 1268 | if (!strcmp(volume_name, "")) | ||
| 1269 | volume_name = strdup("SYS"); | ||
| 1270 | } else if (!strcmp(optarg, "DSDB")) | ||
| 1271 | vars_to_check = DSDB; | ||
| 1272 | else if (!strcmp(optarg, "LOGINS")) | ||
| 1273 | vars_to_check = LOGINS; | ||
| 1274 | else if (!strcmp(optarg, "NRMH")) | ||
| 1275 | vars_to_check = NRMH; | ||
| 1276 | else if (!strcmp(optarg, "UPRB")) | ||
| 1277 | vars_to_check = UPRB; | ||
| 1278 | else if (!strcmp(optarg, "PUPRB")) | ||
| 1279 | vars_to_check = PUPRB; | ||
| 1280 | else if (!strncmp(optarg, "SAPENTRIES", 10)) { | ||
| 1281 | vars_to_check = SAPENTRIES; | ||
| 1282 | if (strlen(optarg) > 10) | ||
| 1283 | sap_number = atoi(optarg + 10); | ||
| 1284 | else | ||
| 1285 | sap_number = -1; | ||
| 1286 | } else if (!strcmp(optarg, "OFILES")) | ||
| 1287 | vars_to_check = OFILES; | ||
| 1288 | else if (strncmp(optarg, "VKP", 3) == 0) { | ||
| 1289 | vars_to_check = VKP; | ||
| 1290 | volume_name = strdup(optarg + 3); | ||
| 1291 | if (!strcmp(volume_name, "")) | ||
| 1292 | volume_name = strdup("SYS"); | ||
| 1293 | } else if (strncmp(optarg, "VMP", 3) == 0) { | ||
| 1294 | vars_to_check = VMP; | ||
| 1295 | volume_name = strdup(optarg + 3); | ||
| 1296 | if (!strcmp(volume_name, "")) | ||
| 1297 | volume_name = strdup("SYS"); | ||
| 1298 | } else if (strncmp(optarg, "VMU", 3) == 0) { | ||
| 1299 | vars_to_check = VMU; | ||
| 1300 | volume_name = strdup(optarg + 3); | ||
| 1301 | if (!strcmp(volume_name, "")) | ||
| 1302 | volume_name = strdup("SYS"); | ||
| 1303 | } else if (strncmp(optarg, "VPU", 3) == 0) { | ||
| 1304 | vars_to_check = VPU; | ||
| 1305 | volume_name = strdup(optarg + 3); | ||
| 1306 | if (!strcmp(volume_name, "")) | ||
| 1307 | volume_name = strdup("SYS"); | ||
| 1308 | } else if (strncmp(optarg, "VPP", 3) == 0) { | ||
| 1309 | vars_to_check = VPP; | ||
| 1310 | volume_name = strdup(optarg + 3); | ||
| 1311 | if (!strcmp(volume_name, "")) | ||
| 1312 | volume_name = strdup("SYS"); | ||
| 1313 | } else if (strncmp(optarg, "VKNP", 4) == 0) { | ||
| 1314 | vars_to_check = VKNP; | ||
| 1315 | volume_name = strdup(optarg + 4); | ||
| 1316 | if (!strcmp(volume_name, "")) | ||
| 1317 | volume_name = strdup("SYS"); | ||
| 1318 | } else if (strncmp(optarg, "VPNP", 4) == 0) { | ||
| 1319 | vars_to_check = VPNP; | ||
| 1320 | volume_name = strdup(optarg + 4); | ||
| 1321 | if (!strcmp(volume_name, "")) | ||
| 1322 | volume_name = strdup("SYS"); | ||
| 1323 | } else if (!strcmp(optarg, "ABENDS")) | ||
| 1324 | vars_to_check = ABENDS; | ||
| 1325 | else if (!strcmp(optarg, "CSPROCS")) | ||
| 1326 | vars_to_check = CSPROCS; | ||
| 1327 | else if (!strcmp(optarg, "TSYNC")) | ||
| 1328 | vars_to_check = TSYNC; | ||
| 1329 | else if (!strcmp(optarg, "DSVER")) | ||
| 1330 | vars_to_check = DSVER; | ||
| 1331 | else if (!strcmp(optarg, "UPTIME")) { | ||
| 1332 | vars_to_check = UPTIME; | ||
| 1333 | } else if (strncmp(optarg, "NLM:", 4) == 0) { | ||
| 1334 | vars_to_check = NLM; | ||
| 1335 | nlm_name = strdup(optarg + 4); | ||
| 1336 | } else if (strncmp(optarg, "NRMP", 4) == 0) { | ||
| 1337 | vars_to_check = NRMP; | ||
| 1338 | nrmp_name = strdup(optarg + 4); | ||
| 1339 | if (!strcmp(nrmp_name, "")) | ||
| 1340 | nrmp_name = strdup("AVAILABLE_MEMORY"); | ||
| 1341 | } else if (strncmp(optarg, "NRMM", 4) == 0) { | ||
| 1342 | vars_to_check = NRMM; | ||
| 1343 | nrmm_name = strdup(optarg + 4); | ||
| 1344 | if (!strcmp(nrmm_name, "")) | ||
| 1345 | nrmm_name = strdup("AVAILABLE_CACHE_MEMORY"); | ||
| 1346 | |||
| 1347 | } | ||
| 1348 | |||
| 1349 | else if (strncmp(optarg, "NRMS", 4) == 0) { | ||
| 1350 | vars_to_check = NRMS; | ||
| 1351 | nrms_name = strdup(optarg + 4); | ||
| 1352 | if (!strcmp(nrms_name, "")) | ||
| 1353 | nrms_name = strdup("USED_SWAP_SPACE"); | ||
| 1354 | |||
| 1355 | } | ||
| 1356 | |||
| 1357 | else if (strncmp(optarg, "NSS1", 4) == 0) { | ||
| 1358 | vars_to_check = NSS1; | ||
| 1359 | nss1_name = strdup(optarg + 4); | ||
| 1360 | if (!strcmp(nss1_name, "")) | ||
| 1361 | nss1_name = strdup("CURRENTBUFFERCACHESIZE"); | ||
| 1362 | |||
| 1363 | } | ||
| 1364 | |||
| 1365 | else if (strncmp(optarg, "NSS2", 4) == 0) { | ||
| 1366 | vars_to_check = NSS2; | ||
| 1367 | nss2_name = strdup(optarg + 4); | ||
| 1368 | if (!strcmp(nss2_name, "")) | ||
| 1369 | nss2_name = strdup("CACHEHITS"); | ||
| 1370 | |||
| 1371 | } | ||
| 1372 | |||
| 1373 | else if (strncmp(optarg, "NSS3", 4) == 0) { | ||
| 1374 | vars_to_check = NSS3; | ||
| 1375 | nss3_name = strdup(optarg + 4); | ||
| 1376 | if (!strcmp(nss3_name, "")) | ||
| 1377 | nss3_name = strdup("CACHEGITPERCENT"); | ||
| 1378 | |||
| 1379 | } | ||
| 1380 | |||
| 1381 | else if (strncmp(optarg, "NSS4", 4) == 0) { | ||
| 1382 | vars_to_check = NSS4; | ||
| 1383 | nss4_name = strdup(optarg + 4); | ||
| 1384 | if (!strcmp(nss4_name, "")) | ||
| 1385 | nss4_name = strdup("CURRENTOPENCOUNT"); | ||
| 1386 | |||
| 1387 | } | ||
| 1388 | |||
| 1389 | else if (strncmp(optarg, "NSS5", 4) == 0) { | ||
| 1390 | vars_to_check = NSS5; | ||
| 1391 | nss5_name = strdup(optarg + 4); | ||
| 1392 | if (!strcmp(nss5_name, "")) | ||
| 1393 | nss5_name = strdup("CACHEMISSES"); | ||
| 1394 | |||
| 1395 | } | ||
| 1396 | |||
| 1397 | else if (strncmp(optarg, "NSS6", 4) == 0) { | ||
| 1398 | vars_to_check = NSS6; | ||
| 1399 | nss6_name = strdup(optarg + 4); | ||
| 1400 | if (!strcmp(nss6_name, "")) | ||
| 1401 | nss6_name = strdup("PENDINGWORKSCOUNT"); | ||
| 1402 | |||
| 1403 | } | ||
| 1404 | |||
| 1405 | else if (strncmp(optarg, "NSS7", 4) == 0) { | ||
| 1406 | vars_to_check = NSS7; | ||
| 1407 | nss7_name = strdup(optarg + 4); | ||
| 1408 | if (!strcmp(nss7_name, "")) | ||
| 1409 | nss7_name = strdup("CACHESIZE"); | ||
| 1410 | |||
| 1411 | } | ||
| 1412 | |||
| 1413 | else | ||
| 1414 | return ERROR; | ||
| 1415 | break; | ||
| 1416 | case 'w': /* warning threshold */ | ||
| 1417 | warning_value = strtoul(optarg, NULL, 10); | ||
| 1418 | check_warning_value = true; | ||
| 1419 | break; | ||
| 1420 | case 'c': /* critical threshold */ | ||
| 1421 | critical_value = strtoul(optarg, NULL, 10); | ||
| 1422 | check_critical_value = true; | ||
| 1423 | break; | ||
| 1424 | case 't': /* timeout */ | ||
| 1425 | socket_timeout = atoi(optarg); | ||
| 1426 | if (socket_timeout <= 0) | ||
| 1427 | return ERROR; | ||
| 1428 | } | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | return OK; | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | void print_help(void) { | ||
| 1435 | char *myport; | ||
| 1436 | xasprintf(&myport, "%d", PORT); | ||
| 1437 | |||
| 1438 | print_revision(progname, NP_VERSION); | ||
| 1439 | |||
| 1440 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | ||
| 1441 | printf(COPYRIGHT, copyright, email); | ||
| 1442 | |||
| 1443 | printf("%s\n", _("This plugin attempts to contact the MRTGEXT NLM running on a")); | ||
| 1444 | printf("%s\n", _("Novell server to gather the requested system information.")); | ||
| 1445 | |||
| 1446 | printf("\n\n"); | ||
| 1447 | |||
| 1448 | print_usage(); | ||
| 1449 | |||
| 1450 | printf(UT_HELP_VRSN); | ||
| 1451 | printf(UT_EXTRA_OPTS); | ||
| 1452 | |||
| 1453 | printf(UT_HOST_PORT, 'p', myport); | ||
| 1454 | |||
| 1455 | printf(" %s\n", "-v, --variable=STRING"); | ||
| 1456 | printf(" %s\n", _("Variable to check. Valid variables include:")); | ||
| 1457 | printf(" %s\n", _("LOAD1 = 1 minute average CPU load")); | ||
| 1458 | printf(" %s\n", _("LOAD5 = 5 minute average CPU load")); | ||
| 1459 | printf(" %s\n", _("LOAD15 = 15 minute average CPU load")); | ||
| 1460 | printf(" %s\n", _("CSPROCS = number of current service processes (NW 5.x only)")); | ||
| 1461 | printf(" %s\n", _("ABENDS = number of abended threads (NW 5.x only)")); | ||
| 1462 | printf(" %s\n", _("UPTIME = server uptime")); | ||
| 1463 | printf(" %s\n", _("LTCH = percent long term cache hits")); | ||
| 1464 | printf(" %s\n", _("CBUFF = current number of cache buffers")); | ||
| 1465 | printf(" %s\n", _("CDBUFF = current number of dirty cache buffers")); | ||
| 1466 | printf(" %s\n", _("DCB = dirty cache buffers as a percentage of the total")); | ||
| 1467 | printf(" %s\n", _("TCB = dirty cache buffers as a percentage of the original")); | ||
| 1468 | printf(" %s\n", _("OFILES = number of open files")); | ||
| 1469 | printf(" %s\n", _(" VMF<vol> = MB of free space on Volume <vol>")); | ||
| 1470 | printf(" %s\n", _(" VMU<vol> = MB used space on Volume <vol>")); | ||
| 1471 | printf(" %s\n", _(" VPU<vol> = percent used space on Volume <vol>")); | ||
| 1472 | printf(" %s\n", _(" VMP<vol> = MB of purgeable space on Volume <vol>")); | ||
| 1473 | printf(" %s\n", _(" VPF<vol> = percent free space on volume <vol>")); | ||
| 1474 | printf(" %s\n", _(" VKF<vol> = KB of free space on volume <vol>")); | ||
| 1475 | printf(" %s\n", _(" VPP<vol> = percent purgeable space on volume <vol>")); | ||
| 1476 | printf(" %s\n", _(" VKP<vol> = KB of purgeable space on volume <vol>")); | ||
| 1477 | printf(" %s\n", _(" VPNP<vol> = percent not yet purgeable space on volume <vol>")); | ||
| 1478 | printf(" %s\n", _(" VKNP<vol> = KB of not yet purgeable space on volume <vol>")); | ||
| 1479 | printf(" %s\n", _(" LRUM = LRU sitting time in minutes")); | ||
| 1480 | printf(" %s\n", _(" LRUS = LRU sitting time in seconds")); | ||
| 1481 | printf(" %s\n", _(" DSDB = check to see if DS Database is open")); | ||
| 1482 | printf(" %s\n", _(" DSVER = NDS version")); | ||
| 1483 | printf(" %s\n", _(" UPRB = used packet receive buffers")); | ||
| 1484 | printf(" %s\n", _(" PUPRB = percent (of max) used packet receive buffers")); | ||
| 1485 | printf(" %s\n", _(" SAPENTRIES = number of entries in the SAP table")); | ||
| 1486 | printf(" %s\n", _(" SAPENTRIES<n> = number of entries in the SAP table for SAP type <n>")); | ||
| 1487 | printf(" %s\n", _(" TSYNC = timesync status")); | ||
| 1488 | printf(" %s\n", _(" LOGINS = check to see if logins are enabled")); | ||
| 1489 | printf(" %s\n", _(" CONNS = number of currently licensed connections")); | ||
| 1490 | printf(" %s\n", _(" NRMH = NRM Summary Status")); | ||
| 1491 | printf(" %s\n", _(" NRMP<stat> = Returns the current value for a NRM health item")); | ||
| 1492 | printf(" %s\n", _(" NRMM<stat> = Returns the current memory stats from NRM")); | ||
| 1493 | printf(" %s\n", _(" NRMS<stat> = Returns the current Swapfile stats from NRM")); | ||
| 1494 | printf(" %s\n", _(" NSS1<stat> = Statistics from _Admin:Manage_NSS\\GeneralStats.xml")); | ||
| 1495 | printf(" %s\n", _(" NSS3<stat> = Statistics from _Admin:Manage_NSS\\NameCache.xml")); | ||
| 1496 | printf(" %s\n", _(" NSS4<stat> = Statistics from _Admin:Manage_NSS\\FileStats.xml")); | ||
| 1497 | printf(" %s\n", _(" NSS5<stat> = Statistics from _Admin:Manage_NSS\\ObjectCache.xml")); | ||
| 1498 | printf(" %s\n", _(" NSS6<stat> = Statistics from _Admin:Manage_NSS\\Thread.xml")); | ||
| 1499 | printf(" %s\n", _(" NSS7<stat> = Statistics from _Admin:Manage_NSS\\AuthorizationCache.xml")); | ||
| 1500 | printf(" %s\n", _(" NLM:<nlm> = check if NLM is loaded and report version")); | ||
| 1501 | printf(" %s\n", _(" (e.g. NLM:TSANDS.NLM)")); | ||
| 1502 | printf("\n"); | ||
| 1503 | printf(" %s\n", "-w, --warning=INTEGER"); | ||
| 1504 | printf(" %s\n", _("Threshold which will result in a warning status")); | ||
| 1505 | printf(" %s\n", "-c, --critical=INTEGER"); | ||
| 1506 | printf(" %s\n", _("Threshold which will result in a critical status")); | ||
| 1507 | printf(" %s\n", "-o, --osversion"); | ||
| 1508 | printf(" %s\n", _("Include server version string in results")); | ||
| 1509 | |||
| 1510 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | ||
| 1511 | |||
| 1512 | printf("\n"); | ||
| 1513 | printf("%s\n", _("Notes:")); | ||
| 1514 | printf(" %s\n", _("- This plugin requires that the MRTGEXT.NLM file from James Drews' MRTG")); | ||
| 1515 | printf(" %s\n", _(" extension for NetWare be loaded on the Novell servers you wish to check.")); | ||
| 1516 | printf(" %s\n", _(" (available from http://www.engr.wisc.edu/~drews/mrtg/)")); | ||
| 1517 | printf(" %s\n", _("- Values for critical thresholds should be lower than warning thresholds")); | ||
| 1518 | printf(" %s\n", _(" when the following variables are checked: VPF, VKF, LTCH, CBUFF, DCB, ")); | ||
| 1519 | printf(" %s\n", _(" TCB, LRUS and LRUM.")); | ||
| 1520 | |||
| 1521 | printf(UT_SUPPORT); | ||
| 1522 | } | ||
| 1523 | |||
| 1524 | void print_usage(void) { | ||
| 1525 | printf("%s\n", _("Usage:")); | ||
| 1526 | printf("%s -H host [-p port] [-v variable] [-w warning] [-c critical] [-t timeout]\n", progname); | ||
| 1527 | } | ||
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c index 84305adb..0ce75e0a 100644 --- a/plugins/check_pgsql.c +++ b/plugins/check_pgsql.c | |||
| @@ -28,32 +28,35 @@ | |||
| 28 | * | 28 | * |
| 29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
| 30 | 30 | ||
| 31 | #include "output.h" | ||
| 32 | #include "perfdata.h" | ||
| 31 | #include "states.h" | 33 | #include "states.h" |
| 32 | const char *progname = "check_pgsql"; | ||
| 33 | const char *copyright = "1999-2024"; | ||
| 34 | const char *email = "devel@monitoring-plugins.org"; | ||
| 35 | |||
| 36 | #include "common.h" | 34 | #include "common.h" |
| 37 | #include "utils.h" | 35 | #include "utils.h" |
| 38 | #include "utils_cmd.h" | 36 | #include "utils_cmd.h" |
| 39 | #include "check_pgsql.d/config.h" | 37 | #include "check_pgsql.d/config.h" |
| 40 | #include "thresholds.h" | 38 | #include "thresholds.h" |
| 41 | |||
| 42 | #include "netutils.h" | 39 | #include "netutils.h" |
| 43 | #include <libpq-fe.h> | 40 | #include <libpq-fe.h> |
| 44 | #include <pg_config_manual.h> | 41 | #include <pg_config_manual.h> |
| 45 | 42 | ||
| 43 | const char *progname = "check_pgsql"; | ||
| 44 | const char *copyright = "1999-2024"; | ||
| 45 | const char *email = "devel@monitoring-plugins.org"; | ||
| 46 | |||
| 46 | #define DEFAULT_HOST "127.0.0.1" | 47 | #define DEFAULT_HOST "127.0.0.1" |
| 47 | 48 | ||
| 48 | /* return the PSQL server version as a 3-tuple */ | 49 | /* return the PSQL server version as a 3-tuple */ |
| 49 | #define PSQL_SERVER_VERSION3(server_version) \ | 50 | #define PSQL_SERVER_VERSION3(server_version) \ |
| 50 | (server_version) / 10000, (server_version) / 100 - (int)((server_version) / 10000) * 100, \ | 51 | ((server_version) / 10000), \ |
| 51 | (server_version) - (int)((server_version) / 100) * 100 | 52 | (((server_version) / 100) - (int)(((server_version) / 10000) * 100)), \ |
| 53 | (server_version) - (int)(((server_version) / 100) * 100) | ||
| 52 | /* return true if the given host is a UNIX domain socket */ | 54 | /* return true if the given host is a UNIX domain socket */ |
| 53 | #define PSQL_IS_UNIX_DOMAIN_SOCKET(host) ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host))) | 55 | #define PSQL_IS_UNIX_DOMAIN_SOCKET(host) ((NULL == (host)) || ('\0' == *(host)) || ('/' == *(host))) |
| 54 | /* return a 3-tuple identifying a host/port independent of the socket type */ | 56 | /* return a 3-tuple identifying a host/port independent of the socket type */ |
| 55 | #define PSQL_SOCKET3(host, port) \ | 57 | #define PSQL_SOCKET3(host, port) \ |
| 56 | ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port | 58 | ((NULL == (host)) || ('\0' == *(host))) ? DEFAULT_PGSOCKET_DIR : host, \ |
| 59 | PSQL_IS_UNIX_DOMAIN_SOCKET(host) ? "/.s.PGSQL." : ":", port | ||
| 57 | 60 | ||
| 58 | typedef struct { | 61 | typedef struct { |
| 59 | int errorcode; | 62 | int errorcode; |
| @@ -63,14 +66,25 @@ static check_pgsql_config_wrapper process_arguments(int /*argc*/, char ** /*argv | |||
| 63 | 66 | ||
| 64 | static void print_help(void); | 67 | static void print_help(void); |
| 65 | static bool is_pg_logname(char * /*username*/); | 68 | static bool is_pg_logname(char * /*username*/); |
| 66 | static mp_state_enum do_query(PGconn * /*conn*/, char * /*query*/, const char /*pgqueryname*/[], thresholds * /*qthresholds*/, | 69 | |
| 67 | char * /*query_warning*/, char * /*query_critical*/); | 70 | typedef enum { |
| 71 | QUERY_OK, | ||
| 72 | ERROR_WITH_QUERY, // critical | ||
| 73 | NO_ROWS_RETURNED, // warning | ||
| 74 | NO_COLUMNS_RETURNED, // warning | ||
| 75 | NO_DATA_RETURNED, // critica/ | ||
| 76 | RESULT_IS_NOT_NUMERIC // critical | ||
| 77 | } do_query_errorcode; | ||
| 78 | |||
| 79 | typedef struct { | ||
| 80 | do_query_errorcode error_code; | ||
| 81 | double numerical_result; | ||
| 82 | } do_query_wrapper; | ||
| 83 | static do_query_wrapper do_query(PGconn * /*conn*/, char * /*query*/); | ||
| 68 | void print_usage(void); | 84 | void print_usage(void); |
| 69 | 85 | ||
| 70 | static int verbose = 0; | 86 | static int verbose = 0; |
| 71 | 87 | ||
| 72 | #define OPTID_QUERYNAME -1000 | ||
| 73 | |||
| 74 | /****************************************************************************** | 88 | /****************************************************************************** |
| 75 | 89 | ||
| 76 | The (pseudo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ | 90 | The (pseudo?)literate programming XML is contained within \@\@\- <XML> \-\@\@ |
| @@ -136,8 +150,8 @@ int main(int argc, char **argv) { | |||
| 136 | 150 | ||
| 137 | const check_pgsql_config config = tmp_config.config; | 151 | const check_pgsql_config config = tmp_config.config; |
| 138 | 152 | ||
| 139 | if (verbose > 2) { | 153 | if (config.output_format_is_set) { |
| 140 | printf("Arguments initialized\n"); | 154 | mp_set_format(config.output_format); |
| 141 | } | 155 | } |
| 142 | 156 | ||
| 143 | /* Set signal handling and alarm */ | 157 | /* Set signal handling and alarm */ |
| @@ -167,7 +181,8 @@ int main(int argc, char **argv) { | |||
| 167 | } | 181 | } |
| 168 | 182 | ||
| 169 | if (verbose) { /* do not include password (see right below) in output */ | 183 | if (verbose) { /* do not include password (see right below) in output */ |
| 170 | printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, config.pgpasswd ? " password = <hidden>" : ""); | 184 | printf("Connecting to PostgreSQL using conninfo: %s%s\n", conninfo, |
| 185 | config.pgpasswd ? " password = <hidden>" : ""); | ||
| 171 | } | 186 | } |
| 172 | 187 | ||
| 173 | if (config.pgpasswd) { | 188 | if (config.pgpasswd) { |
| @@ -185,8 +200,8 @@ int main(int argc, char **argv) { | |||
| 185 | --end_timeval.tv_sec; | 200 | --end_timeval.tv_sec; |
| 186 | end_timeval.tv_usec += 1000000; | 201 | end_timeval.tv_usec += 1000000; |
| 187 | } | 202 | } |
| 188 | double elapsed_time = | 203 | double elapsed_time = (double)(end_timeval.tv_sec - start_timeval.tv_sec) + |
| 189 | (double)(end_timeval.tv_sec - start_timeval.tv_sec) + ((double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0); | 204 | ((double)(end_timeval.tv_usec - start_timeval.tv_usec) / 1000000.0); |
| 190 | 205 | ||
| 191 | if (verbose) { | 206 | if (verbose) { |
| 192 | printf("Time elapsed: %f\n", elapsed_time); | 207 | printf("Time elapsed: %f\n", elapsed_time); |
| @@ -196,21 +211,41 @@ int main(int argc, char **argv) { | |||
| 196 | if (verbose) { | 211 | if (verbose) { |
| 197 | printf("Verifying connection\n"); | 212 | printf("Verifying connection\n"); |
| 198 | } | 213 | } |
| 214 | |||
| 215 | mp_check overall = mp_check_init(); | ||
| 216 | |||
| 217 | mp_subcheck sc_connection = mp_subcheck_init(); | ||
| 218 | |||
| 199 | if (PQstatus(conn) == CONNECTION_BAD) { | 219 | if (PQstatus(conn) == CONNECTION_BAD) { |
| 200 | printf(_("CRITICAL - no connection to '%s' (%s).\n"), config.dbName, PQerrorMessage(conn)); | 220 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_CRITICAL); |
| 221 | xasprintf(&sc_connection.output, "no connection to '%s' (%s)", config.dbName, | ||
| 222 | PQerrorMessage(conn)); | ||
| 201 | PQfinish(conn); | 223 | PQfinish(conn); |
| 202 | return STATE_CRITICAL; | 224 | mp_add_subcheck_to_check(&overall, sc_connection); |
| 203 | } | 225 | mp_exit(overall); |
| 204 | |||
| 205 | mp_state_enum status = STATE_UNKNOWN; | ||
| 206 | if (elapsed_time > config.tcrit) { | ||
| 207 | status = STATE_CRITICAL; | ||
| 208 | } else if (elapsed_time > config.twarn) { | ||
| 209 | status = STATE_WARNING; | ||
| 210 | } else { | 226 | } else { |
| 211 | status = STATE_OK; | 227 | sc_connection = mp_set_subcheck_state(sc_connection, STATE_OK); |
| 228 | xasprintf(&sc_connection.output, "connected to '%s'", config.dbName); | ||
| 229 | mp_add_subcheck_to_check(&overall, sc_connection); | ||
| 212 | } | 230 | } |
| 213 | 231 | ||
| 232 | mp_subcheck sc_connection_time = mp_subcheck_init(); | ||
| 233 | sc_connection_time = mp_set_subcheck_default_state(sc_connection_time, STATE_UNKNOWN); | ||
| 234 | |||
| 235 | xasprintf(&sc_connection_time.output, "connection time: %.10g", elapsed_time); | ||
| 236 | |||
| 237 | mp_perfdata pd_connection_time = perfdata_init(); | ||
| 238 | pd_connection_time.label = "time"; | ||
| 239 | pd_connection_time.uom = "s"; | ||
| 240 | pd_connection_time = mp_set_pd_value(pd_connection_time, elapsed_time); | ||
| 241 | pd_connection_time = mp_pd_set_thresholds(pd_connection_time, config.time_thresholds); | ||
| 242 | |||
| 243 | mp_add_perfdata_to_subcheck(&sc_connection_time, pd_connection_time); | ||
| 244 | sc_connection_time = | ||
| 245 | mp_set_subcheck_state(sc_connection_time, mp_get_pd_status(pd_connection_time)); | ||
| 246 | |||
| 247 | mp_add_subcheck_to_check(&overall, sc_connection_time); | ||
| 248 | |||
| 214 | if (verbose) { | 249 | if (verbose) { |
| 215 | char *server_host = PQhost(conn); | 250 | char *server_host = PQhost(conn); |
| 216 | int server_version = PQserverVersion(conn); | 251 | int server_version = PQserverVersion(conn); |
| @@ -218,27 +253,91 @@ int main(int argc, char **argv) { | |||
| 218 | printf("Successfully connected to database %s (user %s) " | 253 | printf("Successfully connected to database %s (user %s) " |
| 219 | "at server %s%s%s (server version: %d.%d.%d, " | 254 | "at server %s%s%s (server version: %d.%d.%d, " |
| 220 | "protocol version: %d, pid: %d)\n", | 255 | "protocol version: %d, pid: %d)\n", |
| 221 | PQdb(conn), PQuser(conn), PSQL_SOCKET3(server_host, PQport(conn)), PSQL_SERVER_VERSION3(server_version), | 256 | PQdb(conn), PQuser(conn), PSQL_SOCKET3(server_host, PQport(conn)), |
| 222 | PQprotocolVersion(conn), PQbackendPID(conn)); | 257 | PSQL_SERVER_VERSION3(server_version), PQprotocolVersion(conn), PQbackendPID(conn)); |
| 223 | } | 258 | } |
| 224 | 259 | ||
| 225 | printf(_(" %s - database %s (%f sec.)|%s\n"), state_text(status), config.dbName, elapsed_time, | ||
| 226 | fperfdata("time", elapsed_time, "s", (config.twarn > 0.0), config.twarn, (config.tcrit > 0.0), config.tcrit, true, 0, false, 0)); | ||
| 227 | |||
| 228 | mp_state_enum query_status = STATE_UNKNOWN; | ||
| 229 | if (config.pgquery) { | 260 | if (config.pgquery) { |
| 230 | query_status = do_query(conn, config.pgquery, config.pgqueryname, config.qthresholds, config.query_warning, config.query_critical); | 261 | mp_subcheck sc_query = mp_subcheck_init(); |
| 262 | sc_query = mp_set_subcheck_default_state(sc_query, STATE_UNKNOWN); | ||
| 263 | if (config.pgqueryname) { | ||
| 264 | xasprintf(&sc_query.output, "query '%s'", config.pgqueryname); | ||
| 265 | } else { | ||
| 266 | xasprintf(&sc_query.output, "query '%s'", config.pgquery); | ||
| 267 | } | ||
| 268 | |||
| 269 | do_query_wrapper query_result = do_query(conn, config.pgquery); | ||
| 270 | |||
| 271 | switch (query_result.error_code) { | ||
| 272 | case QUERY_OK: { | ||
| 273 | // Query was successful and there is a numerical result | ||
| 274 | sc_query = mp_set_subcheck_state(sc_query, STATE_OK); | ||
| 275 | xasprintf(&sc_query.output, "%s succeeded", sc_query.output); | ||
| 276 | |||
| 277 | mp_perfdata pd_query = perfdata_init(); | ||
| 278 | pd_query = mp_set_pd_value(pd_query, query_result.numerical_result); | ||
| 279 | pd_query = mp_pd_set_thresholds(pd_query, config.qthresholds); | ||
| 280 | pd_query.label = "query"; | ||
| 281 | |||
| 282 | mp_subcheck sc_query_compare = mp_subcheck_init(); | ||
| 283 | mp_state_enum query_compare_state = mp_get_pd_status(pd_query); | ||
| 284 | |||
| 285 | sc_query_compare = mp_set_subcheck_state(sc_query_compare, query_compare_state); | ||
| 286 | mp_add_perfdata_to_subcheck(&sc_query_compare, pd_query); | ||
| 287 | |||
| 288 | if (query_compare_state == STATE_OK) { | ||
| 289 | xasprintf(&sc_query_compare.output, "query result '%f' is within thresholds", | ||
| 290 | query_result.numerical_result); | ||
| 291 | } else { | ||
| 292 | xasprintf(&sc_query_compare.output, "query result '%f' is violating thresholds", | ||
| 293 | query_result.numerical_result); | ||
| 294 | } | ||
| 295 | mp_add_subcheck_to_check(&overall, sc_query_compare); | ||
| 296 | |||
| 297 | } break; | ||
| 298 | case ERROR_WITH_QUERY: | ||
| 299 | xasprintf(&sc_query.output, "%s - Error with query: %s", sc_query.output, | ||
| 300 | PQerrorMessage(conn)); | ||
| 301 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | ||
| 302 | break; | ||
| 303 | case NO_ROWS_RETURNED: | ||
| 304 | xasprintf(&sc_query.output, "%s - no rows were returned by the query", sc_query.output); | ||
| 305 | sc_query = mp_set_subcheck_state(sc_query, STATE_WARNING); | ||
| 306 | break; | ||
| 307 | case NO_COLUMNS_RETURNED: | ||
| 308 | xasprintf(&sc_query.output, "%s - no columns were returned by the query", | ||
| 309 | sc_query.output); | ||
| 310 | sc_query = mp_set_subcheck_state(sc_query, STATE_WARNING); | ||
| 311 | break; | ||
| 312 | case NO_DATA_RETURNED: | ||
| 313 | xasprintf(&sc_query.output, "%s - no data was returned by the query", sc_query.output); | ||
| 314 | sc_query = mp_set_subcheck_state(sc_query, STATE_WARNING); | ||
| 315 | break; | ||
| 316 | case RESULT_IS_NOT_NUMERIC: | ||
| 317 | xasprintf(&sc_query.output, "%s - result of the query is not numeric", sc_query.output); | ||
| 318 | sc_query = mp_set_subcheck_state(sc_query, STATE_CRITICAL); | ||
| 319 | break; | ||
| 320 | }; | ||
| 321 | |||
| 322 | mp_add_subcheck_to_check(&overall, sc_query); | ||
| 231 | } | 323 | } |
| 232 | 324 | ||
| 233 | if (verbose) { | 325 | if (verbose) { |
| 234 | printf("Closing connection\n"); | 326 | printf("Closing connection\n"); |
| 235 | } | 327 | } |
| 236 | PQfinish(conn); | 328 | PQfinish(conn); |
| 237 | return (config.pgquery && query_status > status) ? query_status : status; | 329 | |
| 330 | mp_exit(overall); | ||
| 238 | } | 331 | } |
| 239 | 332 | ||
| 240 | /* process command-line arguments */ | 333 | /* process command-line arguments */ |
| 241 | check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | 334 | static check_pgsql_config_wrapper process_arguments(int argc, char **argv) { |
| 335 | |||
| 336 | enum { | ||
| 337 | OPTID_QUERYNAME = CHAR_MAX + 1, | ||
| 338 | output_format_index, | ||
| 339 | }; | ||
| 340 | |||
| 242 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, | 341 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, |
| 243 | {"version", no_argument, 0, 'V'}, | 342 | {"version", no_argument, 0, 'V'}, |
| 244 | {"timeout", required_argument, 0, 't'}, | 343 | {"timeout", required_argument, 0, 't'}, |
| @@ -256,6 +355,7 @@ check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 256 | {"query_critical", required_argument, 0, 'C'}, | 355 | {"query_critical", required_argument, 0, 'C'}, |
| 257 | {"query_warning", required_argument, 0, 'W'}, | 356 | {"query_warning", required_argument, 0, 'W'}, |
| 258 | {"verbose", no_argument, 0, 'v'}, | 357 | {"verbose", no_argument, 0, 'v'}, |
| 358 | {"output-format", required_argument, 0, output_format_index}, | ||
| 259 | {0, 0, 0, 0}}; | 359 | {0, 0, 0, 0}}; |
| 260 | 360 | ||
| 261 | check_pgsql_config_wrapper result = { | 361 | check_pgsql_config_wrapper result = { |
| @@ -265,13 +365,25 @@ check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 265 | 365 | ||
| 266 | while (true) { | 366 | while (true) { |
| 267 | int option = 0; | 367 | int option = 0; |
| 268 | int option_char = getopt_long(argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option); | 368 | int option_char = |
| 369 | getopt_long(argc, argv, "hVt:c:w:H:P:d:l:p:a:o:q:C:W:v", longopts, &option); | ||
| 269 | 370 | ||
| 270 | if (option_char == EOF) { | 371 | if (option_char == EOF) { |
| 271 | break; | 372 | break; |
| 272 | } | 373 | } |
| 273 | 374 | ||
| 274 | switch (option_char) { | 375 | switch (option_char) { |
| 376 | case output_format_index: { | ||
| 377 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 378 | if (!parser.parsing_success) { | ||
| 379 | printf("Invalid output format: %s\n", optarg); | ||
| 380 | exit(STATE_UNKNOWN); | ||
| 381 | } | ||
| 382 | |||
| 383 | result.config.output_format_is_set = true; | ||
| 384 | result.config.output_format = parser.output_format; | ||
| 385 | break; | ||
| 386 | } | ||
| 275 | case '?': /* usage */ | 387 | case '?': /* usage */ |
| 276 | usage5(); | 388 | usage5(); |
| 277 | case 'h': /* help */ | 389 | case 'h': /* help */ |
| @@ -287,26 +399,40 @@ check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 287 | timeout_interval = atoi(optarg); | 399 | timeout_interval = atoi(optarg); |
| 288 | } | 400 | } |
| 289 | break; | 401 | break; |
| 290 | case 'c': /* critical time threshold */ | 402 | case 'c': /* critical time threshold */ { |
| 291 | if (!is_nonnegative(optarg)) { | 403 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 292 | usage2(_("Critical threshold must be a positive integer"), optarg); | 404 | if (tmp.error != MP_PARSING_SUCCES) { |
| 293 | } else { | 405 | die(STATE_UNKNOWN, "failed to parse critical time threshold"); |
| 294 | result.config.tcrit = strtod(optarg, NULL); | ||
| 295 | } | 406 | } |
| 296 | break; | 407 | result.config.time_thresholds = |
| 297 | case 'w': /* warning time threshold */ | 408 | mp_thresholds_set_crit(result.config.time_thresholds, tmp.range); |
| 298 | if (!is_nonnegative(optarg)) { | 409 | } break; |
| 299 | usage2(_("Warning threshold must be a positive integer"), optarg); | 410 | case 'w': /* warning time threshold */ { |
| 300 | } else { | 411 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 301 | result.config.twarn = strtod(optarg, NULL); | 412 | if (tmp.error != MP_PARSING_SUCCES) { |
| 413 | die(STATE_UNKNOWN, "failed to parse warning time threshold"); | ||
| 302 | } | 414 | } |
| 303 | break; | 415 | result.config.time_thresholds = |
| 304 | case 'C': /* critical query threshold */ | 416 | mp_thresholds_set_warn(result.config.time_thresholds, tmp.range); |
| 305 | result.config.query_critical = optarg; | 417 | } break; |
| 306 | break; | 418 | case 'C': /* critical query threshold */ { |
| 307 | case 'W': /* warning query threshold */ | 419 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 308 | result.config.query_warning = optarg; | 420 | if (tmp.error != MP_PARSING_SUCCES) { |
| 309 | break; | 421 | die(STATE_UNKNOWN, "failed to parse critical query threshold"); |
| 422 | } | ||
| 423 | |||
| 424 | result.config.qthresholds = | ||
| 425 | mp_thresholds_set_crit(result.config.qthresholds, tmp.range); | ||
| 426 | |||
| 427 | } break; | ||
| 428 | case 'W': /* warning query threshold */ { | ||
| 429 | mp_range_parsed tmp = mp_parse_range_string(optarg); | ||
| 430 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 431 | die(STATE_UNKNOWN, "failed to parse warning query threshold"); | ||
| 432 | } | ||
| 433 | result.config.qthresholds = | ||
| 434 | mp_thresholds_set_warn(result.config.qthresholds, tmp.range); | ||
| 435 | } break; | ||
| 310 | case 'H': /* host */ | 436 | case 'H': /* host */ |
| 311 | if ((*optarg != '/') && (!is_host(optarg))) { | 437 | if ((*optarg != '/') && (!is_host(optarg))) { |
| 312 | usage2(_("Invalid hostname/address"), optarg); | 438 | usage2(_("Invalid hostname/address"), optarg); |
| @@ -357,8 +483,6 @@ check_pgsql_config_wrapper process_arguments(int argc, char **argv) { | |||
| 357 | } | 483 | } |
| 358 | } | 484 | } |
| 359 | 485 | ||
| 360 | set_thresholds(&result.config.qthresholds, result.config.query_warning, result.config.query_critical); | ||
| 361 | |||
| 362 | return result; | 486 | return result; |
| 363 | } | 487 | } |
| 364 | 488 | ||
| @@ -386,7 +510,7 @@ should be added.</para> | |||
| 386 | -@@ | 510 | -@@ |
| 387 | ******************************************************************************/ | 511 | ******************************************************************************/ |
| 388 | 512 | ||
| 389 | bool is_pg_logname(char *username) { | 513 | static bool is_pg_logname(char *username) { |
| 390 | if (strlen(username) > NAMEDATALEN - 1) { | 514 | if (strlen(username) > NAMEDATALEN - 1) { |
| 391 | return (false); | 515 | return (false); |
| 392 | } | 516 | } |
| @@ -440,12 +564,13 @@ void print_help(void) { | |||
| 440 | printf(" %s\n", "--queryname=STRING"); | 564 | printf(" %s\n", "--queryname=STRING"); |
| 441 | printf(" %s\n", _("A name for the query, this string is used instead of the query")); | 565 | printf(" %s\n", _("A name for the query, this string is used instead of the query")); |
| 442 | printf(" %s\n", _("in the long output of the plugin")); | 566 | printf(" %s\n", _("in the long output of the plugin")); |
| 443 | printf(" %s\n", "-W, --query-warning=RANGE"); | 567 | printf(" %s\n", "-W, --query_warning=RANGE"); |
| 444 | printf(" %s\n", _("SQL query value to result in warning status (double)")); | 568 | printf(" %s\n", _("SQL query value to result in warning status (double)")); |
| 445 | printf(" %s\n", "-C, --query-critical=RANGE"); | 569 | printf(" %s\n", "-C, --query_critical=RANGE"); |
| 446 | printf(" %s\n", _("SQL query value to result in critical status (double)")); | 570 | printf(" %s\n", _("SQL query value to result in critical status (double)")); |
| 447 | 571 | ||
| 448 | printf(UT_VERBOSE); | 572 | printf(UT_VERBOSE); |
| 573 | printf(UT_OUTPUT_FORMAT); | ||
| 449 | 574 | ||
| 450 | printf("\n"); | 575 | printf("\n"); |
| 451 | printf(" %s\n", _("All parameters are optional.")); | 576 | printf(" %s\n", _("All parameters are optional.")); |
| @@ -457,29 +582,39 @@ void print_help(void) { | |||
| 457 | 582 | ||
| 458 | printf(" %s\n", _("If a query is specified using the -q option, it will be executed after")); | 583 | printf(" %s\n", _("If a query is specified using the -q option, it will be executed after")); |
| 459 | printf(" %s\n", _("connecting to the server. The result from the query has to be numeric.")); | 584 | printf(" %s\n", _("connecting to the server. The result from the query has to be numeric.")); |
| 460 | printf(" %s\n", _("Multiple SQL commands, separated by semicolon, are allowed but the result ")); | 585 | printf(" %s\n", |
| 586 | _("Multiple SQL commands, separated by semicolon, are allowed but the result ")); | ||
| 461 | printf(" %s\n", _("of the last command is taken into account only. The value of the first")); | 587 | printf(" %s\n", _("of the last command is taken into account only. The value of the first")); |
| 462 | printf(" %s\n", _("column in the first row is used as the check result. If a second column is")); | 588 | printf(" %s\n", |
| 589 | _("column in the first row is used as the check result. If a second column is")); | ||
| 463 | printf(" %s\n", _("present in the result set, this is added to the plugin output with a")); | 590 | printf(" %s\n", _("present in the result set, this is added to the plugin output with a")); |
| 464 | printf(" %s\n", _("prefix of \"Extra Info:\". This information can be displayed in the system")); | 591 | printf(" %s\n", |
| 592 | _("prefix of \"Extra Info:\". This information can be displayed in the system")); | ||
| 465 | printf(" %s\n\n", _("executing the plugin.")); | 593 | printf(" %s\n\n", _("executing the plugin.")); |
| 466 | 594 | ||
| 467 | printf(" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual")); | 595 | printf(" %s\n", _("See the chapter \"Monitoring Database Activity\" of the PostgreSQL manual")); |
| 468 | printf(" %s\n\n", _("for details about how to access internal statistics of the database server.")); | 596 | printf(" %s\n\n", |
| 597 | _("for details about how to access internal statistics of the database server.")); | ||
| 469 | 598 | ||
| 470 | printf(" %s\n", _("For a list of available connection parameters which may be used with the -o")); | 599 | printf(" %s\n", |
| 471 | printf(" %s\n", _("command line option, see the documentation for PQconnectdb() in the chapter")); | 600 | _("For a list of available connection parameters which may be used with the -o")); |
| 601 | printf(" %s\n", | ||
| 602 | _("command line option, see the documentation for PQconnectdb() in the chapter")); | ||
| 472 | printf(" %s\n", _("\"libpq - C Library\" of the PostgreSQL manual. For example, this may be")); | 603 | printf(" %s\n", _("\"libpq - C Library\" of the PostgreSQL manual. For example, this may be")); |
| 473 | printf(" %s\n", _("used to specify a service name in pg_service.conf to be used for additional")); | 604 | printf(" %s\n", |
| 605 | _("used to specify a service name in pg_service.conf to be used for additional")); | ||
| 474 | printf(" %s\n", _("connection parameters: -o 'service=<name>' or to specify the SSL mode:")); | 606 | printf(" %s\n", _("connection parameters: -o 'service=<name>' or to specify the SSL mode:")); |
| 475 | printf(" %s\n\n", _("-o 'sslmode=require'.")); | 607 | printf(" %s\n\n", _("-o 'sslmode=require'.")); |
| 476 | 608 | ||
| 477 | printf(" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To")); | 609 | printf(" %s\n", _("The plugin will connect to a local postmaster if no host is specified. To")); |
| 478 | printf(" %s\n", _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP")); | 610 | printf(" %s\n", |
| 611 | _("connect to a remote host, be sure that the remote postmaster accepts TCP/IP")); | ||
| 479 | printf(" %s\n\n", _("connections (start the postmaster with the -i option).")); | 612 | printf(" %s\n\n", _("connections (start the postmaster with the -i option).")); |
| 480 | 613 | ||
| 481 | printf(" %s\n", _("Typically, the monitoring user (unless the --logname option is used) should be")); | 614 | printf(" %s\n", |
| 482 | printf(" %s\n", _("able to connect to the database without a password. The plugin can also send")); | 615 | _("Typically, the monitoring user (unless the --logname option is used) should be")); |
| 616 | printf(" %s\n", | ||
| 617 | _("able to connect to the database without a password. The plugin can also send")); | ||
| 483 | printf(" %s\n", _("a password, but no effort is made to obscure or encrypt the password.")); | 618 | printf(" %s\n", _("a password, but no effort is made to obscure or encrypt the password.")); |
| 484 | 619 | ||
| 485 | printf(UT_SUPPORT); | 620 | printf(UT_SUPPORT); |
| @@ -492,32 +627,44 @@ void print_usage(void) { | |||
| 492 | "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n"); | 627 | "[-q <query>] [-C <critical query range>] [-W <warning query range>]\n"); |
| 493 | } | 628 | } |
| 494 | 629 | ||
| 495 | mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thresholds *qthresholds, char *query_warning, | 630 | static do_query_wrapper do_query(PGconn *conn, char *query) { |
| 496 | char *query_critical) { | ||
| 497 | if (verbose) { | 631 | if (verbose) { |
| 498 | printf("Executing SQL query \"%s\".\n", query); | 632 | printf("Executing SQL query \"%s\".\n", query); |
| 499 | } | 633 | } |
| 500 | PGresult *res = PQexec(conn, query); | 634 | PGresult *res = PQexec(conn, query); |
| 501 | 635 | ||
| 636 | do_query_wrapper result = { | ||
| 637 | .error_code = QUERY_OK, | ||
| 638 | }; | ||
| 639 | |||
| 502 | if (PGRES_TUPLES_OK != PQresultStatus(res)) { | 640 | if (PGRES_TUPLES_OK != PQresultStatus(res)) { |
| 503 | printf(_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"), PQerrorMessage(conn)); | 641 | // TODO |
| 504 | return STATE_CRITICAL; | 642 | // printf(_("QUERY %s - %s: %s.\n"), _("CRITICAL"), _("Error with query"), |
| 643 | // PQerrorMessage(conn)); | ||
| 644 | result.error_code = ERROR_WITH_QUERY; | ||
| 645 | return result; | ||
| 505 | } | 646 | } |
| 506 | 647 | ||
| 507 | if (PQntuples(res) < 1) { | 648 | if (PQntuples(res) < 1) { |
| 508 | printf("QUERY %s - %s.\n", _("WARNING"), _("No rows returned")); | 649 | // TODO |
| 509 | return STATE_WARNING; | 650 | // printf("QUERY %s - %s.\n", _("WARNING"), _("No rows returned")); |
| 651 | result.error_code = NO_ROWS_RETURNED; | ||
| 652 | return result; | ||
| 510 | } | 653 | } |
| 511 | 654 | ||
| 512 | if (PQnfields(res) < 1) { | 655 | if (PQnfields(res) < 1) { |
| 513 | printf("QUERY %s - %s.\n", _("WARNING"), _("No columns returned")); | 656 | // TODO |
| 514 | return STATE_WARNING; | 657 | // printf("QUERY %s - %s.\n", _("WARNING"), _("No columns returned")); |
| 658 | result.error_code = NO_COLUMNS_RETURNED; | ||
| 659 | return result; | ||
| 515 | } | 660 | } |
| 516 | 661 | ||
| 517 | char *val_str = PQgetvalue(res, 0, 0); | 662 | char *val_str = PQgetvalue(res, 0, 0); |
| 518 | if (!val_str) { | 663 | if (!val_str) { |
| 519 | printf("QUERY %s - %s.\n", _("CRITICAL"), _("No data returned")); | 664 | // TODO |
| 520 | return STATE_CRITICAL; | 665 | // printf("QUERY %s - %s.\n", _("CRITICAL"), _("No data returned")); |
| 666 | result.error_code = NO_DATA_RETURNED; | ||
| 667 | return result; | ||
| 521 | } | 668 | } |
| 522 | 669 | ||
| 523 | char *endptr = NULL; | 670 | char *endptr = NULL; |
| @@ -527,8 +674,10 @@ mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thre | |||
| 527 | } | 674 | } |
| 528 | 675 | ||
| 529 | if (endptr == val_str) { | 676 | if (endptr == val_str) { |
| 530 | printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str); | 677 | // TODO |
| 531 | return STATE_CRITICAL; | 678 | // printf("QUERY %s - %s: %s\n", _("CRITICAL"), _("Is not a numeric"), val_str); |
| 679 | result.error_code = RESULT_IS_NOT_NUMERIC; | ||
| 680 | return result; | ||
| 532 | } | 681 | } |
| 533 | 682 | ||
| 534 | if ((endptr != NULL) && (*endptr != '\0')) { | 683 | if ((endptr != NULL) && (*endptr != '\0')) { |
| @@ -537,23 +686,7 @@ mp_state_enum do_query(PGconn *conn, char *query, const char pgqueryname[], thre | |||
| 537 | } | 686 | } |
| 538 | } | 687 | } |
| 539 | 688 | ||
| 540 | mp_state_enum my_status = get_status(value, qthresholds); | 689 | result.numerical_result = value; |
| 541 | printf("QUERY %s - ", (my_status == STATE_OK) ? _("OK") | ||
| 542 | : (my_status == STATE_WARNING) ? _("WARNING") | ||
| 543 | : (my_status == STATE_CRITICAL) ? _("CRITICAL") | ||
| 544 | : _("UNKNOWN")); | ||
| 545 | if (pgqueryname) { | ||
| 546 | printf(_("%s returned %f"), pgqueryname, value); | ||
| 547 | } else { | ||
| 548 | printf(_("'%s' returned %f"), query, value); | ||
| 549 | } | ||
| 550 | 690 | ||
| 551 | printf("|query=%f;%s;%s;;\n", value, query_warning ? query_warning : "", query_critical ? query_critical : ""); | 691 | return result; |
| 552 | if (PQnfields(res) > 1) { | ||
| 553 | char *extra_info = PQgetvalue(res, 0, 1); | ||
| 554 | if (extra_info != NULL) { | ||
| 555 | printf("Extra Info: %s\n", extra_info); | ||
| 556 | } | ||
| 557 | } | ||
| 558 | return my_status; | ||
| 559 | } | 692 | } |
diff --git a/plugins/check_pgsql.d/config.h b/plugins/check_pgsql.d/config.h index 2d4b8b89..7cf0637b 100644 --- a/plugins/check_pgsql.d/config.h +++ b/plugins/check_pgsql.d/config.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "output.h" | ||
| 5 | #include "perfdata.h" | ||
| 4 | #include "thresholds.h" | 6 | #include "thresholds.h" |
| 5 | #include <stddef.h> | 7 | #include <stddef.h> |
| 6 | #include <pg_config_manual.h> | 8 | #include <pg_config_manual.h> |
| @@ -24,11 +26,11 @@ typedef struct { | |||
| 24 | char *pgquery; | 26 | char *pgquery; |
| 25 | char *pgqueryname; | 27 | char *pgqueryname; |
| 26 | 28 | ||
| 27 | double twarn; | 29 | mp_thresholds time_thresholds; |
| 28 | double tcrit; | 30 | mp_thresholds qthresholds; |
| 29 | thresholds *qthresholds; | 31 | |
| 30 | char *query_warning; | 32 | bool output_format_is_set; |
| 31 | char *query_critical; | 33 | mp_output_format output_format; |
| 32 | } check_pgsql_config; | 34 | } check_pgsql_config; |
| 33 | 35 | ||
| 34 | /* begin, by setting the parameters for a backend connection if the | 36 | /* begin, by setting the parameters for a backend connection if the |
| @@ -51,11 +53,18 @@ check_pgsql_config check_pgsql_config_init() { | |||
| 51 | .pgquery = NULL, | 53 | .pgquery = NULL, |
| 52 | .pgqueryname = NULL, | 54 | .pgqueryname = NULL, |
| 53 | 55 | ||
| 54 | .twarn = (double)DEFAULT_WARN, | 56 | .time_thresholds = mp_thresholds_init(), |
| 55 | .tcrit = (double)DEFAULT_CRIT, | 57 | .qthresholds = mp_thresholds_init(), |
| 56 | .qthresholds = NULL, | 58 | |
| 57 | .query_warning = NULL, | 59 | .output_format_is_set = false, |
| 58 | .query_critical = NULL, | ||
| 59 | }; | 60 | }; |
| 61 | |||
| 62 | mp_range tmp_range = mp_range_init(); | ||
| 63 | tmp_range = mp_range_set_end(tmp_range, mp_create_pd_value(DEFAULT_WARN)); | ||
| 64 | tmp.time_thresholds = mp_thresholds_set_warn(tmp.time_thresholds, tmp_range); | ||
| 65 | |||
| 66 | tmp_range = mp_range_set_end(tmp_range, mp_create_pd_value(DEFAULT_CRIT)); | ||
| 67 | tmp.time_thresholds = mp_thresholds_set_crit(tmp.time_thresholds, tmp_range); | ||
| 68 | |||
| 60 | return tmp; | 69 | return tmp; |
| 61 | } | 70 | } |
diff --git a/plugins/check_ping.c b/plugins/check_ping.c index 4aafaf41..61feb958 100644 --- a/plugins/check_ping.c +++ b/plugins/check_ping.c | |||
| @@ -36,61 +36,52 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 36 | #include "netutils.h" | 36 | #include "netutils.h" |
| 37 | #include "popen.h" | 37 | #include "popen.h" |
| 38 | #include "utils.h" | 38 | #include "utils.h" |
| 39 | #include "check_ping.d/config.h" | ||
| 40 | #include "../lib/states.h" | ||
| 39 | 41 | ||
| 40 | #include <signal.h> | 42 | #include <signal.h> |
| 41 | 43 | ||
| 42 | #define WARN_DUPLICATES "DUPLICATES FOUND! " | 44 | #define WARN_DUPLICATES "DUPLICATES FOUND! " |
| 43 | #define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ | ||
| 44 | 45 | ||
| 45 | enum { | 46 | typedef struct { |
| 46 | UNKNOWN_PACKET_LOSS = 200, /* 200% */ | 47 | int errorcode; |
| 47 | DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */ | 48 | check_ping_config config; |
| 48 | }; | 49 | } check_ping_config_wrapper; |
| 50 | static check_ping_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 51 | static check_ping_config_wrapper validate_arguments(check_ping_config_wrapper /*config_wrapper*/); | ||
| 49 | 52 | ||
| 50 | static int process_arguments(int /*argc*/, char ** /*argv*/); | 53 | static int get_threshold(char * /*arg*/, double * /*trta*/, int * /*tpl*/); |
| 51 | static int get_threshold(char * /*arg*/, float * /*trta*/, int * /*tpl*/); | 54 | |
| 52 | static int validate_arguments(void); | 55 | typedef struct { |
| 53 | static int run_ping(const char *cmd, const char *addr); | 56 | mp_state_enum state; |
| 54 | static int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr); | 57 | double round_trip_average; |
| 58 | int packet_loss; | ||
| 59 | } ping_result; | ||
| 60 | static ping_result run_ping(const char *cmd, const char *addr, double /*crta*/); | ||
| 61 | |||
| 62 | static mp_state_enum error_scan(char buf[MAX_INPUT_BUFFER], const char *addr); | ||
| 55 | static void print_help(void); | 63 | static void print_help(void); |
| 56 | void print_usage(void); | 64 | void print_usage(void); |
| 57 | 65 | ||
| 58 | static bool display_html = false; | ||
| 59 | static int wpl = UNKNOWN_PACKET_LOSS; | ||
| 60 | static int cpl = UNKNOWN_PACKET_LOSS; | ||
| 61 | static float wrta = UNKNOWN_TRIP_TIME; | ||
| 62 | static float crta = UNKNOWN_TRIP_TIME; | ||
| 63 | static char **addresses = NULL; | ||
| 64 | static int n_addresses = 0; | ||
| 65 | static int max_addr = 1; | ||
| 66 | static int max_packets = -1; | ||
| 67 | static int verbose = 0; | 66 | static int verbose = 0; |
| 68 | 67 | ||
| 69 | static float rta = UNKNOWN_TRIP_TIME; | ||
| 70 | static int pl = UNKNOWN_PACKET_LOSS; | ||
| 71 | |||
| 72 | static char *warn_text; | 68 | static char *warn_text; |
| 73 | 69 | ||
| 74 | int main(int argc, char **argv) { | 70 | int main(int argc, char **argv) { |
| 75 | char *cmd = NULL; | ||
| 76 | char *rawcmd = NULL; | ||
| 77 | int result = STATE_UNKNOWN; | ||
| 78 | int this_result = STATE_UNKNOWN; | ||
| 79 | int i; | ||
| 80 | |||
| 81 | setlocale(LC_ALL, ""); | 71 | setlocale(LC_ALL, ""); |
| 82 | setlocale(LC_NUMERIC, "C"); | 72 | setlocale(LC_NUMERIC, "C"); |
| 83 | bindtextdomain(PACKAGE, LOCALEDIR); | 73 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 84 | textdomain(PACKAGE); | 74 | textdomain(PACKAGE); |
| 85 | 75 | ||
| 86 | addresses = malloc(sizeof(char *) * max_addr); | ||
| 87 | addresses[0] = NULL; | ||
| 88 | |||
| 89 | /* Parse extra opts if any */ | 76 | /* Parse extra opts if any */ |
| 90 | argv = np_extra_opts(&argc, argv, progname); | 77 | argv = np_extra_opts(&argc, argv, progname); |
| 91 | 78 | ||
| 92 | if (process_arguments(argc, argv) == ERROR) | 79 | check_ping_config_wrapper tmp_config = process_arguments(argc, argv); |
| 80 | if (tmp_config.errorcode == ERROR) { | ||
| 93 | usage4(_("Could not parse arguments")); | 81 | usage4(_("Could not parse arguments")); |
| 82 | } | ||
| 83 | |||
| 84 | const check_ping_config config = tmp_config.config; | ||
| 94 | 85 | ||
| 95 | /* Set signal handling and alarm */ | 86 | /* Set signal handling and alarm */ |
| 96 | if (signal(SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { | 87 | if (signal(SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { |
| @@ -105,71 +96,90 @@ int main(int argc, char **argv) { | |||
| 105 | alarm(timeout_interval); | 96 | alarm(timeout_interval); |
| 106 | #endif | 97 | #endif |
| 107 | 98 | ||
| 108 | for (i = 0; i < n_addresses; i++) { | 99 | int result = STATE_UNKNOWN; |
| 109 | 100 | char *rawcmd = NULL; | |
| 101 | for (size_t i = 0; i < config.n_addresses; i++) { | ||
| 110 | #ifdef PING6_COMMAND | 102 | #ifdef PING6_COMMAND |
| 111 | if (address_family != AF_INET && is_inet6_addr(addresses[i])) | 103 | if (address_family != AF_INET && is_inet6_addr(config.addresses[i])) { |
| 112 | rawcmd = strdup(PING6_COMMAND); | 104 | rawcmd = strdup(PING6_COMMAND); |
| 113 | else | 105 | } else { |
| 114 | rawcmd = strdup(PING_COMMAND); | 106 | rawcmd = strdup(PING_COMMAND); |
| 107 | } | ||
| 115 | #else | 108 | #else |
| 116 | rawcmd = strdup(PING_COMMAND); | 109 | rawcmd = strdup(PING_COMMAND); |
| 117 | #endif | 110 | #endif |
| 118 | 111 | ||
| 119 | /* does the host address of number of packets argument come first? */ | 112 | char *cmd = NULL; |
| 113 | |||
| 114 | /* does the host address of number of packets argument come first? */ | ||
| 120 | #ifdef PING_PACKETS_FIRST | 115 | #ifdef PING_PACKETS_FIRST |
| 121 | # ifdef PING_HAS_TIMEOUT | 116 | # ifdef PING_HAS_TIMEOUT |
| 122 | xasprintf(&cmd, rawcmd, timeout_interval, max_packets, addresses[i]); | 117 | xasprintf(&cmd, rawcmd, timeout_interval, config.max_packets, config.addresses[i]); |
| 123 | # else | 118 | # else |
| 124 | xasprintf(&cmd, rawcmd, max_packets, addresses[i]); | 119 | xasprintf(&cmd, rawcmd, config.max_packets, config.addresses[i]); |
| 125 | # endif | 120 | # endif |
| 126 | #else | 121 | #else |
| 127 | xasprintf(&cmd, rawcmd, addresses[i], max_packets); | 122 | xasprintf(&cmd, rawcmd, config.addresses[i], config.max_packets); |
| 128 | #endif | 123 | #endif |
| 129 | 124 | ||
| 130 | if (verbose >= 2) | 125 | if (verbose >= 2) { |
| 131 | printf("CMD: %s\n", cmd); | 126 | printf("CMD: %s\n", cmd); |
| 127 | } | ||
| 132 | 128 | ||
| 133 | /* run the command */ | 129 | /* run the command */ |
| 134 | this_result = run_ping(cmd, addresses[i]); | ||
| 135 | 130 | ||
| 136 | if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) { | 131 | ping_result pinged = run_ping(cmd, config.addresses[i], config.crta); |
| 132 | |||
| 133 | if (pinged.packet_loss == UNKNOWN_PACKET_LOSS || pinged.round_trip_average < 0.0) { | ||
| 137 | printf("%s\n", cmd); | 134 | printf("%s\n", cmd); |
| 138 | die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n")); | 135 | die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n")); |
| 139 | } | 136 | } |
| 140 | 137 | ||
| 141 | if (pl >= cpl || rta >= crta || rta < 0) | 138 | if (pinged.packet_loss >= config.cpl || pinged.round_trip_average >= config.crta || |
| 142 | this_result = STATE_CRITICAL; | 139 | pinged.round_trip_average < 0) { |
| 143 | else if (pl >= wpl || rta >= wrta) | 140 | pinged.state = STATE_CRITICAL; |
| 144 | this_result = STATE_WARNING; | 141 | } else if (pinged.packet_loss >= config.wpl || pinged.round_trip_average >= config.wrta) { |
| 145 | else if (pl >= 0 && rta >= 0) | 142 | pinged.state = STATE_WARNING; |
| 146 | this_result = max_state(STATE_OK, this_result); | 143 | } else if (pinged.packet_loss >= 0 && pinged.round_trip_average >= 0) { |
| 147 | 144 | pinged.state = max_state(STATE_OK, pinged.state); | |
| 148 | if (n_addresses > 1 && this_result != STATE_UNKNOWN) | 145 | } |
| 149 | die(STATE_OK, "%s is alive\n", addresses[i]); | 146 | |
| 150 | 147 | if (config.n_addresses > 1 && pinged.state != STATE_UNKNOWN) { | |
| 151 | if (display_html == true) | 148 | die(STATE_OK, "%s is alive\n", config.addresses[i]); |
| 152 | printf("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, addresses[i]); | 149 | } |
| 153 | if (pl == 100) | 150 | |
| 154 | printf(_("PING %s - %sPacket loss = %d%%"), state_text(this_result), warn_text, pl); | 151 | if (config.display_html) { |
| 155 | else | 152 | printf("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, config.addresses[i]); |
| 156 | printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(this_result), warn_text, pl, rta); | 153 | } |
| 157 | if (display_html == true) | 154 | if (pinged.packet_loss == 100) { |
| 155 | printf(_("PING %s - %sPacket loss = %d%%"), state_text(pinged.state), warn_text, | ||
| 156 | pinged.packet_loss); | ||
| 157 | } else { | ||
| 158 | printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(pinged.state), | ||
| 159 | warn_text, pinged.packet_loss, pinged.round_trip_average); | ||
| 160 | } | ||
| 161 | if (config.display_html) { | ||
| 158 | printf("</A>"); | 162 | printf("</A>"); |
| 163 | } | ||
| 159 | 164 | ||
| 160 | /* Print performance data */ | 165 | /* Print performance data */ |
| 161 | if (pl != 100) { | 166 | if (pinged.packet_loss != 100) { |
| 162 | printf("|%s", | 167 | printf("|%s", |
| 163 | fperfdata("rta", (double)rta, "ms", wrta > 0 ? true : false, wrta, crta > 0 ? true : false, crta, true, 0, false, 0)); | 168 | fperfdata("rta", pinged.round_trip_average, "ms", (bool)(config.wrta > 0), |
| 169 | config.wrta, (bool)(config.crta > 0), config.crta, true, 0, false, 0)); | ||
| 164 | } else { | 170 | } else { |
| 165 | printf("| rta=U;%f;%f;;", wrta, crta); | 171 | printf("| rta=U;%f;%f;;", config.wrta, config.crta); |
| 166 | } | 172 | } |
| 167 | printf(" %s\n", perfdata("pl", (long)pl, "%", wpl > 0 ? true : false, wpl, cpl > 0 ? true : false, cpl, true, 0, false, 0)); | ||
| 168 | 173 | ||
| 169 | if (verbose >= 2) | 174 | printf(" %s\n", |
| 170 | printf("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl); | 175 | perfdata("pl", (long)pinged.packet_loss, "%", (bool)(config.wpl > 0), config.wpl, |
| 176 | (bool)(config.cpl > 0), config.cpl, true, 0, false, 0)); | ||
| 177 | |||
| 178 | if (verbose >= 2) { | ||
| 179 | printf("%f:%d%% %f:%d%%\n", config.wrta, config.wpl, config.crta, config.cpl); | ||
| 180 | } | ||
| 171 | 181 | ||
| 172 | result = max_state(result, this_result); | 182 | result = max_state(result, pinged.state); |
| 173 | free(rawcmd); | 183 | free(rawcmd); |
| 174 | free(cmd); | 184 | free(cmd); |
| 175 | } | 185 | } |
| @@ -178,11 +188,7 @@ int main(int argc, char **argv) { | |||
| 178 | } | 188 | } |
| 179 | 189 | ||
| 180 | /* process command-line arguments */ | 190 | /* process command-line arguments */ |
| 181 | int process_arguments(int argc, char **argv) { | 191 | check_ping_config_wrapper process_arguments(int argc, char **argv) { |
| 182 | int c = 1; | ||
| 183 | char *ptr; | ||
| 184 | |||
| 185 | int option = 0; | ||
| 186 | static struct option longopts[] = {STD_LONG_OPTS, | 192 | static struct option longopts[] = {STD_LONG_OPTS, |
| 187 | {"packets", required_argument, 0, 'p'}, | 193 | {"packets", required_argument, 0, 'p'}, |
| 188 | {"nohtml", no_argument, 0, 'n'}, | 194 | {"nohtml", no_argument, 0, 'n'}, |
| @@ -191,23 +197,35 @@ int process_arguments(int argc, char **argv) { | |||
| 191 | {"use-ipv6", no_argument, 0, '6'}, | 197 | {"use-ipv6", no_argument, 0, '6'}, |
| 192 | {0, 0, 0, 0}}; | 198 | {0, 0, 0, 0}}; |
| 193 | 199 | ||
| 194 | if (argc < 2) | 200 | check_ping_config_wrapper result = { |
| 195 | return ERROR; | 201 | .errorcode = OK, |
| 202 | .config = check_ping_config_init(), | ||
| 203 | }; | ||
| 204 | |||
| 205 | if (argc < 2) { | ||
| 206 | result.errorcode = ERROR; | ||
| 207 | return result; | ||
| 208 | } | ||
| 196 | 209 | ||
| 197 | for (c = 1; c < argc; c++) { | 210 | for (int index = 1; index < argc; index++) { |
| 198 | if (strcmp("-to", argv[c]) == 0) | 211 | if (strcmp("-to", argv[index]) == 0) { |
| 199 | strcpy(argv[c], "-t"); | 212 | strcpy(argv[index], "-t"); |
| 200 | if (strcmp("-nohtml", argv[c]) == 0) | 213 | } |
| 201 | strcpy(argv[c], "-n"); | 214 | if (strcmp("-nohtml", argv[index]) == 0) { |
| 215 | strcpy(argv[index], "-n"); | ||
| 216 | } | ||
| 202 | } | 217 | } |
| 203 | 218 | ||
| 204 | while (1) { | 219 | int option = 0; |
| 205 | c = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option); | 220 | size_t max_addr = MAX_ADDR_START; |
| 221 | while (true) { | ||
| 222 | int option_index = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option); | ||
| 206 | 223 | ||
| 207 | if (c == -1 || c == EOF) | 224 | if (option_index == -1 || option_index == EOF) { |
| 208 | break; | 225 | break; |
| 226 | } | ||
| 209 | 227 | ||
| 210 | switch (c) { | 228 | switch (option_index) { |
| 211 | case '?': /* usage */ | 229 | case '?': /* usage */ |
| 212 | usage5(); | 230 | usage5(); |
| 213 | case 'h': /* help */ | 231 | case 'h': /* help */ |
| @@ -234,17 +252,19 @@ int process_arguments(int argc, char **argv) { | |||
| 234 | usage(_("IPv6 support not available\n")); | 252 | usage(_("IPv6 support not available\n")); |
| 235 | #endif | 253 | #endif |
| 236 | break; | 254 | break; |
| 237 | case 'H': /* hostname */ | 255 | case 'H': /* hostname */ { |
| 238 | ptr = optarg; | 256 | char *ptr = optarg; |
| 239 | while (1) { | 257 | while (true) { |
| 240 | n_addresses++; | 258 | result.config.n_addresses++; |
| 241 | if (n_addresses > max_addr) { | 259 | if (result.config.n_addresses > max_addr) { |
| 242 | max_addr *= 2; | 260 | max_addr *= 2; |
| 243 | addresses = realloc(addresses, sizeof(char *) * max_addr); | 261 | result.config.addresses = |
| 244 | if (addresses == NULL) | 262 | realloc(result.config.addresses, sizeof(char *) * max_addr); |
| 263 | if (result.config.addresses == NULL) { | ||
| 245 | die(STATE_UNKNOWN, _("Could not realloc() addresses\n")); | 264 | die(STATE_UNKNOWN, _("Could not realloc() addresses\n")); |
| 265 | } | ||
| 246 | } | 266 | } |
| 247 | addresses[n_addresses - 1] = ptr; | 267 | result.config.addresses[result.config.n_addresses - 1] = ptr; |
| 248 | if ((ptr = index(ptr, ','))) { | 268 | if ((ptr = index(ptr, ','))) { |
| 249 | strcpy(ptr, ""); | 269 | strcpy(ptr, ""); |
| 250 | ptr += sizeof(char); | 270 | ptr += sizeof(char); |
| @@ -252,219 +272,302 @@ int process_arguments(int argc, char **argv) { | |||
| 252 | break; | 272 | break; |
| 253 | } | 273 | } |
| 254 | } | 274 | } |
| 255 | break; | 275 | } break; |
| 256 | case 'p': /* number of packets to send */ | 276 | case 'p': /* number of packets to send */ |
| 257 | if (is_intnonneg(optarg)) | 277 | if (is_intnonneg(optarg)) { |
| 258 | max_packets = atoi(optarg); | 278 | result.config.max_packets = atoi(optarg); |
| 259 | else | 279 | } else { |
| 260 | usage2(_("<max_packets> (%s) must be a non-negative number\n"), optarg); | 280 | usage2(_("<max_packets> (%s) must be a non-negative number\n"), optarg); |
| 281 | } | ||
| 261 | break; | 282 | break; |
| 262 | case 'n': /* no HTML */ | 283 | case 'n': /* no HTML */ |
| 263 | display_html = false; | 284 | result.config.display_html = false; |
| 264 | break; | 285 | break; |
| 265 | case 'L': /* show HTML */ | 286 | case 'L': /* show HTML */ |
| 266 | display_html = true; | 287 | result.config.display_html = true; |
| 267 | break; | 288 | break; |
| 268 | case 'c': | 289 | case 'c': |
| 269 | get_threshold(optarg, &crta, &cpl); | 290 | get_threshold(optarg, &result.config.crta, &result.config.cpl); |
| 270 | break; | 291 | break; |
| 271 | case 'w': | 292 | case 'w': |
| 272 | get_threshold(optarg, &wrta, &wpl); | 293 | get_threshold(optarg, &result.config.wrta, &result.config.wpl); |
| 273 | break; | 294 | break; |
| 274 | } | 295 | } |
| 275 | } | 296 | } |
| 276 | 297 | ||
| 277 | c = optind; | 298 | int arg_counter = optind; |
| 278 | if (c == argc) | 299 | if (arg_counter == argc) { |
| 279 | return validate_arguments(); | 300 | return validate_arguments(result); |
| 301 | } | ||
| 280 | 302 | ||
| 281 | if (addresses[0] == NULL) { | 303 | if (result.config.addresses[0] == NULL) { |
| 282 | if (!is_host(argv[c])) { | 304 | if (!is_host(argv[arg_counter])) { |
| 283 | usage2(_("Invalid hostname/address"), argv[c]); | 305 | usage2(_("Invalid hostname/address"), argv[arg_counter]); |
| 284 | } else { | 306 | } else { |
| 285 | addresses[0] = argv[c++]; | 307 | result.config.addresses[0] = argv[arg_counter++]; |
| 286 | n_addresses++; | 308 | result.config.n_addresses++; |
| 287 | if (c == argc) | 309 | if (arg_counter == argc) { |
| 288 | return validate_arguments(); | 310 | return validate_arguments(result); |
| 311 | } | ||
| 289 | } | 312 | } |
| 290 | } | 313 | } |
| 291 | 314 | ||
| 292 | if (wpl == UNKNOWN_PACKET_LOSS) { | 315 | if (result.config.wpl == UNKNOWN_PACKET_LOSS) { |
| 293 | if (!is_intpercent(argv[c])) { | 316 | if (!is_intpercent(argv[arg_counter])) { |
| 294 | printf(_("<wpl> (%s) must be an integer percentage\n"), argv[c]); | 317 | printf(_("<wpl> (%s) must be an integer percentage\n"), argv[arg_counter]); |
| 295 | return ERROR; | 318 | result.errorcode = ERROR; |
| 296 | } else { | 319 | return result; |
| 297 | wpl = atoi(argv[c++]); | 320 | } |
| 298 | if (c == argc) | 321 | result.config.wpl = atoi(argv[arg_counter++]); |
| 299 | return validate_arguments(); | 322 | if (arg_counter == argc) { |
| 323 | return validate_arguments(result); | ||
| 300 | } | 324 | } |
| 301 | } | 325 | } |
| 302 | 326 | ||
| 303 | if (cpl == UNKNOWN_PACKET_LOSS) { | 327 | if (result.config.cpl == UNKNOWN_PACKET_LOSS) { |
| 304 | if (!is_intpercent(argv[c])) { | 328 | if (!is_intpercent(argv[arg_counter])) { |
| 305 | printf(_("<cpl> (%s) must be an integer percentage\n"), argv[c]); | 329 | printf(_("<cpl> (%s) must be an integer percentage\n"), argv[arg_counter]); |
| 306 | return ERROR; | 330 | result.errorcode = ERROR; |
| 307 | } else { | 331 | return result; |
| 308 | cpl = atoi(argv[c++]); | 332 | } |
| 309 | if (c == argc) | 333 | result.config.cpl = atoi(argv[arg_counter++]); |
| 310 | return validate_arguments(); | 334 | if (arg_counter == argc) { |
| 335 | return validate_arguments(result); | ||
| 311 | } | 336 | } |
| 312 | } | 337 | } |
| 313 | 338 | ||
| 314 | if (wrta < 0.0) { | 339 | if (result.config.wrta < 0.0) { |
| 315 | if (is_negative(argv[c])) { | 340 | if (is_negative(argv[arg_counter])) { |
| 316 | printf(_("<wrta> (%s) must be a non-negative number\n"), argv[c]); | 341 | printf(_("<wrta> (%s) must be a non-negative number\n"), argv[arg_counter]); |
| 317 | return ERROR; | 342 | result.errorcode = ERROR; |
| 318 | } else { | 343 | return result; |
| 319 | wrta = atof(argv[c++]); | 344 | } |
| 320 | if (c == argc) | 345 | result.config.wrta = atof(argv[arg_counter++]); |
| 321 | return validate_arguments(); | 346 | if (arg_counter == argc) { |
| 347 | return validate_arguments(result); | ||
| 322 | } | 348 | } |
| 323 | } | 349 | } |
| 324 | 350 | ||
| 325 | if (crta < 0.0) { | 351 | if (result.config.crta < 0.0) { |
| 326 | if (is_negative(argv[c])) { | 352 | if (is_negative(argv[arg_counter])) { |
| 327 | printf(_("<crta> (%s) must be a non-negative number\n"), argv[c]); | 353 | printf(_("<crta> (%s) must be a non-negative number\n"), argv[arg_counter]); |
| 328 | return ERROR; | 354 | result.errorcode = ERROR; |
| 329 | } else { | 355 | return result; |
| 330 | crta = atof(argv[c++]); | 356 | } |
| 331 | if (c == argc) | 357 | result.config.crta = atof(argv[arg_counter++]); |
| 332 | return validate_arguments(); | 358 | if (arg_counter == argc) { |
| 359 | return validate_arguments(result); | ||
| 333 | } | 360 | } |
| 334 | } | 361 | } |
| 335 | 362 | ||
| 336 | if (max_packets == -1) { | 363 | if (result.config.max_packets == -1) { |
| 337 | if (is_intnonneg(argv[c])) { | 364 | if (is_intnonneg(argv[arg_counter])) { |
| 338 | max_packets = atoi(argv[c++]); | 365 | result.config.max_packets = atoi(argv[arg_counter++]); |
| 339 | } else { | 366 | } else { |
| 340 | printf(_("<max_packets> (%s) must be a non-negative number\n"), argv[c]); | 367 | printf(_("<max_packets> (%s) must be a non-negative number\n"), argv[arg_counter]); |
| 341 | return ERROR; | 368 | result.errorcode = ERROR; |
| 369 | return result; | ||
| 342 | } | 370 | } |
| 343 | } | 371 | } |
| 344 | 372 | ||
| 345 | return validate_arguments(); | 373 | return validate_arguments(result); |
| 346 | } | 374 | } |
| 347 | 375 | ||
| 348 | int get_threshold(char *arg, float *trta, int *tpl) { | 376 | int get_threshold(char *arg, double *trta, int *tpl) { |
| 349 | if (is_intnonneg(arg) && sscanf(arg, "%f", trta) == 1) | 377 | if (is_intnonneg(arg) && sscanf(arg, "%lf", trta) == 1) { |
| 350 | return OK; | 378 | return OK; |
| 351 | else if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%f%*[:,]%d%%", trta, tpl) == 2) | 379 | } |
| 380 | |||
| 381 | if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%lf%*[:,]%d%%", trta, tpl) == 2) { | ||
| 352 | return OK; | 382 | return OK; |
| 353 | else if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1) | 383 | } |
| 384 | |||
| 385 | if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1) { | ||
| 354 | return OK; | 386 | return OK; |
| 387 | } | ||
| 355 | 388 | ||
| 356 | usage2(_("%s: Warning threshold must be integer or percentage!\n\n"), arg); | 389 | usage2(_("%s: Warning threshold must be integer or percentage!\n\n"), arg); |
| 357 | return STATE_UNKNOWN; | 390 | return STATE_UNKNOWN; |
| 358 | } | 391 | } |
| 359 | 392 | ||
| 360 | int validate_arguments() { | 393 | check_ping_config_wrapper validate_arguments(check_ping_config_wrapper config_wrapper) { |
| 361 | float max_seconds; | 394 | if (config_wrapper.config.wrta < 0.0) { |
| 362 | int i; | ||
| 363 | |||
| 364 | if (wrta < 0.0) { | ||
| 365 | printf(_("<wrta> was not set\n")); | 395 | printf(_("<wrta> was not set\n")); |
| 366 | return ERROR; | 396 | config_wrapper.errorcode = ERROR; |
| 367 | } else if (crta < 0.0) { | 397 | return config_wrapper; |
| 398 | } | ||
| 399 | |||
| 400 | if (config_wrapper.config.crta < 0.0) { | ||
| 368 | printf(_("<crta> was not set\n")); | 401 | printf(_("<crta> was not set\n")); |
| 369 | return ERROR; | 402 | config_wrapper.errorcode = ERROR; |
| 370 | } else if (wpl == UNKNOWN_PACKET_LOSS) { | 403 | return config_wrapper; |
| 404 | } | ||
| 405 | |||
| 406 | if (config_wrapper.config.wpl == UNKNOWN_PACKET_LOSS) { | ||
| 371 | printf(_("<wpl> was not set\n")); | 407 | printf(_("<wpl> was not set\n")); |
| 372 | return ERROR; | 408 | config_wrapper.errorcode = ERROR; |
| 373 | } else if (cpl == UNKNOWN_PACKET_LOSS) { | 409 | return config_wrapper; |
| 410 | } | ||
| 411 | |||
| 412 | if (config_wrapper.config.cpl == UNKNOWN_PACKET_LOSS) { | ||
| 374 | printf(_("<cpl> was not set\n")); | 413 | printf(_("<cpl> was not set\n")); |
| 375 | return ERROR; | 414 | config_wrapper.errorcode = ERROR; |
| 376 | } else if (wrta > crta) { | 415 | return config_wrapper; |
| 377 | printf(_("<wrta> (%f) cannot be larger than <crta> (%f)\n"), wrta, crta); | 416 | } |
| 378 | return ERROR; | 417 | |
| 379 | } else if (wpl > cpl) { | 418 | if (config_wrapper.config.wrta > config_wrapper.config.crta) { |
| 380 | printf(_("<wpl> (%d) cannot be larger than <cpl> (%d)\n"), wpl, cpl); | 419 | printf(_("<wrta> (%f) cannot be larger than <crta> (%f)\n"), config_wrapper.config.wrta, |
| 381 | return ERROR; | 420 | config_wrapper.config.crta); |
| 421 | config_wrapper.errorcode = ERROR; | ||
| 422 | return config_wrapper; | ||
| 382 | } | 423 | } |
| 383 | 424 | ||
| 384 | if (max_packets == -1) | 425 | if (config_wrapper.config.wpl > config_wrapper.config.cpl) { |
| 385 | max_packets = DEFAULT_MAX_PACKETS; | 426 | printf(_("<wpl> (%d) cannot be larger than <cpl> (%d)\n"), config_wrapper.config.wpl, |
| 427 | config_wrapper.config.cpl); | ||
| 428 | config_wrapper.errorcode = ERROR; | ||
| 429 | return config_wrapper; | ||
| 430 | } | ||
| 386 | 431 | ||
| 387 | max_seconds = crta / 1000.0 * max_packets + max_packets; | 432 | if (config_wrapper.config.max_packets == -1) { |
| 388 | if (max_seconds > timeout_interval) | 433 | config_wrapper.config.max_packets = DEFAULT_MAX_PACKETS; |
| 389 | timeout_interval = (int)max_seconds; | 434 | } |
| 390 | 435 | ||
| 391 | for (i = 0; i < n_addresses; i++) { | 436 | double max_seconds = (config_wrapper.config.crta / 1000.0 * config_wrapper.config.max_packets) + |
| 392 | if (!is_host(addresses[i])) | 437 | config_wrapper.config.max_packets; |
| 393 | usage2(_("Invalid hostname/address"), addresses[i]); | 438 | if (max_seconds > timeout_interval) { |
| 439 | timeout_interval = (unsigned int)max_seconds; | ||
| 440 | } | ||
| 441 | |||
| 442 | for (size_t i = 0; i < config_wrapper.config.n_addresses; i++) { | ||
| 443 | if (!is_host(config_wrapper.config.addresses[i])) { | ||
| 444 | usage2(_("Invalid hostname/address"), config_wrapper.config.addresses[i]); | ||
| 445 | } | ||
| 394 | } | 446 | } |
| 395 | 447 | ||
| 396 | if (n_addresses == 0) { | 448 | if (config_wrapper.config.n_addresses == 0) { |
| 397 | usage(_("You must specify a server address or host name")); | 449 | usage(_("You must specify a server address or host name")); |
| 398 | } | 450 | } |
| 399 | 451 | ||
| 400 | return OK; | 452 | return config_wrapper; |
| 401 | } | 453 | } |
| 402 | 454 | ||
| 403 | int run_ping(const char *cmd, const char *addr) { | 455 | ping_result run_ping(const char *cmd, const char *addr, double crta) { |
| 404 | char buf[MAX_INPUT_BUFFER]; | 456 | if ((child_process = spopen(cmd)) == NULL) { |
| 405 | int result = STATE_UNKNOWN; | ||
| 406 | int match; | ||
| 407 | |||
| 408 | if ((child_process = spopen(cmd)) == NULL) | ||
| 409 | die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd); | 457 | die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd); |
| 458 | } | ||
| 410 | 459 | ||
| 411 | child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); | 460 | child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); |
| 412 | if (child_stderr == NULL) | 461 | if (child_stderr == NULL) { |
| 413 | printf(_("Cannot open stderr for %s\n"), cmd); | 462 | printf(_("Cannot open stderr for %s\n"), cmd); |
| 463 | } | ||
| 414 | 464 | ||
| 415 | while (fgets(buf, MAX_INPUT_BUFFER - 1, child_process)) { | 465 | char buf[MAX_INPUT_BUFFER]; |
| 466 | ping_result result = { | ||
| 467 | .state = STATE_UNKNOWN, | ||
| 468 | .packet_loss = UNKNOWN_PACKET_LOSS, | ||
| 469 | .round_trip_average = UNKNOWN_TRIP_TIME, | ||
| 470 | }; | ||
| 416 | 471 | ||
| 417 | if (verbose >= 3) | 472 | while (fgets(buf, MAX_INPUT_BUFFER - 1, child_process)) { |
| 473 | if (verbose >= 3) { | ||
| 418 | printf("Output: %s", buf); | 474 | printf("Output: %s", buf); |
| 475 | } | ||
| 419 | 476 | ||
| 420 | result = max_state(result, error_scan(buf, addr)); | 477 | result.state = max_state(result.state, error_scan(buf, addr)); |
| 421 | 478 | ||
| 422 | /* get the percent loss statistics */ | 479 | /* get the percent loss statistics */ |
| 423 | match = 0; | 480 | int match = 0; |
| 424 | if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) || | 481 | if ((sscanf( |
| 425 | (sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) || | 482 | buf, |
| 426 | (sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) || | 483 | "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", |
| 427 | (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &pl, &match) && match) || | 484 | &result.packet_loss, &match) == 1 && |
| 428 | (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &pl, &match) && match) || | 485 | match) || |
| 429 | (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &pl, &match) && match) || | 486 | (sscanf(buf, |
| 430 | (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &pl, &match) && match) || | 487 | "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet " |
| 431 | (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) || | 488 | "loss%n", |
| 432 | (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) || | 489 | &result.packet_loss, &match) == 1 && |
| 433 | (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &pl, &match) && match)) | 490 | match) || |
| 491 | (sscanf(buf, | ||
| 492 | "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", | ||
| 493 | &result.packet_loss, &match) == 1 && | ||
| 494 | match) || | ||
| 495 | (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", | ||
| 496 | &result.packet_loss, &match) == 1 && | ||
| 497 | match) || | ||
| 498 | (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", | ||
| 499 | &result.packet_loss, &match) == 1 && | ||
| 500 | match) || | ||
| 501 | (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", | ||
| 502 | &result.packet_loss, &match) == 1 && | ||
| 503 | match) || | ||
| 504 | (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", | ||
| 505 | &result.packet_loss, &match) == 1 && | ||
| 506 | match) == 1 || | ||
| 507 | (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", | ||
| 508 | &result.packet_loss, &match) == 1 && | ||
| 509 | match) || | ||
| 510 | (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", | ||
| 511 | &result.packet_loss, &match) == 1 && | ||
| 512 | match) || | ||
| 513 | (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &result.packet_loss, &match) == 1 && match)) { | ||
| 434 | continue; | 514 | continue; |
| 515 | } | ||
| 435 | 516 | ||
| 436 | /* get the round trip average */ | 517 | /* get the round trip average */ |
| 437 | else if ((sscanf(buf, "round-trip min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) || | 518 | if ((sscanf(buf, "round-trip min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, |
| 438 | (sscanf(buf, "round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || | 519 | &match) == 1 && |
| 439 | (sscanf(buf, "round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || | 520 | match) || |
| 440 | (sscanf(buf, "round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || | 521 | (sscanf(buf, "round-trip min/avg/max/mdev = %*f/%lf/%*f/%*f%n", |
| 441 | (sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || | 522 | &result.round_trip_average, &match) == 1 && |
| 442 | (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) || | 523 | match) || |
| 443 | (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) || | 524 | (sscanf(buf, "round-trip min/avg/max/sdev = %*f/%lf/%*f/%*f%n", |
| 444 | (sscanf(buf, "rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n", &rta, &match) && match) || | 525 | &result.round_trip_average, &match) == 1 && |
| 445 | (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &rta, &match) && match)) | 526 | match) || |
| 527 | (sscanf(buf, "round-trip min/avg/max/stddev = %*f/%lf/%*f/%*f%n", | ||
| 528 | &result.round_trip_average, &match) == 1 && | ||
| 529 | match) || | ||
| 530 | (sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%lf/%*f/%*f%n", | ||
| 531 | &result.round_trip_average, &match) == 1 && | ||
| 532 | match) || | ||
| 533 | (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%lf/%*f%n", &result.round_trip_average, | ||
| 534 | &match) == 1 && | ||
| 535 | match) || | ||
| 536 | (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%lf/%*f/%*f%n", | ||
| 537 | &result.round_trip_average, &match) == 1 && | ||
| 538 | match) || | ||
| 539 | (sscanf(buf, "rtt min/avg/max/mdev = %*f/%lf/%*f/%*f ms%n", &result.round_trip_average, | ||
| 540 | &match) == 1 && | ||
| 541 | match) || | ||
| 542 | (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %lfms%n", | ||
| 543 | &result.round_trip_average, &match) == 1 && | ||
| 544 | match)) { | ||
| 446 | continue; | 545 | continue; |
| 546 | } | ||
| 447 | } | 547 | } |
| 448 | 548 | ||
| 449 | /* this is needed because there is no rta if all packets are lost */ | 549 | /* this is needed because there is no rta if all packets are lost */ |
| 450 | if (pl == 100) | 550 | if (result.packet_loss == 100) { |
| 451 | rta = crta; | 551 | result.round_trip_average = crta; |
| 552 | } | ||
| 452 | 553 | ||
| 453 | /* check stderr, setting at least WARNING if there is output here */ | 554 | /* check stderr, setting at least WARNING if there is output here */ |
| 454 | /* Add warning into warn_text */ | 555 | /* Add warning into warn_text */ |
| 455 | while (fgets(buf, MAX_INPUT_BUFFER - 1, child_stderr)) { | 556 | while (fgets(buf, MAX_INPUT_BUFFER - 1, child_stderr)) { |
| 456 | if (!strstr(buf, "WARNING - no SO_TIMESTAMP support, falling back to SIOCGSTAMP") && !strstr(buf, "Warning: time of day goes back") | 557 | if (!strstr(buf, "WARNING - no SO_TIMESTAMP support, falling back to SIOCGSTAMP") && |
| 558 | !strstr(buf, "Warning: time of day goes back") | ||
| 457 | 559 | ||
| 458 | ) { | 560 | ) { |
| 459 | if (verbose >= 3) { | 561 | if (verbose >= 3) { |
| 460 | printf("Got stderr: %s", buf); | 562 | printf("Got stderr: %s", buf); |
| 461 | } | 563 | } |
| 462 | if ((result = error_scan(buf, addr)) == STATE_OK) { | 564 | if ((result.state = error_scan(buf, addr)) == STATE_OK) { |
| 463 | result = STATE_WARNING; | 565 | result.state = STATE_WARNING; |
| 464 | if (warn_text == NULL) { | 566 | if (warn_text == NULL) { |
| 465 | warn_text = strdup(_("System call sent warnings to stderr ")); | 567 | warn_text = strdup(_("System call sent warnings to stderr ")); |
| 466 | } else { | 568 | } else { |
| 467 | xasprintf(&warn_text, "%s %s", warn_text, _("System call sent warnings to stderr ")); | 569 | xasprintf(&warn_text, "%s %s", warn_text, |
| 570 | _("System call sent warnings to stderr ")); | ||
| 468 | } | 571 | } |
| 469 | } | 572 | } |
| 470 | } | 573 | } |
| @@ -474,43 +577,48 @@ int run_ping(const char *cmd, const char *addr) { | |||
| 474 | 577 | ||
| 475 | spclose(child_process); | 578 | spclose(child_process); |
| 476 | 579 | ||
| 477 | if (warn_text == NULL) | 580 | if (warn_text == NULL) { |
| 478 | warn_text = strdup(""); | 581 | warn_text = strdup(""); |
| 582 | } | ||
| 479 | 583 | ||
| 480 | return result; | 584 | return result; |
| 481 | } | 585 | } |
| 482 | 586 | ||
| 483 | int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) { | 587 | mp_state_enum error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) { |
| 484 | if (strstr(buf, "Network is unreachable") || strstr(buf, "Destination Net Unreachable") || strstr(buf, "No route")) | 588 | if (strstr(buf, "Network is unreachable") || strstr(buf, "Destination Net Unreachable") || |
| 589 | strstr(buf, "No route")) { | ||
| 485 | die(STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr); | 590 | die(STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr); |
| 486 | else if (strstr(buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable")) | 591 | } else if (strstr(buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable")) { |
| 487 | die(STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr); | 592 | die(STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr); |
| 488 | else if (strstr(buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable")) | 593 | } else if (strstr(buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable")) { |
| 489 | die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr); | 594 | die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr); |
| 490 | else if (strstr(buf, "Destination Protocol Unreachable")) | 595 | } else if (strstr(buf, "Destination Protocol Unreachable")) { |
| 491 | die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr); | 596 | die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr); |
| 492 | else if (strstr(buf, "Destination Net Prohibited")) | 597 | } else if (strstr(buf, "Destination Net Prohibited")) { |
| 493 | die(STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr); | 598 | die(STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr); |
| 494 | else if (strstr(buf, "Destination Host Prohibited")) | 599 | } else if (strstr(buf, "Destination Host Prohibited")) { |
| 495 | die(STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr); | 600 | die(STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr); |
| 496 | else if (strstr(buf, "Packet filtered") || strstr(buf, "Administratively prohibited")) | 601 | } else if (strstr(buf, "Packet filtered") || strstr(buf, "Administratively prohibited")) { |
| 497 | die(STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr); | 602 | die(STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr); |
| 498 | else if (strstr(buf, "unknown host")) | 603 | } else if (strstr(buf, "unknown host")) { |
| 499 | die(STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr); | 604 | die(STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr); |
| 500 | else if (strstr(buf, "Time to live exceeded") || strstr(buf, "Time exceeded")) | 605 | } else if (strstr(buf, "Time to live exceeded") || strstr(buf, "Time exceeded")) { |
| 501 | die(STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr); | 606 | die(STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr); |
| 502 | else if (strstr(buf, "Destination unreachable: ")) | 607 | } else if (strstr(buf, "Destination unreachable: ")) { |
| 503 | die(STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr); | 608 | die(STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr); |
| 609 | } | ||
| 504 | 610 | ||
| 505 | if (strstr(buf, "(DUP!)") || strstr(buf, "DUPLICATES FOUND")) { | 611 | if (strstr(buf, "(DUP!)") || strstr(buf, "DUPLICATES FOUND")) { |
| 506 | if (warn_text == NULL) | 612 | if (warn_text == NULL) { |
| 507 | warn_text = strdup(_(WARN_DUPLICATES)); | 613 | warn_text = strdup(_(WARN_DUPLICATES)); |
| 508 | else if (!strstr(warn_text, _(WARN_DUPLICATES)) && xasprintf(&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1) | 614 | } else if (!strstr(warn_text, _(WARN_DUPLICATES)) && |
| 615 | xasprintf(&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1) { | ||
| 509 | die(STATE_UNKNOWN, _("Unable to realloc warn_text\n")); | 616 | die(STATE_UNKNOWN, _("Unable to realloc warn_text\n")); |
| 510 | return (STATE_WARNING); | 617 | } |
| 618 | return STATE_WARNING; | ||
| 511 | } | 619 | } |
| 512 | 620 | ||
| 513 | return (STATE_OK); | 621 | return STATE_OK; |
| 514 | } | 622 | } |
| 515 | 623 | ||
| 516 | void print_help(void) { | 624 | void print_help(void) { |
| @@ -550,10 +658,10 @@ void print_help(void) { | |||
| 550 | printf("%s\n", _("percentage of packet loss to trigger an alarm state.")); | 658 | printf("%s\n", _("percentage of packet loss to trigger an alarm state.")); |
| 551 | 659 | ||
| 552 | printf("\n"); | 660 | printf("\n"); |
| 553 | printf("%s\n", _("This plugin uses the ping command to probe the specified host for packet loss")); | 661 | printf("%s\n", |
| 554 | printf("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output")); | 662 | _("This plugin uses the ping command to probe the specified host for packet loss")); |
| 555 | printf("%s\n", _("linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in")); | 663 | printf("%s\n", |
| 556 | printf("%s\n", _("the contrib area of the downloads section at http://www.nagios.org/")); | 664 | _("(percentage) and round trip average (milliseconds). It can produce HTML output.")); |
| 557 | 665 | ||
| 558 | printf(UT_SUPPORT); | 666 | printf(UT_SUPPORT); |
| 559 | } | 667 | } |
diff --git a/plugins/check_ping.d/config.h b/plugins/check_ping.d/config.h new file mode 100644 index 00000000..eb2735a7 --- /dev/null +++ b/plugins/check_ping.d/config.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include <stddef.h> | ||
| 5 | #include <stdlib.h> | ||
| 6 | |||
| 7 | enum { | ||
| 8 | UNKNOWN_PACKET_LOSS = 200, /* 200% */ | ||
| 9 | DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */ | ||
| 10 | }; | ||
| 11 | |||
| 12 | #define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ | ||
| 13 | |||
| 14 | #define MAX_ADDR_START 1 | ||
| 15 | |||
| 16 | typedef struct { | ||
| 17 | bool display_html; | ||
| 18 | int max_packets; | ||
| 19 | |||
| 20 | char **addresses; | ||
| 21 | size_t n_addresses; | ||
| 22 | |||
| 23 | int wpl; | ||
| 24 | int cpl; | ||
| 25 | double wrta; | ||
| 26 | double crta; | ||
| 27 | } check_ping_config; | ||
| 28 | |||
| 29 | check_ping_config check_ping_config_init() { | ||
| 30 | check_ping_config tmp = { | ||
| 31 | .display_html = false, | ||
| 32 | .max_packets = -1, | ||
| 33 | |||
| 34 | .addresses = NULL, | ||
| 35 | .n_addresses = 0, | ||
| 36 | |||
| 37 | .wpl = UNKNOWN_PACKET_LOSS, | ||
| 38 | .cpl = UNKNOWN_PACKET_LOSS, | ||
| 39 | .wrta = UNKNOWN_TRIP_TIME, | ||
| 40 | .crta = UNKNOWN_TRIP_TIME, | ||
| 41 | }; | ||
| 42 | |||
| 43 | tmp.addresses = calloc(MAX_ADDR_START, sizeof(char *)); | ||
| 44 | tmp.addresses[0] = NULL; | ||
| 45 | return tmp; | ||
| 46 | } | ||
diff --git a/plugins/check_procs.c b/plugins/check_procs.c index 1d78ccee..ae6e9c23 100644 --- a/plugins/check_procs.c +++ b/plugins/check_procs.c | |||
| @@ -1,41 +1,41 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Monitoring check_procs plugin | 3 | * Monitoring check_procs plugin |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 2000-2024 Monitoring Plugins Development Team | 6 | * Copyright (c) 2000-2024 Monitoring Plugins Development Team |
| 7 | * | 7 | * |
| 8 | * Description: | 8 | * Description: |
| 9 | * | 9 | * |
| 10 | * This file contains the check_procs plugin | 10 | * This file contains the check_procs plugin |
| 11 | * | 11 | * |
| 12 | * Checks all processes and generates WARNING or CRITICAL states if the | 12 | * Checks all processes and generates WARNING or CRITICAL states if the |
| 13 | * specified metric is outside the required threshold ranges. The metric | 13 | * specified metric is outside the required threshold ranges. The metric |
| 14 | * defaults to number of processes. Search filters can be applied to limit | 14 | * defaults to number of processes. Search filters can be applied to limit |
| 15 | * the processes to check. | 15 | * the processes to check. |
| 16 | * | 16 | * |
| 17 | * The parent process, check_procs itself and any child process of | 17 | * The parent process, check_procs itself and any child process of |
| 18 | * check_procs (ps) are excluded from any checks to prevent false positives. | 18 | * check_procs (ps) are excluded from any checks to prevent false positives. |
| 19 | * | 19 | * |
| 20 | * | 20 | * |
| 21 | * This program is free software: you can redistribute it and/or modify | 21 | * This program is free software: you can redistribute it and/or modify |
| 22 | * it under the terms of the GNU General Public License as published by | 22 | * it under the terms of the GNU General Public License as published by |
| 23 | * the Free Software Foundation, either version 3 of the License, or | 23 | * the Free Software Foundation, either version 3 of the License, or |
| 24 | * (at your option) any later version. | 24 | * (at your option) any later version. |
| 25 | * | 25 | * |
| 26 | * This program is distributed in the hope that it will be useful, | 26 | * This program is distributed in the hope that it will be useful, |
| 27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 29 | * GNU General Public License for more details. | 29 | * GNU General Public License for more details. |
| 30 | * | 30 | * |
| 31 | * You should have received a copy of the GNU General Public License | 31 | * You should have received a copy of the GNU General Public License |
| 32 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 32 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 33 | * | 33 | * |
| 34 | * | 34 | * |
| 35 | *****************************************************************************/ | 35 | *****************************************************************************/ |
| 36 | 36 | ||
| 37 | const char *progname = "check_procs"; | 37 | const char *progname = "check_procs"; |
| 38 | const char *program_name = "check_procs"; /* Required for coreutils libs */ | 38 | const char *program_name = "check_procs"; /* Required for coreutils libs */ |
| 39 | const char *copyright = "2000-2024"; | 39 | const char *copyright = "2000-2024"; |
| 40 | const char *email = "devel@monitoring-plugins.org"; | 40 | const char *email = "devel@monitoring-plugins.org"; |
| 41 | 41 | ||
| @@ -43,313 +43,297 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 43 | #include "utils.h" | 43 | #include "utils.h" |
| 44 | #include "utils_cmd.h" | 44 | #include "utils_cmd.h" |
| 45 | #include "regex.h" | 45 | #include "regex.h" |
| 46 | #include "states.h" | ||
| 47 | #include "check_procs.d/config.h" | ||
| 46 | 48 | ||
| 47 | #include <pwd.h> | 49 | #include <pwd.h> |
| 48 | #include <errno.h> | 50 | #include <errno.h> |
| 49 | 51 | ||
| 50 | #ifdef HAVE_SYS_STAT_H | 52 | #ifdef HAVE_SYS_STAT_H |
| 51 | #include <sys/stat.h> | 53 | # include <sys/stat.h> |
| 52 | #endif | 54 | #endif |
| 53 | 55 | ||
| 54 | static int process_arguments (int /*argc*/, char ** /*argv*/); | 56 | typedef struct { |
| 55 | static int validate_arguments (void); | 57 | int errorcode; |
| 56 | static int convert_to_seconds (char * /*etime*/); | 58 | check_procs_config config; |
| 57 | static void print_help (void); | 59 | } check_procs_config_wrapper; |
| 58 | void print_usage (void); | 60 | static check_procs_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 59 | 61 | static check_procs_config_wrapper validate_arguments(check_procs_config_wrapper /*config_wrapper*/); | |
| 60 | static char *warning_range = NULL; | 62 | |
| 61 | static char *critical_range = NULL; | 63 | static int convert_to_seconds(char * /*etime*/, enum metric /*metric*/); |
| 62 | static thresholds *procs_thresholds = NULL; | 64 | static void print_help(void); |
| 63 | 65 | void print_usage(void); | |
| 64 | static int options = 0; /* bitmask of filter criteria to test against */ | 66 | |
| 65 | #define ALL 1 | 67 | #define ALL 1 |
| 66 | #define STAT 2 | 68 | #define STAT 2 |
| 67 | #define PPID 4 | 69 | #define PPID 4 |
| 68 | #define USER 8 | 70 | #define USER 8 |
| 69 | #define PROG 16 | 71 | #define PROG 16 |
| 70 | #define ARGS 32 | 72 | #define ARGS 32 |
| 71 | #define VSZ 64 | 73 | #define VSZ 64 |
| 72 | #define RSS 128 | 74 | #define RSS 128 |
| 73 | #define PCPU 256 | 75 | #define PCPU 256 |
| 74 | #define ELAPSED 512 | 76 | #define ELAPSED 512 |
| 75 | #define EREG_ARGS 1024 | 77 | #define EREG_ARGS 1024 |
| 76 | #define EXCLUDE_PROGS 2048 | 78 | #define EXCLUDE_PROGS 2048 |
| 77 | 79 | ||
| 78 | #define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads: | 80 | #define KTHREAD_PARENT \ |
| 79 | ppid of procs are compared to pid of this proc*/ | 81 | "kthreadd" /* the parent process of kernel threads: \ |
| 80 | 82 | ppid of procs are compared to pid of this proc*/ | |
| 81 | /* Different metrics */ | ||
| 82 | char *metric_name; | ||
| 83 | enum metric { | ||
| 84 | METRIC_PROCS, | ||
| 85 | METRIC_VSZ, | ||
| 86 | METRIC_RSS, | ||
| 87 | METRIC_CPU, | ||
| 88 | METRIC_ELAPSED | ||
| 89 | }; | ||
| 90 | enum metric metric = METRIC_PROCS; | ||
| 91 | 83 | ||
| 92 | static int verbose = 0; | 84 | static int verbose = 0; |
| 93 | static int uid; | 85 | |
| 94 | static pid_t ppid; | 86 | static int stat_exe(const pid_t pid, struct stat *buf) { |
| 95 | static int vsz; | ||
| 96 | static int rss; | ||
| 97 | static float pcpu; | ||
| 98 | static char *statopts; | ||
| 99 | static char *prog; | ||
| 100 | static char *exclude_progs; | ||
| 101 | static char **exclude_progs_arr = NULL; | ||
| 102 | static char exclude_progs_counter = 0; | ||
| 103 | static char *args; | ||
| 104 | static char *input_filename = NULL; | ||
| 105 | static regex_t re_args; | ||
| 106 | static char *fmt; | ||
| 107 | static char *fails; | ||
| 108 | static char tmp[MAX_INPUT_BUFFER]; | ||
| 109 | static int kthread_filter = 0; | ||
| 110 | static int usepid = 0; /* whether to test for pid or /proc/pid/exe */ | ||
| 111 | |||
| 112 | static int | ||
| 113 | stat_exe (const pid_t pid, struct stat *buf) { | ||
| 114 | char *path; | 87 | char *path; |
| 115 | int ret; | ||
| 116 | xasprintf(&path, "/proc/%d/exe", pid); | 88 | xasprintf(&path, "/proc/%d/exe", pid); |
| 117 | ret = stat(path, buf); | 89 | int ret = stat(path, buf); |
| 118 | free(path); | 90 | free(path); |
| 119 | return ret; | 91 | return ret; |
| 120 | } | 92 | } |
| 121 | 93 | ||
| 122 | 94 | int main(int argc, char **argv) { | |
| 123 | int | 95 | setlocale(LC_ALL, ""); |
| 124 | main (int argc, char **argv) | ||
| 125 | { | ||
| 126 | char *input_buffer; | ||
| 127 | char *input_line; | ||
| 128 | char *procprog; | ||
| 129 | |||
| 130 | pid_t mypid = 0; | ||
| 131 | pid_t myppid = 0; | ||
| 132 | struct stat statbuf; | ||
| 133 | dev_t mydev = 0; | ||
| 134 | ino_t myino = 0; | ||
| 135 | int procuid = 0; | ||
| 136 | pid_t procpid = 0; | ||
| 137 | pid_t procppid = 0; | ||
| 138 | pid_t kthread_ppid = 0; | ||
| 139 | int procvsz = 0; | ||
| 140 | int procrss = 0; | ||
| 141 | int procseconds = 0; | ||
| 142 | float procpcpu = 0; | ||
| 143 | char procstat[8]; | ||
| 144 | char procetime[MAX_INPUT_BUFFER] = { '\0' }; | ||
| 145 | char *procargs; | ||
| 146 | |||
| 147 | const char *zombie = "Z"; | ||
| 148 | |||
| 149 | int resultsum = 0; /* bitmask of the filter criteria met by a process */ | ||
| 150 | int found = 0; /* counter for number of lines returned in `ps` output */ | ||
| 151 | int procs = 0; /* counter for number of processes meeting filter criteria */ | ||
| 152 | int pos; /* number of spaces before 'args' in `ps` output */ | ||
| 153 | int cols; /* number of columns in ps output */ | ||
| 154 | int expected_cols = PS_COLS - 1; | ||
| 155 | int warn = 0; /* number of processes in warn state */ | ||
| 156 | int crit = 0; /* number of processes in crit state */ | ||
| 157 | int i = 0; | ||
| 158 | int result = STATE_UNKNOWN; | ||
| 159 | int ret = 0; | ||
| 160 | output chld_out, chld_err; | ||
| 161 | |||
| 162 | setlocale (LC_ALL, ""); | ||
| 163 | bindtextdomain (PACKAGE, LOCALEDIR); | ||
| 164 | textdomain (PACKAGE); | ||
| 165 | setlocale(LC_NUMERIC, "POSIX"); | 96 | setlocale(LC_NUMERIC, "POSIX"); |
| 166 | 97 | bindtextdomain(PACKAGE, LOCALEDIR); | |
| 167 | input_buffer = malloc (MAX_INPUT_BUFFER); | 98 | textdomain(PACKAGE); |
| 168 | procprog = malloc (MAX_INPUT_BUFFER); | ||
| 169 | |||
| 170 | xasprintf (&metric_name, "PROCS"); | ||
| 171 | metric = METRIC_PROCS; | ||
| 172 | 99 | ||
| 173 | /* Parse extra opts if any */ | 100 | /* Parse extra opts if any */ |
| 174 | argv=np_extra_opts (&argc, argv, progname); | 101 | argv = np_extra_opts(&argc, argv, progname); |
| 102 | |||
| 103 | check_procs_config_wrapper tmp_config = process_arguments(argc, argv); | ||
| 104 | if (tmp_config.errorcode == ERROR) { | ||
| 105 | usage4(_("Could not parse arguments")); | ||
| 106 | } | ||
| 175 | 107 | ||
| 176 | if (process_arguments (argc, argv) == ERROR) | 108 | check_procs_config config = tmp_config.config; |
| 177 | usage4 (_("Could not parse arguments")); | ||
| 178 | 109 | ||
| 179 | /* find ourself */ | 110 | /* find ourself */ |
| 180 | mypid = getpid(); | 111 | pid_t mypid = getpid(); |
| 181 | myppid = getppid(); | 112 | pid_t myppid = getppid(); |
| 182 | if (usepid || stat_exe(mypid, &statbuf) == -1) { | 113 | dev_t mydev = 0; |
| 114 | ino_t myino = 0; | ||
| 115 | struct stat statbuf; | ||
| 116 | if (config.usepid || stat_exe(mypid, &statbuf) == -1) { | ||
| 183 | /* usepid might have been set by -T */ | 117 | /* usepid might have been set by -T */ |
| 184 | usepid = 1; | 118 | config.usepid = true; |
| 185 | } else { | 119 | } else { |
| 186 | usepid = 0; | 120 | config.usepid = false; |
| 187 | mydev = statbuf.st_dev; | 121 | mydev = statbuf.st_dev; |
| 188 | myino = statbuf.st_ino; | 122 | myino = statbuf.st_ino; |
| 189 | } | 123 | } |
| 190 | 124 | ||
| 191 | /* Set signal handling and alarm timeout */ | 125 | /* Set signal handling and alarm timeout */ |
| 192 | if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 126 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { |
| 193 | die (STATE_UNKNOWN, _("Cannot catch SIGALRM")); | 127 | die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); |
| 194 | } | 128 | } |
| 195 | (void) alarm ((unsigned) timeout_interval); | 129 | (void)alarm(timeout_interval); |
| 196 | 130 | ||
| 197 | if (verbose >= 2) | 131 | if (verbose >= 2) { |
| 198 | printf (_("CMD: %s\n"), PS_COMMAND); | 132 | printf(_("CMD: %s\n"), PS_COMMAND); |
| 133 | } | ||
| 199 | 134 | ||
| 200 | if (input_filename == NULL) { | 135 | output chld_out; |
| 201 | result = cmd_run( PS_COMMAND, &chld_out, &chld_err, 0); | 136 | output chld_err; |
| 137 | mp_state_enum result = STATE_UNKNOWN; | ||
| 138 | if (config.input_filename == NULL) { | ||
| 139 | result = cmd_run(PS_COMMAND, &chld_out, &chld_err, 0); | ||
| 202 | if (chld_err.lines > 0) { | 140 | if (chld_err.lines > 0) { |
| 203 | printf ("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); | 141 | printf("%s: %s", _("System call sent warnings to stderr"), chld_err.line[0]); |
| 204 | exit(STATE_WARNING); | 142 | exit(STATE_WARNING); |
| 205 | } | 143 | } |
| 206 | } else { | 144 | } else { |
| 207 | result = cmd_file_read( input_filename, &chld_out, 0); | 145 | result = cmd_file_read(config.input_filename, &chld_out, 0); |
| 208 | } | 146 | } |
| 209 | 147 | ||
| 148 | int pos; /* number of spaces before 'args' in `ps` output */ | ||
| 149 | uid_t procuid = 0; | ||
| 150 | pid_t procpid = 0; | ||
| 151 | pid_t procppid = 0; | ||
| 152 | pid_t kthread_ppid = 0; | ||
| 153 | int warn = 0; /* number of processes in warn state */ | ||
| 154 | int crit = 0; /* number of processes in crit state */ | ||
| 155 | int procvsz = 0; | ||
| 156 | int procrss = 0; | ||
| 157 | int procseconds = 0; | ||
| 158 | float procpcpu = 0; | ||
| 159 | char procstat[8]; | ||
| 160 | char procetime[MAX_INPUT_BUFFER] = {'\0'}; | ||
| 161 | int resultsum = 0; /* bitmask of the filter criteria met by a process */ | ||
| 162 | int found = 0; /* counter for number of lines returned in `ps` output */ | ||
| 163 | int procs = 0; /* counter for number of processes meeting filter criteria */ | ||
| 164 | char *input_buffer = malloc(MAX_INPUT_BUFFER); | ||
| 165 | char *procprog = malloc(MAX_INPUT_BUFFER); | ||
| 166 | const int expected_cols = PS_COLS - 1; | ||
| 167 | |||
| 210 | /* flush first line: j starts at 1 */ | 168 | /* flush first line: j starts at 1 */ |
| 211 | for (size_t j = 1; j < chld_out.lines; j++) { | 169 | for (size_t j = 1; j < chld_out.lines; j++) { |
| 212 | input_line = chld_out.line[j]; | 170 | char *input_line = chld_out.line[j]; |
| 213 | 171 | ||
| 214 | if (verbose >= 3) | 172 | if (verbose >= 3) { |
| 215 | printf ("%s", input_line); | 173 | printf("%s", input_line); |
| 174 | } | ||
| 216 | 175 | ||
| 217 | strcpy (procprog, ""); | 176 | strcpy(procprog, ""); |
| 218 | xasprintf (&procargs, "%s", ""); | 177 | char *procargs; |
| 178 | xasprintf(&procargs, "%s", ""); | ||
| 219 | 179 | ||
| 220 | cols = sscanf (input_line, PS_FORMAT, PS_VARLIST); | 180 | /* number of columns in ps output */ |
| 181 | int cols = sscanf(input_line, PS_FORMAT, PS_VARLIST); | ||
| 221 | 182 | ||
| 222 | /* Zombie processes do not give a procprog command */ | 183 | /* Zombie processes do not give a procprog command */ |
| 223 | if ( cols < expected_cols && strstr(procstat, zombie) ) { | 184 | const char *zombie = "Z"; |
| 185 | if (cols < expected_cols && strstr(procstat, zombie)) { | ||
| 224 | cols = expected_cols; | 186 | cols = expected_cols; |
| 225 | } | 187 | } |
| 226 | if ( cols >= expected_cols ) { | 188 | if (cols >= expected_cols) { |
| 227 | resultsum = 0; | 189 | resultsum = 0; |
| 228 | xasprintf (&procargs, "%s", input_line + pos); | 190 | xasprintf(&procargs, "%s", input_line + pos); |
| 229 | strip (procargs); | 191 | strip(procargs); |
| 230 | 192 | ||
| 231 | /* Some ps return full pathname for command. This removes path */ | 193 | /* Some ps return full pathname for command. This removes path */ |
| 232 | strcpy(procprog, base_name(procprog)); | 194 | strcpy(procprog, base_name(procprog)); |
| 233 | 195 | ||
| 234 | /* we need to convert the elapsed time to seconds */ | 196 | /* we need to convert the elapsed time to seconds */ |
| 235 | procseconds = convert_to_seconds(procetime); | 197 | procseconds = convert_to_seconds(procetime, config.metric); |
| 236 | 198 | ||
| 237 | if (verbose >= 3) | 199 | if (verbose >= 3) { |
| 238 | printf ("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", | 200 | printf("proc#=%d uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s " |
| 239 | procs, procuid, procvsz, procrss, | 201 | "prog=%s args=%s\n", |
| 240 | procpid, procppid, procpcpu, procstat, | 202 | procs, procuid, procvsz, procrss, procpid, procppid, procpcpu, procstat, |
| 241 | procetime, procprog, procargs); | 203 | procetime, procprog, procargs); |
| 204 | } | ||
| 242 | 205 | ||
| 243 | /* Ignore self */ | 206 | /* Ignore self */ |
| 244 | if ((usepid && mypid == procpid) || | 207 | int ret = 0; |
| 245 | ( ((!usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino)) || | 208 | if ((config.usepid && mypid == procpid) || |
| 246 | (ret == -1 && errno == ENOENT)) | 209 | (((!config.usepid) && ((ret = stat_exe(procpid, &statbuf) != -1) && |
| 247 | ) { | 210 | statbuf.st_dev == mydev && statbuf.st_ino == myino)) || |
| 248 | if (verbose >= 3) | 211 | (ret == -1 && errno == ENOENT))) { |
| 249 | printf("not considering - is myself or gone\n"); | 212 | if (verbose >= 3) { |
| 213 | printf("not considering - is myself or gone\n"); | ||
| 214 | } | ||
| 250 | continue; | 215 | continue; |
| 251 | } | 216 | } |
| 252 | /* Ignore parent*/ | 217 | /* Ignore parent*/ |
| 253 | else if (myppid == procpid) { | 218 | if (myppid == procpid) { |
| 254 | if (verbose >= 3) | 219 | if (verbose >= 3) { |
| 255 | printf("not considering - is parent\n"); | 220 | printf("not considering - is parent\n"); |
| 221 | } | ||
| 256 | continue; | 222 | continue; |
| 257 | } | 223 | } |
| 258 | 224 | ||
| 259 | /* Ignore our own children */ | 225 | /* Ignore our own children */ |
| 260 | if (procppid == mypid) { | 226 | if (procppid == mypid) { |
| 261 | if (verbose >= 3) | 227 | if (verbose >= 3) { |
| 262 | printf("not considering - is our child\n"); | 228 | printf("not considering - is our child\n"); |
| 229 | } | ||
| 263 | continue; | 230 | continue; |
| 264 | } | 231 | } |
| 265 | 232 | ||
| 266 | /* Ignore excluded processes by name */ | 233 | /* Ignore excluded processes by name */ |
| 267 | if(options & EXCLUDE_PROGS) { | 234 | if (config.options & EXCLUDE_PROGS) { |
| 268 | int found = 0; | 235 | bool found = false; |
| 269 | int i = 0; | 236 | for (int i = 0; i < (config.exclude_progs_counter); i++) { |
| 270 | 237 | if (!strcmp(procprog, config.exclude_progs_arr[i])) { | |
| 271 | for(i=0; i < (exclude_progs_counter); i++) { | 238 | found = true; |
| 272 | if(!strcmp(procprog, exclude_progs_arr[i])) { | 239 | } |
| 273 | found = 1; | 240 | } |
| 274 | } | 241 | if (!found) { |
| 275 | } | 242 | resultsum |= EXCLUDE_PROGS; |
| 276 | if(found == 0) { | 243 | } else { |
| 277 | resultsum |= EXCLUDE_PROGS; | 244 | if (verbose >= 3) { |
| 278 | } else | 245 | printf("excluding - by ignorelist\n"); |
| 279 | { | 246 | } |
| 280 | if(verbose >= 3) | 247 | } |
| 281 | printf("excluding - by ignorelist\n"); | ||
| 282 | } | ||
| 283 | } | 248 | } |
| 284 | 249 | ||
| 285 | /* filter kernel threads (children of KTHREAD_PARENT)*/ | 250 | /* filter kernel threads (children of KTHREAD_PARENT)*/ |
| 286 | /* TODO adapt for other OSes than GNU/Linux | 251 | /* TODO adapt for other OSes than GNU/Linux |
| 287 | sorry for not doing that, but I've no other OSes to test :-( */ | 252 | sorry for not doing that, but I've no other OSes to test :-( */ |
| 288 | if (kthread_filter == 1) { | 253 | if (config.kthread_filter) { |
| 289 | /* get pid KTHREAD_PARENT */ | 254 | /* get pid KTHREAD_PARENT */ |
| 290 | if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT) ) | 255 | if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT)) { |
| 291 | kthread_ppid = procpid; | 256 | kthread_ppid = procpid; |
| 257 | } | ||
| 292 | 258 | ||
| 293 | if (kthread_ppid == procppid) { | 259 | if (kthread_ppid == procppid) { |
| 294 | if (verbose >= 2) | 260 | if (verbose >= 2) { |
| 295 | printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs); | 261 | printf("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, |
| 262 | procppid, procprog, procargs); | ||
| 263 | } | ||
| 296 | continue; | 264 | continue; |
| 297 | } | 265 | } |
| 298 | } | 266 | } |
| 299 | 267 | ||
| 300 | if ((options & STAT) && (strstr (procstat, statopts))) | 268 | if ((config.options & STAT) && (strstr(procstat, config.statopts))) { |
| 301 | resultsum |= STAT; | 269 | resultsum |= STAT; |
| 302 | if ((options & ARGS) && procargs && (strstr (procargs, args) != NULL)) | 270 | } |
| 271 | if ((config.options & ARGS) && procargs && (strstr(procargs, config.args) != NULL)) { | ||
| 303 | resultsum |= ARGS; | 272 | resultsum |= ARGS; |
| 304 | if ((options & EREG_ARGS) && procargs && (regexec(&re_args, procargs, (size_t) 0, NULL, 0) == 0)) | 273 | } |
| 274 | if ((config.options & EREG_ARGS) && procargs && | ||
| 275 | (regexec(&config.re_args, procargs, (size_t)0, NULL, 0) == 0)) { | ||
| 305 | resultsum |= EREG_ARGS; | 276 | resultsum |= EREG_ARGS; |
| 306 | if ((options & PROG) && procprog && (strcmp (prog, procprog) == 0)) | 277 | } |
| 278 | if ((config.options & PROG) && procprog && (strcmp(config.prog, procprog) == 0)) { | ||
| 307 | resultsum |= PROG; | 279 | resultsum |= PROG; |
| 308 | if ((options & PPID) && (procppid == ppid)) | 280 | } |
| 281 | if ((config.options & PPID) && (procppid == config.ppid)) { | ||
| 309 | resultsum |= PPID; | 282 | resultsum |= PPID; |
| 310 | if ((options & USER) && (procuid == uid)) | 283 | } |
| 284 | if ((config.options & USER) && (procuid == config.uid)) { | ||
| 311 | resultsum |= USER; | 285 | resultsum |= USER; |
| 312 | if ((options & VSZ) && (procvsz >= vsz)) | 286 | } |
| 287 | if ((config.options & VSZ) && (procvsz >= config.vsz)) { | ||
| 313 | resultsum |= VSZ; | 288 | resultsum |= VSZ; |
| 314 | if ((options & RSS) && (procrss >= rss)) | 289 | } |
| 290 | if ((config.options & RSS) && (procrss >= config.rss)) { | ||
| 315 | resultsum |= RSS; | 291 | resultsum |= RSS; |
| 316 | if ((options & PCPU) && (procpcpu >= pcpu)) | 292 | } |
| 293 | if ((config.options & PCPU) && (procpcpu >= config.pcpu)) { | ||
| 317 | resultsum |= PCPU; | 294 | resultsum |= PCPU; |
| 295 | } | ||
| 318 | 296 | ||
| 319 | found++; | 297 | found++; |
| 320 | 298 | ||
| 321 | /* Next line if filters not matched */ | 299 | /* Next line if filters not matched */ |
| 322 | if (!(options == resultsum || options == ALL)) | 300 | if (!(config.options == resultsum || config.options == ALL)) { |
| 323 | continue; | 301 | continue; |
| 302 | } | ||
| 324 | 303 | ||
| 325 | procs++; | 304 | procs++; |
| 326 | if (verbose >= 2) { | 305 | if (verbose >= 2) { |
| 327 | printf ("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s prog=%s args=%s\n", | 306 | printf("Matched: uid=%d vsz=%d rss=%d pid=%d ppid=%d pcpu=%.2f stat=%s etime=%s " |
| 328 | procuid, procvsz, procrss, | 307 | "prog=%s args=%s\n", |
| 329 | procpid, procppid, procpcpu, procstat, | 308 | procuid, procvsz, procrss, procpid, procppid, procpcpu, procstat, procetime, |
| 330 | procetime, procprog, procargs); | 309 | procprog, procargs); |
| 331 | } | 310 | } |
| 332 | 311 | ||
| 333 | if (metric == METRIC_VSZ) | 312 | mp_state_enum temporary_result = STATE_OK; |
| 334 | i = get_status ((double)procvsz, procs_thresholds); | 313 | if (config.metric == METRIC_VSZ) { |
| 335 | else if (metric == METRIC_RSS) | 314 | temporary_result = get_status((double)procvsz, config.procs_thresholds); |
| 336 | i = get_status ((double)procrss, procs_thresholds); | 315 | } else if (config.metric == METRIC_RSS) { |
| 316 | temporary_result = get_status((double)procrss, config.procs_thresholds); | ||
| 317 | } | ||
| 337 | /* TODO? float thresholds for --metric=CPU */ | 318 | /* TODO? float thresholds for --metric=CPU */ |
| 338 | else if (metric == METRIC_CPU) | 319 | else if (config.metric == METRIC_CPU) { |
| 339 | i = get_status (procpcpu, procs_thresholds); | 320 | temporary_result = get_status(procpcpu, config.procs_thresholds); |
| 340 | else if (metric == METRIC_ELAPSED) | 321 | } else if (config.metric == METRIC_ELAPSED) { |
| 341 | i = get_status ((double)procseconds, procs_thresholds); | 322 | temporary_result = get_status((double)procseconds, config.procs_thresholds); |
| 323 | } | ||
| 342 | 324 | ||
| 343 | if (metric != METRIC_PROCS) { | 325 | if (config.metric != METRIC_PROCS) { |
| 344 | if (i == STATE_WARNING) { | 326 | if (temporary_result == STATE_WARNING) { |
| 345 | warn++; | 327 | warn++; |
| 346 | xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); | 328 | xasprintf(&config.fails, "%s%s%s", config.fails, |
| 347 | result = max_state (result, i); | 329 | (strcmp(config.fails, "") ? ", " : ""), procprog); |
| 330 | result = max_state(result, temporary_result); | ||
| 348 | } | 331 | } |
| 349 | if (i == STATE_CRITICAL) { | 332 | if (temporary_result == STATE_CRITICAL) { |
| 350 | crit++; | 333 | crit++; |
| 351 | xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog); | 334 | xasprintf(&config.fails, "%s%s%s", config.fails, |
| 352 | result = max_state (result, i); | 335 | (strcmp(config.fails, "") ? ", " : ""), procprog); |
| 336 | result = max_state(result, temporary_result); | ||
| 353 | } | 337 | } |
| 354 | } | 338 | } |
| 355 | } | 339 | } |
| @@ -359,339 +343,366 @@ main (int argc, char **argv) | |||
| 359 | } | 343 | } |
| 360 | } | 344 | } |
| 361 | 345 | ||
| 362 | if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ | 346 | if (found == 0) { /* no process lines parsed so return STATE_UNKNOWN */ |
| 363 | printf (_("Unable to read output\n")); | 347 | printf(_("Unable to read output\n")); |
| 364 | return STATE_UNKNOWN; | 348 | return STATE_UNKNOWN; |
| 365 | } | 349 | } |
| 366 | 350 | ||
| 367 | if ( result == STATE_UNKNOWN ) | 351 | if (result == STATE_UNKNOWN) { |
| 368 | result = STATE_OK; | 352 | result = STATE_OK; |
| 353 | } | ||
| 369 | 354 | ||
| 370 | /* Needed if procs found, but none match filter */ | 355 | /* Needed if procs found, but none match filter */ |
| 371 | if ( metric == METRIC_PROCS ) { | 356 | if (config.metric == METRIC_PROCS) { |
| 372 | result = max_state (result, get_status ((double)procs, procs_thresholds) ); | 357 | result = max_state(result, get_status((double)procs, config.procs_thresholds)); |
| 373 | } | 358 | } |
| 374 | 359 | ||
| 375 | if ( result == STATE_OK ) { | 360 | if (result == STATE_OK) { |
| 376 | printf ("%s %s: ", metric_name, _("OK")); | 361 | printf("%s %s: ", config.metric_name, _("OK")); |
| 377 | } else if (result == STATE_WARNING) { | 362 | } else if (result == STATE_WARNING) { |
| 378 | printf ("%s %s: ", metric_name, _("WARNING")); | 363 | printf("%s %s: ", config.metric_name, _("WARNING")); |
| 379 | if ( metric != METRIC_PROCS ) { | 364 | if (config.metric != METRIC_PROCS) { |
| 380 | printf (_("%d warn out of "), warn); | 365 | printf(_("%d warn out of "), warn); |
| 381 | } | 366 | } |
| 382 | } else if (result == STATE_CRITICAL) { | 367 | } else if (result == STATE_CRITICAL) { |
| 383 | printf ("%s %s: ", metric_name, _("CRITICAL")); | 368 | printf("%s %s: ", config.metric_name, _("CRITICAL")); |
| 384 | if (metric != METRIC_PROCS) { | 369 | if (config.metric != METRIC_PROCS) { |
| 385 | printf (_("%d crit, %d warn out of "), crit, warn); | 370 | printf(_("%d crit, %d warn out of "), crit, warn); |
| 386 | } | 371 | } |
| 387 | } | 372 | } |
| 388 | printf (ngettext ("%d process", "%d processes", (unsigned long) procs), procs); | 373 | printf(ngettext("%d process", "%d processes", (unsigned long)procs), procs); |
| 389 | 374 | ||
| 390 | if (strcmp(fmt,"") != 0) { | 375 | if (strcmp(config.fmt, "") != 0) { |
| 391 | printf (_(" with %s"), fmt); | 376 | printf(_(" with %s"), config.fmt); |
| 392 | } | 377 | } |
| 393 | 378 | ||
| 394 | if ( verbose >= 1 && strcmp(fails,"") ) | 379 | if (verbose >= 1 && strcmp(config.fails, "")) { |
| 395 | printf (" [%s]", fails); | 380 | printf(" [%s]", config.fails); |
| 381 | } | ||
| 396 | 382 | ||
| 397 | if (metric == METRIC_PROCS) | 383 | if (config.metric == METRIC_PROCS) { |
| 398 | printf (" | procs=%d;%s;%s;0;", procs, | 384 | printf(" | procs=%d;%s;%s;0;", procs, config.warning_range ? config.warning_range : "", |
| 399 | warning_range ? warning_range : "", | 385 | config.critical_range ? config.critical_range : ""); |
| 400 | critical_range ? critical_range : ""); | 386 | } else { |
| 401 | else | 387 | printf(" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); |
| 402 | printf (" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit); | 388 | } |
| 403 | 389 | ||
| 404 | printf ("\n"); | 390 | printf("\n"); |
| 405 | return result; | 391 | exit(result); |
| 406 | } | 392 | } |
| 407 | 393 | ||
| 408 | |||
| 409 | |||
| 410 | /* process command-line arguments */ | 394 | /* process command-line arguments */ |
| 411 | int | 395 | check_procs_config_wrapper process_arguments(int argc, char **argv) { |
| 412 | process_arguments (int argc, char **argv) | 396 | static struct option longopts[] = {{"warning", required_argument, 0, 'w'}, |
| 413 | { | 397 | {"critical", required_argument, 0, 'c'}, |
| 414 | int c = 1; | 398 | {"metric", required_argument, 0, 'm'}, |
| 415 | char *user; | 399 | {"timeout", required_argument, 0, 't'}, |
| 416 | struct passwd *pw; | 400 | {"status", required_argument, 0, 's'}, |
| 417 | int option = 0; | 401 | {"ppid", required_argument, 0, 'p'}, |
| 418 | int err; | 402 | {"user", required_argument, 0, 'u'}, |
| 419 | int cflags = REG_NOSUB | REG_EXTENDED; | 403 | {"command", required_argument, 0, 'C'}, |
| 420 | char errbuf[MAX_INPUT_BUFFER]; | 404 | {"vsz", required_argument, 0, 'z'}, |
| 421 | char *temp_string; | 405 | {"rss", required_argument, 0, 'r'}, |
| 422 | int i=0; | 406 | {"pcpu", required_argument, 0, 'P'}, |
| 423 | static struct option longopts[] = { | 407 | {"elapsed", required_argument, 0, 'e'}, |
| 424 | {"warning", required_argument, 0, 'w'}, | 408 | {"argument-array", required_argument, 0, 'a'}, |
| 425 | {"critical", required_argument, 0, 'c'}, | 409 | {"help", no_argument, 0, 'h'}, |
| 426 | {"metric", required_argument, 0, 'm'}, | 410 | {"version", no_argument, 0, 'V'}, |
| 427 | {"timeout", required_argument, 0, 't'}, | 411 | {"verbose", no_argument, 0, 'v'}, |
| 428 | {"status", required_argument, 0, 's'}, | 412 | {"ereg-argument-array", required_argument, 0, CHAR_MAX + 1}, |
| 429 | {"ppid", required_argument, 0, 'p'}, | 413 | {"input-file", required_argument, 0, CHAR_MAX + 2}, |
| 430 | {"user", required_argument, 0, 'u'}, | 414 | {"no-kthreads", required_argument, 0, 'k'}, |
| 431 | {"command", required_argument, 0, 'C'}, | 415 | {"traditional-filter", no_argument, 0, 'T'}, |
| 432 | {"vsz", required_argument, 0, 'z'}, | 416 | {"exclude-process", required_argument, 0, 'X'}, |
| 433 | {"rss", required_argument, 0, 'r'}, | 417 | {0, 0, 0, 0}}; |
| 434 | {"pcpu", required_argument, 0, 'P'}, | 418 | |
| 435 | {"elapsed", required_argument, 0, 'e'}, | 419 | for (int index = 1; index < argc; index++) { |
| 436 | {"argument-array", required_argument, 0, 'a'}, | 420 | if (strcmp("-to", argv[index]) == 0) { |
| 437 | {"help", no_argument, 0, 'h'}, | 421 | strcpy(argv[index], "-t"); |
| 438 | {"version", no_argument, 0, 'V'}, | 422 | } |
| 439 | {"verbose", no_argument, 0, 'v'}, | 423 | } |
| 440 | {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, | ||
| 441 | {"input-file", required_argument, 0, CHAR_MAX+2}, | ||
| 442 | {"no-kthreads", required_argument, 0, 'k'}, | ||
| 443 | {"traditional-filter", no_argument, 0, 'T'}, | ||
| 444 | {"exclude-process", required_argument, 0, 'X'}, | ||
| 445 | {0, 0, 0, 0} | ||
| 446 | }; | ||
| 447 | 424 | ||
| 448 | for (c = 1; c < argc; c++) | 425 | check_procs_config_wrapper result = { |
| 449 | if (strcmp ("-to", argv[c]) == 0) | 426 | .errorcode = OK, |
| 450 | strcpy (argv[c], "-t"); | 427 | .config = check_procs_config_init(), |
| 428 | }; | ||
| 451 | 429 | ||
| 452 | while (1) { | 430 | while (true) { |
| 453 | c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", | 431 | int option = 0; |
| 454 | longopts, &option); | 432 | int option_index = |
| 433 | getopt_long(argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T:X:", longopts, &option); | ||
| 455 | 434 | ||
| 456 | if (c == -1 || c == EOF) | 435 | if (option_index == -1 || option_index == EOF) { |
| 457 | break; | 436 | break; |
| 437 | } | ||
| 458 | 438 | ||
| 459 | switch (c) { | 439 | switch (option_index) { |
| 460 | case '?': /* help */ | 440 | case '?': /* help */ |
| 461 | usage5 (); | 441 | usage5(); |
| 462 | case 'h': /* help */ | 442 | case 'h': /* help */ |
| 463 | print_help (); | 443 | print_help(); |
| 464 | exit (STATE_UNKNOWN); | 444 | exit(STATE_UNKNOWN); |
| 465 | case 'V': /* version */ | 445 | case 'V': /* version */ |
| 466 | print_revision (progname, NP_VERSION); | 446 | print_revision(progname, NP_VERSION); |
| 467 | exit (STATE_UNKNOWN); | 447 | exit(STATE_UNKNOWN); |
| 468 | case 't': /* timeout period */ | 448 | case 't': /* timeout period */ |
| 469 | if (!is_integer (optarg)) | 449 | if (!is_integer(optarg)) { |
| 470 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 450 | usage2(_("Timeout interval must be a positive integer"), optarg); |
| 471 | else | 451 | } else { |
| 472 | timeout_interval = atoi (optarg); | 452 | timeout_interval = atoi(optarg); |
| 453 | } | ||
| 473 | break; | 454 | break; |
| 474 | case 'c': /* critical threshold */ | 455 | case 'c': /* critical threshold */ |
| 475 | critical_range = optarg; | 456 | result.config.critical_range = optarg; |
| 476 | break; | 457 | break; |
| 477 | case 'w': /* warning threshold */ | 458 | case 'w': /* warning threshold */ |
| 478 | warning_range = optarg; | 459 | result.config.warning_range = optarg; |
| 479 | break; | 460 | break; |
| 480 | case 'p': /* process id */ | 461 | case 'p': { /* process id */ |
| 481 | if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) { | 462 | static char tmp[MAX_INPUT_BUFFER]; |
| 482 | xasprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid); | 463 | if (sscanf(optarg, "%d%[^0-9]", &result.config.ppid, tmp) == 1) { |
| 483 | options |= PPID; | 464 | xasprintf(&result.config.fmt, "%s%sPPID = %d", |
| 465 | (result.config.fmt ? result.config.fmt : ""), | ||
| 466 | (result.config.options ? ", " : ""), result.config.ppid); | ||
| 467 | result.config.options |= PPID; | ||
| 484 | break; | 468 | break; |
| 485 | } | 469 | } |
| 486 | usage4 (_("Parent Process ID must be an integer!")); | 470 | usage4(_("Parent Process ID must be an integer!")); |
| 487 | case 's': /* status */ | 471 | } |
| 488 | if (statopts) | 472 | case 's': /* status */ |
| 473 | if (result.config.statopts) { | ||
| 489 | break; | 474 | break; |
| 490 | else | 475 | } else { |
| 491 | statopts = optarg; | 476 | result.config.statopts = optarg; |
| 492 | xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 477 | } |
| 493 | options |= STAT; | 478 | xasprintf(&result.config.fmt, _("%s%sSTATE = %s"), |
| 479 | (result.config.fmt ? result.config.fmt : ""), | ||
| 480 | (result.config.options ? ", " : ""), result.config.statopts); | ||
| 481 | result.config.options |= STAT; | ||
| 494 | break; | 482 | break; |
| 495 | case 'u': /* user or user id */ | 483 | case 'u': /* user or user id */ { |
| 496 | if (is_integer (optarg)) { | 484 | struct passwd *pw; |
| 497 | uid = atoi (optarg); | 485 | if (is_integer(optarg)) { |
| 498 | pw = getpwuid ((uid_t) uid); | 486 | result.config.uid = atoi(optarg); |
| 487 | pw = getpwuid(result.config.uid); | ||
| 499 | /* check to be sure user exists */ | 488 | /* check to be sure user exists */ |
| 500 | if (pw == NULL) | 489 | if (pw == NULL) { |
| 501 | usage2 (_("UID was not found"), optarg); | 490 | usage2(_("UID was not found"), optarg); |
| 502 | } | 491 | } |
| 503 | else { | 492 | } else { |
| 504 | pw = getpwnam (optarg); | 493 | pw = getpwnam(optarg); |
| 505 | /* check to be sure user exists */ | 494 | /* check to be sure user exists */ |
| 506 | if (pw == NULL) | 495 | if (pw == NULL) { |
| 507 | usage2 (_("User name was not found"), optarg); | 496 | usage2(_("User name was not found"), optarg); |
| 497 | } | ||
| 508 | /* then get uid */ | 498 | /* then get uid */ |
| 509 | uid = pw->pw_uid; | 499 | result.config.uid = pw->pw_uid; |
| 510 | } | 500 | } |
| 511 | user = pw->pw_name; | 501 | |
| 512 | xasprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""), | 502 | char *user = pw->pw_name; |
| 513 | uid, user); | 503 | xasprintf(&result.config.fmt, "%s%sUID = %d (%s)", |
| 514 | options |= USER; | 504 | (result.config.fmt ? result.config.fmt : ""), |
| 515 | break; | 505 | (result.config.options ? ", " : ""), result.config.uid, user); |
| 516 | case 'C': /* command */ | 506 | result.config.options |= USER; |
| 507 | } break; | ||
| 508 | case 'C': /* command */ | ||
| 517 | /* TODO: allow this to be passed in with --metric */ | 509 | /* TODO: allow this to be passed in with --metric */ |
| 518 | if (prog) | 510 | if (result.config.prog) { |
| 519 | break; | 511 | break; |
| 520 | else | 512 | } else { |
| 521 | prog = optarg; | 513 | result.config.prog = optarg; |
| 522 | xasprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), | 514 | } |
| 523 | prog); | 515 | xasprintf(&result.config.fmt, _("%s%scommand name '%s'"), |
| 524 | options |= PROG; | 516 | (result.config.fmt ? result.config.fmt : ""), |
| 517 | (result.config.options ? ", " : ""), result.config.prog); | ||
| 518 | result.config.options |= PROG; | ||
| 525 | break; | 519 | break; |
| 526 | case 'X': | 520 | case 'X': |
| 527 | if(exclude_progs) | 521 | if (result.config.exclude_progs) { |
| 528 | break; | 522 | break; |
| 529 | else | 523 | } else { |
| 530 | exclude_progs = optarg; | 524 | result.config.exclude_progs = optarg; |
| 531 | xasprintf (&fmt, _("%s%sexclude progs '%s'"), (fmt ? fmt : ""), (options ? ", " : ""), | 525 | } |
| 532 | exclude_progs); | 526 | xasprintf(&result.config.fmt, _("%s%sexclude progs '%s'"), |
| 533 | char *p = strtok(exclude_progs, ","); | 527 | (result.config.fmt ? result.config.fmt : ""), |
| 534 | 528 | (result.config.options ? ", " : ""), result.config.exclude_progs); | |
| 535 | while(p){ | 529 | char *tmp_pointer = strtok(result.config.exclude_progs, ","); |
| 536 | exclude_progs_arr = realloc(exclude_progs_arr, sizeof(char*) * ++exclude_progs_counter); | 530 | |
| 537 | exclude_progs_arr[exclude_progs_counter-1] = p; | 531 | while (tmp_pointer) { |
| 538 | p = strtok(NULL, ","); | 532 | result.config.exclude_progs_arr = |
| 533 | realloc(result.config.exclude_progs_arr, | ||
| 534 | sizeof(char *) * ++result.config.exclude_progs_counter); | ||
| 535 | result.config.exclude_progs_arr[result.config.exclude_progs_counter - 1] = | ||
| 536 | tmp_pointer; | ||
| 537 | tmp_pointer = strtok(NULL, ","); | ||
| 539 | } | 538 | } |
| 540 | 539 | ||
| 541 | options |= EXCLUDE_PROGS; | 540 | result.config.options |= EXCLUDE_PROGS; |
| 542 | break; | 541 | break; |
| 543 | case 'a': /* args (full path name with args) */ | 542 | case 'a': /* args (full path name with args) */ |
| 544 | /* TODO: allow this to be passed in with --metric */ | 543 | /* TODO: allow this to be passed in with --metric */ |
| 545 | if (args) | 544 | if (result.config.args) { |
| 546 | break; | 545 | break; |
| 547 | else | 546 | } else { |
| 548 | args = optarg; | 547 | result.config.args = optarg; |
| 549 | xasprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args); | 548 | } |
| 550 | options |= ARGS; | 549 | xasprintf(&result.config.fmt, "%s%sargs '%s'", |
| 550 | (result.config.fmt ? result.config.fmt : ""), | ||
| 551 | (result.config.options ? ", " : ""), result.config.args); | ||
| 552 | result.config.options |= ARGS; | ||
| 551 | break; | 553 | break; |
| 552 | case CHAR_MAX+1: | 554 | case CHAR_MAX + 1: { |
| 553 | err = regcomp(&re_args, optarg, cflags); | 555 | int cflags = REG_NOSUB | REG_EXTENDED; |
| 556 | int err = regcomp(&result.config.re_args, optarg, cflags); | ||
| 554 | if (err != 0) { | 557 | if (err != 0) { |
| 555 | regerror (err, &re_args, errbuf, MAX_INPUT_BUFFER); | 558 | char errbuf[MAX_INPUT_BUFFER]; |
| 556 | die (STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), _("Could not compile regular expression"), errbuf); | 559 | regerror(err, &result.config.re_args, errbuf, MAX_INPUT_BUFFER); |
| 560 | die(STATE_UNKNOWN, "PROCS %s: %s - %s\n", _("UNKNOWN"), | ||
| 561 | _("Could not compile regular expression"), errbuf); | ||
| 557 | } | 562 | } |
| 558 | /* Strip off any | within the regex optarg */ | 563 | /* Strip off any | within the regex optarg */ |
| 559 | temp_string = strdup(optarg); | 564 | char *temp_string = strdup(optarg); |
| 560 | while(temp_string[i]!='\0'){ | 565 | int index = 0; |
| 561 | if(temp_string[i]=='|') | 566 | while (temp_string[index] != '\0') { |
| 562 | temp_string[i]=','; | 567 | if (temp_string[index] == '|') { |
| 563 | i++; | 568 | temp_string[index] = ','; |
| 564 | } | 569 | } |
| 565 | xasprintf (&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string); | 570 | index++; |
| 566 | options |= EREG_ARGS; | 571 | } |
| 567 | break; | 572 | xasprintf(&result.config.fmt, "%s%sregex args '%s'", |
| 568 | case 'r': /* RSS */ | 573 | (result.config.fmt ? result.config.fmt : ""), |
| 569 | if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) { | 574 | (result.config.options ? ", " : ""), temp_string); |
| 570 | xasprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss); | 575 | result.config.options |= EREG_ARGS; |
| 571 | options |= RSS; | 576 | } break; |
| 577 | case 'r': { /* RSS */ | ||
| 578 | static char tmp[MAX_INPUT_BUFFER]; | ||
| 579 | if (sscanf(optarg, "%d%[^0-9]", &result.config.rss, tmp) == 1) { | ||
| 580 | xasprintf(&result.config.fmt, "%s%sRSS >= %d", | ||
| 581 | (result.config.fmt ? result.config.fmt : ""), | ||
| 582 | (result.config.options ? ", " : ""), result.config.rss); | ||
| 583 | result.config.options |= RSS; | ||
| 572 | break; | 584 | break; |
| 573 | } | 585 | } |
| 574 | usage4 (_("RSS must be an integer!")); | 586 | usage4(_("RSS must be an integer!")); |
| 575 | case 'z': /* VSZ */ | 587 | } |
| 576 | if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) { | 588 | case 'z': { /* VSZ */ |
| 577 | xasprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz); | 589 | static char tmp[MAX_INPUT_BUFFER]; |
| 578 | options |= VSZ; | 590 | if (sscanf(optarg, "%d%[^0-9]", &result.config.vsz, tmp) == 1) { |
| 591 | xasprintf(&result.config.fmt, "%s%sVSZ >= %d", | ||
| 592 | (result.config.fmt ? result.config.fmt : ""), | ||
| 593 | (result.config.options ? ", " : ""), result.config.vsz); | ||
| 594 | result.config.options |= VSZ; | ||
| 579 | break; | 595 | break; |
| 580 | } | 596 | } |
| 581 | usage4 (_("VSZ must be an integer!")); | 597 | usage4(_("VSZ must be an integer!")); |
| 582 | case 'P': /* PCPU */ | 598 | } |
| 599 | case 'P': { /* PCPU */ | ||
| 583 | /* TODO: -P 1.5.5 is accepted */ | 600 | /* TODO: -P 1.5.5 is accepted */ |
| 584 | if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) { | 601 | static char tmp[MAX_INPUT_BUFFER]; |
| 585 | xasprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu); | 602 | if (sscanf(optarg, "%f%[^0-9.]", &result.config.pcpu, tmp) == 1) { |
| 586 | options |= PCPU; | 603 | xasprintf(&result.config.fmt, "%s%sPCPU >= %.2f", |
| 604 | (result.config.fmt ? result.config.fmt : ""), | ||
| 605 | (result.config.options ? ", " : ""), result.config.pcpu); | ||
| 606 | result.config.options |= PCPU; | ||
| 587 | break; | 607 | break; |
| 588 | } | 608 | } |
| 589 | usage4 (_("PCPU must be a float!")); | 609 | usage4(_("PCPU must be a float!")); |
| 610 | } | ||
| 590 | case 'm': | 611 | case 'm': |
| 591 | xasprintf (&metric_name, "%s", optarg); | 612 | xasprintf(&result.config.metric_name, "%s", optarg); |
| 592 | if ( strcmp(optarg, "PROCS") == 0) { | 613 | if (strcmp(optarg, "PROCS") == 0) { |
| 593 | metric = METRIC_PROCS; | 614 | result.config.metric = METRIC_PROCS; |
| 594 | break; | 615 | break; |
| 595 | } | 616 | } |
| 596 | else if ( strcmp(optarg, "VSZ") == 0) { | 617 | if (strcmp(optarg, "VSZ") == 0) { |
| 597 | metric = METRIC_VSZ; | 618 | result.config.metric = METRIC_VSZ; |
| 598 | break; | 619 | break; |
| 599 | } | 620 | } |
| 600 | else if ( strcmp(optarg, "RSS") == 0 ) { | 621 | if (strcmp(optarg, "RSS") == 0) { |
| 601 | metric = METRIC_RSS; | 622 | result.config.metric = METRIC_RSS; |
| 602 | break; | 623 | break; |
| 603 | } | 624 | } |
| 604 | else if ( strcmp(optarg, "CPU") == 0 ) { | 625 | if (strcmp(optarg, "CPU") == 0) { |
| 605 | metric = METRIC_CPU; | 626 | result.config.metric = METRIC_CPU; |
| 606 | break; | 627 | break; |
| 607 | } | 628 | } |
| 608 | else if ( strcmp(optarg, "ELAPSED") == 0) { | 629 | if (strcmp(optarg, "ELAPSED") == 0) { |
| 609 | metric = METRIC_ELAPSED; | 630 | result.config.metric = METRIC_ELAPSED; |
| 610 | break; | 631 | break; |
| 611 | } | 632 | } |
| 612 | 633 | ||
| 613 | usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); | 634 | usage4(_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); |
| 614 | case 'k': /* linux kernel thread filter */ | 635 | case 'k': /* linux kernel thread filter */ |
| 615 | kthread_filter = 1; | 636 | result.config.kthread_filter = true; |
| 616 | break; | 637 | break; |
| 617 | case 'v': /* command */ | 638 | case 'v': /* command */ |
| 618 | verbose++; | 639 | verbose++; |
| 619 | break; | 640 | break; |
| 620 | case 'T': | 641 | case 'T': |
| 621 | usepid = 1; | 642 | result.config.usepid = true; |
| 622 | break; | 643 | break; |
| 623 | case CHAR_MAX+2: | 644 | case CHAR_MAX + 2: |
| 624 | input_filename = optarg; | 645 | result.config.input_filename = optarg; |
| 625 | break; | 646 | break; |
| 626 | } | 647 | } |
| 627 | } | 648 | } |
| 628 | 649 | ||
| 629 | c = optind; | 650 | int index = optind; |
| 630 | if ((! warning_range) && argv[c]) | 651 | if ((!result.config.warning_range) && argv[index]) { |
| 631 | warning_range = argv[c++]; | 652 | result.config.warning_range = argv[index++]; |
| 632 | if ((! critical_range) && argv[c]) | 653 | } |
| 633 | critical_range = argv[c++]; | 654 | if ((!result.config.critical_range) && argv[index]) { |
| 634 | if (statopts == NULL && argv[c]) { | 655 | result.config.critical_range = argv[index++]; |
| 635 | xasprintf (&statopts, "%s", argv[c++]); | 656 | } |
| 636 | xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts); | 657 | if (result.config.statopts == NULL && argv[index]) { |
| 637 | options |= STAT; | 658 | xasprintf(&result.config.statopts, "%s", argv[index++]); |
| 659 | xasprintf(&result.config.fmt, _("%s%sSTATE = %s"), | ||
| 660 | (result.config.fmt ? result.config.fmt : ""), (result.config.options ? ", " : ""), | ||
| 661 | result.config.statopts); | ||
| 662 | result.config.options |= STAT; | ||
| 638 | } | 663 | } |
| 639 | 664 | ||
| 640 | /* this will abort in case of invalid ranges */ | 665 | /* this will abort in case of invalid ranges */ |
| 641 | set_thresholds (&procs_thresholds, warning_range, critical_range); | 666 | set_thresholds(&result.config.procs_thresholds, result.config.warning_range, |
| 667 | result.config.critical_range); | ||
| 642 | 668 | ||
| 643 | return validate_arguments (); | 669 | return validate_arguments(result); |
| 644 | } | 670 | } |
| 645 | 671 | ||
| 672 | check_procs_config_wrapper validate_arguments(check_procs_config_wrapper config_wrapper) { | ||
| 673 | if (config_wrapper.config.options == 0) { | ||
| 674 | config_wrapper.config.options = ALL; | ||
| 675 | } | ||
| 646 | 676 | ||
| 677 | if (config_wrapper.config.statopts == NULL) { | ||
| 678 | config_wrapper.config.statopts = strdup(""); | ||
| 679 | } | ||
| 647 | 680 | ||
| 648 | int | 681 | if (config_wrapper.config.prog == NULL) { |
| 649 | validate_arguments () | 682 | config_wrapper.config.prog = strdup(""); |
| 650 | { | 683 | } |
| 651 | if (options == 0) | ||
| 652 | options = ALL; | ||
| 653 | |||
| 654 | if (statopts==NULL) | ||
| 655 | statopts = strdup(""); | ||
| 656 | |||
| 657 | if (prog==NULL) | ||
| 658 | prog = strdup(""); | ||
| 659 | 684 | ||
| 660 | if (args==NULL) | 685 | if (config_wrapper.config.args == NULL) { |
| 661 | args = strdup(""); | 686 | config_wrapper.config.args = strdup(""); |
| 687 | } | ||
| 662 | 688 | ||
| 663 | if (fmt==NULL) | 689 | if (config_wrapper.config.fmt == NULL) { |
| 664 | fmt = strdup(""); | 690 | config_wrapper.config.fmt = strdup(""); |
| 691 | } | ||
| 665 | 692 | ||
| 666 | if (fails==NULL) | 693 | if (config_wrapper.config.fails == NULL) { |
| 667 | fails = strdup(""); | 694 | config_wrapper.config.fails = strdup(""); |
| 695 | } | ||
| 668 | 696 | ||
| 669 | return options; | 697 | // return options; |
| 698 | return config_wrapper; | ||
| 670 | } | 699 | } |
| 671 | 700 | ||
| 672 | |||
| 673 | /* convert the elapsed time to seconds */ | 701 | /* convert the elapsed time to seconds */ |
| 674 | int | 702 | int convert_to_seconds(char *etime, enum metric metric) { |
| 675 | convert_to_seconds(char *etime) { | 703 | int hyphcnt = 0; |
| 676 | 704 | int coloncnt = 0; | |
| 677 | char *ptr; | 705 | for (char *ptr = etime; *ptr != '\0'; ptr++) { |
| 678 | int total; | ||
| 679 | |||
| 680 | int hyphcnt; | ||
| 681 | int coloncnt; | ||
| 682 | int days; | ||
| 683 | int hours; | ||
| 684 | int minutes; | ||
| 685 | int seconds; | ||
| 686 | |||
| 687 | hyphcnt = 0; | ||
| 688 | coloncnt = 0; | ||
| 689 | days = 0; | ||
| 690 | hours = 0; | ||
| 691 | minutes = 0; | ||
| 692 | seconds = 0; | ||
| 693 | |||
| 694 | for (ptr = etime; *ptr != '\0'; ptr++) { | ||
| 695 | 706 | ||
| 696 | if (*ptr == '-') { | 707 | if (*ptr == '-') { |
| 697 | hyphcnt++; | 708 | hyphcnt++; |
| @@ -703,9 +714,12 @@ convert_to_seconds(char *etime) { | |||
| 703 | } | 714 | } |
| 704 | } | 715 | } |
| 705 | 716 | ||
| 717 | int days = 0; | ||
| 718 | int hours = 0; | ||
| 719 | int minutes = 0; | ||
| 720 | int seconds = 0; | ||
| 706 | if (hyphcnt > 0) { | 721 | if (hyphcnt > 0) { |
| 707 | sscanf(etime, "%d-%d:%d:%d", | 722 | sscanf(etime, "%d-%d:%d:%d", &days, &hours, &minutes, &seconds); |
| 708 | &days, &hours, &minutes, &seconds); | ||
| 709 | /* linux 2.6.5/2.6.6 reporting some processes with infinite | 723 | /* linux 2.6.5/2.6.6 reporting some processes with infinite |
| 710 | * elapsed times for some reason */ | 724 | * elapsed times for some reason */ |
| 711 | if (days == 49710) { | 725 | if (days == 49710) { |
| @@ -713,135 +727,129 @@ convert_to_seconds(char *etime) { | |||
| 713 | } | 727 | } |
| 714 | } else { | 728 | } else { |
| 715 | if (coloncnt == 2) { | 729 | if (coloncnt == 2) { |
| 716 | sscanf(etime, "%d:%d:%d", | 730 | sscanf(etime, "%d:%d:%d", &hours, &minutes, &seconds); |
| 717 | &hours, &minutes, &seconds); | ||
| 718 | } else if (coloncnt == 1) { | 731 | } else if (coloncnt == 1) { |
| 719 | sscanf(etime, "%d:%d", | 732 | sscanf(etime, "%d:%d", &minutes, &seconds); |
| 720 | &minutes, &seconds); | ||
| 721 | } | 733 | } |
| 722 | } | 734 | } |
| 723 | 735 | ||
| 724 | total = (days * 86400) + | 736 | int total = (days * 86400) + (hours * 3600) + (minutes * 60) + seconds; |
| 725 | (hours * 3600) + | ||
| 726 | (minutes * 60) + | ||
| 727 | seconds; | ||
| 728 | 737 | ||
| 729 | if (verbose >= 3 && metric == METRIC_ELAPSED) { | 738 | if (verbose >= 3 && metric == METRIC_ELAPSED) { |
| 730 | printf("seconds: %d\n", total); | 739 | printf("seconds: %d\n", total); |
| 731 | } | 740 | } |
| 732 | return total; | 741 | return total; |
| 733 | } | 742 | } |
| 734 | 743 | ||
| 735 | 744 | void print_help(void) { | |
| 736 | void | 745 | print_revision(progname, NP_VERSION); |
| 737 | print_help (void) | 746 | |
| 738 | { | 747 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); |
| 739 | print_revision (progname, NP_VERSION); | 748 | printf(COPYRIGHT, copyright, email); |
| 740 | 749 | ||
| 741 | printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | 750 | printf("%s\n", |
| 742 | printf (COPYRIGHT, copyright, email); | 751 | _("Checks all processes and generates WARNING or CRITICAL states if the specified")); |
| 743 | 752 | printf("%s\n", | |
| 744 | printf ("%s\n", _("Checks all processes and generates WARNING or CRITICAL states if the specified")); | 753 | _("metric is outside the required threshold ranges. The metric defaults to number")); |
| 745 | printf ("%s\n", _("metric is outside the required threshold ranges. The metric defaults to number")); | 754 | printf("%s\n", |
| 746 | printf ("%s\n", _("of processes. Search filters can be applied to limit the processes to check.")); | 755 | _("of processes. Search filters can be applied to limit the processes to check.")); |
| 747 | 756 | ||
| 748 | printf ("\n\n"); | 757 | printf("\n\n"); |
| 749 | 758 | ||
| 750 | printf ("%s\n", _("The parent process, check_procs itself and any child process of check_procs (ps)")); | 759 | printf("%s\n", |
| 751 | printf ("%s\n", _("are excluded from any checks to prevent false positives.")); | 760 | _("The parent process, check_procs itself and any child process of check_procs (ps)")); |
| 752 | 761 | printf("%s\n", _("are excluded from any checks to prevent false positives.")); | |
| 753 | printf ("\n\n"); | 762 | |
| 754 | 763 | printf("\n\n"); | |
| 755 | print_usage (); | 764 | |
| 756 | 765 | print_usage(); | |
| 757 | printf (UT_HELP_VRSN); | 766 | |
| 758 | printf (UT_EXTRA_OPTS); | 767 | printf(UT_HELP_VRSN); |
| 759 | printf (" %s\n", "-w, --warning=RANGE"); | 768 | printf(UT_EXTRA_OPTS); |
| 760 | printf (" %s\n", _("Generate warning state if metric is outside this range")); | 769 | printf(" %s\n", "-w, --warning=RANGE"); |
| 761 | printf (" %s\n", "-c, --critical=RANGE"); | 770 | printf(" %s\n", _("Generate warning state if metric is outside this range")); |
| 762 | printf (" %s\n", _("Generate critical state if metric is outside this range")); | 771 | printf(" %s\n", "-c, --critical=RANGE"); |
| 763 | printf (" %s\n", "-m, --metric=TYPE"); | 772 | printf(" %s\n", _("Generate critical state if metric is outside this range")); |
| 764 | printf (" %s\n", _("Check thresholds against metric. Valid types:")); | 773 | printf(" %s\n", "-m, --metric=TYPE"); |
| 765 | printf (" %s\n", _("PROCS - number of processes (default)")); | 774 | printf(" %s\n", _("Check thresholds against metric. Valid types:")); |
| 766 | printf (" %s\n", _("VSZ - virtual memory size")); | 775 | printf(" %s\n", _("PROCS - number of processes (default)")); |
| 767 | printf (" %s\n", _("RSS - resident set memory size")); | 776 | printf(" %s\n", _("VSZ - virtual memory size")); |
| 768 | printf (" %s\n", _("CPU - percentage CPU")); | 777 | printf(" %s\n", _("RSS - resident set memory size")); |
| 778 | printf(" %s\n", _("CPU - percentage CPU")); | ||
| 769 | /* only linux etime is support currently */ | 779 | /* only linux etime is support currently */ |
| 770 | #if defined( __linux__ ) | 780 | #if defined(__linux__) |
| 771 | printf (" %s\n", _("ELAPSED - time elapsed in seconds")); | 781 | printf(" %s\n", _("ELAPSED - time elapsed in seconds")); |
| 772 | #endif /* defined(__linux__) */ | 782 | #endif /* defined(__linux__) */ |
| 773 | printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 783 | printf(UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 774 | 784 | ||
| 775 | printf (" %s\n", "-v, --verbose"); | 785 | printf(" %s\n", "-v, --verbose"); |
| 776 | printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); | 786 | printf(" %s\n", _("Extra information. Up to 3 verbosity levels")); |
| 777 | 787 | ||
| 778 | printf (" %s\n", "-T, --traditional"); | 788 | printf(" %s\n", "-T, --traditional"); |
| 779 | printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); | 789 | printf(" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); |
| 780 | 790 | ||
| 781 | printf ("\n"); | 791 | printf("\n"); |
| 782 | printf ("%s\n", "Filters:"); | 792 | printf("%s\n", "Filters:"); |
| 783 | printf (" %s\n", "-s, --state=STATUSFLAGS"); | 793 | printf(" %s\n", "-s, --state=STATUSFLAGS"); |
| 784 | printf (" %s\n", _("Only scan for processes that have, in the output of `ps`, one or")); | 794 | printf(" %s\n", _("Only scan for processes that have, in the output of `ps`, one or")); |
| 785 | printf (" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,")); | 795 | printf(" %s\n", _("more of the status flags you specify (for example R, Z, S, RS,")); |
| 786 | printf (" %s\n", _("RSZDT, plus others based on the output of your 'ps' command).")); | 796 | printf(" %s\n", _("RSZDT, plus others based on the output of your 'ps' command).")); |
| 787 | printf (" %s\n", "-p, --ppid=PPID"); | 797 | printf(" %s\n", "-p, --ppid=PPID"); |
| 788 | printf (" %s\n", _("Only scan for children of the parent process ID indicated.")); | 798 | printf(" %s\n", _("Only scan for children of the parent process ID indicated.")); |
| 789 | printf (" %s\n", "-z, --vsz=VSZ"); | 799 | printf(" %s\n", "-z, --vsz=VSZ"); |
| 790 | printf (" %s\n", _("Only scan for processes with VSZ higher than indicated.")); | 800 | printf(" %s\n", _("Only scan for processes with VSZ higher than indicated.")); |
| 791 | printf (" %s\n", "-r, --rss=RSS"); | 801 | printf(" %s\n", "-r, --rss=RSS"); |
| 792 | printf (" %s\n", _("Only scan for processes with RSS higher than indicated.")); | 802 | printf(" %s\n", _("Only scan for processes with RSS higher than indicated.")); |
| 793 | printf (" %s\n", "-P, --pcpu=PCPU"); | 803 | printf(" %s\n", "-P, --pcpu=PCPU"); |
| 794 | printf (" %s\n", _("Only scan for processes with PCPU higher than indicated.")); | 804 | printf(" %s\n", _("Only scan for processes with PCPU higher than indicated.")); |
| 795 | printf (" %s\n", "-u, --user=USER"); | 805 | printf(" %s\n", "-u, --user=USER"); |
| 796 | printf (" %s\n", _("Only scan for processes with user name or ID indicated.")); | 806 | printf(" %s\n", _("Only scan for processes with user name or ID indicated.")); |
| 797 | printf (" %s\n", "-a, --argument-array=STRING"); | 807 | printf(" %s\n", "-a, --argument-array=STRING"); |
| 798 | printf (" %s\n", _("Only scan for processes with args that contain STRING.")); | 808 | printf(" %s\n", _("Only scan for processes with args that contain STRING.")); |
| 799 | printf (" %s\n", "--ereg-argument-array=STRING"); | 809 | printf(" %s\n", "--ereg-argument-array=STRING"); |
| 800 | printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); | 810 | printf(" %s\n", _("Only scan for processes with args that contain the regex STRING.")); |
| 801 | printf (" %s\n", "-C, --command=COMMAND"); | 811 | printf(" %s\n", "-C, --command=COMMAND"); |
| 802 | printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); | 812 | printf(" %s\n", _("Only scan for exact matches of COMMAND (without path).")); |
| 803 | printf (" %s\n", "-X, --exclude-process"); | 813 | printf(" %s\n", "-X, --exclude-process"); |
| 804 | printf (" %s\n", _("Exclude processes which match this comma separated list")); | 814 | printf(" %s\n", _("Exclude processes which match this comma separated list")); |
| 805 | printf (" %s\n", "-k, --no-kthreads"); | 815 | printf(" %s\n", "-k, --no-kthreads"); |
| 806 | printf (" %s\n", _("Only scan for non kernel threads (works on Linux only).")); | 816 | printf(" %s\n", _("Only scan for non kernel threads (works on Linux only).")); |
| 807 | 817 | ||
| 808 | printf(_("\n\ | 818 | printf(_("\n\ |
| 809 | RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ | 819 | RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ |
| 810 | specified 'max:min', a warning status will be generated if the\n\ | 820 | specified 'max:min', a warning status will be generated if the\n\ |
| 811 | count is inside the specified range\n\n")); | 821 | count is inside the specified range\n\n")); |
| 812 | 822 | ||
| 813 | printf(_("\ | 823 | printf(_("\ |
| 814 | This plugin checks the number of currently running processes and\n\ | 824 | This plugin checks the number of currently running processes and\n\ |
| 815 | generates WARNING or CRITICAL states if the process count is outside\n\ | 825 | generates WARNING or CRITICAL states if the process count is outside\n\ |
| 816 | the specified threshold ranges. The process count can be filtered by\n\ | 826 | the specified threshold ranges. The process count can be filtered by\n\ |
| 817 | process owner, parent process PID, current state (e.g., 'Z'), or may\n\ | 827 | process owner, parent process PID, current state (e.g., 'Z'), or may\n\ |
| 818 | be the total number of running processes\n\n")); | 828 | be the total number of running processes\n\n")); |
| 819 | 829 | ||
| 820 | printf ("%s\n", _("Examples:")); | 830 | printf("%s\n", _("Examples:")); |
| 821 | printf (" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); | 831 | printf(" %s\n", "check_procs -w 2:2 -c 2:1024 -C portsentry"); |
| 822 | printf (" %s\n", _("Warning if not two processes with command name portsentry.")); | 832 | printf(" %s\n", _("Warning if not two processes with command name portsentry.")); |
| 823 | printf (" %s\n\n", _("Critical if < 2 or > 1024 processes")); | 833 | printf(" %s\n\n", _("Critical if < 2 or > 1024 processes")); |
| 824 | printf (" %s\n", "check_procs -c 1: -C sshd"); | 834 | printf(" %s\n", "check_procs -c 1: -C sshd"); |
| 825 | printf (" %s\n", _("Critical if not at least 1 process with command sshd")); | 835 | printf(" %s\n", _("Critical if not at least 1 process with command sshd")); |
| 826 | printf (" %s\n", "check_procs -w 1024 -c 1: -C sshd"); | 836 | printf(" %s\n", "check_procs -w 1024 -c 1: -C sshd"); |
| 827 | printf (" %s\n", _("Warning if > 1024 processes with command name sshd.")); | 837 | printf(" %s\n", _("Warning if > 1024 processes with command name sshd.")); |
| 828 | printf (" %s\n\n", _("Critical if < 1 processes with command name sshd.")); | 838 | printf(" %s\n\n", _("Critical if < 1 processes with command name sshd.")); |
| 829 | printf (" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); | 839 | printf(" %s\n", "check_procs -w 10 -a '/usr/local/bin/perl' -u root"); |
| 830 | printf (" %s\n", _("Warning alert if > 10 processes with command arguments containing")); | 840 | printf(" %s\n", _("Warning alert if > 10 processes with command arguments containing")); |
| 831 | printf (" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); | 841 | printf(" %s\n\n", _("'/usr/local/bin/perl' and owned by root")); |
| 832 | printf (" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); | 842 | printf(" %s\n", "check_procs -w 50000 -c 100000 --metric=VSZ"); |
| 833 | printf (" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); | 843 | printf(" %s\n\n", _("Alert if VSZ of any processes over 50K or 100K")); |
| 834 | printf (" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); | 844 | printf(" %s\n", "check_procs -w 10 -c 20 --metric=CPU"); |
| 835 | printf (" %s\n", _("Alert if CPU of any processes over 10%% or 20%%")); | 845 | printf(" %s\n", _("Alert if CPU of any processes over 10%% or 20%%")); |
| 836 | 846 | ||
| 837 | printf (UT_SUPPORT); | 847 | printf(UT_SUPPORT); |
| 838 | } | 848 | } |
| 839 | 849 | ||
| 840 | void | 850 | void print_usage(void) { |
| 841 | print_usage (void) | 851 | printf("%s\n", _("Usage:")); |
| 842 | { | 852 | printf("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); |
| 843 | printf ("%s\n", _("Usage:")); | 853 | printf(" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); |
| 844 | printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); | 854 | printf(" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n"); |
| 845 | printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); | ||
| 846 | printf (" [-C command] [-X process_to_exclude] [-k] [-t timeout] [-v]\n"); | ||
| 847 | } | 855 | } |
diff --git a/plugins/check_procs.d/config.h b/plugins/check_procs.d/config.h new file mode 100644 index 00000000..e32ca066 --- /dev/null +++ b/plugins/check_procs.d/config.h | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include "regex.h" | ||
| 5 | #include "thresholds.h" | ||
| 6 | #include <stddef.h> | ||
| 7 | #include <string.h> | ||
| 8 | #include <sys/types.h> | ||
| 9 | |||
| 10 | enum metric { | ||
| 11 | METRIC_PROCS, | ||
| 12 | METRIC_VSZ, | ||
| 13 | METRIC_RSS, | ||
| 14 | METRIC_CPU, | ||
| 15 | METRIC_ELAPSED | ||
| 16 | }; | ||
| 17 | |||
| 18 | typedef struct { | ||
| 19 | int options; /* bitmask of filter criteria to test against */ | ||
| 20 | enum metric metric; | ||
| 21 | char *metric_name; | ||
| 22 | char *input_filename; | ||
| 23 | char *prog; | ||
| 24 | char *args; | ||
| 25 | char *fmt; | ||
| 26 | char *fails; | ||
| 27 | char *exclude_progs; | ||
| 28 | char **exclude_progs_arr; | ||
| 29 | char exclude_progs_counter; | ||
| 30 | regex_t re_args; | ||
| 31 | |||
| 32 | bool kthread_filter; | ||
| 33 | bool usepid; /* whether to test for pid or /proc/pid/exe */ | ||
| 34 | uid_t uid; | ||
| 35 | pid_t ppid; | ||
| 36 | int vsz; | ||
| 37 | int rss; | ||
| 38 | float pcpu; | ||
| 39 | char *statopts; | ||
| 40 | |||
| 41 | char *warning_range; | ||
| 42 | char *critical_range; | ||
| 43 | thresholds *procs_thresholds; | ||
| 44 | } check_procs_config; | ||
| 45 | |||
| 46 | check_procs_config check_procs_config_init() { | ||
| 47 | check_procs_config tmp = { | ||
| 48 | .options = 0, | ||
| 49 | .metric = METRIC_PROCS, | ||
| 50 | .metric_name = strdup("PROCS"), | ||
| 51 | .input_filename = NULL, | ||
| 52 | .prog = NULL, | ||
| 53 | .args = NULL, | ||
| 54 | .fmt = NULL, | ||
| 55 | .fails = NULL, | ||
| 56 | .exclude_progs = NULL, | ||
| 57 | .exclude_progs_arr = NULL, | ||
| 58 | .exclude_progs_counter = 0, | ||
| 59 | .re_args = {0}, | ||
| 60 | |||
| 61 | .kthread_filter = false, | ||
| 62 | .usepid = false, | ||
| 63 | .uid = 0, | ||
| 64 | .ppid = 0, | ||
| 65 | .vsz = 0, | ||
| 66 | .rss = 0, | ||
| 67 | .pcpu = 0, | ||
| 68 | .statopts = NULL, | ||
| 69 | |||
| 70 | .warning_range = NULL, | ||
| 71 | .critical_range = NULL, | ||
| 72 | .procs_thresholds = NULL, | ||
| 73 | }; | ||
| 74 | return tmp; | ||
| 75 | } | ||
diff --git a/plugins/check_radius.c b/plugins/check_radius.c index d9ff8fa7..d26f7cf3 100644 --- a/plugins/check_radius.c +++ b/plugins/check_radius.c | |||
| @@ -1,32 +1,32 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Monitoring check_radius plugin | 3 | * Monitoring check_radius plugin |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 1999-2024 Monitoring Plugins Development Team | 6 | * Copyright (c) 1999-2024 Monitoring Plugins Development Team |
| 7 | * | 7 | * |
| 8 | * Description: | 8 | * Description: |
| 9 | * | 9 | * |
| 10 | * This file contains the check_radius plugin | 10 | * This file contains the check_radius plugin |
| 11 | * | 11 | * |
| 12 | * Tests to see if a radius server is accepting connections. | 12 | * Tests to see if a radius server is accepting connections. |
| 13 | * | 13 | * |
| 14 | * | 14 | * |
| 15 | * This program is free software: you can redistribute it and/or modify | 15 | * This program is free software: you can redistribute it and/or modify |
| 16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
| 17 | * the Free Software Foundation, either version 3 of the License, or | 17 | * the Free Software Foundation, either version 3 of the License, or |
| 18 | * (at your option) any later version. | 18 | * (at your option) any later version. |
| 19 | * | 19 | * |
| 20 | * This program is distributed in the hope that it will be useful, | 20 | * This program is distributed in the hope that it will be useful, |
| 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 23 | * GNU General Public License for more details. | 23 | * GNU General Public License for more details. |
| 24 | * | 24 | * |
| 25 | * You should have received a copy of the GNU General Public License | 25 | * You should have received a copy of the GNU General Public License |
| 26 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 26 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 27 | * | 27 | * |
| 28 | * | 28 | * |
| 29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
| 30 | 30 | ||
| 31 | const char *progname = "check_radius"; | 31 | const char *progname = "check_radius"; |
| 32 | const char *copyright = "2000-2024"; | 32 | const char *copyright = "2000-2024"; |
| @@ -35,64 +35,58 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 35 | #include "common.h" | 35 | #include "common.h" |
| 36 | #include "utils.h" | 36 | #include "utils.h" |
| 37 | #include "netutils.h" | 37 | #include "netutils.h" |
| 38 | #include "states.h" | ||
| 39 | #include "check_radius.d/config.h" | ||
| 38 | 40 | ||
| 39 | #if defined(HAVE_LIBRADCLI) | 41 | #if defined(HAVE_LIBRADCLI) |
| 40 | #include <radcli/radcli.h> | 42 | # include <radcli/radcli.h> |
| 41 | #elif defined(HAVE_LIBFREERADIUS_CLIENT) | 43 | #elif defined(HAVE_LIBFREERADIUS_CLIENT) |
| 42 | #include <freeradius-client.h> | 44 | # include <freeradius-client.h> |
| 43 | #elif defined(HAVE_LIBRADIUSCLIENT_NG) | 45 | #elif defined(HAVE_LIBRADIUSCLIENT_NG) |
| 44 | #include <radiusclient-ng.h> | 46 | # include <radiusclient-ng.h> |
| 45 | #else | 47 | #else |
| 46 | #include <radiusclient.h> | 48 | # include <radiusclient.h> |
| 47 | #endif | 49 | #endif |
| 48 | 50 | ||
| 49 | static int process_arguments (int /*argc*/, char ** /*argv*/); | 51 | typedef struct { |
| 50 | static void print_help (void); | 52 | int errorcode; |
| 51 | void print_usage (void); | 53 | check_radius_config config; |
| 52 | 54 | } check_radius_config_wrapper; | |
| 53 | #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) | 55 | static check_radius_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 54 | #define my_rc_conf_str(a) rc_conf_str(rch,a) | 56 | static void print_help(void); |
| 55 | #if defined(HAVE_LIBRADCLI) | 57 | void print_usage(void); |
| 56 | #define my_rc_send_server(a,b) rc_send_server(rch,a,b,AUTH) | 58 | |
| 57 | #else | 59 | #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \ |
| 58 | #define my_rc_send_server(a,b) rc_send_server(rch,a,b) | 60 | defined(HAVE_LIBRADCLI) |
| 59 | #endif | 61 | # define my_rc_conf_str(a) rc_conf_str(rch, a) |
| 60 | #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADCLI) | 62 | # if defined(HAVE_LIBRADCLI) |
| 61 | #define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,(a)->secret,e,f) | 63 | # define my_rc_send_server(a, b) rc_send_server(rch, a, b, AUTH) |
| 64 | # else | ||
| 65 | # define my_rc_send_server(a, b) rc_send_server(rch, a, b) | ||
| 66 | # endif | ||
| 67 | # if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADCLI) | ||
| 68 | # define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(rch, a, b, c, d, (a)->secret, e, f) | ||
| 69 | # else | ||
| 70 | # define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(rch, a, b, c, d, e, f) | ||
| 71 | # endif | ||
| 72 | # define my_rc_avpair_add(a, b, c, d) rc_avpair_add(rch, a, b, c, -1, d) | ||
| 73 | # define my_rc_read_dictionary(a) rc_read_dictionary(rch, a) | ||
| 62 | #else | 74 | #else |
| 63 | #define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,e,f) | 75 | # define my_rc_conf_str(a) rc_conf_str(a) |
| 64 | #endif | 76 | # define my_rc_send_server(a, b) rc_send_server(a, b) |
| 65 | #define my_rc_avpair_add(a,b,c,d) rc_avpair_add(rch,a,b,c,-1,d) | 77 | # define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(a, b, c, d, e, f) |
| 66 | #define my_rc_read_dictionary(a) rc_read_dictionary(rch, a) | 78 | # define my_rc_avpair_add(a, b, c, d) rc_avpair_add(a, b, c, d) |
| 67 | #else | 79 | # define my_rc_read_dictionary(a) rc_read_dictionary(a) |
| 68 | #define my_rc_conf_str(a) rc_conf_str(a) | ||
| 69 | #define my_rc_send_server(a,b) rc_send_server(a, b) | ||
| 70 | #define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(a,b,c,d,e,f) | ||
| 71 | #define my_rc_avpair_add(a,b,c,d) rc_avpair_add(a, b, c, d) | ||
| 72 | #define my_rc_read_dictionary(a) rc_read_dictionary(a) | ||
| 73 | #endif | 80 | #endif |
| 74 | 81 | ||
| 75 | /* REJECT_RC is only defined in some version of radiusclient. It has | 82 | /* REJECT_RC is only defined in some version of radiusclient. It has |
| 76 | * been reported from radiusclient-ng 0.5.6 on FreeBSD 7.2-RELEASE */ | 83 | * been reported from radiusclient-ng 0.5.6 on FreeBSD 7.2-RELEASE */ |
| 77 | #ifndef REJECT_RC | 84 | #ifndef REJECT_RC |
| 78 | #define REJECT_RC BADRESP_RC | 85 | # define REJECT_RC BADRESP_RC |
| 79 | #endif | 86 | #endif |
| 80 | 87 | ||
| 81 | static int my_rc_read_config(char * /*a*/); | 88 | static int my_rc_read_config(char * /*a*/, rc_handle ** /*rch*/); |
| 82 | |||
| 83 | #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) | ||
| 84 | static rc_handle *rch = NULL; | ||
| 85 | #endif | ||
| 86 | 89 | ||
| 87 | static char *server = NULL; | ||
| 88 | static char *username = NULL; | ||
| 89 | static char *password = NULL; | ||
| 90 | static char *nasid = NULL; | ||
| 91 | static char *nasipaddress = NULL; | ||
| 92 | static char *expect = NULL; | ||
| 93 | static char *config_file = NULL; | ||
| 94 | static unsigned short port = PW_AUTH_UDP_PORT; | ||
| 95 | static int retries = 1; | ||
| 96 | static bool verbose = false; | 90 | static bool verbose = false; |
| 97 | 91 | ||
| 98 | /****************************************************************************** | 92 | /****************************************************************************** |
| @@ -148,149 +142,171 @@ Please note that all tags must be lowercase to use the DocBook XML DTD. | |||
| 148 | -@@ | 142 | -@@ |
| 149 | ******************************************************************************/ | 143 | ******************************************************************************/ |
| 150 | 144 | ||
| 145 | int main(int argc, char **argv) { | ||
| 146 | setlocale(LC_ALL, ""); | ||
| 147 | bindtextdomain(PACKAGE, LOCALEDIR); | ||
| 148 | textdomain(PACKAGE); | ||
| 151 | 149 | ||
| 150 | /* Parse extra opts if any */ | ||
| 151 | argv = np_extra_opts(&argc, argv, progname); | ||
| 152 | |||
| 153 | check_radius_config_wrapper tmp_config = process_arguments(argc, argv); | ||
| 154 | |||
| 155 | if (tmp_config.errorcode == ERROR) { | ||
| 156 | usage4(_("Could not parse arguments")); | ||
| 157 | } | ||
| 158 | |||
| 159 | check_radius_config config = tmp_config.config; | ||
| 160 | |||
| 161 | #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \ | ||
| 162 | defined(HAVE_LIBRADCLI) | ||
| 163 | rc_handle *rch = NULL; | ||
| 164 | #endif | ||
| 165 | |||
| 166 | char *str = strdup("dictionary"); | ||
| 167 | if ((config.config_file && my_rc_read_config(config.config_file, &rch)) || | ||
| 168 | my_rc_read_dictionary(my_rc_conf_str(str))) { | ||
| 169 | die(STATE_UNKNOWN, _("Config file error\n")); | ||
| 170 | } | ||
| 171 | |||
| 172 | uint32_t service = PW_AUTHENTICATE_ONLY; | ||
| 173 | |||
| 174 | SEND_DATA data; | ||
| 175 | memset(&data, 0, sizeof(data)); | ||
| 176 | if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && | ||
| 177 | my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, config.username, 0) && | ||
| 178 | my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) { | ||
| 179 | die(STATE_UNKNOWN, _("Out of Memory?\n")); | ||
| 180 | } | ||
| 181 | |||
| 182 | if (config.nas_id != NULL) { | ||
| 183 | if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) { | ||
| 184 | die(STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); | ||
| 185 | } | ||
| 186 | } | ||
| 152 | 187 | ||
| 153 | int | ||
| 154 | main (int argc, char **argv) | ||
| 155 | { | ||
| 156 | struct sockaddr_storage ss; | ||
| 157 | char name[HOST_NAME_MAX]; | 188 | char name[HOST_NAME_MAX]; |
| 189 | if (config.nas_ip_address == NULL) { | ||
| 190 | if (gethostname(name, sizeof(name)) != 0) { | ||
| 191 | die(STATE_UNKNOWN, _("gethostname() failed!\n")); | ||
| 192 | } | ||
| 193 | config.nas_ip_address = name; | ||
| 194 | } | ||
| 195 | |||
| 196 | struct sockaddr_storage radius_server_socket; | ||
| 197 | if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) { | ||
| 198 | die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); | ||
| 199 | } | ||
| 200 | |||
| 201 | uint32_t client_id = ntohl(((struct sockaddr_in *)&radius_server_socket)->sin_addr.s_addr); | ||
| 202 | if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) { | ||
| 203 | die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); | ||
| 204 | } | ||
| 205 | |||
| 206 | my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval, | ||
| 207 | config.retries); | ||
| 208 | |||
| 158 | #ifdef RC_BUFFER_LEN | 209 | #ifdef RC_BUFFER_LEN |
| 159 | char msg[RC_BUFFER_LEN]; | 210 | char msg[RC_BUFFER_LEN]; |
| 160 | #else | 211 | #else |
| 161 | char msg[BUFFER_LEN]; | 212 | char msg[BUFFER_LEN]; |
| 162 | #endif | 213 | #endif |
| 163 | SEND_DATA data; | ||
| 164 | int result = STATE_UNKNOWN; | ||
| 165 | uint32_t client_id, service; | ||
| 166 | char *str; | ||
| 167 | 214 | ||
| 168 | setlocale (LC_ALL, ""); | 215 | int result = my_rc_send_server(&data, msg); |
| 169 | bindtextdomain (PACKAGE, LOCALEDIR); | 216 | rc_avpair_free(data.send_pairs); |
| 170 | textdomain (PACKAGE); | 217 | if (data.receive_pairs) { |
| 171 | 218 | rc_avpair_free(data.receive_pairs); | |
| 172 | /* Parse extra opts if any */ | 219 | } |
| 173 | argv=np_extra_opts (&argc, argv, progname); | ||
| 174 | 220 | ||
| 175 | if (process_arguments (argc, argv) == ERROR) | 221 | if (result == TIMEOUT_RC) { |
| 176 | usage4 (_("Could not parse arguments")); | 222 | printf("Timeout\n"); |
| 223 | exit(STATE_CRITICAL); | ||
| 224 | } | ||
| 177 | 225 | ||
| 178 | str = strdup ("dictionary"); | 226 | if (result == ERROR_RC) { |
| 179 | if ((config_file && my_rc_read_config (config_file)) || | 227 | printf(_("Auth Error\n")); |
| 180 | my_rc_read_dictionary (my_rc_conf_str (str))) | 228 | exit(STATE_CRITICAL); |
| 181 | die (STATE_UNKNOWN, _("Config file error\n")); | 229 | } |
| 182 | 230 | ||
| 183 | service = PW_AUTHENTICATE_ONLY; | 231 | if (result == REJECT_RC) { |
| 232 | printf(_("Auth Failed\n")); | ||
| 233 | exit(STATE_WARNING); | ||
| 234 | } | ||
| 184 | 235 | ||
| 185 | memset (&data, 0, sizeof(data)); | 236 | if (result == BADRESP_RC) { |
| 186 | if (!(my_rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && | 237 | printf(_("Bad Response\n")); |
| 187 | my_rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) && | 238 | exit(STATE_WARNING); |
| 188 | my_rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0) | 239 | } |
| 189 | )) | ||
| 190 | die (STATE_UNKNOWN, _("Out of Memory?\n")); | ||
| 191 | 240 | ||
| 192 | if (nasid != NULL) { | 241 | if (config.expect && !strstr(msg, config.expect)) { |
| 193 | if (!(my_rc_avpair_add (&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))) | 242 | printf("%s\n", msg); |
| 194 | die (STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); | 243 | exit(STATE_WARNING); |
| 195 | } | 244 | } |
| 196 | 245 | ||
| 197 | if (nasipaddress == NULL) { | 246 | if (result == OK_RC) { |
| 198 | if (gethostname (name, sizeof(name)) != 0) | 247 | printf(_("Auth OK\n")); |
| 199 | die (STATE_UNKNOWN, _("gethostname() failed!\n")); | 248 | exit(STATE_OK); |
| 200 | nasipaddress = name; | ||
| 201 | } | 249 | } |
| 202 | if (!dns_lookup (nasipaddress, &ss, AF_INET)) /* TODO: Support IPv6. */ | 250 | |
| 203 | die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); | ||
| 204 | client_id = ntohl (((struct sockaddr_in *)&ss)->sin_addr.s_addr); | ||
| 205 | if (my_rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) | ||
| 206 | die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); | ||
| 207 | |||
| 208 | my_rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval, | ||
| 209 | retries); | ||
| 210 | |||
| 211 | result = my_rc_send_server (&data, msg); | ||
| 212 | rc_avpair_free (data.send_pairs); | ||
| 213 | if (data.receive_pairs) | ||
| 214 | rc_avpair_free (data.receive_pairs); | ||
| 215 | |||
| 216 | if (result == TIMEOUT_RC) | ||
| 217 | die (STATE_CRITICAL, _("Timeout\n")); | ||
| 218 | if (result == ERROR_RC) | ||
| 219 | die (STATE_CRITICAL, _("Auth Error\n")); | ||
| 220 | if (result == REJECT_RC) | ||
| 221 | die (STATE_WARNING, _("Auth Failed\n")); | ||
| 222 | if (result == BADRESP_RC) | ||
| 223 | die (STATE_WARNING, _("Bad Response\n")); | ||
| 224 | if (expect && !strstr (msg, expect)) | ||
| 225 | die (STATE_WARNING, "%s\n", msg); | ||
| 226 | if (result == OK_RC) | ||
| 227 | die (STATE_OK, _("Auth OK\n")); | ||
| 228 | (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); | 251 | (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); |
| 229 | die (STATE_UNKNOWN, "%s\n", msg); | 252 | printf("%s\n", msg); |
| 253 | exit(STATE_UNKNOWN); | ||
| 230 | } | 254 | } |
| 231 | 255 | ||
| 232 | |||
| 233 | |||
| 234 | /* process command-line arguments */ | 256 | /* process command-line arguments */ |
| 235 | int | 257 | check_radius_config_wrapper process_arguments(int argc, char **argv) { |
| 236 | process_arguments (int argc, char **argv) | ||
| 237 | { | ||
| 238 | int c; | ||
| 239 | |||
| 240 | int option = 0; | ||
| 241 | static struct option longopts[] = { | 258 | static struct option longopts[] = { |
| 242 | {"hostname", required_argument, 0, 'H'}, | 259 | {"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'}, |
| 243 | {"port", required_argument, 0, 'P'}, | 260 | {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, |
| 244 | {"username", required_argument, 0, 'u'}, | 261 | {"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'}, |
| 245 | {"password", required_argument, 0, 'p'}, | 262 | {"filename", required_argument, 0, 'F'}, {"expect", required_argument, 0, 'e'}, |
| 246 | {"nas-id", required_argument, 0, 'n'}, | 263 | {"retries", required_argument, 0, 'r'}, {"timeout", required_argument, 0, 't'}, |
| 247 | {"nas-ip-address", required_argument, 0, 'N'}, | 264 | {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, |
| 248 | {"filename", required_argument, 0, 'F'}, | 265 | {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; |
| 249 | {"expect", required_argument, 0, 'e'}, | 266 | |
| 250 | {"retries", required_argument, 0, 'r'}, | 267 | check_radius_config_wrapper result = { |
| 251 | {"timeout", required_argument, 0, 't'}, | 268 | .errorcode = OK, |
| 252 | {"verbose", no_argument, 0, 'v'}, | 269 | .config = check_radius_config_init(), |
| 253 | {"version", no_argument, 0, 'V'}, | ||
| 254 | {"help", no_argument, 0, 'h'}, | ||
| 255 | {0, 0, 0, 0} | ||
| 256 | }; | 270 | }; |
| 257 | 271 | ||
| 258 | while (1) { | 272 | while (true) { |
| 259 | c = getopt_long (argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, | 273 | int option = 0; |
| 260 | &option); | 274 | int option_index = getopt_long(argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, &option); |
| 261 | 275 | ||
| 262 | if (c == -1 || c == EOF || c == 1) | 276 | if (option_index == -1 || option_index == EOF || option_index == 1) { |
| 263 | break; | 277 | break; |
| 278 | } | ||
| 264 | 279 | ||
| 265 | switch (c) { | 280 | switch (option_index) { |
| 266 | case '?': /* print short usage statement if args not parsable */ | 281 | case '?': /* print short usage statement if args not parsable */ |
| 267 | usage5 (); | 282 | usage5(); |
| 268 | case 'h': /* help */ | 283 | case 'h': /* help */ |
| 269 | print_help (); | 284 | print_help(); |
| 270 | exit (STATE_UNKNOWN); | 285 | exit(STATE_UNKNOWN); |
| 271 | case 'V': /* version */ | 286 | case 'V': /* version */ |
| 272 | print_revision (progname, NP_VERSION); | 287 | print_revision(progname, NP_VERSION); |
| 273 | exit (STATE_UNKNOWN); | 288 | exit(STATE_UNKNOWN); |
| 274 | case 'v': /* verbose mode */ | 289 | case 'v': /* verbose mode */ |
| 275 | verbose = true; | 290 | verbose = true; |
| 276 | break; | 291 | break; |
| 277 | case 'H': /* hostname */ | 292 | case 'H': /* hostname */ |
| 278 | if (!is_host (optarg)) { | 293 | if (!is_host(optarg)) { |
| 279 | usage2 (_("Invalid hostname/address"), optarg); | 294 | usage2(_("Invalid hostname/address"), optarg); |
| 280 | } | 295 | } |
| 281 | server = optarg; | 296 | result.config.server = optarg; |
| 282 | break; | 297 | break; |
| 283 | case 'P': /* port */ | 298 | case 'P': /* port */ |
| 284 | if (is_intnonneg (optarg)) | 299 | if (is_intnonneg(optarg)) { |
| 285 | port = (unsigned short)atoi (optarg); | 300 | result.config.port = (unsigned short)atoi(optarg); |
| 286 | else | 301 | } else { |
| 287 | usage4 (_("Port must be a positive integer")); | 302 | usage4(_("Port must be a positive integer")); |
| 303 | } | ||
| 288 | break; | 304 | break; |
| 289 | case 'u': /* username */ | 305 | case 'u': /* username */ |
| 290 | username = optarg; | 306 | result.config.username = optarg; |
| 291 | break; | 307 | break; |
| 292 | case 'p': /* password */ | 308 | case 'p': /* password */ |
| 293 | password = strdup(optarg); | 309 | result.config.password = strdup(optarg); |
| 294 | 310 | ||
| 295 | /* Delete the password from process list */ | 311 | /* Delete the password from process list */ |
| 296 | while (*optarg != '\0') { | 312 | while (*optarg != '\0') { |
| @@ -298,119 +314,118 @@ process_arguments (int argc, char **argv) | |||
| 298 | optarg++; | 314 | optarg++; |
| 299 | } | 315 | } |
| 300 | break; | 316 | break; |
| 301 | case 'n': /* nas id */ | 317 | case 'n': /* nas id */ |
| 302 | nasid = optarg; | 318 | result.config.nas_id = optarg; |
| 303 | break; | 319 | break; |
| 304 | case 'N': /* nas ip address */ | 320 | case 'N': /* nas ip address */ |
| 305 | nasipaddress = optarg; | 321 | result.config.nas_ip_address = optarg; |
| 306 | break; | 322 | break; |
| 307 | case 'F': /* configuration file */ | 323 | case 'F': /* configuration file */ |
| 308 | config_file = optarg; | 324 | result.config.config_file = optarg; |
| 309 | break; | 325 | break; |
| 310 | case 'e': /* expect */ | 326 | case 'e': /* expect */ |
| 311 | expect = optarg; | 327 | result.config.expect = optarg; |
| 312 | break; | 328 | break; |
| 313 | case 'r': /* retries */ | 329 | case 'r': /* retries */ |
| 314 | if (is_intpos (optarg)) | 330 | if (is_intpos(optarg)) { |
| 315 | retries = atoi (optarg); | 331 | result.config.retries = atoi(optarg); |
| 316 | else | 332 | } else { |
| 317 | usage4 (_("Number of retries must be a positive integer")); | 333 | usage4(_("Number of retries must be a positive integer")); |
| 334 | } | ||
| 318 | break; | 335 | break; |
| 319 | case 't': /* timeout */ | 336 | case 't': /* timeout */ |
| 320 | if (is_intpos (optarg)) | 337 | if (is_intpos(optarg)) { |
| 321 | timeout_interval = (unsigned)atoi (optarg); | 338 | timeout_interval = (unsigned)atoi(optarg); |
| 322 | else | 339 | } else { |
| 323 | usage2 (_("Timeout interval must be a positive integer"), optarg); | 340 | usage2(_("Timeout interval must be a positive integer"), optarg); |
| 341 | } | ||
| 324 | break; | 342 | break; |
| 325 | } | 343 | } |
| 326 | } | 344 | } |
| 327 | 345 | ||
| 328 | if (server == NULL) | 346 | if (result.config.server == NULL) { |
| 329 | usage4 (_("Hostname was not supplied")); | 347 | usage4(_("Hostname was not supplied")); |
| 330 | if (username == NULL) | 348 | } |
| 331 | usage4 (_("User not specified")); | 349 | if (result.config.username == NULL) { |
| 332 | if (password == NULL) | 350 | usage4(_("User not specified")); |
| 333 | usage4 (_("Password not specified")); | 351 | } |
| 334 | if (config_file == NULL) | 352 | if (result.config.password == NULL) { |
| 335 | usage4 (_("Configuration file not specified")); | 353 | usage4(_("Password not specified")); |
| 354 | } | ||
| 355 | if (result.config.config_file == NULL) { | ||
| 356 | usage4(_("Configuration file not specified")); | ||
| 357 | } | ||
| 336 | 358 | ||
| 337 | return OK; | 359 | return result; |
| 338 | } | 360 | } |
| 339 | 361 | ||
| 340 | 362 | void print_help(void) { | |
| 341 | |||
| 342 | void | ||
| 343 | print_help (void) | ||
| 344 | { | ||
| 345 | char *myport; | 363 | char *myport; |
| 346 | xasprintf (&myport, "%d", PW_AUTH_UDP_PORT); | 364 | xasprintf(&myport, "%d", PW_AUTH_UDP_PORT); |
| 347 | 365 | ||
| 348 | print_revision (progname, NP_VERSION); | 366 | print_revision(progname, NP_VERSION); |
| 349 | 367 | ||
| 350 | printf ("Copyright (c) 1999 Robert August Vincent II\n"); | 368 | printf("Copyright (c) 1999 Robert August Vincent II\n"); |
| 351 | printf (COPYRIGHT, copyright, email); | 369 | printf(COPYRIGHT, copyright, email); |
| 352 | 370 | ||
| 353 | printf("%s\n", _("Tests to see if a RADIUS server is accepting connections.")); | 371 | printf("%s\n", _("Tests to see if a RADIUS server is accepting connections.")); |
| 354 | 372 | ||
| 355 | printf ("\n\n"); | 373 | printf("\n\n"); |
| 356 | 374 | ||
| 357 | print_usage (); | 375 | print_usage(); |
| 358 | 376 | ||
| 359 | printf (UT_HELP_VRSN); | 377 | printf(UT_HELP_VRSN); |
| 360 | printf (UT_EXTRA_OPTS); | 378 | printf(UT_EXTRA_OPTS); |
| 361 | 379 | ||
| 362 | printf (UT_HOST_PORT, 'P', myport); | 380 | printf(UT_HOST_PORT, 'P', myport); |
| 363 | 381 | ||
| 364 | printf (" %s\n", "-u, --username=STRING"); | 382 | printf(" %s\n", "-u, --username=STRING"); |
| 365 | printf (" %s\n", _("The user to authenticate")); | 383 | printf(" %s\n", _("The user to authenticate")); |
| 366 | printf (" %s\n", "-p, --password=STRING"); | 384 | printf(" %s\n", "-p, --password=STRING"); |
| 367 | printf (" %s\n", _("Password for authentication (SECURITY RISK)")); | 385 | printf(" %s\n", _("Password for authentication (SECURITY RISK)")); |
| 368 | printf (" %s\n", "-n, --nas-id=STRING"); | 386 | printf(" %s\n", "-n, --nas-id=STRING"); |
| 369 | printf (" %s\n", _("NAS identifier")); | 387 | printf(" %s\n", _("NAS identifier")); |
| 370 | printf (" %s\n", "-N, --nas-ip-address=STRING"); | 388 | printf(" %s\n", "-N, --nas-ip-address=STRING"); |
| 371 | printf (" %s\n", _("NAS IP Address")); | 389 | printf(" %s\n", _("NAS IP Address")); |
| 372 | printf (" %s\n", "-F, --filename=STRING"); | 390 | printf(" %s\n", "-F, --filename=STRING"); |
| 373 | printf (" %s\n", _("Configuration file")); | 391 | printf(" %s\n", _("Configuration file")); |
| 374 | printf (" %s\n", "-e, --expect=STRING"); | 392 | printf(" %s\n", "-e, --expect=STRING"); |
| 375 | printf (" %s\n", _("Response string to expect from the server")); | 393 | printf(" %s\n", _("Response string to expect from the server")); |
| 376 | printf (" %s\n", "-r, --retries=INTEGER"); | 394 | printf(" %s\n", "-r, --retries=INTEGER"); |
| 377 | printf (" %s\n", _("Number of times to retry a failed connection")); | 395 | printf(" %s\n", _("Number of times to retry a failed connection")); |
| 378 | 396 | ||
| 379 | printf (UT_CONN_TIMEOUT, timeout_interval); | 397 | printf(UT_CONN_TIMEOUT, timeout_interval); |
| 380 | 398 | ||
| 381 | printf ("\n"); | 399 | printf("\n"); |
| 382 | printf ("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections.")); | 400 | printf("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections.")); |
| 383 | printf ("%s\n", _("The server to test must be specified in the invocation, as well as a user")); | 401 | printf("%s\n", _("The server to test must be specified in the invocation, as well as a user")); |
| 384 | printf ("%s\n", _("name and password. A configuration file must be present. The format of")); | 402 | printf("%s\n", _("name and password. A configuration file must be present. The format of")); |
| 385 | printf ("%s\n", _("the configuration file is described in the radiusclient library sources.")); | 403 | printf("%s\n", _("the configuration file is described in the radiusclient library sources.")); |
| 386 | printf ("%s\n", _("The password option presents a substantial security issue because the")); | 404 | printf("%s\n", _("The password option presents a substantial security issue because the")); |
| 387 | printf ("%s\n", _("password can possibly be determined by careful watching of the command line")); | 405 | printf("%s\n", |
| 388 | printf ("%s\n", _("in a process listing. This risk is exacerbated because the plugin will")); | 406 | _("password can possibly be determined by careful watching of the command line")); |
| 389 | printf ("%s\n", _("typically be executed at regular predictable intervals. Please be sure that")); | 407 | printf("%s\n", _("in a process listing. This risk is exacerbated because the plugin will")); |
| 390 | printf ("%s\n", _("the password used does not allow access to sensitive system resources.")); | 408 | printf("%s\n", |
| 391 | 409 | _("typically be executed at regular predictable intervals. Please be sure that")); | |
| 392 | printf (UT_SUPPORT); | 410 | printf("%s\n", _("the password used does not allow access to sensitive system resources.")); |
| 411 | |||
| 412 | printf(UT_SUPPORT); | ||
| 393 | } | 413 | } |
| 394 | 414 | ||
| 395 | 415 | void print_usage(void) { | |
| 396 | 416 | printf("%s\n", _("Usage:")); | |
| 397 | void | 417 | printf("%s -H host -F config_file -u username -p password\n\ |
| 398 | print_usage (void) | ||
| 399 | { | ||
| 400 | printf ("%s\n", _("Usage:")); | ||
| 401 | printf ("%s -H host -F config_file -u username -p password\n\ | ||
| 402 | [-P port] [-t timeout] [-r retries] [-e expect]\n\ | 418 | [-P port] [-t timeout] [-r retries] [-e expect]\n\ |
| 403 | [-n nas-id] [-N nas-ip-addr]\n", progname); | 419 | [-n nas-id] [-N nas-ip-addr]\n", |
| 420 | progname); | ||
| 404 | } | 421 | } |
| 405 | 422 | ||
| 406 | 423 | int my_rc_read_config(char *config_file_name, rc_handle **rch) { | |
| 407 | 424 | #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \ | |
| 408 | int my_rc_read_config(char * a) | 425 | defined(HAVE_LIBRADCLI) |
| 409 | { | 426 | *rch = rc_read_config(config_file_name); |
| 410 | #if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) | ||
| 411 | rch = rc_read_config(a); | ||
| 412 | return (rch == NULL) ? 1 : 0; | 427 | return (rch == NULL) ? 1 : 0; |
| 413 | #else | 428 | #else |
| 414 | return rc_read_config(a); | 429 | return rc_read_config(config_file_name); |
| 415 | #endif | 430 | #endif |
| 416 | } | 431 | } |
diff --git a/plugins/check_radius.d/config.h b/plugins/check_radius.d/config.h new file mode 100644 index 00000000..b27d31e7 --- /dev/null +++ b/plugins/check_radius.d/config.h | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include <stddef.h> | ||
| 5 | #if defined(HAVE_LIBRADCLI) | ||
| 6 | # include <radcli/radcli.h> | ||
| 7 | #elif defined(HAVE_LIBFREERADIUS_CLIENT) | ||
| 8 | # include <freeradius-client.h> | ||
| 9 | #elif defined(HAVE_LIBRADIUSCLIENT_NG) | ||
| 10 | # include <radiusclient-ng.h> | ||
| 11 | #else | ||
| 12 | # include <radiusclient.h> | ||
| 13 | #endif | ||
| 14 | |||
| 15 | typedef struct { | ||
| 16 | char *server; | ||
| 17 | char *username; | ||
| 18 | char *password; | ||
| 19 | char *config_file; | ||
| 20 | char *nas_id; | ||
| 21 | char *nas_ip_address; | ||
| 22 | int retries; | ||
| 23 | unsigned short port; | ||
| 24 | |||
| 25 | char *expect; | ||
| 26 | } check_radius_config; | ||
| 27 | |||
| 28 | check_radius_config check_radius_config_init() { | ||
| 29 | check_radius_config tmp = { | ||
| 30 | .server = NULL, | ||
| 31 | .username = NULL, | ||
| 32 | .password = NULL, | ||
| 33 | .config_file = NULL, | ||
| 34 | .nas_id = NULL, | ||
| 35 | .nas_ip_address = NULL, | ||
| 36 | .retries = 1, | ||
| 37 | .port = PW_AUTH_UDP_PORT, | ||
| 38 | |||
| 39 | .expect = NULL, | ||
| 40 | }; | ||
| 41 | return tmp; | ||
| 42 | } | ||
diff --git a/plugins/check_real.c b/plugins/check_real.c index 369a88b1..66d07f8f 100644 --- a/plugins/check_real.c +++ b/plugins/check_real.c | |||
| @@ -28,6 +28,8 @@ | |||
| 28 | * | 28 | * |
| 29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
| 30 | 30 | ||
| 31 | #include "states.h" | ||
| 32 | #include <stdio.h> | ||
| 31 | const char *progname = "check_real"; | 33 | const char *progname = "check_real"; |
| 32 | const char *copyright = "2000-2024"; | 34 | const char *copyright = "2000-2024"; |
| 33 | const char *email = "devel@monitoring-plugins.org"; | 35 | const char *email = "devel@monitoring-plugins.org"; |
| @@ -35,27 +37,20 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 35 | #include "common.h" | 37 | #include "common.h" |
| 36 | #include "netutils.h" | 38 | #include "netutils.h" |
| 37 | #include "utils.h" | 39 | #include "utils.h" |
| 38 | 40 | #include "check_real.d/config.h" | |
| 39 | enum { | ||
| 40 | PORT = 554 | ||
| 41 | }; | ||
| 42 | 41 | ||
| 43 | #define EXPECT "RTSP/1." | 42 | #define EXPECT "RTSP/1." |
| 44 | #define URL "" | 43 | #define URL "" |
| 45 | 44 | ||
| 46 | static int process_arguments(int, char **); | 45 | typedef struct { |
| 46 | int errorcode; | ||
| 47 | check_real_config config; | ||
| 48 | } check_real_config_wrapper; | ||
| 49 | static check_real_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 50 | |||
| 47 | static void print_help(void); | 51 | static void print_help(void); |
| 48 | void print_usage(void); | 52 | void print_usage(void); |
| 49 | 53 | ||
| 50 | static int server_port = PORT; | ||
| 51 | static char *server_address; | ||
| 52 | static char *host_name; | ||
| 53 | static char *server_url = NULL; | ||
| 54 | static char *server_expect; | ||
| 55 | static int warning_time = 0; | ||
| 56 | static bool check_warning_time = false; | ||
| 57 | static int critical_time = 0; | ||
| 58 | static bool check_critical_time = false; | ||
| 59 | static bool verbose = false; | 54 | static bool verbose = false; |
| 60 | 55 | ||
| 61 | int main(int argc, char **argv) { | 56 | int main(int argc, char **argv) { |
| @@ -66,8 +61,12 @@ int main(int argc, char **argv) { | |||
| 66 | /* Parse extra opts if any */ | 61 | /* Parse extra opts if any */ |
| 67 | argv = np_extra_opts(&argc, argv, progname); | 62 | argv = np_extra_opts(&argc, argv, progname); |
| 68 | 63 | ||
| 69 | if (process_arguments(argc, argv) == ERROR) | 64 | check_real_config_wrapper tmp_config = process_arguments(argc, argv); |
| 65 | if (tmp_config.errorcode == ERROR) { | ||
| 70 | usage4(_("Could not parse arguments")); | 66 | usage4(_("Could not parse arguments")); |
| 67 | } | ||
| 68 | |||
| 69 | const check_real_config config = tmp_config.config; | ||
| 71 | 70 | ||
| 72 | /* initialize alarm signal handling */ | 71 | /* initialize alarm signal handling */ |
| 73 | signal(SIGALRM, socket_timeout_alarm_handler); | 72 | signal(SIGALRM, socket_timeout_alarm_handler); |
| @@ -78,38 +77,52 @@ int main(int argc, char **argv) { | |||
| 78 | 77 | ||
| 79 | /* try to connect to the host at the given port number */ | 78 | /* try to connect to the host at the given port number */ |
| 80 | int socket; | 79 | int socket; |
| 81 | if (my_tcp_connect(server_address, server_port, &socket) != STATE_OK) | 80 | if (my_tcp_connect(config.server_address, config.server_port, &socket) != STATE_OK) { |
| 82 | die(STATE_CRITICAL, _("Unable to connect to %s on port %d\n"), server_address, server_port); | 81 | die(STATE_CRITICAL, _("Unable to connect to %s on port %d\n"), config.server_address, |
| 82 | config.server_port); | ||
| 83 | } | ||
| 83 | 84 | ||
| 84 | /* Part I - Server Check */ | 85 | /* Part I - Server Check */ |
| 85 | 86 | ||
| 86 | /* send the OPTIONS request */ | 87 | /* send the OPTIONS request */ |
| 87 | char buffer[MAX_INPUT_BUFFER]; | 88 | char buffer[MAX_INPUT_BUFFER]; |
| 88 | sprintf(buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", host_name, server_port); | 89 | sprintf(buffer, "OPTIONS rtsp://%s:%d RTSP/1.0\r\n", config.host_name, config.server_port); |
| 89 | int result = send(socket, buffer, strlen(buffer), 0); | 90 | ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0); |
| 91 | if (sent_bytes == -1) { | ||
| 92 | die(STATE_CRITICAL, _("Sending options to %s failed\n"), config.host_name); | ||
| 93 | } | ||
| 90 | 94 | ||
| 91 | /* send the header sync */ | 95 | /* send the header sync */ |
| 92 | sprintf(buffer, "CSeq: 1\r\n"); | 96 | sprintf(buffer, "CSeq: 1\r\n"); |
| 93 | result = send(socket, buffer, strlen(buffer), 0); | 97 | sent_bytes = send(socket, buffer, strlen(buffer), 0); |
| 98 | if (sent_bytes == -1) { | ||
| 99 | die(STATE_CRITICAL, _("Sending header sync to %s failed\n"), config.host_name); | ||
| 100 | } | ||
| 94 | 101 | ||
| 95 | /* send a newline so the server knows we're done with the request */ | 102 | /* send a newline so the server knows we're done with the request */ |
| 96 | sprintf(buffer, "\r\n"); | 103 | sprintf(buffer, "\r\n"); |
| 97 | result = send(socket, buffer, strlen(buffer), 0); | 104 | sent_bytes = send(socket, buffer, strlen(buffer), 0); |
| 105 | if (sent_bytes == -1) { | ||
| 106 | die(STATE_CRITICAL, _("Sending newline to %s failed\n"), config.host_name); | ||
| 107 | } | ||
| 98 | 108 | ||
| 99 | /* watch for the REAL connection string */ | 109 | /* watch for the REAL connection string */ |
| 100 | result = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); | 110 | ssize_t received_bytes = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); |
| 101 | 111 | ||
| 102 | /* return a CRITICAL status if we couldn't read any data */ | 112 | /* return a CRITICAL status if we couldn't read any data */ |
| 103 | if (result == -1) | 113 | if (received_bytes == -1) { |
| 104 | die(STATE_CRITICAL, _("No data received from %s\n"), host_name); | 114 | die(STATE_CRITICAL, _("No data received from %s\n"), config.host_name); |
| 115 | } | ||
| 105 | 116 | ||
| 117 | mp_state_enum result = STATE_OK; | ||
| 106 | char *status_line = NULL; | 118 | char *status_line = NULL; |
| 107 | /* make sure we find the response we are looking for */ | 119 | /* make sure we find the response we are looking for */ |
| 108 | if (!strstr(buffer, server_expect)) { | 120 | if (!strstr(buffer, config.server_expect)) { |
| 109 | if (server_port == PORT) | 121 | if (config.server_port == PORT) { |
| 110 | printf("%s\n", _("Invalid REAL response received from host")); | 122 | printf("%s\n", _("Invalid REAL response received from host")); |
| 111 | else | 123 | } else { |
| 112 | printf(_("Invalid REAL response received from host on port %d\n"), server_port); | 124 | printf(_("Invalid REAL response received from host on port %d\n"), config.server_port); |
| 125 | } | ||
| 113 | } else { | 126 | } else { |
| 114 | /* else we got the REAL string, so check the return code */ | 127 | /* else we got the REAL string, so check the return code */ |
| 115 | 128 | ||
| @@ -117,69 +130,81 @@ int main(int argc, char **argv) { | |||
| 117 | 130 | ||
| 118 | result = STATE_OK; | 131 | result = STATE_OK; |
| 119 | 132 | ||
| 120 | status_line = (char *)strtok(buffer, "\n"); | 133 | status_line = strtok(buffer, "\n"); |
| 121 | 134 | ||
| 122 | if (strstr(status_line, "200")) | 135 | if (strstr(status_line, "200")) { |
| 123 | result = STATE_OK; | 136 | result = STATE_OK; |
| 137 | } | ||
| 124 | 138 | ||
| 125 | /* client errors result in a warning state */ | 139 | /* client errors result in a warning state */ |
| 126 | else if (strstr(status_line, "400")) | 140 | else if (strstr(status_line, "400")) { |
| 127 | result = STATE_WARNING; | 141 | result = STATE_WARNING; |
| 128 | else if (strstr(status_line, "401")) | 142 | } else if (strstr(status_line, "401")) { |
| 129 | result = STATE_WARNING; | 143 | result = STATE_WARNING; |
| 130 | else if (strstr(status_line, "402")) | 144 | } else if (strstr(status_line, "402")) { |
| 131 | result = STATE_WARNING; | 145 | result = STATE_WARNING; |
| 132 | else if (strstr(status_line, "403")) | 146 | } else if (strstr(status_line, "403")) { |
| 133 | result = STATE_WARNING; | 147 | result = STATE_WARNING; |
| 134 | else if (strstr(status_line, "404")) | 148 | } else if (strstr(status_line, "404")) { |
| 135 | result = STATE_WARNING; | 149 | result = STATE_WARNING; |
| 136 | 150 | } else if (strstr(status_line, "500")) { | |
| 137 | /* server errors result in a critical state */ | 151 | /* server errors result in a critical state */ |
| 138 | else if (strstr(status_line, "500")) | ||
| 139 | result = STATE_CRITICAL; | 152 | result = STATE_CRITICAL; |
| 140 | else if (strstr(status_line, "501")) | 153 | } else if (strstr(status_line, "501")) { |
| 141 | result = STATE_CRITICAL; | 154 | result = STATE_CRITICAL; |
| 142 | else if (strstr(status_line, "502")) | 155 | } else if (strstr(status_line, "502")) { |
| 143 | result = STATE_CRITICAL; | 156 | result = STATE_CRITICAL; |
| 144 | else if (strstr(status_line, "503")) | 157 | } else if (strstr(status_line, "503")) { |
| 145 | result = STATE_CRITICAL; | 158 | result = STATE_CRITICAL; |
| 146 | 159 | } else { | |
| 147 | else | ||
| 148 | result = STATE_UNKNOWN; | 160 | result = STATE_UNKNOWN; |
| 161 | } | ||
| 149 | } | 162 | } |
| 150 | 163 | ||
| 151 | /* Part II - Check stream exists and is ok */ | 164 | /* Part II - Check stream exists and is ok */ |
| 152 | if ((result == STATE_OK) && (server_url != NULL)) { | 165 | if ((result == STATE_OK) && (config.server_url != NULL)) { |
| 153 | 166 | ||
| 154 | /* Part I - Server Check */ | 167 | /* Part I - Server Check */ |
| 155 | 168 | ||
| 156 | /* send the DESCRIBE request */ | 169 | /* send the DESCRIBE request */ |
| 157 | sprintf(buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", host_name, server_port, server_url); | 170 | sprintf(buffer, "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n", config.host_name, |
| 158 | result = send(socket, buffer, strlen(buffer), 0); | 171 | config.server_port, config.server_url); |
| 172 | |||
| 173 | ssize_t sent_bytes = send(socket, buffer, strlen(buffer), 0); | ||
| 174 | if (sent_bytes == -1) { | ||
| 175 | die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name); | ||
| 176 | } | ||
| 159 | 177 | ||
| 160 | /* send the header sync */ | 178 | /* send the header sync */ |
| 161 | sprintf(buffer, "CSeq: 2\r\n"); | 179 | sprintf(buffer, "CSeq: 2\r\n"); |
| 162 | result = send(socket, buffer, strlen(buffer), 0); | 180 | sent_bytes = send(socket, buffer, strlen(buffer), 0); |
| 181 | if (sent_bytes == -1) { | ||
| 182 | die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name); | ||
| 183 | } | ||
| 163 | 184 | ||
| 164 | /* send a newline so the server knows we're done with the request */ | 185 | /* send a newline so the server knows we're done with the request */ |
| 165 | sprintf(buffer, "\r\n"); | 186 | sprintf(buffer, "\r\n"); |
| 166 | result = send(socket, buffer, strlen(buffer), 0); | 187 | sent_bytes = send(socket, buffer, strlen(buffer), 0); |
| 188 | if (sent_bytes == -1) { | ||
| 189 | die(STATE_CRITICAL, _("Sending DESCRIBE request to %s failed\n"), config.host_name); | ||
| 190 | } | ||
| 167 | 191 | ||
| 168 | /* watch for the REAL connection string */ | 192 | /* watch for the REAL connection string */ |
| 169 | result = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); | 193 | ssize_t recv_bytes = recv(socket, buffer, MAX_INPUT_BUFFER - 1, 0); |
| 170 | buffer[result] = '\0'; /* null terminate received buffer */ | 194 | if (recv_bytes == -1) { |
| 171 | 195 | /* return a CRITICAL status if we couldn't read any data */ | |
| 172 | /* return a CRITICAL status if we couldn't read any data */ | ||
| 173 | if (result == -1) { | ||
| 174 | printf(_("No data received from host\n")); | 196 | printf(_("No data received from host\n")); |
| 175 | result = STATE_CRITICAL; | 197 | result = STATE_CRITICAL; |
| 176 | } else { | 198 | } else { |
| 199 | buffer[result] = '\0'; /* null terminate received buffer */ | ||
| 177 | /* make sure we find the response we are looking for */ | 200 | /* make sure we find the response we are looking for */ |
| 178 | if (!strstr(buffer, server_expect)) { | 201 | if (!strstr(buffer, config.server_expect)) { |
| 179 | if (server_port == PORT) | 202 | if (config.server_port == PORT) { |
| 180 | printf("%s\n", _("Invalid REAL response received from host")); | 203 | printf("%s\n", _("Invalid REAL response received from host")); |
| 181 | else | 204 | } else { |
| 182 | printf(_("Invalid REAL response received from host on port %d\n"), server_port); | 205 | printf(_("Invalid REAL response received from host on port %d\n"), |
| 206 | config.server_port); | ||
| 207 | } | ||
| 183 | } else { | 208 | } else { |
| 184 | 209 | ||
| 185 | /* else we got the REAL string, so check the return code */ | 210 | /* else we got the REAL string, so check the return code */ |
| @@ -188,51 +213,57 @@ int main(int argc, char **argv) { | |||
| 188 | 213 | ||
| 189 | result = STATE_OK; | 214 | result = STATE_OK; |
| 190 | 215 | ||
| 191 | status_line = (char *)strtok(buffer, "\n"); | 216 | status_line = strtok(buffer, "\n"); |
| 192 | 217 | ||
| 193 | if (strstr(status_line, "200")) | 218 | if (strstr(status_line, "200")) { |
| 194 | result = STATE_OK; | 219 | result = STATE_OK; |
| 220 | } | ||
| 195 | 221 | ||
| 196 | /* client errors result in a warning state */ | 222 | /* client errors result in a warning state */ |
| 197 | else if (strstr(status_line, "400")) | 223 | else if (strstr(status_line, "400")) { |
| 198 | result = STATE_WARNING; | 224 | result = STATE_WARNING; |
| 199 | else if (strstr(status_line, "401")) | 225 | } else if (strstr(status_line, "401")) { |
| 200 | result = STATE_WARNING; | 226 | result = STATE_WARNING; |
| 201 | else if (strstr(status_line, "402")) | 227 | } else if (strstr(status_line, "402")) { |
| 202 | result = STATE_WARNING; | 228 | result = STATE_WARNING; |
| 203 | else if (strstr(status_line, "403")) | 229 | } else if (strstr(status_line, "403")) { |
| 204 | result = STATE_WARNING; | 230 | result = STATE_WARNING; |
| 205 | else if (strstr(status_line, "404")) | 231 | } else if (strstr(status_line, "404")) { |
| 206 | result = STATE_WARNING; | 232 | result = STATE_WARNING; |
| 233 | } | ||
| 207 | 234 | ||
| 208 | /* server errors result in a critical state */ | 235 | /* server errors result in a critical state */ |
| 209 | else if (strstr(status_line, "500")) | 236 | else if (strstr(status_line, "500")) { |
| 210 | result = STATE_CRITICAL; | 237 | result = STATE_CRITICAL; |
| 211 | else if (strstr(status_line, "501")) | 238 | } else if (strstr(status_line, "501")) { |
| 212 | result = STATE_CRITICAL; | 239 | result = STATE_CRITICAL; |
| 213 | else if (strstr(status_line, "502")) | 240 | } else if (strstr(status_line, "502")) { |
| 214 | result = STATE_CRITICAL; | 241 | result = STATE_CRITICAL; |
| 215 | else if (strstr(status_line, "503")) | 242 | } else if (strstr(status_line, "503")) { |
| 216 | result = STATE_CRITICAL; | 243 | result = STATE_CRITICAL; |
| 244 | } | ||
| 217 | 245 | ||
| 218 | else | 246 | else { |
| 219 | result = STATE_UNKNOWN; | 247 | result = STATE_UNKNOWN; |
| 248 | } | ||
| 220 | } | 249 | } |
| 221 | } | 250 | } |
| 222 | } | 251 | } |
| 223 | 252 | ||
| 224 | /* Return results */ | 253 | /* Return results */ |
| 225 | if (result == STATE_OK) { | 254 | if (result == STATE_OK) { |
| 226 | 255 | if (config.check_critical_time && (end_time - start_time) > config.critical_time) { | |
| 227 | if (check_critical_time && (end_time - start_time) > critical_time) | ||
| 228 | result = STATE_CRITICAL; | 256 | result = STATE_CRITICAL; |
| 229 | else if (check_warning_time && (end_time - start_time) > warning_time) | 257 | } else if (config.check_warning_time && (end_time - start_time) > config.warning_time) { |
| 230 | result = STATE_WARNING; | 258 | result = STATE_WARNING; |
| 259 | } | ||
| 231 | 260 | ||
| 232 | /* Put some HTML in here to create a dynamic link */ | 261 | /* Put some HTML in here to create a dynamic link */ |
| 233 | printf(_("REAL %s - %d second response time\n"), state_text(result), (int)(end_time - start_time)); | 262 | printf(_("REAL %s - %d second response time\n"), state_text(result), |
| 234 | } else | 263 | (int)(end_time - start_time)); |
| 264 | } else { | ||
| 235 | printf("%s\n", status_line); | 265 | printf("%s\n", status_line); |
| 266 | } | ||
| 236 | 267 | ||
| 237 | /* close the connection */ | 268 | /* close the connection */ |
| 238 | close(socket); | 269 | close(socket); |
| @@ -240,73 +271,83 @@ int main(int argc, char **argv) { | |||
| 240 | /* reset the alarm */ | 271 | /* reset the alarm */ |
| 241 | alarm(0); | 272 | alarm(0); |
| 242 | 273 | ||
| 243 | return result; | 274 | exit(result); |
| 244 | } | 275 | } |
| 245 | 276 | ||
| 246 | /* process command-line arguments */ | 277 | /* process command-line arguments */ |
| 247 | int process_arguments(int argc, char **argv) { | 278 | check_real_config_wrapper process_arguments(int argc, char **argv) { |
| 248 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"IPaddress", required_argument, 0, 'I'}, | 279 | static struct option longopts[] = { |
| 249 | {"expect", required_argument, 0, 'e'}, {"url", required_argument, 0, 'u'}, | 280 | {"hostname", required_argument, 0, 'H'}, {"IPaddress", required_argument, 0, 'I'}, |
| 250 | {"port", required_argument, 0, 'p'}, {"critical", required_argument, 0, 'c'}, | 281 | {"expect", required_argument, 0, 'e'}, {"url", required_argument, 0, 'u'}, |
| 251 | {"warning", required_argument, 0, 'w'}, {"timeout", required_argument, 0, 't'}, | 282 | {"port", required_argument, 0, 'p'}, {"critical", required_argument, 0, 'c'}, |
| 252 | {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, | 283 | {"warning", required_argument, 0, 'w'}, {"timeout", required_argument, 0, 't'}, |
| 253 | {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; | 284 | {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, |
| 254 | 285 | {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; | |
| 255 | if (argc < 2) | 286 | |
| 256 | return ERROR; | 287 | check_real_config_wrapper result = { |
| 288 | .errorcode = OK, | ||
| 289 | .config = check_real_config_init(), | ||
| 290 | }; | ||
| 291 | |||
| 292 | if (argc < 2) { | ||
| 293 | result.errorcode = ERROR; | ||
| 294 | return result; | ||
| 295 | } | ||
| 257 | 296 | ||
| 258 | for (int i = 1; i < argc; i++) { | 297 | for (int i = 1; i < argc; i++) { |
| 259 | if (strcmp("-to", argv[i]) == 0) | 298 | if (strcmp("-to", argv[i]) == 0) { |
| 260 | strcpy(argv[i], "-t"); | 299 | strcpy(argv[i], "-t"); |
| 261 | else if (strcmp("-wt", argv[i]) == 0) | 300 | } else if (strcmp("-wt", argv[i]) == 0) { |
| 262 | strcpy(argv[i], "-w"); | 301 | strcpy(argv[i], "-w"); |
| 263 | else if (strcmp("-ct", argv[i]) == 0) | 302 | } else if (strcmp("-ct", argv[i]) == 0) { |
| 264 | strcpy(argv[i], "-c"); | 303 | strcpy(argv[i], "-c"); |
| 304 | } | ||
| 265 | } | 305 | } |
| 266 | 306 | ||
| 267 | int option_char; | ||
| 268 | while (true) { | 307 | while (true) { |
| 269 | int option = 0; | 308 | int option = 0; |
| 270 | option_char = getopt_long(argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts, &option); | 309 | int option_char = getopt_long(argc, argv, "+hvVI:H:e:u:p:w:c:t:", longopts, &option); |
| 271 | 310 | ||
| 272 | if (option_char == -1 || option_char == EOF) | 311 | if (option_char == -1 || option_char == EOF) { |
| 273 | break; | 312 | break; |
| 313 | } | ||
| 274 | 314 | ||
| 275 | switch (option_char) { | 315 | switch (option_char) { |
| 276 | case 'I': /* hostname */ | 316 | case 'I': /* hostname */ |
| 277 | case 'H': /* hostname */ | 317 | case 'H': /* hostname */ |
| 278 | if (server_address) | 318 | if (result.config.server_address) { |
| 279 | break; | 319 | break; |
| 280 | else if (is_host(optarg)) | 320 | } else if (is_host(optarg)) { |
| 281 | server_address = optarg; | 321 | result.config.server_address = optarg; |
| 282 | else | 322 | } else { |
| 283 | usage2(_("Invalid hostname/address"), optarg); | 323 | usage2(_("Invalid hostname/address"), optarg); |
| 324 | } | ||
| 284 | break; | 325 | break; |
| 285 | case 'e': /* string to expect in response header */ | 326 | case 'e': /* string to expect in response header */ |
| 286 | server_expect = optarg; | 327 | result.config.server_expect = optarg; |
| 287 | break; | 328 | break; |
| 288 | case 'u': /* server URL */ | 329 | case 'u': /* server URL */ |
| 289 | server_url = optarg; | 330 | result.config.server_url = optarg; |
| 290 | break; | 331 | break; |
| 291 | case 'p': /* port */ | 332 | case 'p': /* port */ |
| 292 | if (is_intpos(optarg)) { | 333 | if (is_intpos(optarg)) { |
| 293 | server_port = atoi(optarg); | 334 | result.config.server_port = atoi(optarg); |
| 294 | } else { | 335 | } else { |
| 295 | usage4(_("Port must be a positive integer")); | 336 | usage4(_("Port must be a positive integer")); |
| 296 | } | 337 | } |
| 297 | break; | 338 | break; |
| 298 | case 'w': /* warning time threshold */ | 339 | case 'w': /* warning time threshold */ |
| 299 | if (is_intnonneg(optarg)) { | 340 | if (is_intnonneg(optarg)) { |
| 300 | warning_time = atoi(optarg); | 341 | result.config.warning_time = atoi(optarg); |
| 301 | check_warning_time = true; | 342 | result.config.check_warning_time = true; |
| 302 | } else { | 343 | } else { |
| 303 | usage4(_("Warning time must be a positive integer")); | 344 | usage4(_("Warning time must be a positive integer")); |
| 304 | } | 345 | } |
| 305 | break; | 346 | break; |
| 306 | case 'c': /* critical time threshold */ | 347 | case 'c': /* critical time threshold */ |
| 307 | if (is_intnonneg(optarg)) { | 348 | if (is_intnonneg(optarg)) { |
| 308 | critical_time = atoi(optarg); | 349 | result.config.critical_time = atoi(optarg); |
| 309 | check_critical_time = true; | 350 | result.config.check_critical_time = true; |
| 310 | } else { | 351 | } else { |
| 311 | usage4(_("Critical time must be a positive integer")); | 352 | usage4(_("Critical time must be a positive integer")); |
| 312 | } | 353 | } |
| @@ -332,25 +373,28 @@ int process_arguments(int argc, char **argv) { | |||
| 332 | } | 373 | } |
| 333 | } | 374 | } |
| 334 | 375 | ||
| 335 | option_char = optind; | 376 | int option_char = optind; |
| 336 | if (server_address == NULL && argc > option_char) { | 377 | if (result.config.server_address == NULL && argc > option_char) { |
| 337 | if (is_host(argv[option_char])) { | 378 | if (is_host(argv[option_char])) { |
| 338 | server_address = argv[option_char++]; | 379 | result.config.server_address = argv[option_char++]; |
| 339 | } else { | 380 | } else { |
| 340 | usage2(_("Invalid hostname/address"), argv[option_char]); | 381 | usage2(_("Invalid hostname/address"), argv[option_char]); |
| 341 | } | 382 | } |
| 342 | } | 383 | } |
| 343 | 384 | ||
| 344 | if (server_address == NULL) | 385 | if (result.config.server_address == NULL) { |
| 345 | usage4(_("You must provide a server to check")); | 386 | usage4(_("You must provide a server to check")); |
| 387 | } | ||
| 346 | 388 | ||
| 347 | if (host_name == NULL) | 389 | if (result.config.host_name == NULL) { |
| 348 | host_name = strdup(server_address); | 390 | result.config.host_name = strdup(result.config.server_address); |
| 391 | } | ||
| 349 | 392 | ||
| 350 | if (server_expect == NULL) | 393 | if (result.config.server_expect == NULL) { |
| 351 | server_expect = strdup(EXPECT); | 394 | result.config.server_expect = strdup(EXPECT); |
| 395 | } | ||
| 352 | 396 | ||
| 353 | return OK; | 397 | return result; |
| 354 | } | 398 | } |
| 355 | 399 | ||
| 356 | void print_help(void) { | 400 | void print_help(void) { |
| @@ -388,7 +432,8 @@ void print_help(void) { | |||
| 388 | printf("%s\n", _("This plugin will attempt to open an RTSP connection with the host.")); | 432 | printf("%s\n", _("This plugin will attempt to open an RTSP connection with the host.")); |
| 389 | printf("%s\n", _("Successful connects return STATE_OK, refusals and timeouts return")); | 433 | printf("%s\n", _("Successful connects return STATE_OK, refusals and timeouts return")); |
| 390 | printf("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful connects,")); | 434 | printf("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful connects,")); |
| 391 | printf("%s\n", _("but incorrect response messages from the host result in STATE_WARNING return")); | 435 | printf("%s\n", |
| 436 | _("but incorrect response messages from the host result in STATE_WARNING return")); | ||
| 392 | printf("%s\n", _("values.")); | 437 | printf("%s\n", _("values.")); |
| 393 | 438 | ||
| 394 | printf(UT_SUPPORT); | 439 | printf(UT_SUPPORT); |
diff --git a/plugins/check_real.d/config.h b/plugins/check_real.d/config.h new file mode 100644 index 00000000..c4663cf9 --- /dev/null +++ b/plugins/check_real.d/config.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include <stddef.h> | ||
| 5 | |||
| 6 | enum { | ||
| 7 | PORT = 554 | ||
| 8 | }; | ||
| 9 | |||
| 10 | typedef struct { | ||
| 11 | char *server_address; | ||
| 12 | char *host_name; | ||
| 13 | int server_port; | ||
| 14 | char *server_url; | ||
| 15 | |||
| 16 | char *server_expect; | ||
| 17 | int warning_time; | ||
| 18 | bool check_warning_time; | ||
| 19 | int critical_time; | ||
| 20 | bool check_critical_time; | ||
| 21 | } check_real_config; | ||
| 22 | |||
| 23 | check_real_config check_real_config_init() { | ||
| 24 | check_real_config tmp = { | ||
| 25 | .server_address = NULL, | ||
| 26 | .host_name = NULL, | ||
| 27 | .server_port = PORT, | ||
| 28 | .server_url = NULL, | ||
| 29 | |||
| 30 | .server_expect = NULL, | ||
| 31 | .warning_time = 0, | ||
| 32 | .check_warning_time = false, | ||
| 33 | .critical_time = 0, | ||
| 34 | .check_critical_time = false, | ||
| 35 | }; | ||
| 36 | return tmp; | ||
| 37 | } | ||
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index 44b735f9..e8c35f58 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c | |||
| @@ -28,20 +28,24 @@ | |||
| 28 | * | 28 | * |
| 29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
| 30 | 30 | ||
| 31 | const char *progname = "check_smtp"; | ||
| 32 | const char *copyright = "2000-2024"; | ||
| 33 | const char *email = "devel@monitoring-plugins.org"; | ||
| 34 | |||
| 35 | #include "common.h" | 31 | #include "common.h" |
| 36 | #include "netutils.h" | 32 | #include "netutils.h" |
| 33 | #include "output.h" | ||
| 34 | #include "perfdata.h" | ||
| 35 | #include "thresholds.h" | ||
| 37 | #include "utils.h" | 36 | #include "utils.h" |
| 38 | #include "base64.h" | 37 | #include "base64.h" |
| 39 | #include "regex.h" | 38 | #include "regex.h" |
| 40 | 39 | ||
| 41 | #include <ctype.h> | 40 | #include <ctype.h> |
| 41 | #include <string.h> | ||
| 42 | #include "check_smtp.d/config.h" | 42 | #include "check_smtp.d/config.h" |
| 43 | #include "../lib/states.h" | 43 | #include "../lib/states.h" |
| 44 | 44 | ||
| 45 | const char *progname = "check_smtp"; | ||
| 46 | const char *copyright = "2000-2024"; | ||
| 47 | const char *email = "devel@monitoring-plugins.org"; | ||
| 48 | |||
| 45 | #define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n" | 49 | #define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n" |
| 46 | #define SMTP_HELO "HELO " | 50 | #define SMTP_HELO "HELO " |
| 47 | #define SMTP_EHLO "EHLO " | 51 | #define SMTP_EHLO "EHLO " |
| @@ -58,7 +62,8 @@ typedef struct { | |||
| 58 | } check_smtp_config_wrapper; | 62 | } check_smtp_config_wrapper; |
| 59 | static check_smtp_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | 63 | static check_smtp_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 60 | 64 | ||
| 61 | int my_recv(check_smtp_config config, void *buf, int num, int socket_descriptor, bool ssl_established) { | 65 | int my_recv(check_smtp_config config, void *buf, int num, int socket_descriptor, |
| 66 | bool ssl_established) { | ||
| 62 | #ifdef HAVE_SSL | 67 | #ifdef HAVE_SSL |
| 63 | if ((config.use_starttls || config.use_ssl) && ssl_established) { | 68 | if ((config.use_starttls || config.use_ssl) && ssl_established) { |
| 64 | return np_net_ssl_read(buf, num); | 69 | return np_net_ssl_read(buf, num); |
| @@ -69,7 +74,8 @@ int my_recv(check_smtp_config config, void *buf, int num, int socket_descriptor, | |||
| 69 | #endif | 74 | #endif |
| 70 | } | 75 | } |
| 71 | 76 | ||
| 72 | int my_send(check_smtp_config config, void *buf, int num, int socket_descriptor, bool ssl_established) { | 77 | int my_send(check_smtp_config config, void *buf, int num, int socket_descriptor, |
| 78 | bool ssl_established) { | ||
| 73 | #ifdef HAVE_SSL | 79 | #ifdef HAVE_SSL |
| 74 | if ((config.use_starttls || config.use_ssl) && ssl_established) { | 80 | if ((config.use_starttls || config.use_ssl) && ssl_established) { |
| 75 | 81 | ||
| @@ -83,10 +89,12 @@ int my_send(check_smtp_config config, void *buf, int num, int socket_descriptor, | |||
| 83 | 89 | ||
| 84 | static void print_help(void); | 90 | static void print_help(void); |
| 85 | void print_usage(void); | 91 | void print_usage(void); |
| 86 | static char *smtp_quit(check_smtp_config /*config*/, char /*buffer*/[MAX_INPUT_BUFFER], int /*socket_descriptor*/, | 92 | static char *smtp_quit(check_smtp_config /*config*/, char /*buffer*/[MAX_INPUT_BUFFER], |
| 87 | bool /*ssl_established*/); | 93 | int /*socket_descriptor*/, bool /*ssl_established*/); |
| 88 | static int recvline(char * /*buf*/, size_t /*bufsize*/, check_smtp_config /*config*/, int /*socket_descriptor*/, bool /*ssl_established*/); | 94 | static int recvline(char * /*buf*/, size_t /*bufsize*/, check_smtp_config /*config*/, |
| 89 | static int recvlines(check_smtp_config /*config*/, char * /*buf*/, size_t /*bufsize*/, int /*socket_descriptor*/, bool /*ssl_established*/); | 95 | int /*socket_descriptor*/, bool /*ssl_established*/); |
| 96 | static int recvlines(check_smtp_config /*config*/, char * /*buf*/, size_t /*bufsize*/, | ||
| 97 | int /*socket_descriptor*/, bool /*ssl_established*/); | ||
| 90 | static int my_close(int /*socket_descriptor*/); | 98 | static int my_close(int /*socket_descriptor*/); |
| 91 | 99 | ||
| 92 | static int verbose = 0; | 100 | static int verbose = 0; |
| @@ -107,6 +115,10 @@ int main(int argc, char **argv) { | |||
| 107 | 115 | ||
| 108 | const check_smtp_config config = tmp_config.config; | 116 | const check_smtp_config config = tmp_config.config; |
| 109 | 117 | ||
| 118 | if (config.output_format_is_set) { | ||
| 119 | mp_set_format(config.output_format); | ||
| 120 | } | ||
| 121 | |||
| 110 | /* If localhostname not set on command line, use gethostname to set */ | 122 | /* If localhostname not set on command line, use gethostname to set */ |
| 111 | char *localhostname = config.localhostname; | 123 | char *localhostname = config.localhostname; |
| 112 | if (!localhostname) { | 124 | if (!localhostname) { |
| @@ -157,342 +169,459 @@ int main(int argc, char **argv) { | |||
| 157 | gettimeofday(&start_time, NULL); | 169 | gettimeofday(&start_time, NULL); |
| 158 | 170 | ||
| 159 | int socket_descriptor = 0; | 171 | int socket_descriptor = 0; |
| 172 | |||
| 160 | /* try to connect to the host at the given port number */ | 173 | /* try to connect to the host at the given port number */ |
| 161 | mp_state_enum result = my_tcp_connect(config.server_address, config.server_port, &socket_descriptor); | 174 | mp_state_enum tcp_result = |
| 175 | my_tcp_connect(config.server_address, config.server_port, &socket_descriptor); | ||
| 162 | 176 | ||
| 163 | char *error_msg = ""; | 177 | mp_check overall = mp_check_init(); |
| 178 | mp_subcheck sc_tcp_connect = mp_subcheck_init(); | ||
| 164 | char buffer[MAX_INPUT_BUFFER]; | 179 | char buffer[MAX_INPUT_BUFFER]; |
| 165 | bool ssl_established = false; | 180 | bool ssl_established = false; |
| 166 | if (result == STATE_OK) { /* we connected */ | 181 | |
| 167 | /* If requested, send PROXY header */ | 182 | if (tcp_result != STATE_OK) { |
| 168 | if (config.use_proxy_prefix) { | 183 | // Connect failed |
| 169 | if (verbose) { | 184 | sc_tcp_connect = mp_set_subcheck_state(sc_tcp_connect, STATE_CRITICAL); |
| 170 | printf("Sending header %s\n", PROXY_PREFIX); | 185 | xasprintf(&sc_tcp_connect.output, "TCP connect to '%s' failed", config.server_address); |
| 171 | } | 186 | mp_add_subcheck_to_check(&overall, sc_tcp_connect); |
| 172 | my_send(config, PROXY_PREFIX, strlen(PROXY_PREFIX), socket_descriptor, ssl_established); | 187 | mp_exit(overall); |
| 188 | } | ||
| 189 | |||
| 190 | /* we connected */ | ||
| 191 | /* If requested, send PROXY header */ | ||
| 192 | if (config.use_proxy_prefix) { | ||
| 193 | if (verbose) { | ||
| 194 | printf("Sending header %s\n", PROXY_PREFIX); | ||
| 173 | } | 195 | } |
| 196 | my_send(config, PROXY_PREFIX, strlen(PROXY_PREFIX), socket_descriptor, ssl_established); | ||
| 197 | } | ||
| 174 | 198 | ||
| 175 | #ifdef HAVE_SSL | 199 | #ifdef HAVE_SSL |
| 176 | if (config.use_ssl) { | 200 | if (config.use_ssl) { |
| 177 | result = np_net_ssl_init_with_hostname(socket_descriptor, (config.use_sni ? config.server_address : NULL)); | 201 | int tls_result = np_net_ssl_init_with_hostname( |
| 178 | if (result != STATE_OK) { | 202 | socket_descriptor, (config.use_sni ? config.server_address : NULL)); |
| 179 | printf(_("CRITICAL - Cannot create SSL context.\n")); | 203 | |
| 180 | close(socket_descriptor); | 204 | mp_subcheck sc_tls_connection = mp_subcheck_init(); |
| 181 | np_net_ssl_cleanup(); | 205 | |
| 182 | exit(STATE_CRITICAL); | 206 | if (tls_result != STATE_OK) { |
| 183 | } | 207 | close(socket_descriptor); |
| 184 | ssl_established = true; | 208 | np_net_ssl_cleanup(); |
| 209 | |||
| 210 | sc_tls_connection = mp_set_subcheck_state(sc_tls_connection, STATE_CRITICAL); | ||
| 211 | xasprintf(&sc_tls_connection.output, "cannot create TLS context"); | ||
| 212 | mp_add_subcheck_to_check(&overall, sc_tls_connection); | ||
| 213 | mp_exit(overall); | ||
| 185 | } | 214 | } |
| 215 | |||
| 216 | sc_tls_connection = mp_set_subcheck_state(sc_tls_connection, STATE_OK); | ||
| 217 | xasprintf(&sc_tls_connection.output, "TLS context established"); | ||
| 218 | mp_add_subcheck_to_check(&overall, sc_tls_connection); | ||
| 219 | ssl_established = true; | ||
| 220 | } | ||
| 186 | #endif | 221 | #endif |
| 187 | 222 | ||
| 188 | /* watch for the SMTP connection string and */ | 223 | /* watch for the SMTP connection string and */ |
| 189 | /* return a WARNING status if we couldn't read any data */ | 224 | /* return a WARNING status if we couldn't read any data */ |
| 190 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) <= 0) { | 225 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) <= 0) { |
| 191 | printf(_("recv() failed\n")); | 226 | mp_subcheck sc_read_data = mp_subcheck_init(); |
| 192 | exit(STATE_WARNING); | 227 | sc_read_data = mp_set_subcheck_state(sc_read_data, STATE_WARNING); |
| 193 | } | 228 | xasprintf(&sc_read_data.output, "recv() failed"); |
| 229 | mp_add_subcheck_to_check(&overall, sc_read_data); | ||
| 230 | mp_exit(overall); | ||
| 231 | } | ||
| 194 | 232 | ||
| 195 | char *server_response = NULL; | 233 | char *server_response = NULL; |
| 196 | /* save connect return (220 hostname ..) for later use */ | 234 | /* save connect return (220 hostname ..) for later use */ |
| 197 | xasprintf(&server_response, "%s", buffer); | 235 | xasprintf(&server_response, "%s", buffer); |
| 198 | 236 | ||
| 199 | /* send the HELO/EHLO command */ | 237 | /* send the HELO/EHLO command */ |
| 200 | my_send(config, helocmd, (int)strlen(helocmd), socket_descriptor, ssl_established); | 238 | my_send(config, helocmd, (int)strlen(helocmd), socket_descriptor, ssl_established); |
| 201 | 239 | ||
| 202 | /* allow for response to helo command to reach us */ | 240 | /* allow for response to helo command to reach us */ |
| 203 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) <= 0) { | 241 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) <= 0) { |
| 204 | printf(_("recv() failed\n")); | 242 | mp_subcheck sc_read_data = mp_subcheck_init(); |
| 205 | exit(STATE_WARNING); | 243 | sc_read_data = mp_set_subcheck_state(sc_read_data, STATE_WARNING); |
| 206 | } | 244 | xasprintf(&sc_read_data.output, "recv() failed"); |
| 245 | mp_add_subcheck_to_check(&overall, sc_read_data); | ||
| 246 | mp_exit(overall); | ||
| 247 | } | ||
| 207 | 248 | ||
| 208 | bool supports_tls = false; | 249 | bool supports_tls = false; |
| 209 | if (config.use_ehlo || config.use_lhlo) { | 250 | if (config.use_ehlo || config.use_lhlo) { |
| 210 | if (strstr(buffer, "250 STARTTLS") != NULL || strstr(buffer, "250-STARTTLS") != NULL) { | 251 | if (strstr(buffer, "250 STARTTLS") != NULL || strstr(buffer, "250-STARTTLS") != NULL) { |
| 211 | supports_tls = true; | 252 | supports_tls = true; |
| 212 | } | ||
| 213 | } | 253 | } |
| 254 | } | ||
| 214 | 255 | ||
| 215 | if (config.use_starttls && !supports_tls) { | 256 | if (config.use_starttls && !supports_tls) { |
| 216 | printf(_("WARNING - TLS not supported by server\n")); | 257 | smtp_quit(config, buffer, socket_descriptor, ssl_established); |
| 258 | |||
| 259 | mp_subcheck sc_read_data = mp_subcheck_init(); | ||
| 260 | sc_read_data = mp_set_subcheck_state(sc_read_data, STATE_WARNING); | ||
| 261 | xasprintf(&sc_read_data.output, "StartTLS not supported by server"); | ||
| 262 | mp_add_subcheck_to_check(&overall, sc_read_data); | ||
| 263 | mp_exit(overall); | ||
| 264 | } | ||
| 265 | |||
| 266 | #ifdef HAVE_SSL | ||
| 267 | if (config.use_starttls) { | ||
| 268 | /* send the STARTTLS command */ | ||
| 269 | send(socket_descriptor, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); | ||
| 270 | |||
| 271 | mp_subcheck sc_starttls_init = mp_subcheck_init(); | ||
| 272 | recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, | ||
| 273 | ssl_established); /* wait for it */ | ||
| 274 | if (!strstr(buffer, SMTP_EXPECT)) { | ||
| 217 | smtp_quit(config, buffer, socket_descriptor, ssl_established); | 275 | smtp_quit(config, buffer, socket_descriptor, ssl_established); |
| 218 | exit(STATE_WARNING); | 276 | |
| 277 | xasprintf(&sc_starttls_init.output, "StartTLS not supported by server"); | ||
| 278 | sc_starttls_init = mp_set_subcheck_state(sc_starttls_init, STATE_UNKNOWN); | ||
| 279 | mp_add_subcheck_to_check(&overall, sc_starttls_init); | ||
| 280 | mp_exit(overall); | ||
| 219 | } | 281 | } |
| 220 | 282 | ||
| 221 | #ifdef HAVE_SSL | 283 | mp_state_enum starttls_result = np_net_ssl_init_with_hostname( |
| 222 | if (config.use_starttls) { | 284 | socket_descriptor, (config.use_sni ? config.server_address : NULL)); |
| 223 | /* send the STARTTLS command */ | 285 | if (starttls_result != STATE_OK) { |
| 224 | send(socket_descriptor, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); | 286 | close(socket_descriptor); |
| 225 | 287 | np_net_ssl_cleanup(); | |
| 226 | recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established); /* wait for it */ | ||
| 227 | if (!strstr(buffer, SMTP_EXPECT)) { | ||
| 228 | printf(_("Server does not support STARTTLS\n")); | ||
| 229 | smtp_quit(config, buffer, socket_descriptor, ssl_established); | ||
| 230 | exit(STATE_UNKNOWN); | ||
| 231 | } | ||
| 232 | 288 | ||
| 233 | result = np_net_ssl_init_with_hostname(socket_descriptor, (config.use_sni ? config.server_address : NULL)); | 289 | sc_starttls_init = mp_set_subcheck_state(sc_starttls_init, STATE_CRITICAL); |
| 234 | if (result != STATE_OK) { | 290 | xasprintf(&sc_starttls_init.output, "failed to create StartTLS context"); |
| 235 | printf(_("CRITICAL - Cannot create SSL context.\n")); | 291 | mp_add_subcheck_to_check(&overall, sc_starttls_init); |
| 236 | close(socket_descriptor); | 292 | mp_exit(overall); |
| 237 | np_net_ssl_cleanup(); | 293 | } |
| 238 | exit(STATE_CRITICAL); | 294 | sc_starttls_init = mp_set_subcheck_state(sc_starttls_init, STATE_OK); |
| 239 | } | 295 | xasprintf(&sc_starttls_init.output, "created StartTLS context"); |
| 296 | mp_add_subcheck_to_check(&overall, sc_starttls_init); | ||
| 297 | |||
| 298 | ssl_established = true; | ||
| 299 | |||
| 300 | /* | ||
| 301 | * Resend the EHLO command. | ||
| 302 | * | ||
| 303 | * RFC 3207 (4.2) says: ``The client MUST discard any knowledge | ||
| 304 | * obtained from the server, such as the list of SMTP service | ||
| 305 | * extensions, which was not obtained from the TLS negotiation | ||
| 306 | * itself. The client SHOULD send an EHLO command as the first | ||
| 307 | * command after a successful TLS negotiation.'' For this | ||
| 308 | * reason, some MTAs will not allow an AUTH LOGIN command before | ||
| 309 | * we resent EHLO via TLS. | ||
| 310 | */ | ||
| 311 | if (my_send(config, helocmd, (int)strlen(helocmd), socket_descriptor, ssl_established) <= | ||
| 312 | 0) { | ||
| 313 | my_close(socket_descriptor); | ||
| 314 | |||
| 315 | mp_subcheck sc_ehlo = mp_subcheck_init(); | ||
| 316 | sc_ehlo = mp_set_subcheck_state(sc_ehlo, STATE_UNKNOWN); | ||
| 317 | xasprintf(&sc_ehlo.output, "cannot send EHLO command via StartTLS"); | ||
| 318 | mp_add_subcheck_to_check(&overall, sc_ehlo); | ||
| 319 | mp_exit(overall); | ||
| 320 | } | ||
| 240 | 321 | ||
| 241 | ssl_established = true; | 322 | if (verbose) { |
| 242 | 323 | printf(_("sent %s"), helocmd); | |
| 243 | /* | 324 | } |
| 244 | * Resend the EHLO command. | ||
| 245 | * | ||
| 246 | * RFC 3207 (4.2) says: ``The client MUST discard any knowledge | ||
| 247 | * obtained from the server, such as the list of SMTP service | ||
| 248 | * extensions, which was not obtained from the TLS negotiation | ||
| 249 | * itself. The client SHOULD send an EHLO command as the first | ||
| 250 | * command after a successful TLS negotiation.'' For this | ||
| 251 | * reason, some MTAs will not allow an AUTH LOGIN command before | ||
| 252 | * we resent EHLO via TLS. | ||
| 253 | */ | ||
| 254 | if (my_send(config, helocmd, strlen(helocmd), socket_descriptor, ssl_established) <= 0) { | ||
| 255 | printf("%s\n", _("SMTP UNKNOWN - Cannot send EHLO command via TLS.")); | ||
| 256 | my_close(socket_descriptor); | ||
| 257 | exit(STATE_UNKNOWN); | ||
| 258 | } | ||
| 259 | 325 | ||
| 260 | if (verbose) { | 326 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) <= 0) { |
| 261 | printf(_("sent %s"), helocmd); | 327 | my_close(socket_descriptor); |
| 262 | } | ||
| 263 | 328 | ||
| 264 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) <= 0) { | 329 | mp_subcheck sc_ehlo = mp_subcheck_init(); |
| 265 | printf("%s\n", _("SMTP UNKNOWN - Cannot read EHLO response via TLS.")); | 330 | sc_ehlo = mp_set_subcheck_state(sc_ehlo, STATE_UNKNOWN); |
| 266 | my_close(socket_descriptor); | 331 | xasprintf(&sc_ehlo.output, "cannot read EHLO response via StartTLS"); |
| 267 | exit(STATE_UNKNOWN); | 332 | mp_add_subcheck_to_check(&overall, sc_ehlo); |
| 268 | } | 333 | mp_exit(overall); |
| 334 | } | ||
| 269 | 335 | ||
| 270 | if (verbose) { | 336 | if (verbose) { |
| 271 | printf("%s", buffer); | 337 | printf("%s", buffer); |
| 272 | } | 338 | } |
| 339 | } | ||
| 273 | 340 | ||
| 274 | # ifdef USE_OPENSSL | 341 | # ifdef USE_OPENSSL |
| 275 | if (config.check_cert) { | 342 | if (ssl_established) { |
| 276 | result = np_net_ssl_check_cert(config.days_till_exp_warn, config.days_till_exp_crit); | 343 | net_ssl_check_cert_result cert_check_result = |
| 277 | smtp_quit(config, buffer, socket_descriptor, ssl_established); | 344 | np_net_ssl_check_cert2(config.days_till_exp_warn, config.days_till_exp_crit); |
| 278 | my_close(socket_descriptor); | 345 | |
| 279 | exit(result); | 346 | mp_subcheck sc_cert_check = mp_subcheck_init(); |
| 347 | |||
| 348 | switch (cert_check_result.errors) { | ||
| 349 | case ALL_OK: { | ||
| 350 | |||
| 351 | if (cert_check_result.result_state != STATE_OK && | ||
| 352 | config.ignore_certificate_expiration) { | ||
| 353 | xasprintf(&sc_cert_check.output, | ||
| 354 | "Remaining certificate lifetime: %d days. Expiration will be ignored", | ||
| 355 | (int)(cert_check_result.remaining_seconds / 86400)); | ||
| 356 | sc_cert_check = mp_set_subcheck_state(sc_cert_check, STATE_OK); | ||
| 357 | } else { | ||
| 358 | xasprintf(&sc_cert_check.output, "Remaining certificate lifetime: %d days", | ||
| 359 | (int)(cert_check_result.remaining_seconds / 86400)); | ||
| 360 | sc_cert_check = | ||
| 361 | mp_set_subcheck_state(sc_cert_check, cert_check_result.result_state); | ||
| 280 | } | 362 | } |
| 363 | } break; | ||
| 364 | case NO_SERVER_CERTIFICATE_PRESENT: { | ||
| 365 | xasprintf(&sc_cert_check.output, "no server certificate present"); | ||
| 366 | sc_cert_check = mp_set_subcheck_state(sc_cert_check, cert_check_result.result_state); | ||
| 367 | } break; | ||
| 368 | case UNABLE_TO_RETRIEVE_CERTIFICATE_SUBJECT: { | ||
| 369 | xasprintf(&sc_cert_check.output, "can not retrieve certificate subject"); | ||
| 370 | sc_cert_check = mp_set_subcheck_state(sc_cert_check, cert_check_result.result_state); | ||
| 371 | } break; | ||
| 372 | case WRONG_TIME_FORMAT_IN_CERTIFICATE: { | ||
| 373 | xasprintf(&sc_cert_check.output, "wrong time format in certificate"); | ||
| 374 | sc_cert_check = mp_set_subcheck_state(sc_cert_check, cert_check_result.result_state); | ||
| 375 | } break; | ||
| 376 | }; | ||
| 377 | |||
| 378 | mp_add_subcheck_to_check(&overall, sc_cert_check); | ||
| 379 | } | ||
| 281 | # endif /* USE_OPENSSL */ | 380 | # endif /* USE_OPENSSL */ |
| 282 | } | 381 | |
| 283 | #endif | 382 | #endif |
| 284 | 383 | ||
| 285 | if (verbose) { | 384 | if (verbose) { |
| 385 | printf("%s", buffer); | ||
| 386 | } | ||
| 387 | |||
| 388 | /* save buffer for later use */ | ||
| 389 | xasprintf(&server_response, "%s%s", server_response, buffer); | ||
| 390 | /* strip the buffer of carriage returns */ | ||
| 391 | strip(server_response); | ||
| 392 | |||
| 393 | /* make sure we find the droids we are looking for */ | ||
| 394 | mp_subcheck sc_expect_response = mp_subcheck_init(); | ||
| 395 | |||
| 396 | if (!strstr(server_response, config.server_expect)) { | ||
| 397 | sc_expect_response = mp_set_subcheck_state(sc_expect_response, STATE_WARNING); | ||
| 398 | if (config.server_port == SMTP_PORT) { | ||
| 399 | xasprintf(&sc_expect_response.output, _("invalid SMTP response received from host: %s"), | ||
| 400 | server_response); | ||
| 401 | } else { | ||
| 402 | xasprintf(&sc_expect_response.output, | ||
| 403 | _("invalid SMTP response received from host on port %d: %s"), | ||
| 404 | config.server_port, server_response); | ||
| 405 | } | ||
| 406 | exit(STATE_WARNING); | ||
| 407 | } else { | ||
| 408 | xasprintf(&sc_expect_response.output, "received valid SMTP response '%s' from host: '%s'", | ||
| 409 | config.server_expect, server_response); | ||
| 410 | sc_expect_response = mp_set_subcheck_state(sc_expect_response, STATE_OK); | ||
| 411 | } | ||
| 412 | |||
| 413 | mp_add_subcheck_to_check(&overall, sc_expect_response); | ||
| 414 | |||
| 415 | if (config.send_mail_from) { | ||
| 416 | my_send(config, cmd_str, (int)strlen(cmd_str), socket_descriptor, ssl_established); | ||
| 417 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) >= 1 && | ||
| 418 | verbose) { | ||
| 286 | printf("%s", buffer); | 419 | printf("%s", buffer); |
| 287 | } | 420 | } |
| 421 | } | ||
| 288 | 422 | ||
| 289 | /* save buffer for later use */ | 423 | size_t counter = 0; |
| 290 | xasprintf(&server_response, "%s%s", server_response, buffer); | 424 | while (counter < config.ncommands) { |
| 291 | /* strip the buffer of carriage returns */ | 425 | xasprintf(&cmd_str, "%s%s", config.commands[counter], "\r\n"); |
| 292 | strip(server_response); | 426 | my_send(config, cmd_str, (int)strlen(cmd_str), socket_descriptor, ssl_established); |
| 427 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) >= 1 && | ||
| 428 | verbose) { | ||
| 429 | printf("%s", buffer); | ||
| 430 | } | ||
| 293 | 431 | ||
| 294 | /* make sure we find the droids we are looking for */ | 432 | strip(buffer); |
| 295 | if (!strstr(server_response, config.server_expect)) { | 433 | |
| 296 | if (config.server_port == SMTP_PORT) { | 434 | if (counter < config.nresponses) { |
| 297 | printf(_("Invalid SMTP response received from host: %s\n"), server_response); | 435 | int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; |
| 298 | } else { | 436 | regex_t preg; |
| 299 | printf(_("Invalid SMTP response received from host on port %d: %s\n"), config.server_port, server_response); | 437 | int errcode = regcomp(&preg, config.responses[counter], cflags); |
| 438 | char errbuf[MAX_INPUT_BUFFER]; | ||
| 439 | if (errcode != 0) { | ||
| 440 | regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); | ||
| 441 | printf(_("Could Not Compile Regular Expression")); | ||
| 442 | exit(STATE_UNKNOWN); | ||
| 300 | } | 443 | } |
| 301 | exit(STATE_WARNING); | ||
| 302 | } | ||
| 303 | 444 | ||
| 304 | if (config.send_mail_from) { | 445 | regmatch_t pmatch[10]; |
| 305 | my_send(config, cmd_str, (int)strlen(cmd_str), socket_descriptor, ssl_established); | 446 | int eflags = 0; |
| 306 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) >= 1 && verbose) { | 447 | int excode = regexec(&preg, buffer, 10, pmatch, eflags); |
| 307 | printf("%s", buffer); | 448 | mp_subcheck sc_expected_responses = mp_subcheck_init(); |
| 449 | if (excode == 0) { | ||
| 450 | xasprintf(&sc_expected_responses.output, "valid response '%s' to command '%s'", | ||
| 451 | buffer, config.commands[counter]); | ||
| 452 | sc_expected_responses = mp_set_subcheck_state(sc_expected_responses, STATE_OK); | ||
| 453 | } else if (excode == REG_NOMATCH) { | ||
| 454 | sc_expected_responses = mp_set_subcheck_state(sc_expected_responses, STATE_WARNING); | ||
| 455 | xasprintf(&sc_expected_responses.output, "invalid response '%s' to command '%s'", | ||
| 456 | buffer, config.commands[counter]); | ||
| 457 | } else { | ||
| 458 | regerror(excode, &preg, errbuf, MAX_INPUT_BUFFER); | ||
| 459 | xasprintf(&sc_expected_responses.output, "regexec execute error: %s", errbuf); | ||
| 460 | sc_expected_responses = mp_set_subcheck_state(sc_expected_responses, STATE_UNKNOWN); | ||
| 308 | } | 461 | } |
| 309 | } | 462 | } |
| 463 | counter++; | ||
| 464 | } | ||
| 310 | 465 | ||
| 311 | int counter = 0; | 466 | if (config.authtype != NULL) { |
| 312 | while (counter < config.ncommands) { | 467 | mp_subcheck sc_auth = mp_subcheck_init(); |
| 313 | xasprintf(&cmd_str, "%s%s", config.commands[counter], "\r\n"); | 468 | |
| 314 | my_send(config, cmd_str, (int)strlen(cmd_str), socket_descriptor, ssl_established); | 469 | if (strcmp(config.authtype, "LOGIN") == 0) { |
| 315 | if (recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established) >= 1 && verbose) { | 470 | char *abuf; |
| 316 | printf("%s", buffer); | 471 | int ret; |
| 317 | } | 472 | do { |
| 318 | strip(buffer); | 473 | /* send AUTH LOGIN */ |
| 319 | if (counter < config.nresponses) { | 474 | my_send(config, SMTP_AUTH_LOGIN, strlen(SMTP_AUTH_LOGIN), socket_descriptor, |
| 320 | int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; | 475 | ssl_established); |
| 321 | regex_t preg; | 476 | |
| 322 | int errcode = regcomp(&preg, config.responses[counter], cflags); | 477 | if (verbose) { |
| 323 | char errbuf[MAX_INPUT_BUFFER]; | 478 | printf(_("sent %s\n"), "AUTH LOGIN"); |
| 324 | if (errcode != 0) { | ||
| 325 | regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); | ||
| 326 | printf(_("Could Not Compile Regular Expression")); | ||
| 327 | exit(STATE_UNKNOWN); | ||
| 328 | } | 479 | } |
| 329 | 480 | ||
| 330 | regmatch_t pmatch[10]; | 481 | if ((ret = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, |
| 331 | int eflags = 0; | 482 | ssl_established)) <= 0) { |
| 332 | int excode = regexec(&preg, buffer, 10, pmatch, eflags); | 483 | xasprintf(&sc_auth.output, _("recv() failed after AUTH LOGIN")); |
| 333 | if (excode == 0) { | 484 | sc_auth = mp_set_subcheck_state(sc_auth, STATE_WARNING); |
| 334 | result = STATE_OK; | 485 | break; |
| 335 | } else if (excode == REG_NOMATCH) { | ||
| 336 | result = STATE_WARNING; | ||
| 337 | printf(_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text(result), buffer, config.commands[counter]); | ||
| 338 | } else { | ||
| 339 | regerror(excode, &preg, errbuf, MAX_INPUT_BUFFER); | ||
| 340 | printf(_("Execute Error: %s\n"), errbuf); | ||
| 341 | result = STATE_UNKNOWN; | ||
| 342 | } | 486 | } |
| 343 | } | ||
| 344 | counter++; | ||
| 345 | } | ||
| 346 | 487 | ||
| 347 | if (config.authtype != NULL) { | 488 | if (verbose) { |
| 348 | if (strcmp(config.authtype, "LOGIN") == 0) { | 489 | printf(_("received %s\n"), buffer); |
| 349 | char *abuf; | 490 | } |
| 350 | int ret; | 491 | |
| 351 | do { | 492 | if (strncmp(buffer, "334", 3) != 0) { |
| 352 | if (config.authuser == NULL) { | 493 | xasprintf(&sc_auth.output, "invalid response received after AUTH LOGIN"); |
| 353 | result = STATE_CRITICAL; | 494 | sc_auth = mp_set_subcheck_state(sc_auth, STATE_CRITICAL); |
| 354 | xasprintf(&error_msg, _("no authuser specified, ")); | ||
| 355 | break; | ||
| 356 | } | ||
| 357 | if (config.authpass == NULL) { | ||
| 358 | result = STATE_CRITICAL; | ||
| 359 | xasprintf(&error_msg, _("no authpass specified, ")); | ||
| 360 | break; | ||
| 361 | } | ||
| 362 | |||
| 363 | /* send AUTH LOGIN */ | ||
| 364 | my_send(config, SMTP_AUTH_LOGIN, strlen(SMTP_AUTH_LOGIN), socket_descriptor, ssl_established); | ||
| 365 | if (verbose) { | ||
| 366 | printf(_("sent %s\n"), "AUTH LOGIN"); | ||
| 367 | } | ||
| 368 | |||
| 369 | if ((ret = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established)) <= 0) { | ||
| 370 | xasprintf(&error_msg, _("recv() failed after AUTH LOGIN, ")); | ||
| 371 | result = STATE_WARNING; | ||
| 372 | break; | ||
| 373 | } | ||
| 374 | if (verbose) { | ||
| 375 | printf(_("received %s\n"), buffer); | ||
| 376 | } | ||
| 377 | |||
| 378 | if (strncmp(buffer, "334", 3) != 0) { | ||
| 379 | result = STATE_CRITICAL; | ||
| 380 | xasprintf(&error_msg, _("invalid response received after AUTH LOGIN, ")); | ||
| 381 | break; | ||
| 382 | } | ||
| 383 | |||
| 384 | /* encode authuser with base64 */ | ||
| 385 | base64_encode_alloc(config.authuser, strlen(config.authuser), &abuf); | ||
| 386 | xasprintf(&abuf, "%s\r\n", abuf); | ||
| 387 | my_send(config, abuf, (int)strlen(abuf), socket_descriptor, ssl_established); | ||
| 388 | if (verbose) { | ||
| 389 | printf(_("sent %s\n"), abuf); | ||
| 390 | } | ||
| 391 | |||
| 392 | if ((ret = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established)) <= 0) { | ||
| 393 | result = STATE_CRITICAL; | ||
| 394 | xasprintf(&error_msg, _("recv() failed after sending authuser, ")); | ||
| 395 | break; | ||
| 396 | } | ||
| 397 | if (verbose) { | ||
| 398 | printf(_("received %s\n"), buffer); | ||
| 399 | } | ||
| 400 | if (strncmp(buffer, "334", 3) != 0) { | ||
| 401 | result = STATE_CRITICAL; | ||
| 402 | xasprintf(&error_msg, _("invalid response received after authuser, ")); | ||
| 403 | break; | ||
| 404 | } | ||
| 405 | /* encode authpass with base64 */ | ||
| 406 | base64_encode_alloc(config.authpass, strlen(config.authpass), &abuf); | ||
| 407 | xasprintf(&abuf, "%s\r\n", abuf); | ||
| 408 | my_send(config, abuf, (int)strlen(abuf), socket_descriptor, ssl_established); | ||
| 409 | if (verbose) { | ||
| 410 | printf(_("sent %s\n"), abuf); | ||
| 411 | } | ||
| 412 | if ((ret = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, ssl_established)) <= 0) { | ||
| 413 | result = STATE_CRITICAL; | ||
| 414 | xasprintf(&error_msg, _("recv() failed after sending authpass, ")); | ||
| 415 | break; | ||
| 416 | } | ||
| 417 | if (verbose) { | ||
| 418 | printf(_("received %s\n"), buffer); | ||
| 419 | } | ||
| 420 | if (strncmp(buffer, "235", 3) != 0) { | ||
| 421 | result = STATE_CRITICAL; | ||
| 422 | xasprintf(&error_msg, _("invalid response received after authpass, ")); | ||
| 423 | break; | ||
| 424 | } | ||
| 425 | break; | 495 | break; |
| 426 | } while (false); | 496 | } |
| 427 | } else { | ||
| 428 | result = STATE_CRITICAL; | ||
| 429 | xasprintf(&error_msg, _("only authtype LOGIN is supported, ")); | ||
| 430 | } | ||
| 431 | } | ||
| 432 | 497 | ||
| 433 | /* tell the server we're done */ | 498 | /* encode authuser with base64 */ |
| 434 | smtp_quit(config, buffer, socket_descriptor, ssl_established); | 499 | base64_encode_alloc(config.authuser, strlen(config.authuser), &abuf); |
| 500 | xasprintf(&abuf, "%s\r\n", abuf); | ||
| 501 | my_send(config, abuf, (int)strlen(abuf), socket_descriptor, ssl_established); | ||
| 502 | if (verbose) { | ||
| 503 | printf(_("sent %s\n"), abuf); | ||
| 504 | } | ||
| 505 | |||
| 506 | if ((ret = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, | ||
| 507 | ssl_established)) <= 0) { | ||
| 508 | xasprintf(&sc_auth.output, "recv() failed after sending authuser"); | ||
| 509 | sc_auth = mp_set_subcheck_state(sc_auth, STATE_CRITICAL); | ||
| 510 | break; | ||
| 511 | } | ||
| 512 | |||
| 513 | if (verbose) { | ||
| 514 | printf(_("received %s\n"), buffer); | ||
| 515 | } | ||
| 516 | |||
| 517 | if (strncmp(buffer, "334", 3) != 0) { | ||
| 518 | xasprintf(&sc_auth.output, "invalid response received after authuser"); | ||
| 519 | sc_auth = mp_set_subcheck_state(sc_auth, STATE_CRITICAL); | ||
| 520 | break; | ||
| 521 | } | ||
| 435 | 522 | ||
| 436 | /* finally close the connection */ | 523 | /* encode authpass with base64 */ |
| 437 | close(socket_descriptor); | 524 | base64_encode_alloc(config.authpass, strlen(config.authpass), &abuf); |
| 525 | xasprintf(&abuf, "%s\r\n", abuf); | ||
| 526 | my_send(config, abuf, (int)strlen(abuf), socket_descriptor, ssl_established); | ||
| 527 | |||
| 528 | if (verbose) { | ||
| 529 | printf(_("sent %s\n"), abuf); | ||
| 530 | } | ||
| 531 | |||
| 532 | if ((ret = recvlines(config, buffer, MAX_INPUT_BUFFER, socket_descriptor, | ||
| 533 | ssl_established)) <= 0) { | ||
| 534 | xasprintf(&sc_auth.output, "recv() failed after sending authpass"); | ||
| 535 | sc_auth = mp_set_subcheck_state(sc_auth, STATE_CRITICAL); | ||
| 536 | break; | ||
| 537 | } | ||
| 538 | |||
| 539 | if (verbose) { | ||
| 540 | printf(_("received %s\n"), buffer); | ||
| 541 | } | ||
| 542 | |||
| 543 | if (strncmp(buffer, "235", 3) != 0) { | ||
| 544 | xasprintf(&sc_auth.output, "invalid response received after authpass"); | ||
| 545 | sc_auth = mp_set_subcheck_state(sc_auth, STATE_CRITICAL); | ||
| 546 | break; | ||
| 547 | } | ||
| 548 | break; | ||
| 549 | } while (false); | ||
| 550 | } else { | ||
| 551 | sc_auth = mp_set_subcheck_state(sc_auth, STATE_CRITICAL); | ||
| 552 | xasprintf(&sc_auth.output, "only authtype LOGIN is supported"); | ||
| 553 | } | ||
| 554 | |||
| 555 | mp_add_subcheck_to_check(&overall, sc_auth); | ||
| 438 | } | 556 | } |
| 439 | 557 | ||
| 558 | /* tell the server we're done */ | ||
| 559 | smtp_quit(config, buffer, socket_descriptor, ssl_established); | ||
| 560 | |||
| 561 | /* finally close the connection */ | ||
| 562 | close(socket_descriptor); | ||
| 563 | |||
| 440 | /* reset the alarm */ | 564 | /* reset the alarm */ |
| 441 | alarm(0); | 565 | alarm(0); |
| 442 | 566 | ||
| 443 | long microsec = deltime(start_time); | 567 | long microsec = deltime(start_time); |
| 444 | double elapsed_time = (double)microsec / 1.0e6; | 568 | double elapsed_time = (double)microsec / 1.0e6; |
| 445 | 569 | ||
| 446 | if (result == STATE_OK) { | 570 | mp_perfdata pd_elapsed_time = perfdata_init(); |
| 447 | if (config.check_critical_time && elapsed_time > config.critical_time) { | 571 | pd_elapsed_time = mp_set_pd_value(pd_elapsed_time, elapsed_time); |
| 448 | result = STATE_CRITICAL; | 572 | pd_elapsed_time.label = "time"; |
| 449 | } else if (config.check_warning_time && elapsed_time > config.warning_time) { | 573 | pd_elapsed_time.uom = "s"; |
| 450 | result = STATE_WARNING; | 574 | |
| 451 | } | 575 | pd_elapsed_time = mp_pd_set_thresholds(pd_elapsed_time, config.connection_time); |
| 452 | } | ||
| 453 | 576 | ||
| 454 | printf(_("SMTP %s - %s%.3f sec. response time%s%s|%s\n"), state_text(result), error_msg, elapsed_time, verbose ? ", " : "", | 577 | mp_subcheck sc_connection_time = mp_subcheck_init(); |
| 455 | verbose ? buffer : "", | 578 | xasprintf(&sc_connection_time.output, "connection time: %.3gs", elapsed_time); |
| 456 | fperfdata("time", elapsed_time, "s", config.check_warning_time, config.warning_time, config.check_critical_time, | 579 | sc_connection_time = |
| 457 | config.critical_time, true, 0, false, 0)); | 580 | mp_set_subcheck_state(sc_connection_time, mp_get_pd_status(pd_elapsed_time)); |
| 581 | mp_add_subcheck_to_check(&overall, sc_connection_time); | ||
| 458 | 582 | ||
| 459 | exit(result); | 583 | mp_exit(overall); |
| 460 | } | 584 | } |
| 461 | 585 | ||
| 462 | /* process command-line arguments */ | 586 | /* process command-line arguments */ |
| 463 | check_smtp_config_wrapper process_arguments(int argc, char **argv) { | 587 | check_smtp_config_wrapper process_arguments(int argc, char **argv) { |
| 464 | enum { | 588 | enum { |
| 465 | SNI_OPTION = CHAR_MAX + 1 | 589 | SNI_OPTION = CHAR_MAX + 1, |
| 590 | output_format_index, | ||
| 591 | ignore_certificate_expiration_index, | ||
| 466 | }; | 592 | }; |
| 467 | 593 | ||
| 468 | int option = 0; | 594 | int option = 0; |
| 469 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, | 595 | static struct option longopts[] = { |
| 470 | {"expect", required_argument, 0, 'e'}, | 596 | {"hostname", required_argument, 0, 'H'}, |
| 471 | {"critical", required_argument, 0, 'c'}, | 597 | {"expect", required_argument, 0, 'e'}, |
| 472 | {"warning", required_argument, 0, 'w'}, | 598 | {"critical", required_argument, 0, 'c'}, |
| 473 | {"timeout", required_argument, 0, 't'}, | 599 | {"warning", required_argument, 0, 'w'}, |
| 474 | {"port", required_argument, 0, 'p'}, | 600 | {"timeout", required_argument, 0, 't'}, |
| 475 | {"from", required_argument, 0, 'f'}, | 601 | {"port", required_argument, 0, 'p'}, |
| 476 | {"fqdn", required_argument, 0, 'F'}, | 602 | {"from", required_argument, 0, 'f'}, |
| 477 | {"authtype", required_argument, 0, 'A'}, | 603 | {"fqdn", required_argument, 0, 'F'}, |
| 478 | {"authuser", required_argument, 0, 'U'}, | 604 | {"authtype", required_argument, 0, 'A'}, |
| 479 | {"authpass", required_argument, 0, 'P'}, | 605 | {"authuser", required_argument, 0, 'U'}, |
| 480 | {"command", required_argument, 0, 'C'}, | 606 | {"authpass", required_argument, 0, 'P'}, |
| 481 | {"response", required_argument, 0, 'R'}, | 607 | {"command", required_argument, 0, 'C'}, |
| 482 | {"verbose", no_argument, 0, 'v'}, | 608 | {"response", required_argument, 0, 'R'}, |
| 483 | {"version", no_argument, 0, 'V'}, | 609 | {"verbose", no_argument, 0, 'v'}, |
| 484 | {"use-ipv4", no_argument, 0, '4'}, | 610 | {"version", no_argument, 0, 'V'}, |
| 485 | {"use-ipv6", no_argument, 0, '6'}, | 611 | {"use-ipv4", no_argument, 0, '4'}, |
| 486 | {"help", no_argument, 0, 'h'}, | 612 | {"use-ipv6", no_argument, 0, '6'}, |
| 487 | {"lmtp", no_argument, 0, 'L'}, | 613 | {"help", no_argument, 0, 'h'}, |
| 488 | {"ssl", no_argument, 0, 's'}, | 614 | {"lmtp", no_argument, 0, 'L'}, |
| 489 | {"tls", no_argument, 0, 's'}, | 615 | {"ssl", no_argument, 0, 's'}, |
| 490 | {"starttls", no_argument, 0, 'S'}, | 616 | {"tls", no_argument, 0, 's'}, |
| 491 | {"sni", no_argument, 0, SNI_OPTION}, | 617 | {"starttls", no_argument, 0, 'S'}, |
| 492 | {"certificate", required_argument, 0, 'D'}, | 618 | {"sni", no_argument, 0, SNI_OPTION}, |
| 493 | {"ignore-quit-failure", no_argument, 0, 'q'}, | 619 | {"certificate", required_argument, 0, 'D'}, |
| 494 | {"proxy", no_argument, 0, 'r'}, | 620 | {"ignore-quit-failure", no_argument, 0, 'q'}, |
| 495 | {0, 0, 0, 0}}; | 621 | {"proxy", no_argument, 0, 'r'}, |
| 622 | {"ignore-certificate-expiration", no_argument, 0, ignore_certificate_expiration_index}, | ||
| 623 | {"output-format", required_argument, 0, output_format_index}, | ||
| 624 | {0, 0, 0, 0}}; | ||
| 496 | 625 | ||
| 497 | check_smtp_config_wrapper result = { | 626 | check_smtp_config_wrapper result = { |
| 498 | .config = check_smtp_config_init(), | 627 | .config = check_smtp_config_init(), |
| @@ -514,12 +643,13 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 514 | } | 643 | } |
| 515 | } | 644 | } |
| 516 | 645 | ||
| 517 | int command_size = 0; | 646 | unsigned long command_size = 0; |
| 518 | int response_size = 0; | 647 | unsigned long response_size = 0; |
| 519 | bool implicit_tls = false; | 648 | bool implicit_tls = false; |
| 520 | int server_port_option = 0; | 649 | int server_port_option = 0; |
| 521 | while (true) { | 650 | while (true) { |
| 522 | int opt_index = getopt_long(argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q", longopts, &option); | 651 | int opt_index = |
| 652 | getopt_long(argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q", longopts, &option); | ||
| 523 | 653 | ||
| 524 | if (opt_index == -1 || opt_index == EOF) { | 654 | if (opt_index == -1 || opt_index == EOF) { |
| 525 | break; | 655 | break; |
| @@ -546,7 +676,8 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 546 | break; | 676 | break; |
| 547 | case 'f': /* from argument */ | 677 | case 'f': /* from argument */ |
| 548 | result.config.from_arg = optarg + strspn(optarg, "<"); | 678 | result.config.from_arg = optarg + strspn(optarg, "<"); |
| 549 | result.config.from_arg = strndup(result.config.from_arg, strcspn(result.config.from_arg, ">")); | 679 | result.config.from_arg = |
| 680 | strndup(result.config.from_arg, strcspn(result.config.from_arg, ">")); | ||
| 550 | result.config.send_mail_from = true; | 681 | result.config.send_mail_from = true; |
| 551 | break; | 682 | break; |
| 552 | case 'A': | 683 | case 'A': |
| @@ -565,9 +696,11 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 565 | case 'C': /* commands */ | 696 | case 'C': /* commands */ |
| 566 | if (result.config.ncommands >= command_size) { | 697 | if (result.config.ncommands >= command_size) { |
| 567 | command_size += 8; | 698 | command_size += 8; |
| 568 | result.config.commands = realloc(result.config.commands, sizeof(char *) * command_size); | 699 | result.config.commands = |
| 700 | realloc(result.config.commands, sizeof(char *) * command_size); | ||
| 569 | if (result.config.commands == NULL) { | 701 | if (result.config.commands == NULL) { |
| 570 | die(STATE_UNKNOWN, _("Could not realloc() units [%d]\n"), result.config.ncommands); | 702 | die(STATE_UNKNOWN, _("Could not realloc() units [%lu]\n"), |
| 703 | result.config.ncommands); | ||
| 571 | } | 704 | } |
| 572 | } | 705 | } |
| 573 | result.config.commands[result.config.ncommands] = (char *)malloc(sizeof(char) * 255); | 706 | result.config.commands[result.config.ncommands] = (char *)malloc(sizeof(char) * 255); |
| @@ -577,31 +710,33 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 577 | case 'R': /* server responses */ | 710 | case 'R': /* server responses */ |
| 578 | if (result.config.nresponses >= response_size) { | 711 | if (result.config.nresponses >= response_size) { |
| 579 | response_size += 8; | 712 | response_size += 8; |
| 580 | result.config.responses = realloc(result.config.responses, sizeof(char *) * response_size); | 713 | result.config.responses = |
| 714 | realloc(result.config.responses, sizeof(char *) * response_size); | ||
| 581 | if (result.config.responses == NULL) { | 715 | if (result.config.responses == NULL) { |
| 582 | die(STATE_UNKNOWN, _("Could not realloc() units [%d]\n"), result.config.nresponses); | 716 | die(STATE_UNKNOWN, _("Could not realloc() units [%lu]\n"), |
| 717 | result.config.nresponses); | ||
| 583 | } | 718 | } |
| 584 | } | 719 | } |
| 585 | result.config.responses[result.config.nresponses] = (char *)malloc(sizeof(char) * 255); | 720 | result.config.responses[result.config.nresponses] = (char *)malloc(sizeof(char) * 255); |
| 586 | strncpy(result.config.responses[result.config.nresponses], optarg, 255); | 721 | strncpy(result.config.responses[result.config.nresponses], optarg, 255); |
| 587 | result.config.nresponses++; | 722 | result.config.nresponses++; |
| 588 | break; | 723 | break; |
| 589 | case 'c': /* critical time threshold */ | 724 | case 'c': /* critical time threshold */ { |
| 590 | if (!is_nonnegative(optarg)) { | 725 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 591 | usage4(_("Critical time must be a positive")); | 726 | if (tmp.error != MP_PARSING_SUCCES) { |
| 592 | } else { | 727 | die(STATE_UNKNOWN, "failed to parse critical time threshold"); |
| 593 | result.config.critical_time = strtod(optarg, NULL); | ||
| 594 | result.config.check_critical_time = true; | ||
| 595 | } | 728 | } |
| 596 | break; | 729 | result.config.connection_time = |
| 597 | case 'w': /* warning time threshold */ | 730 | mp_thresholds_set_warn(result.config.connection_time, tmp.range); |
| 598 | if (!is_nonnegative(optarg)) { | 731 | } break; |
| 599 | usage4(_("Warning time must be a positive")); | 732 | case 'w': /* warning time threshold */ { |
| 600 | } else { | 733 | mp_range_parsed tmp = mp_parse_range_string(optarg); |
| 601 | result.config.warning_time = strtod(optarg, NULL); | 734 | if (tmp.error != MP_PARSING_SUCCES) { |
| 602 | result.config.check_warning_time = true; | 735 | die(STATE_UNKNOWN, "failed to parse warning time threshold"); |
| 603 | } | 736 | } |
| 604 | break; | 737 | result.config.connection_time = |
| 738 | mp_thresholds_set_crit(result.config.connection_time, tmp.range); | ||
| 739 | } break; | ||
| 605 | case 'v': /* verbose */ | 740 | case 'v': /* verbose */ |
| 606 | verbose++; | 741 | verbose++; |
| 607 | break; | 742 | break; |
| @@ -638,7 +773,6 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 638 | } | 773 | } |
| 639 | result.config.days_till_exp_warn = atoi(optarg); | 774 | result.config.days_till_exp_warn = atoi(optarg); |
| 640 | } | 775 | } |
| 641 | result.config.check_cert = true; | ||
| 642 | result.config.ignore_send_quit_failure = true; | 776 | result.config.ignore_send_quit_failure = true; |
| 643 | #else | 777 | #else |
| 644 | usage(_("SSL support not available - install OpenSSL and recompile")); | 778 | usage(_("SSL support not available - install OpenSSL and recompile")); |
| @@ -687,6 +821,21 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 687 | exit(STATE_UNKNOWN); | 821 | exit(STATE_UNKNOWN); |
| 688 | case '?': /* help */ | 822 | case '?': /* help */ |
| 689 | usage5(); | 823 | usage5(); |
| 824 | case output_format_index: { | ||
| 825 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 826 | if (!parser.parsing_success) { | ||
| 827 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 828 | printf("Invalid output format: %s\n", optarg); | ||
| 829 | exit(STATE_UNKNOWN); | ||
| 830 | } | ||
| 831 | |||
| 832 | result.config.output_format_is_set = true; | ||
| 833 | result.config.output_format = parser.output_format; | ||
| 834 | break; | ||
| 835 | } | ||
| 836 | case ignore_certificate_expiration_index: { | ||
| 837 | result.config.ignore_certificate_expiration = true; | ||
| 838 | } | ||
| 690 | } | 839 | } |
| 691 | } | 840 | } |
| 692 | 841 | ||
| @@ -715,11 +864,26 @@ check_smtp_config_wrapper process_arguments(int argc, char **argv) { | |||
| 715 | result.config.server_port = server_port_option; | 864 | result.config.server_port = server_port_option; |
| 716 | } | 865 | } |
| 717 | 866 | ||
| 867 | if (result.config.authtype) { | ||
| 868 | if (strcmp(result.config.authtype, "LOGIN") == 0) { | ||
| 869 | if (result.config.authuser == NULL) { | ||
| 870 | usage4("no authuser specified"); | ||
| 871 | } | ||
| 872 | if (result.config.authpass == NULL) { | ||
| 873 | usage4("no authpass specified"); | ||
| 874 | } | ||
| 875 | } else { | ||
| 876 | usage4("only authtype LOGIN is supported"); | ||
| 877 | } | ||
| 878 | } | ||
| 879 | |||
| 718 | return result; | 880 | return result; |
| 719 | } | 881 | } |
| 720 | 882 | ||
| 721 | char *smtp_quit(check_smtp_config config, char buffer[MAX_INPUT_BUFFER], int socket_descriptor, bool ssl_established) { | 883 | char *smtp_quit(check_smtp_config config, char buffer[MAX_INPUT_BUFFER], int socket_descriptor, |
| 722 | int sent_bytes = my_send(config, SMTP_QUIT, strlen(SMTP_QUIT), socket_descriptor, ssl_established); | 884 | bool ssl_established) { |
| 885 | int sent_bytes = | ||
| 886 | my_send(config, SMTP_QUIT, strlen(SMTP_QUIT), socket_descriptor, ssl_established); | ||
| 723 | if (sent_bytes < 0) { | 887 | if (sent_bytes < 0) { |
| 724 | if (config.ignore_send_quit_failure) { | 888 | if (config.ignore_send_quit_failure) { |
| 725 | if (verbose) { | 889 | if (verbose) { |
| @@ -759,9 +923,10 @@ char *smtp_quit(check_smtp_config config, char buffer[MAX_INPUT_BUFFER], int soc | |||
| 759 | * function which buffers the data, move that to netutils.c and change | 923 | * function which buffers the data, move that to netutils.c and change |
| 760 | * check_smtp and other plugins to use that. Also, remove (\r)\n. | 924 | * check_smtp and other plugins to use that. Also, remove (\r)\n. |
| 761 | */ | 925 | */ |
| 762 | int recvline(char *buf, size_t bufsize, check_smtp_config config, int socket_descriptor, bool ssl_established) { | 926 | int recvline(char *buf, size_t bufsize, check_smtp_config config, int socket_descriptor, |
| 927 | bool ssl_established) { | ||
| 763 | int result; | 928 | int result; |
| 764 | int counter; | 929 | size_t counter; |
| 765 | 930 | ||
| 766 | for (counter = result = 0; counter < bufsize - 1; counter++) { | 931 | for (counter = result = 0; counter < bufsize - 1; counter++) { |
| 767 | if ((result = my_recv(config, &buf[counter], 1, socket_descriptor, ssl_established)) != 1) { | 932 | if ((result = my_recv(config, &buf[counter], 1, socket_descriptor, ssl_established)) != 1) { |
| @@ -769,7 +934,7 @@ int recvline(char *buf, size_t bufsize, check_smtp_config config, int socket_des | |||
| 769 | } | 934 | } |
| 770 | if (buf[counter] == '\n') { | 935 | if (buf[counter] == '\n') { |
| 771 | buf[++counter] = '\0'; | 936 | buf[++counter] = '\0'; |
| 772 | return counter; | 937 | return (int)counter; |
| 773 | } | 938 | } |
| 774 | } | 939 | } |
| 775 | return (result == 1 || counter == 0) ? -2 : result; /* -2 if out of space */ | 940 | return (result == 1 || counter == 0) ? -2 : result; /* -2 if out of space */ |
| @@ -789,13 +954,16 @@ int recvline(char *buf, size_t bufsize, check_smtp_config config, int socket_des | |||
| 789 | * | 954 | * |
| 790 | * TODO: Move this to netutils.c. Also, remove \r and possibly the final \n. | 955 | * TODO: Move this to netutils.c. Also, remove \r and possibly the final \n. |
| 791 | */ | 956 | */ |
| 792 | int recvlines(check_smtp_config config, char *buf, size_t bufsize, int socket_descriptor, bool ssl_established) { | 957 | int recvlines(check_smtp_config config, char *buf, size_t bufsize, int socket_descriptor, |
| 958 | bool ssl_established) { | ||
| 793 | int result; | 959 | int result; |
| 794 | int counter; | 960 | int counter; |
| 795 | 961 | ||
| 796 | for (counter = 0; /* forever */; counter += result) { | 962 | for (counter = 0; /* forever */; counter += result) { |
| 797 | if (!((result = recvline(buf + counter, bufsize - counter, config, socket_descriptor, ssl_established)) > 3 && | 963 | if (!((result = recvline(buf + counter, bufsize - counter, config, socket_descriptor, |
| 798 | isdigit((int)buf[counter]) && isdigit((int)buf[counter + 1]) && isdigit((int)buf[counter + 2]) && buf[counter + 3] == '-')) { | 964 | ssl_established)) > 3 && |
| 965 | isdigit((int)buf[counter]) && isdigit((int)buf[counter + 1]) && | ||
| 966 | isdigit((int)buf[counter + 2]) && buf[counter + 3] == '-')) { | ||
| 799 | break; | 967 | break; |
| 800 | } | 968 | } |
| 801 | } | 969 | } |
| @@ -835,13 +1003,15 @@ void print_help(void) { | |||
| 835 | printf(UT_IPv46); | 1003 | printf(UT_IPv46); |
| 836 | 1004 | ||
| 837 | printf(" %s\n", "-e, --expect=STRING"); | 1005 | printf(" %s\n", "-e, --expect=STRING"); |
| 838 | printf(_(" String to expect in first line of server response (default: '%s')\n"), SMTP_EXPECT); | 1006 | printf(_(" String to expect in first line of server response (default: '%s')\n"), |
| 1007 | SMTP_EXPECT); | ||
| 839 | printf(" %s\n", "-C, --command=STRING"); | 1008 | printf(" %s\n", "-C, --command=STRING"); |
| 840 | printf(" %s\n", _("SMTP command (may be used repeatedly)")); | 1009 | printf(" %s\n", _("SMTP command (may be used repeatedly)")); |
| 841 | printf(" %s\n", "-R, --response=STRING"); | 1010 | printf(" %s\n", "-R, --response=STRING"); |
| 842 | printf(" %s\n", _("Expected response to command (may be used repeatedly)")); | 1011 | printf(" %s\n", _("Expected response to command (may be used repeatedly)")); |
| 843 | printf(" %s\n", "-f, --from=STRING"); | 1012 | printf(" %s\n", "-f, --from=STRING"); |
| 844 | printf(" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")), printf(" %s\n", "-F, --fqdn=STRING"); | 1013 | printf(" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")), |
| 1014 | printf(" %s\n", "-F, --fqdn=STRING"); | ||
| 845 | printf(" %s\n", _("FQDN used for HELO")); | 1015 | printf(" %s\n", _("FQDN used for HELO")); |
| 846 | printf(" %s\n", "-r, --proxy"); | 1016 | printf(" %s\n", "-r, --proxy"); |
| 847 | printf(" %s\n", _("Use PROXY protocol prefix for the connection.")); | 1017 | printf(" %s\n", _("Use PROXY protocol prefix for the connection.")); |
| @@ -867,11 +1037,15 @@ void print_help(void) { | |||
| 867 | printf(" %s\n", _("Send LHLO instead of HELO/EHLO")); | 1037 | printf(" %s\n", _("Send LHLO instead of HELO/EHLO")); |
| 868 | printf(" %s\n", "-q, --ignore-quit-failure"); | 1038 | printf(" %s\n", "-q, --ignore-quit-failure"); |
| 869 | printf(" %s\n", _("Ignore failure when sending QUIT command to server")); | 1039 | printf(" %s\n", _("Ignore failure when sending QUIT command to server")); |
| 1040 | printf(" %s\n", "--ignore-certificate-expiration"); | ||
| 1041 | printf(" %s\n", _("Ignore certificate expiration")); | ||
| 870 | 1042 | ||
| 871 | printf(UT_WARN_CRIT); | 1043 | printf(UT_WARN_CRIT); |
| 872 | 1044 | ||
| 873 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 1045 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 874 | 1046 | ||
| 1047 | printf(UT_OUTPUT_FORMAT); | ||
| 1048 | |||
| 875 | printf(UT_VERBOSE); | 1049 | printf(UT_VERBOSE); |
| 876 | 1050 | ||
| 877 | printf("\n"); | 1051 | printf("\n"); |
| @@ -885,7 +1059,9 @@ void print_help(void) { | |||
| 885 | 1059 | ||
| 886 | void print_usage(void) { | 1060 | void print_usage(void) { |
| 887 | printf("%s\n", _("Usage:")); | 1061 | printf("%s\n", _("Usage:")); |
| 888 | printf("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", progname); | 1062 | printf("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", |
| 1063 | progname); | ||
| 889 | printf("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-q]\n"); | 1064 | printf("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-q]\n"); |
| 890 | printf("[-F fqdn] [-S] [-L] [-D warn days cert expire[,crit days cert expire]] [-r] [--sni] [-v] \n"); | 1065 | printf("[-F fqdn] [-S] [-L] [-D warn days cert expire[,crit days cert expire]] [-r] [--sni] " |
| 1066 | "[-v] \n"); | ||
| 891 | } | 1067 | } |
diff --git a/plugins/check_smtp.d/config.h b/plugins/check_smtp.d/config.h index 0a6511ef..b0d42ed1 100644 --- a/plugins/check_smtp.d/config.h +++ b/plugins/check_smtp.d/config.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../../config.h" | 3 | #include "../../config.h" |
| 4 | #include "output.h" | ||
| 5 | #include "thresholds.h" | ||
| 4 | #include <stddef.h> | 6 | #include <stddef.h> |
| 5 | #include <string.h> | 7 | #include <string.h> |
| 6 | 8 | ||
| @@ -18,20 +20,18 @@ typedef struct { | |||
| 18 | char *server_expect; | 20 | char *server_expect; |
| 19 | bool ignore_send_quit_failure; | 21 | bool ignore_send_quit_failure; |
| 20 | 22 | ||
| 21 | double warning_time; | 23 | mp_thresholds connection_time; |
| 22 | bool check_warning_time; | 24 | |
| 23 | double critical_time; | ||
| 24 | bool check_critical_time; | ||
| 25 | bool use_ehlo; | 25 | bool use_ehlo; |
| 26 | bool use_lhlo; | 26 | bool use_lhlo; |
| 27 | 27 | ||
| 28 | char *from_arg; | 28 | char *from_arg; |
| 29 | bool send_mail_from; | 29 | bool send_mail_from; |
| 30 | 30 | ||
| 31 | int ncommands; | 31 | unsigned long ncommands; |
| 32 | char **commands; | 32 | char **commands; |
| 33 | 33 | ||
| 34 | int nresponses; | 34 | unsigned long nresponses; |
| 35 | char **responses; | 35 | char **responses; |
| 36 | 36 | ||
| 37 | char *authtype; | 37 | char *authtype; |
| @@ -40,13 +40,17 @@ typedef struct { | |||
| 40 | 40 | ||
| 41 | bool use_proxy_prefix; | 41 | bool use_proxy_prefix; |
| 42 | #ifdef HAVE_SSL | 42 | #ifdef HAVE_SSL |
| 43 | bool check_cert; | ||
| 44 | int days_till_exp_warn; | 43 | int days_till_exp_warn; |
| 45 | int days_till_exp_crit; | 44 | int days_till_exp_crit; |
| 46 | bool use_ssl; | 45 | bool use_ssl; |
| 47 | bool use_starttls; | 46 | bool use_starttls; |
| 48 | bool use_sni; | 47 | bool use_sni; |
| 48 | |||
| 49 | bool ignore_certificate_expiration; | ||
| 49 | #endif | 50 | #endif |
| 51 | |||
| 52 | bool output_format_is_set; | ||
| 53 | mp_output_format output_format; | ||
| 50 | } check_smtp_config; | 54 | } check_smtp_config; |
| 51 | 55 | ||
| 52 | check_smtp_config check_smtp_config_init() { | 56 | check_smtp_config check_smtp_config_init() { |
| @@ -58,10 +62,7 @@ check_smtp_config check_smtp_config_init() { | |||
| 58 | .server_expect = SMTP_EXPECT, | 62 | .server_expect = SMTP_EXPECT, |
| 59 | .ignore_send_quit_failure = false, | 63 | .ignore_send_quit_failure = false, |
| 60 | 64 | ||
| 61 | .warning_time = 0, | 65 | .connection_time = mp_thresholds_init(), |
| 62 | .check_warning_time = false, | ||
| 63 | .critical_time = 0, | ||
| 64 | .check_critical_time = false, | ||
| 65 | .use_ehlo = false, | 66 | .use_ehlo = false, |
| 66 | .use_lhlo = false, | 67 | .use_lhlo = false, |
| 67 | 68 | ||
| @@ -80,13 +81,16 @@ check_smtp_config check_smtp_config_init() { | |||
| 80 | 81 | ||
| 81 | .use_proxy_prefix = false, | 82 | .use_proxy_prefix = false, |
| 82 | #ifdef HAVE_SSL | 83 | #ifdef HAVE_SSL |
| 83 | .check_cert = false, | ||
| 84 | .days_till_exp_warn = 0, | 84 | .days_till_exp_warn = 0, |
| 85 | .days_till_exp_crit = 0, | 85 | .days_till_exp_crit = 0, |
| 86 | .use_ssl = false, | 86 | .use_ssl = false, |
| 87 | .use_starttls = false, | 87 | .use_starttls = false, |
| 88 | .use_sni = false, | 88 | .use_sni = false, |
| 89 | |||
| 90 | .ignore_certificate_expiration = false, | ||
| 89 | #endif | 91 | #endif |
| 92 | |||
| 93 | .output_format_is_set = false, | ||
| 90 | }; | 94 | }; |
| 91 | return tmp; | 95 | return tmp; |
| 92 | } | 96 | } |
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index c1d8e2dd..f470d222 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c | |||
| @@ -32,716 +32,492 @@ const char *progname = "check_snmp"; | |||
| 32 | const char *copyright = "1999-2024"; | 32 | const char *copyright = "1999-2024"; |
| 33 | const char *email = "devel@monitoring-plugins.org"; | 33 | const char *email = "devel@monitoring-plugins.org"; |
| 34 | 34 | ||
| 35 | #include "common.h" | 35 | #include "./common.h" |
| 36 | #include "runcmd.h" | 36 | #include "./runcmd.h" |
| 37 | #include "utils.h" | 37 | #include "./utils.h" |
| 38 | #include "utils_cmd.h" | 38 | #include "../lib/states.h" |
| 39 | 39 | ||
| 40 | #define DEFAULT_COMMUNITY "public" | 40 | #include "../lib/utils_base.h" |
| 41 | #define DEFAULT_PORT "161" | 41 | #include "../lib/output.h" |
| 42 | #define DEFAULT_MIBLIST "ALL" | 42 | #include "check_snmp.d/check_snmp_helpers.h" |
| 43 | #define DEFAULT_PROTOCOL "1" | 43 | |
| 44 | #define DEFAULT_RETRIES 5 | 44 | #include <strings.h> |
| 45 | #define DEFAULT_AUTH_PROTOCOL "MD5" | 45 | #include <stdint.h> |
| 46 | #define DEFAULT_PRIV_PROTOCOL "DES" | 46 | |
| 47 | #define DEFAULT_DELIMITER "=" | 47 | #include "check_snmp.d/config.h" |
| 48 | #define DEFAULT_OUTPUT_DELIMITER " " | 48 | #include <stdlib.h> |
| 49 | #define DEFAULT_BUFFER_SIZE 100 | 49 | #include <arpa/inet.h> |
| 50 | 50 | #include <net-snmp/library/parse.h> | |
| 51 | #define mark(a) ((a) != 0 ? "*" : "") | 51 | #include <net-snmp/net-snmp-config.h> |
| 52 | 52 | #include <net-snmp/net-snmp-includes.h> | |
| 53 | #define CHECK_UNDEF 0 | 53 | #include <net-snmp/library/snmp.h> |
| 54 | #define CRIT_PRESENT 1 | 54 | #include <net-snmp/library/keytools.h> |
| 55 | #define CRIT_STRING 2 | 55 | #include <net-snmp/library/snmp_api.h> |
| 56 | #define CRIT_REGEX 4 | 56 | #include <net-snmp/session_api.h> |
| 57 | #define WARN_PRESENT 8 | 57 | #include <net-snmp/definitions.h> |
| 58 | 58 | #include <net-snmp/library/asn1.h> | |
| 59 | #define OID_COUNT_STEP 8 | 59 | #include <net-snmp/mib_api.h> |
| 60 | 60 | #include <net-snmp/library/snmp_impl.h> | |
| 61 | /* Longopts only arguments */ | 61 | #include <string.h> |
| 62 | #define L_CALCULATE_RATE CHAR_MAX + 1 | 62 | #include "../gl/regex.h" |
| 63 | #define L_RATE_MULTIPLIER CHAR_MAX + 2 | 63 | #include "../gl/base64.h" |
| 64 | #define L_INVERT_SEARCH CHAR_MAX + 3 | 64 | #include <assert.h> |
| 65 | #define L_OFFSET CHAR_MAX + 4 | 65 | |
| 66 | #define L_IGNORE_MIB_PARSING_ERRORS CHAR_MAX + 5 | 66 | const char DEFAULT_COMMUNITY[] = "public"; |
| 67 | 67 | const char DEFAULT_MIBLIST[] = "ALL"; | |
| 68 | /* Gobble to string - stop incrementing c when c[0] match one of the | 68 | #define DEFAULT_AUTH_PROTOCOL "MD5" |
| 69 | * characters in s */ | 69 | |
| 70 | #define GOBBLE_TOS(c, s) \ | 70 | #ifdef HAVE_USM_DES_PRIV_PROTOCOL |
| 71 | while (c[0] != '\0' && strchr(s, c[0]) == NULL) { \ | 71 | # define DEFAULT_PRIV_PROTOCOL "DES" |
| 72 | c++; \ | 72 | #else |
| 73 | # define DEFAULT_PRIV_PROTOCOL "AES" | ||
| 74 | #endif | ||
| 75 | |||
| 76 | typedef struct proces_arguments_wrapper { | ||
| 77 | int errorcode; | ||
| 78 | check_snmp_config config; | ||
| 79 | } process_arguments_wrapper; | ||
| 80 | |||
| 81 | static process_arguments_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 82 | static char *trim_whitespaces_and_check_quoting(char *str); | ||
| 83 | static char *get_next_argument(char *str); | ||
| 84 | void print_usage(void); | ||
| 85 | void print_help(void); | ||
| 86 | |||
| 87 | int verbose = 0; | ||
| 88 | |||
| 89 | typedef struct { | ||
| 90 | int errorcode; | ||
| 91 | char *state_string; | ||
| 92 | } gen_state_string_type; | ||
| 93 | gen_state_string_type gen_state_string(check_snmp_state_entry *entries, size_t num_of_entries) { | ||
| 94 | char *encoded_string = NULL; | ||
| 95 | gen_state_string_type result = {.errorcode = OK, .state_string = NULL}; | ||
| 96 | |||
| 97 | if (verbose > 1) { | ||
| 98 | printf("%s:\n", __FUNCTION__); | ||
| 99 | for (size_t i = 0; i < num_of_entries; i++) { | ||
| 100 | printf("Entry timestamp %lu: %s", entries[i].timestamp, ctime(&entries[i].timestamp)); | ||
| 101 | switch (entries[i].type) { | ||
| 102 | case ASN_GAUGE: | ||
| 103 | printf("Type GAUGE\n"); | ||
| 104 | break; | ||
| 105 | case ASN_TIMETICKS: | ||
| 106 | printf("Type TIMETICKS\n"); | ||
| 107 | break; | ||
| 108 | case ASN_COUNTER: | ||
| 109 | printf("Type COUNTER\n"); | ||
| 110 | break; | ||
| 111 | case ASN_UINTEGER: | ||
| 112 | printf("Type UINTEGER\n"); | ||
| 113 | break; | ||
| 114 | case ASN_COUNTER64: | ||
| 115 | printf("Type COUNTER64\n"); | ||
| 116 | break; | ||
| 117 | case ASN_FLOAT: | ||
| 118 | printf("Type FLOAT\n"); | ||
| 119 | case ASN_DOUBLE: | ||
| 120 | printf("Type DOUBLE\n"); | ||
| 121 | break; | ||
| 122 | case ASN_INTEGER: | ||
| 123 | printf("Type INTEGER\n"); | ||
| 124 | break; | ||
| 125 | } | ||
| 126 | |||
| 127 | switch (entries[i].type) { | ||
| 128 | case ASN_GAUGE: | ||
| 129 | case ASN_TIMETICKS: | ||
| 130 | case ASN_COUNTER: | ||
| 131 | case ASN_UINTEGER: | ||
| 132 | case ASN_COUNTER64: | ||
| 133 | printf("Value %llu\n", entries[i].value.uIntVal); | ||
| 134 | break; | ||
| 135 | case ASN_FLOAT: | ||
| 136 | case ASN_DOUBLE: | ||
| 137 | printf("Value %f\n", entries[i].value.doubleVal); | ||
| 138 | break; | ||
| 139 | case ASN_INTEGER: | ||
| 140 | printf("Value %lld\n", entries[i].value.intVal); | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | idx_t encoded = base64_encode_alloc((const char *)entries, | ||
| 147 | (idx_t)(num_of_entries * sizeof(check_snmp_state_entry)), | ||
| 148 | &encoded_string); | ||
| 149 | |||
| 150 | if (encoded > 0 && encoded_string != NULL) { | ||
| 151 | // success | ||
| 152 | if (verbose > 1) { | ||
| 153 | printf("encoded string: %s\n", encoded_string); | ||
| 154 | printf("encoded string length: %lu\n", strlen(encoded_string)); | ||
| 155 | } | ||
| 156 | result.state_string = encoded_string; | ||
| 157 | return result; | ||
| 73 | } | 158 | } |
| 74 | /* Given c, keep track of backslashes (bk) and double-quotes (dq) | 159 | result.errorcode = ERROR; |
| 75 | * from c[0] */ | 160 | return result; |
| 76 | #define COUNT_SEQ(c, bk, dq) \ | 161 | } |
| 77 | switch (c[0]) { \ | 162 | |
| 78 | case '\\': \ | 163 | typedef struct { |
| 79 | if (bk) \ | 164 | int errorcode; |
| 80 | bk--; \ | 165 | check_snmp_state_entry *state; |
| 81 | else \ | 166 | } recover_state_data_type; |
| 82 | bk++; \ | 167 | recover_state_data_type recover_state_data(char *state_string, idx_t state_string_length) { |
| 83 | break; \ | 168 | recover_state_data_type result = {.errorcode = OK, .state = NULL}; |
| 84 | case '"': \ | 169 | |
| 85 | if (!dq) { \ | 170 | if (verbose > 1) { |
| 86 | dq++; \ | 171 | printf("%s:\n", __FUNCTION__); |
| 87 | } else if (!bk) { \ | 172 | printf("State string: %s\n", state_string); |
| 88 | dq--; \ | 173 | printf("State string length: %lu\n", state_string_length); |
| 89 | } else { \ | ||
| 90 | bk--; \ | ||
| 91 | } \ | ||
| 92 | break; \ | ||
| 93 | } | 174 | } |
| 94 | 175 | ||
| 95 | static int process_arguments(int, char **); | 176 | idx_t outlen = 0; |
| 96 | static int validate_arguments(void); | 177 | bool decoded = |
| 97 | static char *thisarg(char *str); | 178 | base64_decode_alloc(state_string, state_string_length, (char **)&result.state, &outlen); |
| 98 | static char *nextarg(char *str); | 179 | |
| 99 | void print_usage(void); | 180 | if (!decoded) { |
| 100 | static void print_help(void); | 181 | if (verbose) { |
| 101 | static char *multiply(char *str); | 182 | printf("Failed to decode state string\n"); |
| 102 | 183 | } | |
| 103 | #include "regex.h" | 184 | // failure to decode |
| 104 | static char regex_expect[MAX_INPUT_BUFFER] = ""; | 185 | result.errorcode = ERROR; |
| 105 | static regex_t preg; | 186 | return result; |
| 106 | static regmatch_t pmatch[10]; | 187 | } |
| 107 | static char errbuf[MAX_INPUT_BUFFER] = ""; | 188 | |
| 108 | static char perfstr[MAX_INPUT_BUFFER] = "| "; | 189 | if (result.state == NULL) { |
| 109 | static int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; | 190 | // Memory Error? |
| 110 | static int eflags = 0; | 191 | result.errorcode = ERROR; |
| 111 | static int errcode, excode; | 192 | return result; |
| 112 | 193 | } | |
| 113 | static char *server_address = NULL; | 194 | |
| 114 | static char *community = NULL; | 195 | if (verbose > 1) { |
| 115 | static char **contextargs = NULL; | 196 | printf("Recovered %lu entries of size %lu\n", |
| 116 | static char *context = NULL; | 197 | (size_t)outlen / sizeof(check_snmp_state_entry), outlen); |
| 117 | static char **authpriv = NULL; | 198 | |
| 118 | static char *proto = NULL; | 199 | for (size_t i = 0; i < (size_t)outlen / sizeof(check_snmp_state_entry); i++) { |
| 119 | static char *seclevel = NULL; | 200 | printf("Entry timestamp %lu: %s", result.state[i].timestamp, |
| 120 | static char *secname = NULL; | 201 | ctime(&result.state[i].timestamp)); |
| 121 | static char *authproto = NULL; | 202 | switch (result.state[i].type) { |
| 122 | static char *privproto = NULL; | 203 | case ASN_GAUGE: |
| 123 | static char *authpasswd = NULL; | 204 | printf("Type GAUGE\n"); |
| 124 | static char *privpasswd = NULL; | 205 | break; |
| 125 | static int nulloid = STATE_UNKNOWN; | 206 | case ASN_TIMETICKS: |
| 126 | static char **oids = NULL; | 207 | printf("Type TIMETICKS\n"); |
| 127 | static size_t oids_size = 0; | 208 | break; |
| 128 | static char *label; | 209 | case ASN_COUNTER: |
| 129 | static char *units; | 210 | printf("Type COUNTER\n"); |
| 130 | static char *port; | 211 | break; |
| 131 | static char *snmpcmd; | 212 | case ASN_UINTEGER: |
| 132 | static char string_value[MAX_INPUT_BUFFER] = ""; | 213 | printf("Type UINTEGER\n"); |
| 133 | static int invert_search = 0; | 214 | break; |
| 134 | static char **labels = NULL; | 215 | case ASN_COUNTER64: |
| 135 | static char **unitv = NULL; | 216 | printf("Type COUNTER64\n"); |
| 136 | static size_t nlabels = 0; | 217 | break; |
| 137 | static size_t labels_size = OID_COUNT_STEP; | 218 | case ASN_FLOAT: |
| 138 | static size_t nunits = 0; | 219 | printf("Type FLOAT\n"); |
| 139 | static size_t unitv_size = OID_COUNT_STEP; | 220 | case ASN_DOUBLE: |
| 140 | static size_t numoids = 0; | 221 | printf("Type DOUBLE\n"); |
| 141 | static int numauthpriv = 0; | 222 | break; |
| 142 | static int numcontext = 0; | 223 | case ASN_INTEGER: |
| 143 | static int verbose = 0; | 224 | printf("Type INTEGER\n"); |
| 144 | static bool usesnmpgetnext = false; | 225 | break; |
| 145 | static char *warning_thresholds = NULL; | 226 | } |
| 146 | static char *critical_thresholds = NULL; | 227 | |
| 147 | static thresholds **thlds; | 228 | switch (result.state[i].type) { |
| 148 | static size_t thlds_size = OID_COUNT_STEP; | 229 | case ASN_GAUGE: |
| 149 | static double *response_value; | 230 | case ASN_TIMETICKS: |
| 150 | static size_t response_size = OID_COUNT_STEP; | 231 | case ASN_COUNTER: |
| 151 | static int retries = 0; | 232 | case ASN_UINTEGER: |
| 152 | static int *eval_method; | 233 | case ASN_COUNTER64: |
| 153 | static size_t eval_size = OID_COUNT_STEP; | 234 | printf("Value %llu\n", result.state[i].value.uIntVal); |
| 154 | static char *delimiter; | 235 | break; |
| 155 | static char *output_delim; | 236 | case ASN_FLOAT: |
| 156 | static char *miblist = NULL; | 237 | case ASN_DOUBLE: |
| 157 | static bool needmibs = false; | 238 | printf("Value %f\n", result.state[i].value.doubleVal); |
| 158 | static int calculate_rate = 0; | 239 | break; |
| 159 | static double offset = 0.0; | 240 | case ASN_INTEGER: |
| 160 | static int rate_multiplier = 1; | 241 | printf("Value %lld\n", result.state[i].value.intVal); |
| 161 | static state_data *previous_state; | 242 | break; |
| 162 | static double *previous_value; | 243 | } |
| 163 | static size_t previous_size = OID_COUNT_STEP; | 244 | } |
| 164 | static int perf_labels = 1; | 245 | } |
| 165 | static char *ip_version = ""; | 246 | |
| 166 | static double multiplier = 1.0; | 247 | return result; |
| 167 | static char *fmtstr = ""; | ||
| 168 | static bool fmtstr_set = false; | ||
| 169 | static char buffer[DEFAULT_BUFFER_SIZE]; | ||
| 170 | static bool ignore_mib_parsing_errors = false; | ||
| 171 | |||
| 172 | static char *fix_snmp_range(char *th) { | ||
| 173 | double left; | ||
| 174 | double right; | ||
| 175 | char *colon; | ||
| 176 | char *ret; | ||
| 177 | |||
| 178 | if ((colon = strchr(th, ':')) == NULL || *(colon + 1) == '\0') | ||
| 179 | return th; | ||
| 180 | |||
| 181 | left = strtod(th, NULL); | ||
| 182 | right = strtod(colon + 1, NULL); | ||
| 183 | if (right >= left) | ||
| 184 | return th; | ||
| 185 | |||
| 186 | if ((ret = malloc(strlen(th) + 2)) == NULL) | ||
| 187 | die(STATE_UNKNOWN, _("Cannot malloc")); | ||
| 188 | *colon = '\0'; | ||
| 189 | sprintf(ret, "@%s:%s", colon + 1, th); | ||
| 190 | free(th); | ||
| 191 | return ret; | ||
| 192 | } | 248 | } |
| 193 | 249 | ||
| 194 | int main(int argc, char **argv) { | 250 | int main(int argc, char **argv) { |
| 195 | int len; | ||
| 196 | int total_oids; | ||
| 197 | size_t line; | ||
| 198 | unsigned int bk_count = 0; | ||
| 199 | unsigned int dq_count = 0; | ||
| 200 | int iresult = STATE_UNKNOWN; | ||
| 201 | int result = STATE_UNKNOWN; | ||
| 202 | int return_code = 0; | ||
| 203 | int external_error = 0; | ||
| 204 | char **command_line = NULL; | ||
| 205 | char *cl_hidden_auth = NULL; | ||
| 206 | char *oidname = NULL; | ||
| 207 | char *response = NULL; | ||
| 208 | char *mult_resp = NULL; | ||
| 209 | char *outbuff; | ||
| 210 | char *ptr = NULL; | ||
| 211 | char *show = NULL; | ||
| 212 | char *th_warn = NULL; | ||
| 213 | char *th_crit = NULL; | ||
| 214 | char type[8] = ""; | ||
| 215 | output chld_out; | ||
| 216 | output chld_err; | ||
| 217 | char *previous_string = NULL; | ||
| 218 | char *ap = NULL; | ||
| 219 | char *state_string = NULL; | ||
| 220 | size_t response_length; | ||
| 221 | size_t current_length; | ||
| 222 | size_t string_length; | ||
| 223 | char *temp_string = NULL; | ||
| 224 | char *quote_string = NULL; | ||
| 225 | time_t current_time; | ||
| 226 | double temp_double; | ||
| 227 | time_t duration; | ||
| 228 | char *conv = "12345678"; | ||
| 229 | int is_counter = 0; | ||
| 230 | |||
| 231 | setlocale(LC_ALL, ""); | 251 | setlocale(LC_ALL, ""); |
| 232 | bindtextdomain(PACKAGE, LOCALEDIR); | 252 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 233 | textdomain(PACKAGE); | 253 | textdomain(PACKAGE); |
| 234 | 254 | ||
| 235 | labels = malloc(labels_size * sizeof(*labels)); | ||
| 236 | unitv = malloc(unitv_size * sizeof(*unitv)); | ||
| 237 | thlds = malloc(thlds_size * sizeof(*thlds)); | ||
| 238 | response_value = malloc(response_size * sizeof(*response_value)); | ||
| 239 | previous_value = malloc(previous_size * sizeof(*previous_value)); | ||
| 240 | eval_method = calloc(eval_size, sizeof(*eval_method)); | ||
| 241 | oids = calloc(oids_size, sizeof(char *)); | ||
| 242 | |||
| 243 | label = strdup("SNMP"); | ||
| 244 | units = strdup(""); | ||
| 245 | port = strdup(DEFAULT_PORT); | ||
| 246 | outbuff = strdup(""); | ||
| 247 | delimiter = strdup(" = "); | ||
| 248 | output_delim = strdup(DEFAULT_OUTPUT_DELIMITER); | ||
| 249 | timeout_interval = DEFAULT_SOCKET_TIMEOUT; | 255 | timeout_interval = DEFAULT_SOCKET_TIMEOUT; |
| 250 | retries = DEFAULT_RETRIES; | ||
| 251 | 256 | ||
| 252 | np_init((char *)progname, argc, argv); | 257 | np_init((char *)progname, argc, argv); |
| 253 | 258 | ||
| 259 | state_key stateKey = np_enable_state(NULL, 1, progname, argc, argv); | ||
| 260 | |||
| 254 | /* Parse extra opts if any */ | 261 | /* Parse extra opts if any */ |
| 255 | argv = np_extra_opts(&argc, argv, progname); | 262 | argv = np_extra_opts(&argc, argv, progname); |
| 256 | 263 | ||
| 257 | np_set_args(argc, argv); | 264 | np_set_args(argc, argv); |
| 258 | 265 | ||
| 259 | time(¤t_time); | 266 | // Initialize net-snmp before touching the session we are going to use |
| 267 | init_snmp("check_snmp"); | ||
| 260 | 268 | ||
| 261 | if (process_arguments(argc, argv) == ERROR) | 269 | process_arguments_wrapper paw_tmp = process_arguments(argc, argv); |
| 270 | if (paw_tmp.errorcode == ERROR) { | ||
| 262 | usage4(_("Could not parse arguments")); | 271 | usage4(_("Could not parse arguments")); |
| 263 | |||
| 264 | if (calculate_rate) { | ||
| 265 | if (!strcmp(label, "SNMP")) | ||
| 266 | label = strdup("SNMP RATE"); | ||
| 267 | |||
| 268 | size_t i = 0; | ||
| 269 | |||
| 270 | previous_state = np_state_read(); | ||
| 271 | if (previous_state != NULL) { | ||
| 272 | /* Split colon separated values */ | ||
| 273 | previous_string = strdup((char *)previous_state->data); | ||
| 274 | while ((ap = strsep(&previous_string, ":")) != NULL) { | ||
| 275 | if (verbose > 2) | ||
| 276 | printf("State for %zd=%s\n", i, ap); | ||
| 277 | while (i >= previous_size) { | ||
| 278 | previous_size += OID_COUNT_STEP; | ||
| 279 | previous_value = realloc(previous_value, previous_size * sizeof(*previous_value)); | ||
| 280 | } | ||
| 281 | previous_value[i++] = strtod(ap, NULL); | ||
| 282 | } | ||
| 283 | } | ||
| 284 | } | 272 | } |
| 285 | 273 | ||
| 286 | /* Populate the thresholds */ | 274 | check_snmp_config config = paw_tmp.config; |
| 287 | th_warn = warning_thresholds; | ||
| 288 | th_crit = critical_thresholds; | ||
| 289 | for (size_t i = 0; i < numoids; i++) { | ||
| 290 | char *w = th_warn ? strndup(th_warn, strcspn(th_warn, ",")) : NULL; | ||
| 291 | char *c = th_crit ? strndup(th_crit, strcspn(th_crit, ",")) : NULL; | ||
| 292 | /* translate "2:1" to "@1:2" for backwards compatibility */ | ||
| 293 | w = w ? fix_snmp_range(w) : NULL; | ||
| 294 | c = c ? fix_snmp_range(c) : NULL; | ||
| 295 | |||
| 296 | while (i >= thlds_size) { | ||
| 297 | thlds_size += OID_COUNT_STEP; | ||
| 298 | thlds = realloc(thlds, thlds_size * sizeof(*thlds)); | ||
| 299 | } | ||
| 300 | |||
| 301 | /* Skip empty thresholds, while avoiding segfault */ | ||
| 302 | set_thresholds(&thlds[i], w ? strpbrk(w, NP_THRESHOLDS_CHARS) : NULL, c ? strpbrk(c, NP_THRESHOLDS_CHARS) : NULL); | ||
| 303 | if (w) { | ||
| 304 | th_warn = strchr(th_warn, ','); | ||
| 305 | if (th_warn) | ||
| 306 | th_warn++; | ||
| 307 | free(w); | ||
| 308 | } | ||
| 309 | if (c) { | ||
| 310 | th_crit = strchr(th_crit, ','); | ||
| 311 | if (th_crit) | ||
| 312 | th_crit++; | ||
| 313 | free(c); | ||
| 314 | } | ||
| 315 | } | ||
| 316 | 275 | ||
| 317 | /* Create the command array to execute */ | 276 | if (config.output_format_is_set) { |
| 318 | if (usesnmpgetnext) { | 277 | mp_set_format(config.output_format); |
| 319 | snmpcmd = strdup(PATH_TO_SNMPGETNEXT); | ||
| 320 | } else { | ||
| 321 | snmpcmd = strdup(PATH_TO_SNMPGET); | ||
| 322 | } | 278 | } |
| 323 | 279 | ||
| 324 | /* 10 arguments to pass before context and authpriv options + 1 for host and numoids. Add one for terminating NULL */ | 280 | /* Set signal handling and alarm */ |
| 325 | 281 | if (signal(SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR) { | |
| 326 | unsigned index = 0; | 282 | usage4(_("Cannot catch SIGALRM")); |
| 327 | command_line = calloc(11 + numcontext + numauthpriv + 1 + numoids + 1, sizeof(char *)); | ||
| 328 | |||
| 329 | command_line[index++] = snmpcmd; | ||
| 330 | command_line[index++] = strdup("-Le"); | ||
| 331 | command_line[index++] = strdup("-t"); | ||
| 332 | xasprintf(&command_line[index++], "%d", timeout_interval); | ||
| 333 | command_line[index++] = strdup("-r"); | ||
| 334 | xasprintf(&command_line[index++], "%d", retries); | ||
| 335 | command_line[index++] = strdup("-m"); | ||
| 336 | command_line[index++] = strdup(miblist); | ||
| 337 | command_line[index++] = "-v"; | ||
| 338 | command_line[index++] = strdup(proto); | ||
| 339 | |||
| 340 | xasprintf(&cl_hidden_auth, "%s -Le -t %d -r %d -m %s -v %s", snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", | ||
| 341 | proto); | ||
| 342 | |||
| 343 | if (ignore_mib_parsing_errors) { | ||
| 344 | command_line[index++] = "-Pe"; | ||
| 345 | xasprintf(&cl_hidden_auth, "%s -Pe", cl_hidden_auth); | ||
| 346 | } | 283 | } |
| 347 | 284 | ||
| 348 | for (int i = 0; i < numcontext; i++) { | 285 | time_t current_time; |
| 349 | command_line[index++] = contextargs[i]; | 286 | time(¤t_time); |
| 350 | } | ||
| 351 | 287 | ||
| 352 | for (int i = 0; i < numauthpriv; i++) { | 288 | if (verbose > 2) { |
| 353 | command_line[index++] = authpriv[i]; | 289 | printf("current time: %s (timestamp: %lu)\n", ctime(¤t_time), current_time); |
| 354 | } | 290 | } |
| 355 | 291 | ||
| 356 | xasprintf(&command_line[index++], "%s:%s", server_address, port); | 292 | snmp_responces response = do_snmp_query(config.snmp_params); |
| 357 | 293 | ||
| 358 | xasprintf(&cl_hidden_auth, "%s [context] [authpriv] %s:%s", cl_hidden_auth, server_address, port); | 294 | mp_check overall = mp_check_init(); |
| 359 | 295 | ||
| 360 | for (size_t i = 0; i < numoids; i++) { | 296 | if (response.errorcode == OK) { |
| 361 | command_line[index++] = oids[i]; | 297 | mp_subcheck sc_successfull_query = mp_subcheck_init(); |
| 362 | xasprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]); | 298 | xasprintf(&sc_successfull_query.output, "SNMP query was successful"); |
| 299 | sc_successfull_query = mp_set_subcheck_state(sc_successfull_query, STATE_OK); | ||
| 300 | mp_add_subcheck_to_check(&overall, sc_successfull_query); | ||
| 301 | } else { | ||
| 302 | // Error treatment here, either partial or whole | ||
| 303 | mp_subcheck sc_failed_query = mp_subcheck_init(); | ||
| 304 | xasprintf(&sc_failed_query.output, "SNMP query failed"); | ||
| 305 | sc_failed_query = mp_set_subcheck_state(sc_failed_query, STATE_OK); | ||
| 306 | mp_add_subcheck_to_check(&overall, sc_failed_query); | ||
| 307 | mp_exit(overall); | ||
| 363 | } | 308 | } |
| 364 | 309 | ||
| 365 | command_line[index++] = NULL; | 310 | check_snmp_state_entry *prev_state = NULL; |
| 311 | bool have_previous_state = false; | ||
| 366 | 312 | ||
| 367 | if (verbose) { | 313 | if (config.evaluation_params.calculate_rate) { |
| 368 | printf("%s\n", cl_hidden_auth); | 314 | state_data *previous_state = np_state_read(stateKey); |
| 369 | } | 315 | if (previous_state == NULL) { |
| 316 | // failed to recover state | ||
| 317 | // or no previous state | ||
| 318 | have_previous_state = false; | ||
| 319 | } else { | ||
| 320 | // sanity check | ||
| 321 | recover_state_data_type prev_state_wrapper = | ||
| 322 | recover_state_data(previous_state->data, (idx_t)previous_state->length); | ||
| 370 | 323 | ||
| 371 | /* Set signal handling and alarm */ | 324 | if (prev_state_wrapper.errorcode == OK) { |
| 372 | if (signal(SIGALRM, runcmd_timeout_alarm_handler) == SIG_ERR) { | 325 | have_previous_state = true; |
| 373 | usage4(_("Cannot catch SIGALRM")); | 326 | prev_state = prev_state_wrapper.state; |
| 374 | } | 327 | } else { |
| 375 | alarm(timeout_interval * retries + 5); | 328 | have_previous_state = false; |
| 376 | 329 | prev_state = NULL; | |
| 377 | /* Run the command */ | ||
| 378 | return_code = cmd_run_array(command_line, &chld_out, &chld_err, 0); | ||
| 379 | |||
| 380 | /* disable alarm again */ | ||
| 381 | alarm(0); | ||
| 382 | |||
| 383 | /* Due to net-snmp sometimes showing stderr messages with poorly formed MIBs, | ||
| 384 | only return state unknown if return code is non zero or there is no stdout. | ||
| 385 | Do this way so that if there is stderr, will get added to output, which helps problem diagnosis | ||
| 386 | */ | ||
| 387 | if (return_code != 0) | ||
| 388 | external_error = 1; | ||
| 389 | if (chld_out.lines == 0) | ||
| 390 | external_error = 1; | ||
| 391 | if (external_error) { | ||
| 392 | if (chld_err.lines > 0) { | ||
| 393 | printf(_("External command error: %s\n"), chld_err.line[0]); | ||
| 394 | for (size_t i = 1; i < chld_err.lines; i++) { | ||
| 395 | printf("%s\n", chld_err.line[i]); | ||
| 396 | } | 330 | } |
| 397 | } else { | ||
| 398 | printf(_("External command error with no output (return code: %d)\n"), return_code); | ||
| 399 | } | 331 | } |
| 400 | exit(STATE_UNKNOWN); | ||
| 401 | } | 332 | } |
| 402 | 333 | ||
| 403 | if (verbose) { | 334 | check_snmp_state_entry *new_state = NULL; |
| 404 | for (size_t i = 0; i < chld_out.lines; i++) { | 335 | if (config.evaluation_params.calculate_rate) { |
| 405 | printf("%s\n", chld_out.line[i]); | 336 | new_state = calloc(config.snmp_params.num_of_test_units, sizeof(check_snmp_state_entry)); |
| 337 | if (new_state == NULL) { | ||
| 338 | die(STATE_UNKNOWN, "memory allocation failed"); | ||
| 406 | } | 339 | } |
| 407 | } | 340 | } |
| 408 | 341 | ||
| 409 | line = 0; | 342 | // We got the the query results, now process them |
| 410 | total_oids = 0; | 343 | for (size_t loop_index = 0; loop_index < config.snmp_params.num_of_test_units; loop_index++) { |
| 411 | for (size_t i = 0; line < chld_out.lines && i < numoids; line++, i++, total_oids++) { | 344 | if (verbose > 0) { |
| 412 | if (calculate_rate) | 345 | printf("loop_index: %zu\n", loop_index); |
| 413 | conv = "%.10g"; | ||
| 414 | else | ||
| 415 | conv = "%.0f"; | ||
| 416 | |||
| 417 | ptr = chld_out.line[line]; | ||
| 418 | oidname = strpcpy(oidname, ptr, delimiter); | ||
| 419 | response = strstr(ptr, delimiter); | ||
| 420 | if (response == NULL) | ||
| 421 | break; | ||
| 422 | |||
| 423 | if (verbose > 2) { | ||
| 424 | printf("Processing oid %zi (line %zi)\n oidname: %s\n response: %s\n", i + 1, line + 1, oidname, response); | ||
| 425 | } | 346 | } |
| 426 | 347 | ||
| 427 | /* Clean up type array - Sol10 does not necessarily zero it out */ | 348 | check_snmp_state_entry previous_unit_state = {}; |
| 428 | bzero(type, sizeof(type)); | 349 | if (config.evaluation_params.calculate_rate && have_previous_state) { |
| 429 | 350 | previous_unit_state = prev_state[loop_index]; | |
| 430 | is_counter = 0; | 351 | } |
| 431 | /* We strip out the datatype indicator for PHBs */ | ||
| 432 | if (strstr(response, "Gauge: ")) { | ||
| 433 | show = multiply(strstr(response, "Gauge: ") + 7); | ||
| 434 | } else if (strstr(response, "Gauge32: ")) { | ||
| 435 | show = multiply(strstr(response, "Gauge32: ") + 9); | ||
| 436 | } else if (strstr(response, "Counter32: ")) { | ||
| 437 | show = strstr(response, "Counter32: ") + 11; | ||
| 438 | is_counter = 1; | ||
| 439 | if (!calculate_rate) | ||
| 440 | strcpy(type, "c"); | ||
| 441 | } else if (strstr(response, "Counter64: ")) { | ||
| 442 | show = strstr(response, "Counter64: ") + 11; | ||
| 443 | is_counter = 1; | ||
| 444 | if (!calculate_rate) | ||
| 445 | strcpy(type, "c"); | ||
| 446 | } else if (strstr(response, "INTEGER: ")) { | ||
| 447 | show = multiply(strstr(response, "INTEGER: ") + 9); | ||
| 448 | |||
| 449 | if (fmtstr_set) { | ||
| 450 | conv = fmtstr; | ||
| 451 | } | ||
| 452 | } else if (strstr(response, "OID: ")) { | ||
| 453 | show = strstr(response, "OID: ") + 5; | ||
| 454 | } else if (strstr(response, "STRING: ")) { | ||
| 455 | show = strstr(response, "STRING: ") + 8; | ||
| 456 | conv = "%.10g"; | ||
| 457 | |||
| 458 | /* Get the rest of the string on multi-line strings */ | ||
| 459 | ptr = show; | ||
| 460 | COUNT_SEQ(ptr, bk_count, dq_count) | ||
| 461 | while (dq_count && ptr[0] != '\n' && ptr[0] != '\0') { | ||
| 462 | ptr++; | ||
| 463 | GOBBLE_TOS(ptr, "\n\"\\") | ||
| 464 | COUNT_SEQ(ptr, bk_count, dq_count) | ||
| 465 | } | ||
| 466 | |||
| 467 | if (dq_count) { /* unfinished line */ | ||
| 468 | /* copy show verbatim first */ | ||
| 469 | if (!mult_resp) | ||
| 470 | mult_resp = strdup(""); | ||
| 471 | xasprintf(&mult_resp, "%s%s:\n%s\n", mult_resp, oids[i], show); | ||
| 472 | /* then strip out unmatched double-quote from single-line output */ | ||
| 473 | if (show[0] == '"') | ||
| 474 | show++; | ||
| 475 | |||
| 476 | /* Keep reading until we match end of double-quoted string */ | ||
| 477 | for (line++; line < chld_out.lines; line++) { | ||
| 478 | ptr = chld_out.line[line]; | ||
| 479 | xasprintf(&mult_resp, "%s%s\n", mult_resp, ptr); | ||
| 480 | |||
| 481 | COUNT_SEQ(ptr, bk_count, dq_count) | ||
| 482 | while (dq_count && ptr[0] != '\n' && ptr[0] != '\0') { | ||
| 483 | ptr++; | ||
| 484 | GOBBLE_TOS(ptr, "\n\"\\") | ||
| 485 | COUNT_SEQ(ptr, bk_count, dq_count) | ||
| 486 | } | ||
| 487 | /* Break for loop before next line increment when done */ | ||
| 488 | if (!dq_count) | ||
| 489 | break; | ||
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | } else if (strstr(response, "Timeticks: ")) { | ||
| 494 | show = strstr(response, "Timeticks: "); | ||
| 495 | } else | ||
| 496 | show = response + 3; | ||
| 497 | 352 | ||
| 498 | iresult = STATE_DEPENDENT; | 353 | check_snmp_evaluation single_eval = |
| 354 | evaluate_single_unit(response.response_values[loop_index], config.evaluation_params, | ||
| 355 | config.snmp_params.test_units[loop_index], current_time, | ||
| 356 | previous_unit_state, have_previous_state); | ||
| 499 | 357 | ||
| 500 | /* Process this block for numeric comparisons */ | 358 | if (config.evaluation_params.calculate_rate && |
| 501 | /* Make some special values,like Timeticks numeric only if a threshold is defined */ | 359 | mp_compute_subcheck_state(single_eval.sc) != STATE_UNKNOWN) { |
| 502 | if (thlds[i]->warning || thlds[i]->critical || calculate_rate) { | 360 | new_state[loop_index] = single_eval.state; |
| 503 | if (verbose > 2) { | ||
| 504 | print_thresholds(" thresholds", thlds[i]); | ||
| 505 | } | ||
| 506 | ptr = strpbrk(show, "-0123456789"); | ||
| 507 | if (ptr == NULL) { | ||
| 508 | if (nulloid == 3) | ||
| 509 | die(STATE_UNKNOWN, _("No valid data returned (%s)\n"), show); | ||
| 510 | else if (nulloid == 0) | ||
| 511 | die(STATE_OK, _("No valid data returned (%s)\n"), show); | ||
| 512 | else if (nulloid == 1) | ||
| 513 | die(STATE_WARNING, _("No valid data returned (%s)\n"), show); | ||
| 514 | else if (nulloid == 2) | ||
| 515 | die(STATE_CRITICAL, _("No valid data returned (%s)\n"), show); | ||
| 516 | } | ||
| 517 | while (i >= response_size) { | ||
| 518 | response_size += OID_COUNT_STEP; | ||
| 519 | response_value = realloc(response_value, response_size * sizeof(*response_value)); | ||
| 520 | } | ||
| 521 | response_value[i] = strtod(ptr, NULL) + offset; | ||
| 522 | |||
| 523 | if (calculate_rate) { | ||
| 524 | if (previous_state != NULL) { | ||
| 525 | duration = current_time - previous_state->time; | ||
| 526 | if (duration <= 0) | ||
| 527 | die(STATE_UNKNOWN, _("Time duration between plugin calls is invalid")); | ||
| 528 | temp_double = response_value[i] - previous_value[i]; | ||
| 529 | /* Simple overflow catcher (same as in rrdtool, rrd_update.c) */ | ||
| 530 | if (is_counter) { | ||
| 531 | if (temp_double < (double)0.0) | ||
| 532 | temp_double += (double)4294967296.0; /* 2^32 */ | ||
| 533 | if (temp_double < (double)0.0) | ||
| 534 | temp_double += (double)18446744069414584320.0; /* 2^64-2^32 */ | ||
| 535 | ; | ||
| 536 | } | ||
| 537 | /* Convert to per second, then use multiplier */ | ||
| 538 | temp_double = temp_double / duration * rate_multiplier; | ||
| 539 | iresult = get_status(temp_double, thlds[i]); | ||
| 540 | xasprintf(&show, conv, temp_double); | ||
| 541 | } | ||
| 542 | } else { | ||
| 543 | iresult = get_status(response_value[i], thlds[i]); | ||
| 544 | xasprintf(&show, conv, response_value[i]); | ||
| 545 | } | ||
| 546 | } | 361 | } |
| 547 | 362 | ||
| 548 | /* Process this block for string matching */ | 363 | mp_add_subcheck_to_check(&overall, single_eval.sc); |
| 549 | else if (eval_size > i && eval_method[i] & CRIT_STRING) { | 364 | } |
| 550 | if (strcmp(show, string_value)) | ||
| 551 | iresult = (invert_search == 0) ? STATE_CRITICAL : STATE_OK; | ||
| 552 | else | ||
| 553 | iresult = (invert_search == 0) ? STATE_OK : STATE_CRITICAL; | ||
| 554 | } | ||
| 555 | 365 | ||
| 556 | /* Process this block for regex matching */ | 366 | if (config.evaluation_params.calculate_rate) { |
| 557 | else if (eval_size > i && eval_method[i] & CRIT_REGEX) { | 367 | // store state |
| 558 | excode = regexec(&preg, response, 10, pmatch, eflags); | 368 | gen_state_string_type current_state_wrapper = |
| 559 | if (excode == 0) { | 369 | gen_state_string(new_state, config.snmp_params.num_of_test_units); |
| 560 | iresult = (invert_search == 0) ? STATE_OK : STATE_CRITICAL; | ||
| 561 | } else if (excode != REG_NOMATCH) { | ||
| 562 | regerror(excode, &preg, errbuf, MAX_INPUT_BUFFER); | ||
| 563 | printf(_("Execute Error: %s\n"), errbuf); | ||
| 564 | exit(STATE_CRITICAL); | ||
| 565 | } else { | ||
| 566 | iresult = (invert_search == 0) ? STATE_CRITICAL : STATE_OK; | ||
| 567 | } | ||
| 568 | } | ||
| 569 | 370 | ||
| 570 | /* Process this block for existence-nonexistence checks */ | 371 | if (current_state_wrapper.errorcode == OK) { |
| 571 | /* TV: Should this be outside of this else block? */ | 372 | np_state_write_string(stateKey, current_time, current_state_wrapper.state_string); |
| 572 | else { | 373 | } else { |
| 573 | if (eval_size > i && eval_method[i] & CRIT_PRESENT) | 374 | die(STATE_UNKNOWN, "failed to create state string"); |
| 574 | iresult = STATE_CRITICAL; | ||
| 575 | else if (eval_size > i && eval_method[i] & WARN_PRESENT) | ||
| 576 | iresult = STATE_WARNING; | ||
| 577 | else if (response && iresult == STATE_DEPENDENT) | ||
| 578 | iresult = STATE_OK; | ||
| 579 | } | 375 | } |
| 376 | } | ||
| 377 | mp_exit(overall); | ||
| 378 | } | ||
| 580 | 379 | ||
| 581 | /* Result is the worst outcome of all the OIDs tested */ | 380 | /* process command-line arguments */ |
| 582 | result = max_state(result, iresult); | 381 | static process_arguments_wrapper process_arguments(int argc, char **argv) { |
| 583 | 382 | enum { | |
| 584 | /* Prepend a label for this OID if there is one */ | 383 | /* Longopts only arguments */ |
| 585 | if (nlabels >= (size_t)1 && (size_t)i < nlabels && labels[i] != NULL) | 384 | invert_search_index = CHAR_MAX + 1, |
| 586 | xasprintf(&outbuff, "%s%s%s %s%s%s", outbuff, (i == 0) ? " " : output_delim, labels[i], mark(iresult), show, mark(iresult)); | 385 | offset_index, |
| 587 | else | 386 | ignore_mib_parsing_errors_index, |
| 588 | xasprintf(&outbuff, "%s%s%s%s%s", outbuff, (i == 0) ? " " : output_delim, mark(iresult), show, mark(iresult)); | 387 | connection_prefix_index, |
| 589 | 388 | output_format_index, | |
| 590 | /* Append a unit string for this OID if there is one */ | 389 | calculate_rate, |
| 591 | if (nunits > (size_t)0 && (size_t)i < nunits && unitv[i] != NULL) | 390 | rate_multiplier |
| 592 | xasprintf(&outbuff, "%s %s", outbuff, unitv[i]); | 391 | }; |
| 593 | 392 | ||
| 594 | /* Write perfdata with whatever can be parsed by strtod, if possible */ | 393 | static struct option longopts[] = { |
| 595 | ptr = NULL; | 394 | STD_LONG_OPTS, |
| 596 | strtod(show, &ptr); | 395 | {"community", required_argument, 0, 'C'}, |
| 597 | if (ptr > show) { | 396 | {"oid", required_argument, 0, 'o'}, |
| 598 | if (perf_labels && nlabels >= (size_t)1 && (size_t)i < nlabels && labels[i] != NULL) | 397 | {"object", required_argument, 0, 'o'}, |
| 599 | temp_string = labels[i]; | 398 | {"delimiter", required_argument, 0, 'd'}, |
| 600 | else | 399 | {"nulloid", required_argument, 0, 'z'}, |
| 601 | temp_string = oidname; | 400 | {"output-delimiter", required_argument, 0, 'D'}, |
| 602 | if (strpbrk(temp_string, " ='\"") == NULL) { | 401 | {"string", required_argument, 0, 's'}, |
| 603 | strncat(perfstr, temp_string, sizeof(perfstr) - strlen(perfstr) - 1); | 402 | {"timeout", required_argument, 0, 't'}, |
| 604 | } else { | 403 | {"regex", required_argument, 0, 'r'}, |
| 605 | if (strpbrk(temp_string, "'") == NULL) { | 404 | {"ereg", required_argument, 0, 'r'}, |
| 606 | quote_string = "'"; | 405 | {"eregi", required_argument, 0, 'R'}, |
| 607 | } else { | 406 | {"label", required_argument, 0, 'l'}, |
| 608 | quote_string = "\""; | 407 | {"units", required_argument, 0, 'u'}, |
| 609 | } | 408 | {"port", required_argument, 0, 'p'}, |
| 610 | strncat(perfstr, quote_string, sizeof(perfstr) - strlen(perfstr) - 1); | 409 | {"retries", required_argument, 0, 'e'}, |
| 611 | strncat(perfstr, temp_string, sizeof(perfstr) - strlen(perfstr) - 1); | 410 | {"miblist", required_argument, 0, 'm'}, |
| 612 | strncat(perfstr, quote_string, sizeof(perfstr) - strlen(perfstr) - 1); | 411 | {"protocol", required_argument, 0, 'P'}, |
| 613 | } | 412 | {"context", required_argument, 0, 'N'}, |
| 614 | strncat(perfstr, "=", sizeof(perfstr) - strlen(perfstr) - 1); | 413 | {"seclevel", required_argument, 0, 'L'}, |
| 615 | len = sizeof(perfstr) - strlen(perfstr) - 1; | 414 | {"secname", required_argument, 0, 'U'}, |
| 616 | strncat(perfstr, show, len > ptr - show ? ptr - show : len); | 415 | {"authproto", required_argument, 0, 'a'}, |
| 416 | {"privproto", required_argument, 0, 'x'}, | ||
| 417 | {"authpasswd", required_argument, 0, 'A'}, | ||
| 418 | {"privpasswd", required_argument, 0, 'X'}, | ||
| 419 | {"next", no_argument, 0, 'n'}, | ||
| 420 | {"offset", required_argument, 0, offset_index}, | ||
| 421 | {"invert-search", no_argument, 0, invert_search_index}, | ||
| 422 | {"perf-oids", no_argument, 0, 'O'}, | ||
| 423 | {"ipv4", no_argument, 0, '4'}, | ||
| 424 | {"ipv6", no_argument, 0, '6'}, | ||
| 425 | {"multiplier", required_argument, 0, 'M'}, | ||
| 426 | {"ignore-mib-parsing-errors", no_argument, 0, ignore_mib_parsing_errors_index}, | ||
| 427 | {"connection-prefix", required_argument, 0, connection_prefix_index}, | ||
| 428 | {"output-format", required_argument, 0, output_format_index}, | ||
| 429 | {"rate", no_argument, 0, calculate_rate}, | ||
| 430 | {"rate-multiplier", required_argument, 0, rate_multiplier}, | ||
| 431 | {0, 0, 0, 0}}; | ||
| 432 | |||
| 433 | if (argc < 2) { | ||
| 434 | process_arguments_wrapper result = { | ||
| 435 | .errorcode = ERROR, | ||
| 436 | }; | ||
| 437 | return result; | ||
| 438 | } | ||
| 617 | 439 | ||
| 618 | if (strcmp(type, "") != 0) { | 440 | // Count number of OIDs here first |
| 619 | strncat(perfstr, type, sizeof(perfstr) - strlen(perfstr) - 1); | 441 | int option = 0; |
| 620 | } | 442 | size_t oid_counter = 0; |
| 443 | while (true) { | ||
| 444 | int option_char = getopt_long( | ||
| 445 | argc, argv, | ||
| 446 | "nhvVO46t:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:N:L:U:a:x:A:X:M:f:z:", longopts, &option); | ||
| 621 | 447 | ||
| 622 | if (warning_thresholds) { | 448 | if (option_char == -1 || option_char == EOF) { |
| 623 | strncat(perfstr, ";", sizeof(perfstr) - strlen(perfstr) - 1); | 449 | break; |
| 624 | if (thlds[i]->warning && thlds[i]->warning->text) | 450 | } |
| 625 | strncat(perfstr, thlds[i]->warning->text, sizeof(perfstr) - strlen(perfstr) - 1); | ||
| 626 | } | ||
| 627 | 451 | ||
| 628 | if (critical_thresholds) { | 452 | switch (option_char) { |
| 629 | if (!warning_thresholds) | 453 | case 'o': { |
| 630 | strncat(perfstr, ";", sizeof(perfstr) - strlen(perfstr) - 1); | 454 | // we are going to parse this again, so we work on a copy of that string |
| 631 | strncat(perfstr, ";", sizeof(perfstr) - strlen(perfstr) - 1); | 455 | char *tmp_oids = strdup(optarg); |
| 632 | if (thlds[i]->critical && thlds[i]->critical->text) | 456 | if (tmp_oids == NULL) { |
| 633 | strncat(perfstr, thlds[i]->critical->text, sizeof(perfstr) - strlen(perfstr) - 1); | 457 | die(STATE_UNKNOWN, "strdup failed"); |
| 634 | } | 458 | } |
| 635 | 459 | ||
| 636 | strncat(perfstr, " ", sizeof(perfstr) - strlen(perfstr) - 1); | 460 | for (char *ptr = strtok(tmp_oids, ", "); ptr != NULL; |
| 637 | } | 461 | ptr = strtok(NULL, ", "), oid_counter++) { |
| 638 | } | ||
| 639 | |||
| 640 | /* Save state data, as all data collected now */ | ||
| 641 | if (calculate_rate) { | ||
| 642 | string_length = 1024; | ||
| 643 | state_string = malloc(string_length); | ||
| 644 | if (state_string == NULL) | ||
| 645 | die(STATE_UNKNOWN, _("Cannot malloc")); | ||
| 646 | |||
| 647 | current_length = 0; | ||
| 648 | for (int i = 0; i < total_oids; i++) { | ||
| 649 | xasprintf(&temp_string, "%.0f", response_value[i]); | ||
| 650 | if (temp_string == NULL) | ||
| 651 | die(STATE_UNKNOWN, _("Cannot asprintf()")); | ||
| 652 | response_length = strlen(temp_string); | ||
| 653 | if (current_length + response_length > string_length) { | ||
| 654 | string_length = current_length + 1024; | ||
| 655 | state_string = realloc(state_string, string_length); | ||
| 656 | if (state_string == NULL) | ||
| 657 | die(STATE_UNKNOWN, _("Cannot realloc()")); | ||
| 658 | } | 462 | } |
| 659 | strcpy(&state_string[current_length], temp_string); | 463 | break; |
| 660 | current_length = current_length + response_length; | ||
| 661 | state_string[current_length] = ':'; | ||
| 662 | current_length++; | ||
| 663 | free(temp_string); | ||
| 664 | } | 464 | } |
| 665 | state_string[--current_length] = '\0'; | 465 | case '?': /* usage */ |
| 666 | if (verbose > 2) | 466 | usage5(); |
| 667 | printf("State string=%s\n", state_string); | 467 | // fallthrough |
| 468 | case 'h': /* help */ | ||
| 469 | print_help(); | ||
| 470 | exit(STATE_UNKNOWN); | ||
| 471 | case 'V': /* version */ | ||
| 472 | print_revision(progname, NP_VERSION); | ||
| 473 | exit(STATE_UNKNOWN); | ||
| 668 | 474 | ||
| 669 | /* This is not strictly the same as time now, but any subtle variations will cancel out */ | 475 | default: |
| 670 | np_state_write_string(current_time, state_string); | 476 | continue; |
| 671 | if (previous_state == NULL) { | ||
| 672 | /* Or should this be highest state? */ | ||
| 673 | die(STATE_OK, _("No previous data to calculate rate - assume okay")); | ||
| 674 | } | 477 | } |
| 675 | } | 478 | } |
| 676 | 479 | ||
| 677 | printf("%s %s -%s %s\n", label, state_text(result), outbuff, perfstr); | 480 | /* Check whether at least one OID was given */ |
| 678 | if (mult_resp) | 481 | if (oid_counter == 0) { |
| 679 | printf("%s", mult_resp); | 482 | die(STATE_UNKNOWN, _("No OIDs specified\n")); |
| 483 | } | ||
| 680 | 484 | ||
| 681 | return result; | 485 | // Allocate space for test units |
| 682 | } | 486 | check_snmp_test_unit *tmp = calloc(oid_counter, sizeof(check_snmp_test_unit)); |
| 487 | if (tmp == NULL) { | ||
| 488 | die(STATE_UNKNOWN, "Failed to calloc"); | ||
| 489 | } | ||
| 683 | 490 | ||
| 684 | /* process command-line arguments */ | 491 | for (size_t i = 0; i < oid_counter; i++) { |
| 685 | int process_arguments(int argc, char **argv) { | 492 | tmp[i] = check_snmp_test_unit_init(); |
| 686 | static struct option longopts[] = {STD_LONG_OPTS, | ||
| 687 | {"community", required_argument, 0, 'C'}, | ||
| 688 | {"oid", required_argument, 0, 'o'}, | ||
| 689 | {"object", required_argument, 0, 'o'}, | ||
| 690 | {"delimiter", required_argument, 0, 'd'}, | ||
| 691 | {"nulloid", required_argument, 0, 'z'}, | ||
| 692 | {"output-delimiter", required_argument, 0, 'D'}, | ||
| 693 | {"string", required_argument, 0, 's'}, | ||
| 694 | {"timeout", required_argument, 0, 't'}, | ||
| 695 | {"regex", required_argument, 0, 'r'}, | ||
| 696 | {"ereg", required_argument, 0, 'r'}, | ||
| 697 | {"eregi", required_argument, 0, 'R'}, | ||
| 698 | {"label", required_argument, 0, 'l'}, | ||
| 699 | {"units", required_argument, 0, 'u'}, | ||
| 700 | {"port", required_argument, 0, 'p'}, | ||
| 701 | {"retries", required_argument, 0, 'e'}, | ||
| 702 | {"miblist", required_argument, 0, 'm'}, | ||
| 703 | {"protocol", required_argument, 0, 'P'}, | ||
| 704 | {"context", required_argument, 0, 'N'}, | ||
| 705 | {"seclevel", required_argument, 0, 'L'}, | ||
| 706 | {"secname", required_argument, 0, 'U'}, | ||
| 707 | {"authproto", required_argument, 0, 'a'}, | ||
| 708 | {"privproto", required_argument, 0, 'x'}, | ||
| 709 | {"authpasswd", required_argument, 0, 'A'}, | ||
| 710 | {"privpasswd", required_argument, 0, 'X'}, | ||
| 711 | {"next", no_argument, 0, 'n'}, | ||
| 712 | {"rate", no_argument, 0, L_CALCULATE_RATE}, | ||
| 713 | {"rate-multiplier", required_argument, 0, L_RATE_MULTIPLIER}, | ||
| 714 | {"offset", required_argument, 0, L_OFFSET}, | ||
| 715 | {"invert-search", no_argument, 0, L_INVERT_SEARCH}, | ||
| 716 | {"perf-oids", no_argument, 0, 'O'}, | ||
| 717 | {"ipv4", no_argument, 0, '4'}, | ||
| 718 | {"ipv6", no_argument, 0, '6'}, | ||
| 719 | {"multiplier", required_argument, 0, 'M'}, | ||
| 720 | {"fmtstr", required_argument, 0, 'f'}, | ||
| 721 | {"ignore-mib-parsing-errors", no_argument, false, L_IGNORE_MIB_PARSING_ERRORS}, | ||
| 722 | {0, 0, 0, 0}}; | ||
| 723 | |||
| 724 | if (argc < 2) | ||
| 725 | return ERROR; | ||
| 726 | |||
| 727 | /* reverse compatibility for very old non-POSIX usage forms */ | ||
| 728 | for (int c = 1; c < argc; c++) { | ||
| 729 | if (strcmp("-to", argv[c]) == 0) | ||
| 730 | strcpy(argv[c], "-t"); | ||
| 731 | if (strcmp("-wv", argv[c]) == 0) | ||
| 732 | strcpy(argv[c], "-w"); | ||
| 733 | if (strcmp("-cv", argv[c]) == 0) | ||
| 734 | strcpy(argv[c], "-c"); | ||
| 735 | } | 493 | } |
| 736 | 494 | ||
| 737 | size_t j = 0; | 495 | check_snmp_config config = check_snmp_config_init(); |
| 738 | size_t jj = 0; | 496 | config.snmp_params.test_units = tmp; |
| 497 | config.snmp_params.num_of_test_units = oid_counter; | ||
| 498 | |||
| 499 | option = 0; | ||
| 500 | optind = 1; // Reset argument scanner | ||
| 501 | size_t tmp_oid_counter = 0; | ||
| 502 | size_t eval_counter = 0; | ||
| 503 | size_t unitv_counter = 0; | ||
| 504 | size_t labels_counter = 0; | ||
| 505 | unsigned char *authpasswd = NULL; | ||
| 506 | unsigned char *privpasswd = NULL; | ||
| 507 | int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; | ||
| 508 | char *port = NULL; | ||
| 509 | char *miblist = NULL; | ||
| 510 | char *connection_prefix = NULL; | ||
| 511 | bool snmp_version_set_explicitely = false; | ||
| 512 | // TODO error checking | ||
| 739 | while (true) { | 513 | while (true) { |
| 740 | int option = 0; | 514 | int option_char = getopt_long( |
| 741 | int option_char = getopt_long(argc, argv, "nhvVO46t:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:N:L:U:a:x:A:X:M:f:z:", longopts, &option); | 515 | argc, argv, |
| 516 | "nhvVO46t:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:N:L:U:a:x:A:X:M:f:z:", longopts, &option); | ||
| 742 | 517 | ||
| 743 | if (option_char == -1 || option_char == EOF) | 518 | if (option_char == -1 || option_char == EOF) { |
| 744 | break; | 519 | break; |
| 520 | } | ||
| 745 | 521 | ||
| 746 | switch (option_char) { | 522 | switch (option_char) { |
| 747 | case '?': /* usage */ | 523 | case '?': /* usage */ |
| @@ -758,64 +534,155 @@ int process_arguments(int argc, char **argv) { | |||
| 758 | 534 | ||
| 759 | /* Connection info */ | 535 | /* Connection info */ |
| 760 | case 'C': /* group or community */ | 536 | case 'C': /* group or community */ |
| 761 | community = optarg; | 537 | config.snmp_params.snmp_session.community = (unsigned char *)optarg; |
| 538 | config.snmp_params.snmp_session.community_len = strlen(optarg); | ||
| 762 | break; | 539 | break; |
| 763 | case 'H': /* Host or server */ | 540 | case 'H': /* Host or server */ |
| 764 | server_address = optarg; | 541 | config.snmp_params.snmp_session.peername = optarg; |
| 765 | break; | 542 | break; |
| 766 | case 'p': /* TCP port number */ | 543 | case 'p': /*port number */ |
| 544 | // Add port to "peername" below to not rely on argument order | ||
| 767 | port = optarg; | 545 | port = optarg; |
| 768 | break; | 546 | break; |
| 769 | case 'm': /* List of MIBS */ | 547 | case 'm': /* List of MIBS */ |
| 770 | miblist = optarg; | 548 | miblist = optarg; |
| 771 | break; | 549 | break; |
| 772 | case 'n': /* usesnmpgetnext */ | 550 | case 'n': /* use_getnext instead of get */ |
| 773 | usesnmpgetnext = true; | 551 | config.snmp_params.use_getnext = true; |
| 774 | break; | 552 | break; |
| 775 | case 'P': /* SNMP protocol version */ | 553 | case 'P': /* SNMP protocol version */ |
| 776 | proto = optarg; | 554 | if (strcasecmp("1", optarg) == 0) { |
| 555 | config.snmp_params.snmp_session.version = SNMP_VERSION_1; | ||
| 556 | } else if (strcasecmp("2c", optarg) == 0) { | ||
| 557 | config.snmp_params.snmp_session.version = SNMP_VERSION_2c; | ||
| 558 | } else if (strcasecmp("3", optarg) == 0) { | ||
| 559 | config.snmp_params.snmp_session.version = SNMP_VERSION_3; | ||
| 560 | } else { | ||
| 561 | die(STATE_UNKNOWN, "invalid SNMP version/protocol: %s", optarg); | ||
| 562 | } | ||
| 563 | snmp_version_set_explicitely = true; | ||
| 564 | |||
| 777 | break; | 565 | break; |
| 778 | case 'N': /* SNMPv3 context */ | 566 | case 'N': /* SNMPv3 context name */ |
| 779 | context = optarg; | 567 | config.snmp_params.snmp_session.contextName = optarg; |
| 568 | config.snmp_params.snmp_session.contextNameLen = strlen(optarg); | ||
| 780 | break; | 569 | break; |
| 781 | case 'L': /* security level */ | 570 | case 'L': /* security level */ |
| 782 | seclevel = optarg; | 571 | if (strcasecmp("noAuthNoPriv", optarg) == 0) { |
| 572 | config.snmp_params.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; | ||
| 573 | } else if (strcasecmp("authNoPriv", optarg) == 0) { | ||
| 574 | config.snmp_params.snmp_session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; | ||
| 575 | } else if (strcasecmp("authPriv", optarg) == 0) { | ||
| 576 | config.snmp_params.snmp_session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; | ||
| 577 | } else { | ||
| 578 | die(STATE_UNKNOWN, "invalid security level: %s", optarg); | ||
| 579 | } | ||
| 783 | break; | 580 | break; |
| 784 | case 'U': /* security username */ | 581 | case 'U': /* security username */ |
| 785 | secname = optarg; | 582 | config.snmp_params.snmp_session.securityName = optarg; |
| 583 | config.snmp_params.snmp_session.securityNameLen = strlen(optarg); | ||
| 786 | break; | 584 | break; |
| 787 | case 'a': /* auth protocol */ | 585 | case 'a': /* auth protocol */ |
| 788 | authproto = optarg; | 586 | // SNMPv3: SHA or MD5 |
| 587 | // TODO Test for availability of individual protocols | ||
| 588 | if (strcasecmp("MD5", optarg) == 0) { | ||
| 589 | config.snmp_params.snmp_session.securityAuthProto = usmHMACMD5AuthProtocol; | ||
| 590 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 591 | OID_LENGTH(usmHMACMD5AuthProtocol); | ||
| 592 | } else if (strcasecmp("SHA", optarg) == 0) { | ||
| 593 | config.snmp_params.snmp_session.securityAuthProto = usmHMACSHA1AuthProtocol; | ||
| 594 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 595 | OID_LENGTH(usmHMACSHA1AuthProtocol); | ||
| 596 | } else if (strcasecmp("SHA224", optarg) == 0) { | ||
| 597 | config.snmp_params.snmp_session.securityAuthProto = usmHMAC128SHA224AuthProtocol; | ||
| 598 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 599 | OID_LENGTH(usmHMAC128SHA224AuthProtocol); | ||
| 600 | } else if (strcasecmp("SHA256", optarg) == 0) { | ||
| 601 | config.snmp_params.snmp_session.securityAuthProto = usmHMAC192SHA256AuthProtocol; | ||
| 602 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 603 | OID_LENGTH(usmHMAC192SHA256AuthProtocol); | ||
| 604 | } else if (strcasecmp("SHA384", optarg) == 0) { | ||
| 605 | config.snmp_params.snmp_session.securityAuthProto = usmHMAC256SHA384AuthProtocol; | ||
| 606 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 607 | OID_LENGTH(usmHMAC256SHA384AuthProtocol); | ||
| 608 | } else if (strcasecmp("SHA512", optarg) == 0) { | ||
| 609 | config.snmp_params.snmp_session.securityAuthProto = usmHMAC384SHA512AuthProtocol; | ||
| 610 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 611 | OID_LENGTH(usmHMAC384SHA512AuthProtocol); | ||
| 612 | } else { | ||
| 613 | die(STATE_UNKNOWN, "Unknown authentication protocol"); | ||
| 614 | } | ||
| 789 | break; | 615 | break; |
| 790 | case 'x': /* priv protocol */ | 616 | case 'x': /* priv protocol */ |
| 791 | privproto = optarg; | 617 | if (strcasecmp("DES", optarg) == 0) { |
| 618 | #ifdef HAVE_USM_DES_PRIV_PROTOCOL | ||
| 619 | config.snmp_params.snmp_session.securityAuthProto = usmDESPrivProtocol; | ||
| 620 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 621 | OID_LENGTH(usmDESPrivProtocol); | ||
| 622 | #else | ||
| 623 | die(STATE_UNKNOWN, "DES Privacy Protocol not available on this platform"); | ||
| 624 | #endif | ||
| 625 | } else if (strcasecmp("AES", optarg) == 0) { | ||
| 626 | config.snmp_params.snmp_session.securityAuthProto = usmAESPrivProtocol; | ||
| 627 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 628 | OID_LENGTH(usmAESPrivProtocol); | ||
| 629 | // } else if (strcasecmp("AES128", optarg)) { | ||
| 630 | // config.snmp_session.securityAuthProto = usmAES128PrivProtocol; | ||
| 631 | // config.snmp_session.securityAuthProtoLen = OID_LENGTH(usmAES128PrivProtocol) | ||
| 632 | // / OID_LENGTH(oid); | ||
| 633 | } else if (strcasecmp("AES192", optarg) == 0) { | ||
| 634 | config.snmp_params.snmp_session.securityAuthProto = usmAES192PrivProtocol; | ||
| 635 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 636 | OID_LENGTH(usmAES192PrivProtocol); | ||
| 637 | } else if (strcasecmp("AES256", optarg) == 0) { | ||
| 638 | config.snmp_params.snmp_session.securityAuthProto = usmAES256PrivProtocol; | ||
| 639 | config.snmp_params.snmp_session.securityAuthProtoLen = | ||
| 640 | OID_LENGTH(usmAES256PrivProtocol); | ||
| 641 | // } else if (strcasecmp("AES192Cisco", optarg)) { | ||
| 642 | // config.snmp_session.securityAuthProto = usmAES192CiscoPrivProtocol; | ||
| 643 | // config.snmp_session.securityAuthProtoLen = | ||
| 644 | // sizeof(usmAES192CiscoPrivProtocol) / sizeof(oid); } else if | ||
| 645 | // (strcasecmp("AES256Cisco", optarg)) { config.snmp_session.securityAuthProto = | ||
| 646 | // usmAES256CiscoPrivProtocol; config.snmp_session.securityAuthProtoLen = | ||
| 647 | // sizeof(usmAES256CiscoPrivProtocol) / sizeof(oid); } else if | ||
| 648 | // (strcasecmp("AES192Cisco2", optarg)) { config.snmp_session.securityAuthProto | ||
| 649 | // = usmAES192Cisco2PrivProtocol; config.snmp_session.securityAuthProtoLen = | ||
| 650 | // sizeof(usmAES192Cisco2PrivProtocol) / sizeof(oid); } else if | ||
| 651 | // (strcasecmp("AES256Cisco2", optarg)) { config.snmp_session.securityAuthProto | ||
| 652 | // = usmAES256Cisco2PrivProtocol; config.snmp_session.securityAuthProtoLen = | ||
| 653 | // sizeof(usmAES256Cisco2PrivProtocol) / sizeof(oid); | ||
| 654 | } else { | ||
| 655 | die(STATE_UNKNOWN, "Unknown privacy protocol"); | ||
| 656 | } | ||
| 792 | break; | 657 | break; |
| 793 | case 'A': /* auth passwd */ | 658 | case 'A': /* auth passwd */ |
| 794 | authpasswd = optarg; | 659 | authpasswd = (unsigned char *)optarg; |
| 795 | break; | 660 | break; |
| 796 | case 'X': /* priv passwd */ | 661 | case 'X': /* priv passwd */ |
| 797 | privpasswd = optarg; | 662 | privpasswd = (unsigned char *)optarg; |
| 663 | break; | ||
| 664 | case 'e': | ||
| 665 | case 'E': | ||
| 666 | if (!is_integer(optarg)) { | ||
| 667 | usage2(_("Retries interval must be a positive integer"), optarg); | ||
| 668 | } else { | ||
| 669 | config.snmp_params.snmp_session.retries = atoi(optarg); | ||
| 670 | } | ||
| 798 | break; | 671 | break; |
| 799 | case 't': /* timeout period */ | 672 | case 't': /* timeout period */ |
| 800 | if (!is_integer(optarg)) | 673 | if (!is_integer(optarg)) { |
| 801 | usage2(_("Timeout interval must be a positive integer"), optarg); | 674 | usage2(_("Timeout interval must be a positive integer"), optarg); |
| 802 | else | 675 | } else { |
| 803 | timeout_interval = atoi(optarg); | 676 | timeout_interval = (unsigned int)atoi(optarg); |
| 677 | } | ||
| 804 | break; | 678 | break; |
| 805 | 679 | ||
| 806 | /* Test parameters */ | 680 | /* Test parameters */ |
| 807 | case 'c': /* critical threshold */ | 681 | case 'c': /* critical threshold */ |
| 808 | critical_thresholds = optarg; | 682 | check_snmp_set_thresholds(optarg, config.snmp_params.test_units, oid_counter, true); |
| 809 | break; | 683 | break; |
| 810 | case 'w': /* warning threshold */ | 684 | case 'w': /* warning threshold */ |
| 811 | warning_thresholds = optarg; | 685 | check_snmp_set_thresholds(optarg, config.snmp_params.test_units, oid_counter, false); |
| 812 | break; | ||
| 813 | case 'e': /* PRELIMINARY - may change */ | ||
| 814 | case 'E': /* PRELIMINARY - may change */ | ||
| 815 | if (!is_integer(optarg)) | ||
| 816 | usage2(_("Retries interval must be a positive integer"), optarg); | ||
| 817 | else | ||
| 818 | retries = atoi(optarg); | ||
| 819 | break; | 686 | break; |
| 820 | case 'o': /* object identifier */ | 687 | case 'o': /* object identifier */ |
| 821 | if (strspn(optarg, "0123456789.,") != strlen(optarg)) { | 688 | if (strspn(optarg, "0123456789.,") != strlen(optarg)) { |
| @@ -824,306 +691,292 @@ int process_arguments(int argc, char **argv) { | |||
| 824 | * so we have a mib variable, rather than just an SNMP OID, | 691 | * so we have a mib variable, rather than just an SNMP OID, |
| 825 | * so we have to actually read the mib files | 692 | * so we have to actually read the mib files |
| 826 | */ | 693 | */ |
| 827 | needmibs = true; | 694 | config.snmp_params.need_mibs = true; |
| 828 | } | ||
| 829 | for (char *ptr = strtok(optarg, ", "); ptr != NULL; ptr = strtok(NULL, ", "), j++) { | ||
| 830 | while (j >= oids_size) { | ||
| 831 | oids_size += OID_COUNT_STEP; | ||
| 832 | oids = realloc(oids, oids_size * sizeof(*oids)); | ||
| 833 | } | ||
| 834 | oids[j] = strdup(ptr); | ||
| 835 | } | 695 | } |
| 836 | numoids = j; | 696 | |
| 837 | if (option_char == 'E' || option_char == 'e') { | 697 | for (char *ptr = strtok(optarg, ", "); ptr != NULL; |
| 838 | jj++; | 698 | ptr = strtok(NULL, ", "), tmp_oid_counter++) { |
| 839 | while (j + 1 >= eval_size) { | 699 | config.snmp_params.test_units[tmp_oid_counter].oid = strdup(ptr); |
| 840 | eval_size += OID_COUNT_STEP; | ||
| 841 | eval_method = realloc(eval_method, eval_size * sizeof(*eval_method)); | ||
| 842 | memset(eval_method + eval_size - OID_COUNT_STEP, 0, 8); | ||
| 843 | } | ||
| 844 | if (option_char == 'E') | ||
| 845 | eval_method[j + 1] |= WARN_PRESENT; | ||
| 846 | else if (option_char == 'e') | ||
| 847 | eval_method[j + 1] |= CRIT_PRESENT; | ||
| 848 | } | 700 | } |
| 849 | break; | 701 | break; |
| 850 | case 'z': /* Null OID Return Check */ | 702 | case 'z': /* Null OID Return Check */ |
| 851 | if (!is_integer(optarg)) | 703 | if (!is_integer(optarg)) { |
| 852 | usage2(_("Exit status must be a positive integer"), optarg); | 704 | usage2(_("Exit status must be a positive integer"), optarg); |
| 853 | else | 705 | } else { |
| 854 | nulloid = atoi(optarg); | 706 | config.evaluation_params.nulloid_result = atoi(optarg); |
| 707 | } | ||
| 855 | break; | 708 | break; |
| 856 | case 's': /* string or substring */ | 709 | case 's': /* string or substring */ |
| 857 | strncpy(string_value, optarg, sizeof(string_value) - 1); | 710 | strncpy(config.evaluation_params.string_cmp_value, optarg, |
| 858 | string_value[sizeof(string_value) - 1] = 0; | 711 | sizeof(config.evaluation_params.string_cmp_value) - 1); |
| 859 | while (jj >= eval_size) { | 712 | config.evaluation_params |
| 860 | eval_size += OID_COUNT_STEP; | 713 | .string_cmp_value[sizeof(config.evaluation_params.string_cmp_value) - 1] = 0; |
| 861 | eval_method = realloc(eval_method, eval_size * sizeof(*eval_method)); | 714 | config.snmp_params.test_units[eval_counter++].eval_mthd.crit_string = true; |
| 862 | memset(eval_method + eval_size - OID_COUNT_STEP, 0, 8); | ||
| 863 | } | ||
| 864 | eval_method[jj++] = CRIT_STRING; | ||
| 865 | break; | 715 | break; |
| 866 | case 'R': /* regex */ | 716 | case 'R': /* regex */ |
| 867 | cflags = REG_ICASE; | 717 | cflags = REG_ICASE; |
| 868 | // fall through | 718 | // fall through |
| 869 | case 'r': /* regex */ | 719 | case 'r': /* regex */ |
| 720 | { | ||
| 721 | char regex_expect[MAX_INPUT_BUFFER] = ""; | ||
| 870 | cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; | 722 | cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE; |
| 871 | strncpy(regex_expect, optarg, sizeof(regex_expect) - 1); | 723 | strncpy(regex_expect, optarg, sizeof(regex_expect) - 1); |
| 872 | regex_expect[sizeof(regex_expect) - 1] = 0; | 724 | regex_expect[sizeof(regex_expect) - 1] = 0; |
| 873 | errcode = regcomp(&preg, regex_expect, cflags); | 725 | int errcode = regcomp(&config.evaluation_params.regex_cmp_value, regex_expect, cflags); |
| 874 | if (errcode != 0) { | 726 | if (errcode != 0) { |
| 875 | regerror(errcode, &preg, errbuf, MAX_INPUT_BUFFER); | 727 | char errbuf[MAX_INPUT_BUFFER] = ""; |
| 876 | printf(_("Could Not Compile Regular Expression")); | 728 | regerror(errcode, &config.evaluation_params.regex_cmp_value, errbuf, |
| 877 | return ERROR; | 729 | MAX_INPUT_BUFFER); |
| 878 | } | 730 | printf("Could Not Compile Regular Expression: %s", errbuf); |
| 879 | while (jj >= eval_size) { | 731 | process_arguments_wrapper result = { |
| 880 | eval_size += OID_COUNT_STEP; | 732 | .errorcode = ERROR, |
| 881 | eval_method = realloc(eval_method, eval_size * sizeof(*eval_method)); | 733 | }; |
| 882 | memset(eval_method + eval_size - OID_COUNT_STEP, 0, 8); | 734 | return result; |
| 883 | } | 735 | } |
| 884 | eval_method[jj++] = CRIT_REGEX; | 736 | config.snmp_params.test_units[eval_counter++].eval_mthd.crit_regex = true; |
| 885 | break; | 737 | } break; |
| 886 | |||
| 887 | /* Format */ | ||
| 888 | case 'd': /* delimiter */ | ||
| 889 | delimiter = strscpy(delimiter, optarg); | ||
| 890 | break; | ||
| 891 | case 'D': /* output-delimiter */ | ||
| 892 | output_delim = strscpy(output_delim, optarg); | ||
| 893 | break; | ||
| 894 | case 'l': /* label */ | 738 | case 'l': /* label */ |
| 895 | nlabels++; | 739 | { |
| 896 | if (nlabels > labels_size) { | 740 | if (labels_counter >= config.snmp_params.num_of_test_units) { |
| 897 | labels_size += 8; | 741 | break; |
| 898 | labels = realloc(labels, labels_size * sizeof(*labels)); | 742 | } |
| 899 | if (labels == NULL) | 743 | char *ptr = trim_whitespaces_and_check_quoting(optarg); |
| 900 | die(STATE_UNKNOWN, _("Could not reallocate labels[%d]"), (int)nlabels); | 744 | if (ptr[0] == '\'') { |
| 745 | config.snmp_params.test_units[labels_counter].label = ptr + 1; | ||
| 746 | } else { | ||
| 747 | config.snmp_params.test_units[labels_counter].label = ptr; | ||
| 901 | } | 748 | } |
| 902 | labels[nlabels - 1] = optarg; | 749 | |
| 903 | char *ptr = thisarg(optarg); | 750 | while (ptr && (ptr = get_next_argument(ptr))) { |
| 904 | labels[nlabels - 1] = ptr; | 751 | labels_counter++; |
| 905 | if (ptr[0] == '\'') | 752 | ptr = trim_whitespaces_and_check_quoting(ptr); |
| 906 | labels[nlabels - 1] = ptr + 1; | 753 | if (ptr[0] == '\'') { |
| 907 | while (ptr && (ptr = nextarg(ptr))) { | 754 | config.snmp_params.test_units[labels_counter].label = ptr + 1; |
| 908 | nlabels++; | 755 | } else { |
| 909 | if (nlabels > labels_size) { | 756 | config.snmp_params.test_units[labels_counter].label = ptr; |
| 910 | labels_size += 8; | ||
| 911 | labels = realloc(labels, labels_size * sizeof(*labels)); | ||
| 912 | if (labels == NULL) | ||
| 913 | die(STATE_UNKNOWN, _("Could not reallocate labels\n")); | ||
| 914 | } | 757 | } |
| 915 | ptr = thisarg(ptr); | ||
| 916 | if (ptr[0] == '\'') | ||
| 917 | labels[nlabels - 1] = ptr + 1; | ||
| 918 | else | ||
| 919 | labels[nlabels - 1] = ptr; | ||
| 920 | } | 758 | } |
| 921 | break; | 759 | labels_counter++; |
| 760 | } break; | ||
| 922 | case 'u': /* units */ | 761 | case 'u': /* units */ |
| 923 | units = optarg; | 762 | { |
| 924 | nunits++; | 763 | if (unitv_counter >= config.snmp_params.num_of_test_units) { |
| 925 | if (nunits > unitv_size) { | 764 | break; |
| 926 | unitv_size += 8; | ||
| 927 | unitv = realloc(unitv, unitv_size * sizeof(*unitv)); | ||
| 928 | if (unitv == NULL) | ||
| 929 | die(STATE_UNKNOWN, _("Could not reallocate units [%d]\n"), (int)nunits); | ||
| 930 | } | 765 | } |
| 931 | unitv[nunits - 1] = optarg; | 766 | char *ptr = trim_whitespaces_and_check_quoting(optarg); |
| 932 | ptr = thisarg(optarg); | 767 | if (ptr[0] == '\'') { |
| 933 | unitv[nunits - 1] = ptr; | 768 | config.snmp_params.test_units[unitv_counter].unit_value = ptr + 1; |
| 934 | if (ptr[0] == '\'') | 769 | } else { |
| 935 | unitv[nunits - 1] = ptr + 1; | 770 | config.snmp_params.test_units[unitv_counter].unit_value = ptr; |
| 936 | while (ptr && (ptr = nextarg(ptr))) { | 771 | } |
| 937 | if (nunits > unitv_size) { | 772 | while (ptr && (ptr = get_next_argument(ptr))) { |
| 938 | unitv_size += 8; | 773 | unitv_counter++; |
| 939 | unitv = realloc(unitv, unitv_size * sizeof(*unitv)); | 774 | ptr = trim_whitespaces_and_check_quoting(ptr); |
| 940 | if (units == NULL) | 775 | if (ptr[0] == '\'') { |
| 941 | die(STATE_UNKNOWN, _("Could not realloc() units\n")); | 776 | config.snmp_params.test_units[unitv_counter].unit_value = ptr + 1; |
| 777 | } else { | ||
| 778 | config.snmp_params.test_units[unitv_counter].unit_value = ptr; | ||
| 942 | } | 779 | } |
| 943 | nunits++; | ||
| 944 | ptr = thisarg(ptr); | ||
| 945 | if (ptr[0] == '\'') | ||
| 946 | unitv[nunits - 1] = ptr + 1; | ||
| 947 | else | ||
| 948 | unitv[nunits - 1] = ptr; | ||
| 949 | } | 780 | } |
| 781 | unitv_counter++; | ||
| 782 | } break; | ||
| 783 | case offset_index: | ||
| 784 | config.evaluation_params.offset = strtod(optarg, NULL); | ||
| 785 | config.evaluation_params.offset_set = true; | ||
| 950 | break; | 786 | break; |
| 951 | case L_CALCULATE_RATE: | 787 | case invert_search_index: |
| 952 | if (calculate_rate == 0) | 788 | config.evaluation_params.invert_search = false; |
| 953 | np_enable_state(NULL, 1); | ||
| 954 | calculate_rate = 1; | ||
| 955 | break; | ||
| 956 | case L_RATE_MULTIPLIER: | ||
| 957 | if (!is_integer(optarg) || ((rate_multiplier = atoi(optarg)) <= 0)) | ||
| 958 | usage2(_("Rate multiplier must be a positive integer"), optarg); | ||
| 959 | break; | ||
| 960 | case L_OFFSET: | ||
| 961 | offset = strtod(optarg, NULL); | ||
| 962 | break; | ||
| 963 | case L_INVERT_SEARCH: | ||
| 964 | invert_search = 1; | ||
| 965 | break; | 789 | break; |
| 966 | case 'O': | 790 | case 'O': |
| 967 | perf_labels = 0; | 791 | config.evaluation_params.use_oid_as_perf_data_label = true; |
| 968 | break; | 792 | break; |
| 969 | case '4': | 793 | case '4': |
| 794 | // The default, do something here to be exclusive to -6 instead of doing nothing? | ||
| 795 | connection_prefix = "udp"; | ||
| 970 | break; | 796 | break; |
| 971 | case '6': | 797 | case '6': |
| 972 | xasprintf(&ip_version, "udp6:"); | 798 | connection_prefix = "udp6"; |
| 973 | if (verbose > 2) | 799 | break; |
| 974 | printf("IPv6 detected! Will pass \"udp6:\" to snmpget.\n"); | 800 | case connection_prefix_index: |
| 801 | connection_prefix = optarg; | ||
| 975 | break; | 802 | break; |
| 976 | case 'M': | 803 | case 'M': |
| 977 | if (strspn(optarg, "0123456789.,") == strlen(optarg)) { | 804 | if (strspn(optarg, "0123456789.,") == strlen(optarg)) { |
| 978 | multiplier = strtod(optarg, NULL); | 805 | config.evaluation_params.multiplier = strtod(optarg, NULL); |
| 806 | config.evaluation_params.multiplier_set = true; | ||
| 979 | } | 807 | } |
| 980 | break; | 808 | break; |
| 981 | case 'f': | 809 | case ignore_mib_parsing_errors_index: |
| 982 | if (multiplier != 1.0) { | 810 | config.snmp_params.ignore_mib_parsing_errors = true; |
| 983 | fmtstr = optarg; | 811 | break; |
| 984 | fmtstr_set = true; | 812 | case 'f': // Deprecated format option for floating point values |
| 813 | break; | ||
| 814 | case output_format_index: { | ||
| 815 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 816 | if (!parser.parsing_success) { | ||
| 817 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 818 | printf("Invalid output format: %s\n", optarg); | ||
| 819 | exit(STATE_UNKNOWN); | ||
| 820 | } | ||
| 821 | |||
| 822 | config.output_format_is_set = true; | ||
| 823 | config.output_format = parser.output_format; | ||
| 824 | break; | ||
| 825 | } | ||
| 826 | case calculate_rate: | ||
| 827 | config.evaluation_params.calculate_rate = true; | ||
| 828 | break; | ||
| 829 | case rate_multiplier: | ||
| 830 | if (!is_integer(optarg) || | ||
| 831 | ((config.evaluation_params.rate_multiplier = (unsigned int)atoi(optarg)) <= 0)) { | ||
| 832 | usage2(_("Rate multiplier must be a positive integer"), optarg); | ||
| 985 | } | 833 | } |
| 986 | break; | 834 | break; |
| 987 | case L_IGNORE_MIB_PARSING_ERRORS: | 835 | default: |
| 988 | ignore_mib_parsing_errors = true; | 836 | die(STATE_UNKNOWN, "Unknown option"); |
| 989 | } | 837 | } |
| 990 | } | 838 | } |
| 991 | 839 | ||
| 992 | if (server_address == NULL) | 840 | if (config.snmp_params.snmp_session.peername == NULL) { |
| 993 | server_address = argv[optind]; | 841 | config.snmp_params.snmp_session.peername = argv[optind]; |
| 994 | 842 | } | |
| 995 | if (community == NULL) | ||
| 996 | community = strdup(DEFAULT_COMMUNITY); | ||
| 997 | |||
| 998 | return validate_arguments(); | ||
| 999 | } | ||
| 1000 | |||
| 1001 | /****************************************************************************** | ||
| 1002 | |||
| 1003 | @@- | ||
| 1004 | <sect3> | ||
| 1005 | <title>validate_arguments</title> | ||
| 1006 | |||
| 1007 | <para>&PROTO_validate_arguments;</para> | ||
| 1008 | |||
| 1009 | <para>Checks to see if the default miblist needs to be loaded. Also verifies | ||
| 1010 | the authentication and authorization combinations based on protocol version | ||
| 1011 | selected.</para> | ||
| 1012 | |||
| 1013 | <para></para> | ||
| 1014 | |||
| 1015 | </sect3> | ||
| 1016 | -@@ | ||
| 1017 | ******************************************************************************/ | ||
| 1018 | 843 | ||
| 1019 | static int validate_arguments() { | 844 | // Build true peername here if necessary |
| 1020 | /* check whether to load locally installed MIBS (CPU/disk intensive) */ | 845 | if (connection_prefix != NULL) { |
| 1021 | if (miblist == NULL) { | 846 | // We got something in the connection prefix |
| 1022 | if (needmibs) { | 847 | if (strcasecmp(connection_prefix, "udp") == 0) { |
| 1023 | miblist = strdup(DEFAULT_MIBLIST); | 848 | // The default, do nothing |
| 849 | } else if (strcasecmp(connection_prefix, "tcp") == 0) { | ||
| 850 | // use tcp/ipv4 | ||
| 851 | xasprintf(&config.snmp_params.snmp_session.peername, "tcp:%s", | ||
| 852 | config.snmp_params.snmp_session.peername); | ||
| 853 | } else if (strcasecmp(connection_prefix, "tcp6") == 0 || | ||
| 854 | strcasecmp(connection_prefix, "tcpv6") == 0 || | ||
| 855 | strcasecmp(connection_prefix, "tcpipv6") == 0 || | ||
| 856 | strcasecmp(connection_prefix, "udp6") == 0 || | ||
| 857 | strcasecmp(connection_prefix, "udpipv6") == 0 || | ||
| 858 | strcasecmp(connection_prefix, "udpv6") == 0) { | ||
| 859 | // Man page (or net-snmp) code says IPv6 addresses should be wrapped in [], but it | ||
| 860 | // works anyway therefore do nothing here | ||
| 861 | xasprintf(&config.snmp_params.snmp_session.peername, "%s:%s", connection_prefix, | ||
| 862 | config.snmp_params.snmp_session.peername); | ||
| 863 | } else if (strcmp(connection_prefix, "tls") == 0) { | ||
| 864 | // TODO: Anything else to do here? | ||
| 865 | xasprintf(&config.snmp_params.snmp_session.peername, "tls:%s", | ||
| 866 | config.snmp_params.snmp_session.peername); | ||
| 867 | } else if (strcmp(connection_prefix, "dtls") == 0) { | ||
| 868 | // TODO: Anything else to do here? | ||
| 869 | xasprintf(&config.snmp_params.snmp_session.peername, "dtls:%s", | ||
| 870 | config.snmp_params.snmp_session.peername); | ||
| 871 | } else if (strcmp(connection_prefix, "unix") == 0) { | ||
| 872 | // TODO: Check whether this is a valid path? | ||
| 873 | xasprintf(&config.snmp_params.snmp_session.peername, "unix:%s", | ||
| 874 | config.snmp_params.snmp_session.peername); | ||
| 875 | } else if (strcmp(connection_prefix, "ipx") == 0) { | ||
| 876 | xasprintf(&config.snmp_params.snmp_session.peername, "ipx:%s", | ||
| 877 | config.snmp_params.snmp_session.peername); | ||
| 1024 | } else { | 878 | } else { |
| 1025 | miblist = ""; /* don't read any mib files for numeric oids */ | 879 | // Don't know that prefix, die here |
| 880 | die(STATE_UNKNOWN, "Unknown connection prefix"); | ||
| 1026 | } | 881 | } |
| 1027 | } | 882 | } |
| 1028 | 883 | ||
| 1029 | /* Check server_address is given */ | 884 | /* Check server_address is given */ |
| 1030 | if (server_address == NULL) | 885 | if (config.snmp_params.snmp_session.peername == NULL) { |
| 1031 | die(STATE_UNKNOWN, _("No host specified\n")); | 886 | die(STATE_UNKNOWN, _("No host specified\n")); |
| 887 | } | ||
| 1032 | 888 | ||
| 1033 | /* Check oid is given */ | 889 | if (port != NULL) { |
| 1034 | if (numoids == 0) | 890 | xasprintf(&config.snmp_params.snmp_session.peername, "%s:%s", |
| 1035 | die(STATE_UNKNOWN, _("No OIDs specified\n")); | 891 | config.snmp_params.snmp_session.peername, port); |
| 892 | } | ||
| 1036 | 893 | ||
| 1037 | if (proto == NULL) | 894 | /* check whether to load locally installed MIBS (CPU/disk intensive) */ |
| 1038 | xasprintf(&proto, DEFAULT_PROTOCOL); | 895 | if (miblist == NULL) { |
| 1039 | 896 | if (config.snmp_params.need_mibs) { | |
| 1040 | if ((strcmp(proto, "1") == 0) || (strcmp(proto, "2c") == 0)) { /* snmpv1 or snmpv2c */ | 897 | setenv("MIBLS", DEFAULT_MIBLIST, 1); |
| 1041 | numauthpriv = 2; | 898 | } else { |
| 1042 | authpriv = calloc(numauthpriv, sizeof(char *)); | 899 | setenv("MIBLS", "NONE", 1); |
| 1043 | authpriv[0] = strdup("-c"); | 900 | miblist = ""; /* don't read any mib files for numeric oids */ |
| 1044 | authpriv[1] = strdup(community); | ||
| 1045 | } else if (strcmp(proto, "3") == 0) { /* snmpv3 args */ | ||
| 1046 | if (!(context == NULL)) { | ||
| 1047 | numcontext = 2; | ||
| 1048 | contextargs = calloc(numcontext, sizeof(char *)); | ||
| 1049 | contextargs[0] = strdup("-n"); | ||
| 1050 | contextargs[1] = strdup(context); | ||
| 1051 | } | 901 | } |
| 902 | } else { | ||
| 903 | // Blatantly stolen from snmplib/snmp_parse_args | ||
| 904 | setenv("MIBS", miblist, 1); | ||
| 905 | } | ||
| 1052 | 906 | ||
| 1053 | if (seclevel == NULL) | 907 | // Historical default is SNMP v2c |
| 1054 | xasprintf(&seclevel, "noAuthNoPriv"); | 908 | if (!snmp_version_set_explicitely && config.snmp_params.snmp_session.community != NULL) { |
| 909 | config.snmp_params.snmp_session.version = SNMP_VERSION_2c; | ||
| 910 | } | ||
| 1055 | 911 | ||
| 1056 | if (secname == NULL) | 912 | if ((config.snmp_params.snmp_session.version == SNMP_VERSION_1) || |
| 913 | (config.snmp_params.snmp_session.version == SNMP_VERSION_2c)) { /* snmpv1 or snmpv2c */ | ||
| 914 | /* | ||
| 915 | config.numauthpriv = 2; | ||
| 916 | config.authpriv = calloc(config.numauthpriv, sizeof(char *)); | ||
| 917 | config.authpriv[0] = strdup("-c"); | ||
| 918 | config.authpriv[1] = strdup(community); | ||
| 919 | */ | ||
| 920 | } else if (config.snmp_params.snmp_session.version == SNMP_VERSION_3) { /* snmpv3 args */ | ||
| 921 | // generate keys for priv and auth here (if demanded) | ||
| 922 | |||
| 923 | if (config.snmp_params.snmp_session.securityName == NULL) { | ||
| 1057 | die(STATE_UNKNOWN, _("Required parameter: %s\n"), "secname"); | 924 | die(STATE_UNKNOWN, _("Required parameter: %s\n"), "secname"); |
| 925 | } | ||
| 1058 | 926 | ||
| 1059 | if (strcmp(seclevel, "noAuthNoPriv") == 0) { | 927 | switch (config.snmp_params.snmp_session.securityLevel) { |
| 1060 | numauthpriv = 4; | 928 | case SNMP_SEC_LEVEL_AUTHPRIV: { |
| 1061 | authpriv = calloc(numauthpriv, sizeof(char *)); | 929 | if (authpasswd == NULL) { |
| 1062 | authpriv[0] = strdup("-l"); | 930 | die(STATE_UNKNOWN, |
| 1063 | authpriv[1] = strdup("noAuthNoPriv"); | 931 | "No authentication passphrase was given, but authorization was requested"); |
| 1064 | authpriv[2] = strdup("-u"); | ||
| 1065 | authpriv[3] = strdup(secname); | ||
| 1066 | } else { | ||
| 1067 | if (!((strcmp(seclevel, "authNoPriv") == 0) || (strcmp(seclevel, "authPriv") == 0))) { | ||
| 1068 | usage2(_("Invalid seclevel"), seclevel); | ||
| 1069 | } | 932 | } |
| 1070 | 933 | // auth and priv | |
| 1071 | if (authproto == NULL) | 934 | int priv_key_generated = generate_Ku( |
| 1072 | xasprintf(&authproto, DEFAULT_AUTH_PROTOCOL); | 935 | config.snmp_params.snmp_session.securityPrivProto, |
| 1073 | 936 | (unsigned int)config.snmp_params.snmp_session.securityPrivProtoLen, authpasswd, | |
| 1074 | if (authpasswd == NULL) | 937 | strlen((const char *)authpasswd), config.snmp_params.snmp_session.securityPrivKey, |
| 1075 | die(STATE_UNKNOWN, _("Required parameter: %s\n"), "authpasswd"); | 938 | &config.snmp_params.snmp_session.securityPrivKeyLen); |
| 1076 | 939 | ||
| 1077 | if (strcmp(seclevel, "authNoPriv") == 0) { | 940 | if (priv_key_generated != SNMPERR_SUCCESS) { |
| 1078 | numauthpriv = 8; | 941 | die(STATE_UNKNOWN, "Failed to generate privacy key"); |
| 1079 | authpriv = calloc(numauthpriv, sizeof(char *)); | ||
| 1080 | authpriv[0] = strdup("-l"); | ||
| 1081 | authpriv[1] = strdup("authNoPriv"); | ||
| 1082 | authpriv[2] = strdup("-a"); | ||
| 1083 | authpriv[3] = strdup(authproto); | ||
| 1084 | authpriv[4] = strdup("-u"); | ||
| 1085 | authpriv[5] = strdup(secname); | ||
| 1086 | authpriv[6] = strdup("-A"); | ||
| 1087 | authpriv[7] = strdup(authpasswd); | ||
| 1088 | } else if (strcmp(seclevel, "authPriv") == 0) { | ||
| 1089 | if (privproto == NULL) | ||
| 1090 | xasprintf(&privproto, DEFAULT_PRIV_PROTOCOL); | ||
| 1091 | |||
| 1092 | if (privpasswd == NULL) | ||
| 1093 | die(STATE_UNKNOWN, _("Required parameter: %s\n"), "privpasswd"); | ||
| 1094 | |||
| 1095 | numauthpriv = 12; | ||
| 1096 | authpriv = calloc(numauthpriv, sizeof(char *)); | ||
| 1097 | authpriv[0] = strdup("-l"); | ||
| 1098 | authpriv[1] = strdup("authPriv"); | ||
| 1099 | authpriv[2] = strdup("-a"); | ||
| 1100 | authpriv[3] = strdup(authproto); | ||
| 1101 | authpriv[4] = strdup("-u"); | ||
| 1102 | authpriv[5] = strdup(secname); | ||
| 1103 | authpriv[6] = strdup("-A"); | ||
| 1104 | authpriv[7] = strdup(authpasswd); | ||
| 1105 | authpriv[8] = strdup("-x"); | ||
| 1106 | authpriv[9] = strdup(privproto); | ||
| 1107 | authpriv[10] = strdup("-X"); | ||
| 1108 | authpriv[11] = strdup(privpasswd); | ||
| 1109 | } | 942 | } |
| 1110 | } | 943 | } |
| 1111 | 944 | // fall through | |
| 1112 | } else { | 945 | case SNMP_SEC_LEVEL_AUTHNOPRIV: { |
| 1113 | usage2(_("Invalid SNMP version"), proto); | 946 | if (privpasswd == NULL) { |
| 947 | die(STATE_UNKNOWN, "No privacy passphrase was given, but privacy was requested"); | ||
| 948 | } | ||
| 949 | int auth_key_generated = generate_Ku( | ||
| 950 | config.snmp_params.snmp_session.securityAuthProto, | ||
| 951 | (unsigned int)config.snmp_params.snmp_session.securityAuthProtoLen, privpasswd, | ||
| 952 | strlen((const char *)privpasswd), config.snmp_params.snmp_session.securityAuthKey, | ||
| 953 | &config.snmp_params.snmp_session.securityAuthKeyLen); | ||
| 954 | |||
| 955 | if (auth_key_generated != SNMPERR_SUCCESS) { | ||
| 956 | die(STATE_UNKNOWN, "Failed to generate privacy key"); | ||
| 957 | } | ||
| 958 | } break; | ||
| 959 | case SNMP_SEC_LEVEL_NOAUTH: | ||
| 960 | // No auth, no priv, not much todo | ||
| 961 | break; | ||
| 962 | } | ||
| 1114 | } | 963 | } |
| 1115 | 964 | ||
| 1116 | return OK; | 965 | process_arguments_wrapper result = { |
| 966 | .config = config, | ||
| 967 | .errorcode = OK, | ||
| 968 | }; | ||
| 969 | return result; | ||
| 1117 | } | 970 | } |
| 1118 | 971 | ||
| 1119 | /* trim leading whitespace | 972 | /* trim leading whitespace |
| 1120 | if there is a leading quote, make sure it balances */ | 973 | if there is a leading quote, make sure it balances */ |
| 1121 | 974 | char *trim_whitespaces_and_check_quoting(char *str) { | |
| 1122 | static char *thisarg(char *str) { | ||
| 1123 | str += strspn(str, " \t\r\n"); /* trim any leading whitespace */ | 975 | str += strspn(str, " \t\r\n"); /* trim any leading whitespace */ |
| 1124 | if (str[0] == '\'') { /* handle SIMPLE quoted strings */ | 976 | if (str[0] == '\'') { /* handle SIMPLE quoted strings */ |
| 1125 | if (strlen(str) == 1 || !strstr(str + 1, "'")) | 977 | if (strlen(str) == 1 || !strstr(str + 1, "'")) { |
| 1126 | die(STATE_UNKNOWN, _("Unbalanced quotes\n")); | 978 | die(STATE_UNKNOWN, _("Unbalanced quotes\n")); |
| 979 | } | ||
| 1127 | } | 980 | } |
| 1128 | return str; | 981 | return str; |
| 1129 | } | 982 | } |
| @@ -1132,23 +985,21 @@ static char *thisarg(char *str) { | |||
| 1132 | set the trailing quote to '\x0' | 985 | set the trailing quote to '\x0' |
| 1133 | if the string continues, advance beyond the comma */ | 986 | if the string continues, advance beyond the comma */ |
| 1134 | 987 | ||
| 1135 | static char *nextarg(char *str) { | 988 | char *get_next_argument(char *str) { |
| 1136 | if (str[0] == '\'') { | 989 | if (str[0] == '\'') { |
| 1137 | str[0] = 0; | 990 | str[0] = 0; |
| 1138 | if (strlen(str) > 1) { | 991 | if (strlen(str) > 1) { |
| 1139 | str = strstr(str + 1, "'"); | 992 | str = strstr(str + 1, "'"); |
| 1140 | return (++str); | 993 | return (++str); |
| 1141 | } else { | ||
| 1142 | return NULL; | ||
| 1143 | } | 994 | } |
| 995 | return NULL; | ||
| 1144 | } | 996 | } |
| 1145 | if (str[0] == ',') { | 997 | if (str[0] == ',') { |
| 1146 | str[0] = 0; | 998 | str[0] = 0; |
| 1147 | if (strlen(str) > 1) { | 999 | if (strlen(str) > 1) { |
| 1148 | return (++str); | 1000 | return (++str); |
| 1149 | } else { | ||
| 1150 | return NULL; | ||
| 1151 | } | 1001 | } |
| 1002 | return NULL; | ||
| 1152 | } | 1003 | } |
| 1153 | if ((str = strstr(str, ",")) && strlen(str) > 1) { | 1004 | if ((str = strstr(str, ",")) && strlen(str) > 1) { |
| 1154 | str[0] = 0; | 1005 | str[0] = 0; |
| @@ -1157,41 +1008,7 @@ static char *nextarg(char *str) { | |||
| 1157 | return NULL; | 1008 | return NULL; |
| 1158 | } | 1009 | } |
| 1159 | 1010 | ||
| 1160 | /* multiply result (values 0 < n < 1 work as divider) */ | 1011 | void print_help(void) { |
| 1161 | static char *multiply(char *str) { | ||
| 1162 | if (multiplier == 1) | ||
| 1163 | return (str); | ||
| 1164 | |||
| 1165 | if (verbose > 2) | ||
| 1166 | printf(" multiply input: %s\n", str); | ||
| 1167 | |||
| 1168 | char *endptr; | ||
| 1169 | double val = strtod(str, &endptr); | ||
| 1170 | if ((val == 0.0) && (endptr == str)) { | ||
| 1171 | die(STATE_UNKNOWN, _("multiplier set (%.1f), but input is not a number: %s"), multiplier, str); | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | if (verbose > 2) | ||
| 1175 | printf(" multiply extracted double: %f\n", val); | ||
| 1176 | |||
| 1177 | val *= multiplier; | ||
| 1178 | char *conv = "%f"; | ||
| 1179 | if (fmtstr_set) { | ||
| 1180 | conv = fmtstr; | ||
| 1181 | } | ||
| 1182 | if (val == (int)val) { | ||
| 1183 | snprintf(buffer, DEFAULT_BUFFER_SIZE, "%.0f", val); | ||
| 1184 | } else { | ||
| 1185 | if (verbose > 2) | ||
| 1186 | printf(" multiply using format: %s\n", conv); | ||
| 1187 | snprintf(buffer, DEFAULT_BUFFER_SIZE, conv, val); | ||
| 1188 | } | ||
| 1189 | if (verbose > 2) | ||
| 1190 | printf(" multiply result: %s\n", buffer); | ||
| 1191 | return buffer; | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | static void print_help(void) { | ||
| 1195 | print_revision(progname, NP_VERSION); | 1012 | print_revision(progname, NP_VERSION); |
| 1196 | 1013 | ||
| 1197 | printf(COPYRIGHT, copyright, email); | 1014 | printf(COPYRIGHT, copyright, email); |
| @@ -1204,8 +1021,6 @@ static void print_help(void) { | |||
| 1204 | 1021 | ||
| 1205 | printf(UT_HELP_VRSN); | 1022 | printf(UT_HELP_VRSN); |
| 1206 | printf(UT_EXTRA_OPTS); | 1023 | printf(UT_EXTRA_OPTS); |
| 1207 | printf(UT_IPv46); | ||
| 1208 | |||
| 1209 | printf(UT_HOST_PORT, 'p', DEFAULT_PORT); | 1024 | printf(UT_HOST_PORT, 'p', DEFAULT_PORT); |
| 1210 | 1025 | ||
| 1211 | /* SNMP and Authentication Protocol */ | 1026 | /* SNMP and Authentication Protocol */ |
| @@ -1217,13 +1032,15 @@ static void print_help(void) { | |||
| 1217 | printf(" %s\n", _("SNMPv3 context")); | 1032 | printf(" %s\n", _("SNMPv3 context")); |
| 1218 | printf(" %s\n", "-L, --seclevel=[noAuthNoPriv|authNoPriv|authPriv]"); | 1033 | printf(" %s\n", "-L, --seclevel=[noAuthNoPriv|authNoPriv|authPriv]"); |
| 1219 | printf(" %s\n", _("SNMPv3 securityLevel")); | 1034 | printf(" %s\n", _("SNMPv3 securityLevel")); |
| 1220 | printf(" %s\n", "-a, --authproto=AUTHENTICATION_PROTOCOL"); | 1035 | printf(" %s\n", "-a, --authproto=[MD5|SHA]"); |
| 1221 | printf(" %s\n", | 1036 | printf(" %s\n", _("SNMPv3 auth proto")); |
| 1222 | _("SNMPv3 authentication protocol (default MD5), available options depend on the specific version of the net-snmp tools")); | 1037 | #ifdef HAVE_USM_DES_PRIV_PROTOCOL |
| 1223 | printf(" %s\n", _("if < 5.8 SHA (1) and MD5 should be available, if >= 5.8 additionally SHA-224, SHA-256, SHA-384 and SHA-512")); | 1038 | printf(" %s\n", "-x, --privproto=[DES|AES]"); |
| 1224 | printf(" %s\n", "-x, --privproto=PRIVACY_PROTOCOL"); | 1039 | printf(" %s\n", _("SNMPv3 priv proto (default DES)")); |
| 1225 | printf(" %s\n", _("SNMPv3 privacy protocol (default DES), available options depend on the specific version of the net-snmp tools")); | 1040 | #else |
| 1226 | printf(" %s\n", _("if < 5.8 DES and AES should be available, if >= 5.8 additionally AES-192 and AES-256")); | 1041 | printf(" %s\n", "-x, --privproto=[AES]"); |
| 1042 | printf(" %s\n", _("SNMPv3 priv proto (default AES)")); | ||
| 1043 | #endif | ||
| 1227 | 1044 | ||
| 1228 | /* Authentication Tokens*/ | 1045 | /* Authentication Tokens*/ |
| 1229 | printf(" %s\n", "-C, --community=STRING"); | 1046 | printf(" %s\n", "-C, --community=STRING"); |
| @@ -1235,15 +1052,18 @@ static void print_help(void) { | |||
| 1235 | printf(" %s\n", _("SNMPv3 authentication password")); | 1052 | printf(" %s\n", _("SNMPv3 authentication password")); |
| 1236 | printf(" %s\n", "-X, --privpasswd=PASSWORD"); | 1053 | printf(" %s\n", "-X, --privpasswd=PASSWORD"); |
| 1237 | printf(" %s\n", _("SNMPv3 privacy password")); | 1054 | printf(" %s\n", _("SNMPv3 privacy password")); |
| 1055 | printf(" %s\n", "--connection-prefix"); | ||
| 1056 | printf(" Connection prefix, may be one of udp, udp6, tcp, unix, ipx, udp6, udpv6, udpipv6, " | ||
| 1057 | "tcp6, tcpv6, tcpipv6, tls, dtls - " | ||
| 1058 | "default is \"udp\"\n"); | ||
| 1238 | 1059 | ||
| 1239 | /* OID Stuff */ | 1060 | /* OID Stuff */ |
| 1240 | printf(" %s\n", "-o, --oid=OID(s)"); | 1061 | printf(" %s\n", "-o, --oid=OID(s)"); |
| 1241 | printf(" %s\n", _("Object identifier(s) or SNMP variables whose value you wish to query")); | 1062 | printf(" %s\n", _("Object identifier(s) or SNMP variables whose value you wish to query")); |
| 1242 | printf(" %s\n", "-m, --miblist=STRING"); | 1063 | printf(" %s\n", "-m, --miblist=STRING"); |
| 1243 | printf(" %s\n", _("List of MIBS to be loaded (default = none if using numeric OIDs or 'ALL'")); | 1064 | printf(" %s\n", |
| 1065 | _("List of MIBS to be loaded (default = none if using numeric OIDs or 'ALL'")); | ||
| 1244 | printf(" %s\n", _("for symbolic OIDs.)")); | 1066 | printf(" %s\n", _("for symbolic OIDs.)")); |
| 1245 | printf(" %s\n", "-d, --delimiter=STRING"); | ||
| 1246 | printf(" %s \"%s\"\n", _("Delimiter to use when parsing returned data. Default is"), DEFAULT_DELIMITER); | ||
| 1247 | printf(" %s\n", _("Any data on the right hand side of the delimiter is considered")); | 1067 | printf(" %s\n", _("Any data on the right hand side of the delimiter is considered")); |
| 1248 | printf(" %s\n", _("to be the data that should be used in the evaluation.")); | 1068 | printf(" %s\n", _("to be the data that should be used in the evaluation.")); |
| 1249 | printf(" %s\n", "-z, --nulloid=#"); | 1069 | printf(" %s\n", "-z, --nulloid=#"); |
| @@ -1260,10 +1080,6 @@ static void print_help(void) { | |||
| 1260 | printf(" %s\n", _("Warning threshold range(s)")); | 1080 | printf(" %s\n", _("Warning threshold range(s)")); |
| 1261 | printf(" %s\n", "-c, --critical=THRESHOLD(s)"); | 1081 | printf(" %s\n", "-c, --critical=THRESHOLD(s)"); |
| 1262 | printf(" %s\n", _("Critical threshold range(s)")); | 1082 | printf(" %s\n", _("Critical threshold range(s)")); |
| 1263 | printf(" %s\n", "--rate"); | ||
| 1264 | printf(" %s\n", _("Enable rate calculation. See 'Rate Calculation' below")); | ||
| 1265 | printf(" %s\n", "--rate-multiplier"); | ||
| 1266 | printf(" %s\n", _("Converts rate per second. For example, set to 60 to convert to per minute")); | ||
| 1267 | printf(" %s\n", "--offset=OFFSET"); | 1083 | printf(" %s\n", "--offset=OFFSET"); |
| 1268 | printf(" %s\n", _("Add/subtract the specified OFFSET to numeric sensor data")); | 1084 | printf(" %s\n", _("Add/subtract the specified OFFSET to numeric sensor data")); |
| 1269 | 1085 | ||
| @@ -1271,9 +1087,11 @@ static void print_help(void) { | |||
| 1271 | printf(" %s\n", "-s, --string=STRING"); | 1087 | printf(" %s\n", "-s, --string=STRING"); |
| 1272 | printf(" %s\n", _("Return OK state (for that OID) if STRING is an exact match")); | 1088 | printf(" %s\n", _("Return OK state (for that OID) if STRING is an exact match")); |
| 1273 | printf(" %s\n", "-r, --ereg=REGEX"); | 1089 | printf(" %s\n", "-r, --ereg=REGEX"); |
| 1274 | printf(" %s\n", _("Return OK state (for that OID) if extended regular expression REGEX matches")); | 1090 | printf(" %s\n", |
| 1091 | _("Return OK state (for that OID) if extended regular expression REGEX matches")); | ||
| 1275 | printf(" %s\n", "-R, --eregi=REGEX"); | 1092 | printf(" %s\n", "-R, --eregi=REGEX"); |
| 1276 | printf(" %s\n", _("Return OK state (for that OID) if case-insensitive extended REGEX matches")); | 1093 | printf(" %s\n", |
| 1094 | _("Return OK state (for that OID) if case-insensitive extended REGEX matches")); | ||
| 1277 | printf(" %s\n", "--invert-search"); | 1095 | printf(" %s\n", "--invert-search"); |
| 1278 | printf(" %s\n", _("Invert search result (CRITICAL if found)")); | 1096 | printf(" %s\n", _("Invert search result (CRITICAL if found)")); |
| 1279 | 1097 | ||
| @@ -1282,53 +1100,46 @@ static void print_help(void) { | |||
| 1282 | printf(" %s\n", _("Prefix label for output from plugin")); | 1100 | printf(" %s\n", _("Prefix label for output from plugin")); |
| 1283 | printf(" %s\n", "-u, --units=STRING"); | 1101 | printf(" %s\n", "-u, --units=STRING"); |
| 1284 | printf(" %s\n", _("Units label(s) for output data (e.g., 'sec.').")); | 1102 | printf(" %s\n", _("Units label(s) for output data (e.g., 'sec.').")); |
| 1285 | printf(" %s\n", "-D, --output-delimiter=STRING"); | ||
| 1286 | printf(" %s\n", _("Separates output on multiple OID requests")); | ||
| 1287 | printf(" %s\n", "-M, --multiplier=FLOAT"); | 1103 | printf(" %s\n", "-M, --multiplier=FLOAT"); |
| 1288 | printf(" %s\n", _("Multiplies current value, 0 < n < 1 works as divider, defaults to 1")); | 1104 | printf(" %s\n", _("Multiplies current value, 0 < n < 1 works as divider, defaults to 1")); |
| 1289 | printf(" %s\n", "-f, --fmtstr=STRING"); | 1105 | printf(UT_OUTPUT_FORMAT); |
| 1290 | printf(" %s\n", _("C-style format string for float values (see option -M)")); | ||
| 1291 | 1106 | ||
| 1292 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 1107 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 1293 | printf(" %s\n", _("NOTE the final timeout value is calculated using this formula: timeout_interval * retries + 5")); | 1108 | printf(" %s\n", _("NOTE the final timeout value is calculated using this formula: " |
| 1109 | "timeout_interval * retries + 5")); | ||
| 1294 | printf(" %s\n", "-e, --retries=INTEGER"); | 1110 | printf(" %s\n", "-e, --retries=INTEGER"); |
| 1295 | printf(" %s%i\n", _("Number of retries to be used in the requests, default: "), DEFAULT_RETRIES); | 1111 | printf(" %s%i\n", _("Number of retries to be used in the requests, default: "), |
| 1112 | DEFAULT_RETRIES); | ||
| 1296 | 1113 | ||
| 1297 | printf(" %s\n", "-O, --perf-oids"); | 1114 | printf(" %s\n", "-O, --perf-oids"); |
| 1298 | printf(" %s\n", _("Label performance data with OIDs instead of --label's")); | 1115 | printf(" %s\n", _("Label performance data with OIDs instead of --label's")); |
| 1299 | 1116 | ||
| 1300 | printf(" %s\n", "--ignore-mib-parsing-errors"); | 1117 | printf(" %s\n", "--ignore-mib-parsing-errors"); |
| 1301 | printf(" %s\n", _("Tell snmpget to not print errors encountered when parsing MIB files")); | 1118 | printf(" %s\n", _("Do to not print errors encountered when parsing MIB files")); |
| 1302 | 1119 | ||
| 1303 | printf(UT_VERBOSE); | 1120 | printf(UT_VERBOSE); |
| 1304 | 1121 | ||
| 1305 | printf("\n"); | 1122 | printf("\n"); |
| 1306 | printf("%s\n", _("This plugin uses the 'snmpget' command included with the NET-SNMP package.")); | 1123 | printf("%s\n", _("This plugin relies (links against) on the NET-SNMP libraries.")); |
| 1307 | printf("%s\n", _("if you don't have the package installed, you will need to download it from")); | 1124 | printf("%s\n", |
| 1125 | _("if you don't have the libraries installed, you will need to download them from")); | ||
| 1308 | printf("%s\n", _("http://net-snmp.sourceforge.net before you can use this plugin.")); | 1126 | printf("%s\n", _("http://net-snmp.sourceforge.net before you can use this plugin.")); |
| 1309 | 1127 | ||
| 1310 | printf("\n"); | 1128 | printf("\n"); |
| 1311 | printf("%s\n", _("Notes:")); | 1129 | printf("%s\n", _("Notes:")); |
| 1312 | printf(" %s\n", _("- Multiple OIDs (and labels) may be indicated by a comma or space-delimited ")); | 1130 | printf(" %s\n", |
| 1131 | _("- Multiple OIDs (and labels) may be indicated by a comma or space-delimited ")); | ||
| 1313 | printf(" %s\n", _("list (lists with internal spaces must be quoted).")); | 1132 | printf(" %s\n", _("list (lists with internal spaces must be quoted).")); |
| 1314 | 1133 | ||
| 1315 | printf(" -%s", UT_THRESHOLDS_NOTES); | 1134 | printf(" -%s", UT_THRESHOLDS_NOTES); |
| 1316 | 1135 | ||
| 1317 | printf(" %s\n", _("- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'")); | 1136 | printf(" %s\n", |
| 1137 | _("- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'")); | ||
| 1318 | printf(" %s\n", _("- Note that only one string and one regex may be checked at present")); | 1138 | printf(" %s\n", _("- Note that only one string and one regex may be checked at present")); |
| 1319 | printf(" %s\n", _("- All evaluation methods other than PR, STR, and SUBSTR expect that the value")); | 1139 | printf(" %s\n", |
| 1140 | _("- All evaluation methods other than PR, STR, and SUBSTR expect that the value")); | ||
| 1320 | printf(" %s\n", _("returned from the SNMP query is an unsigned integer.")); | 1141 | printf(" %s\n", _("returned from the SNMP query is an unsigned integer.")); |
| 1321 | 1142 | ||
| 1322 | printf("\n"); | ||
| 1323 | printf("%s\n", _("Rate Calculation:")); | ||
| 1324 | printf(" %s\n", _("In many places, SNMP returns counters that are only meaningful when")); | ||
| 1325 | printf(" %s\n", _("calculating the counter difference since the last check. check_snmp")); | ||
| 1326 | printf(" %s\n", _("saves the last state information in a file so that the rate per second")); | ||
| 1327 | printf(" %s\n", _("can be calculated. Use the --rate option to save state information.")); | ||
| 1328 | printf(" %s\n", _("On the first run, there will be no prior state - this will return with OK.")); | ||
| 1329 | printf(" %s\n", _("The state is uniquely determined by the arguments to the plugin, so")); | ||
| 1330 | printf(" %s\n", _("changing the arguments will create a new state file.")); | ||
| 1331 | |||
| 1332 | printf(UT_SUPPORT); | 1143 | printf(UT_SUPPORT); |
| 1333 | } | 1144 | } |
| 1334 | 1145 | ||
| @@ -1339,5 +1150,5 @@ void print_usage(void) { | |||
| 1339 | printf("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n"); | 1150 | printf("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n"); |
| 1340 | printf("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n"); | 1151 | printf("[-m miblist] [-P snmp version] [-N context] [-L seclevel] [-U secname]\n"); |
| 1341 | printf("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n"); | 1152 | printf("[-a authproto] [-A authpasswd] [-x privproto] [-X privpasswd] [-4|6]\n"); |
| 1342 | printf("[-M multiplier [-f format]]\n"); | 1153 | printf("[-M multiplier]\n"); |
| 1343 | } | 1154 | } |
diff --git a/plugins/check_snmp.d/check_snmp_helpers.c b/plugins/check_snmp.d/check_snmp_helpers.c new file mode 100644 index 00000000..f506537a --- /dev/null +++ b/plugins/check_snmp.d/check_snmp_helpers.c | |||
| @@ -0,0 +1,936 @@ | |||
| 1 | #include "./check_snmp_helpers.h" | ||
| 2 | #include <string.h> | ||
| 3 | #include "../../lib/utils_base.h" | ||
| 4 | #include "config.h" | ||
| 5 | #include <assert.h> | ||
| 6 | #include "../utils.h" | ||
| 7 | #include "output.h" | ||
| 8 | #include "states.h" | ||
| 9 | #include <sys/stat.h> | ||
| 10 | #include <ctype.h> | ||
| 11 | |||
| 12 | extern int verbose; | ||
| 13 | |||
| 14 | check_snmp_test_unit check_snmp_test_unit_init() { | ||
| 15 | check_snmp_test_unit tmp = { | ||
| 16 | .threshold = mp_thresholds_init(), | ||
| 17 | }; | ||
| 18 | return tmp; | ||
| 19 | } | ||
| 20 | |||
| 21 | int check_snmp_set_thresholds(const char *threshold_string, check_snmp_test_unit test_units[], | ||
| 22 | size_t max_test_units, bool is_critical) { | ||
| 23 | |||
| 24 | if (threshold_string == NULL || strlen(threshold_string) == 0) { | ||
| 25 | // No input, do nothing | ||
| 26 | return 0; | ||
| 27 | } | ||
| 28 | |||
| 29 | if (strchr(threshold_string, ',') != NULL) { | ||
| 30 | // Got a comma in the string, should be multiple values | ||
| 31 | size_t tu_index = 0; | ||
| 32 | |||
| 33 | while (threshold_string[0] == ',') { | ||
| 34 | // got commas at the beginning, so skip some values | ||
| 35 | tu_index++; | ||
| 36 | threshold_string++; | ||
| 37 | } | ||
| 38 | |||
| 39 | for (char *ptr = strtok(threshold_string, ", "); ptr != NULL; | ||
| 40 | ptr = strtok(NULL, ", "), tu_index++) { | ||
| 41 | |||
| 42 | if (tu_index > max_test_units) { | ||
| 43 | // More thresholds then values, just ignore them | ||
| 44 | return 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | // edge case: maybe we got `,,` to skip a value | ||
| 48 | if (strlen(ptr) == 0) { | ||
| 49 | // no threshold given, do not set it then | ||
| 50 | continue; | ||
| 51 | } | ||
| 52 | |||
| 53 | mp_range_parsed tmp = mp_parse_range_string(ptr); | ||
| 54 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 55 | die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", ptr); | ||
| 56 | } | ||
| 57 | |||
| 58 | if (is_critical) { | ||
| 59 | test_units[tu_index].threshold.critical = tmp.range; | ||
| 60 | test_units[tu_index].threshold.critical_is_set = true; | ||
| 61 | } else { | ||
| 62 | test_units[tu_index].threshold.warning = tmp.range; | ||
| 63 | test_units[tu_index].threshold.warning_is_set = true; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | } else { | ||
| 68 | // Single value | ||
| 69 | // only valid for the first test unit | ||
| 70 | mp_range_parsed tmp = mp_parse_range_string(threshold_string); | ||
| 71 | if (tmp.error != MP_PARSING_SUCCES) { | ||
| 72 | die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", threshold_string); | ||
| 73 | } | ||
| 74 | |||
| 75 | if (is_critical) { | ||
| 76 | test_units[0].threshold.critical = tmp.range; | ||
| 77 | test_units[0].threshold.critical_is_set = true; | ||
| 78 | } else { | ||
| 79 | test_units[0].threshold.warning = tmp.range; | ||
| 80 | test_units[0].threshold.warning_is_set = true; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | const int DEFAULT_PROTOCOL = SNMP_VERSION_1; | ||
| 88 | const char DEFAULT_OUTPUT_DELIMITER[] = " "; | ||
| 89 | |||
| 90 | const int RANDOM_STATE_DATA_LENGTH_PREDICTION = 8192; | ||
| 91 | |||
| 92 | check_snmp_config check_snmp_config_init() { | ||
| 93 | check_snmp_config tmp = { | ||
| 94 | .snmp_params = | ||
| 95 | { | ||
| 96 | .use_getnext = false, | ||
| 97 | |||
| 98 | .ignore_mib_parsing_errors = false, | ||
| 99 | .need_mibs = false, | ||
| 100 | |||
| 101 | .test_units = NULL, | ||
| 102 | .num_of_test_units = 0, | ||
| 103 | }, | ||
| 104 | |||
| 105 | .evaluation_params = | ||
| 106 | { | ||
| 107 | .nulloid_result = STATE_UNKNOWN, // state to return if no result for query | ||
| 108 | |||
| 109 | .invert_search = true, | ||
| 110 | .regex_cmp_value = {}, | ||
| 111 | .string_cmp_value = "", | ||
| 112 | |||
| 113 | .multiplier = 1.0, | ||
| 114 | .multiplier_set = false, | ||
| 115 | .offset = 0, | ||
| 116 | .offset_set = false, | ||
| 117 | |||
| 118 | .use_oid_as_perf_data_label = false, | ||
| 119 | |||
| 120 | .calculate_rate = false, | ||
| 121 | .rate_multiplier = 1, | ||
| 122 | }, | ||
| 123 | }; | ||
| 124 | |||
| 125 | snmp_sess_init(&tmp.snmp_params.snmp_session); | ||
| 126 | |||
| 127 | tmp.snmp_params.snmp_session.retries = DEFAULT_RETRIES; | ||
| 128 | tmp.snmp_params.snmp_session.version = DEFAULT_SNMP_VERSION; | ||
| 129 | tmp.snmp_params.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; | ||
| 130 | tmp.snmp_params.snmp_session.community = (unsigned char *)"public"; | ||
| 131 | tmp.snmp_params.snmp_session.community_len = strlen("public"); | ||
| 132 | return tmp; | ||
| 133 | } | ||
| 134 | |||
| 135 | snmp_responces do_snmp_query(check_snmp_config_snmp_parameters parameters) { | ||
| 136 | if (parameters.ignore_mib_parsing_errors) { | ||
| 137 | char *opt_toggle_res = snmp_mib_toggle_options("e"); | ||
| 138 | if (opt_toggle_res != NULL) { | ||
| 139 | die(STATE_UNKNOWN, "Unable to disable MIB parsing errors"); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | struct snmp_pdu *pdu = NULL; | ||
| 144 | if (parameters.use_getnext) { | ||
| 145 | pdu = snmp_pdu_create(SNMP_MSG_GETNEXT); | ||
| 146 | } else { | ||
| 147 | pdu = snmp_pdu_create(SNMP_MSG_GET); | ||
| 148 | } | ||
| 149 | |||
| 150 | for (size_t i = 0; i < parameters.num_of_test_units; i++) { | ||
| 151 | assert(parameters.test_units[i].oid != NULL); | ||
| 152 | if (verbose > 0) { | ||
| 153 | printf("OID %zu to parse: %s\n", i, parameters.test_units[i].oid); | ||
| 154 | } | ||
| 155 | |||
| 156 | oid tmp_OID[MAX_OID_LEN]; | ||
| 157 | size_t tmp_OID_len = MAX_OID_LEN; | ||
| 158 | if (snmp_parse_oid(parameters.test_units[i].oid, tmp_OID, &tmp_OID_len) != NULL) { | ||
| 159 | // success | ||
| 160 | snmp_add_null_var(pdu, tmp_OID, tmp_OID_len); | ||
| 161 | } else { | ||
| 162 | // failed | ||
| 163 | snmp_perror("Parsing failure"); | ||
| 164 | die(STATE_UNKNOWN, "Failed to parse OID\n"); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | const int timeout_safety_tolerance = 5; | ||
| 169 | alarm((timeout_interval * (unsigned int)parameters.snmp_session.retries) + | ||
| 170 | timeout_safety_tolerance); | ||
| 171 | |||
| 172 | struct snmp_session *active_session = snmp_open(¶meters.snmp_session); | ||
| 173 | if (active_session == NULL) { | ||
| 174 | int pcliberr = 0; | ||
| 175 | int psnmperr = 0; | ||
| 176 | char *pperrstring = NULL; | ||
| 177 | snmp_error(¶meters.snmp_session, &pcliberr, &psnmperr, &pperrstring); | ||
| 178 | die(STATE_UNKNOWN, "Failed to open SNMP session: %s\n", pperrstring); | ||
| 179 | } | ||
| 180 | |||
| 181 | struct snmp_pdu *response = NULL; | ||
| 182 | int snmp_query_status = snmp_synch_response(active_session, pdu, &response); | ||
| 183 | |||
| 184 | if (!(snmp_query_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR)) { | ||
| 185 | int pcliberr = 0; | ||
| 186 | int psnmperr = 0; | ||
| 187 | char *pperrstring = NULL; | ||
| 188 | snmp_error(active_session, &pcliberr, &psnmperr, &pperrstring); | ||
| 189 | |||
| 190 | if (psnmperr == SNMPERR_TIMEOUT) { | ||
| 191 | // We exit with critical here for some historical reason | ||
| 192 | die(STATE_CRITICAL, "SNMP query ran into a timeout\n"); | ||
| 193 | } | ||
| 194 | die(STATE_UNKNOWN, "SNMP query failed: %s\n", pperrstring); | ||
| 195 | } | ||
| 196 | |||
| 197 | snmp_close(active_session); | ||
| 198 | |||
| 199 | /* disable alarm again */ | ||
| 200 | alarm(0); | ||
| 201 | |||
| 202 | snmp_responces result = { | ||
| 203 | .errorcode = OK, | ||
| 204 | .response_values = calloc(parameters.num_of_test_units, sizeof(response_value)), | ||
| 205 | }; | ||
| 206 | |||
| 207 | if (result.response_values == NULL) { | ||
| 208 | result.errorcode = ERROR; | ||
| 209 | return result; | ||
| 210 | } | ||
| 211 | |||
| 212 | // We got the the query results, now process them | ||
| 213 | size_t loop_index = 0; | ||
| 214 | for (netsnmp_variable_list *vars = response->variables; vars; | ||
| 215 | vars = vars->next_variable, loop_index++) { | ||
| 216 | |||
| 217 | for (size_t jdx = 0; jdx < vars->name_length; jdx++) { | ||
| 218 | result.response_values[loop_index].oid[jdx] = vars->name[jdx]; | ||
| 219 | } | ||
| 220 | result.response_values[loop_index].oid_length = vars->name_length; | ||
| 221 | |||
| 222 | switch (vars->type) { | ||
| 223 | case ASN_OCTET_STR: { | ||
| 224 | result.response_values[loop_index].string_response = strdup((char *)vars->val.string); | ||
| 225 | result.response_values[loop_index].type = vars->type; | ||
| 226 | if (verbose) { | ||
| 227 | printf("Debug: Got a string as response: %s\n", vars->val.string); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | continue; | ||
| 231 | case ASN_OPAQUE: | ||
| 232 | if (verbose) { | ||
| 233 | printf("Debug: Got OPAQUE\n"); | ||
| 234 | } | ||
| 235 | break; | ||
| 236 | /* Numerical values */ | ||
| 237 | case ASN_COUNTER64: { | ||
| 238 | if (verbose) { | ||
| 239 | printf("Debug: Got counter64\n"); | ||
| 240 | } | ||
| 241 | struct counter64 tmp = *(vars->val.counter64); | ||
| 242 | uint64_t counter = (tmp.high << 32) + tmp.low; | ||
| 243 | result.response_values[loop_index].value.uIntVal = counter; | ||
| 244 | result.response_values[loop_index].type = vars->type; | ||
| 245 | } break; | ||
| 246 | case ASN_GAUGE: // same as ASN_UNSIGNED | ||
| 247 | case ASN_TIMETICKS: | ||
| 248 | case ASN_COUNTER: | ||
| 249 | case ASN_UINTEGER: { | ||
| 250 | if (verbose) { | ||
| 251 | printf("Debug: Got a Integer like\n"); | ||
| 252 | } | ||
| 253 | result.response_values[loop_index].value.uIntVal = (unsigned long)*(vars->val.integer); | ||
| 254 | result.response_values[loop_index].type = vars->type; | ||
| 255 | } break; | ||
| 256 | case ASN_INTEGER: { | ||
| 257 | if (verbose) { | ||
| 258 | printf("Debug: Got a Integer\n"); | ||
| 259 | } | ||
| 260 | result.response_values[loop_index].value.intVal = *(vars->val.integer); | ||
| 261 | result.response_values[loop_index].type = vars->type; | ||
| 262 | } break; | ||
| 263 | case ASN_FLOAT: { | ||
| 264 | if (verbose) { | ||
| 265 | printf("Debug: Got a float\n"); | ||
| 266 | } | ||
| 267 | result.response_values[loop_index].value.doubleVal = *(vars->val.floatVal); | ||
| 268 | result.response_values[loop_index].type = vars->type; | ||
| 269 | } break; | ||
| 270 | case ASN_DOUBLE: { | ||
| 271 | if (verbose) { | ||
| 272 | printf("Debug: Got a double\n"); | ||
| 273 | } | ||
| 274 | result.response_values[loop_index].value.doubleVal = *(vars->val.doubleVal); | ||
| 275 | result.response_values[loop_index].type = vars->type; | ||
| 276 | } break; | ||
| 277 | case ASN_IPADDRESS: | ||
| 278 | if (verbose) { | ||
| 279 | printf("Debug: Got an IP address\n"); | ||
| 280 | } | ||
| 281 | result.response_values[loop_index].type = vars->type; | ||
| 282 | |||
| 283 | // TODO: print address here, state always ok? or regex match? | ||
| 284 | break; | ||
| 285 | default: | ||
| 286 | if (verbose) { | ||
| 287 | printf("Debug: Got a unmatched result type: %hhu\n", vars->type); | ||
| 288 | } | ||
| 289 | // TODO: Error here? | ||
| 290 | break; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | |||
| 294 | return result; | ||
| 295 | } | ||
| 296 | |||
| 297 | check_snmp_evaluation evaluate_single_unit(response_value response, | ||
| 298 | check_snmp_evaluation_parameters eval_params, | ||
| 299 | check_snmp_test_unit test_unit, time_t query_timestamp, | ||
| 300 | check_snmp_state_entry prev_state, | ||
| 301 | bool have_previous_state) { | ||
| 302 | mp_subcheck sc_oid_test = mp_subcheck_init(); | ||
| 303 | |||
| 304 | if ((test_unit.label != NULL) && (strcmp(test_unit.label, "") != 0)) { | ||
| 305 | xasprintf(&sc_oid_test.output, "%s - ", test_unit.label); | ||
| 306 | } else { | ||
| 307 | sc_oid_test.output = strdup(""); | ||
| 308 | } | ||
| 309 | |||
| 310 | char oid_string[(MAX_OID_LEN * 2) + 1] = {}; | ||
| 311 | |||
| 312 | int oid_string_result = | ||
| 313 | snprint_objid(oid_string, (MAX_OID_LEN * 2) + 1, response.oid, response.oid_length); | ||
| 314 | if (oid_string_result <= 0) { | ||
| 315 | // TODO error here | ||
| 316 | die(STATE_UNKNOWN, "snprint_objid failed\n"); | ||
| 317 | } | ||
| 318 | |||
| 319 | xasprintf(&sc_oid_test.output, "%sOID: %s", sc_oid_test.output, oid_string); | ||
| 320 | sc_oid_test = mp_set_subcheck_default_state(sc_oid_test, STATE_OK); | ||
| 321 | |||
| 322 | if (verbose > 2) { | ||
| 323 | printf("Processing oid %s\n", oid_string); | ||
| 324 | } | ||
| 325 | |||
| 326 | bool got_a_numerical_value = false; | ||
| 327 | mp_perfdata_value pd_result_val = {0}; | ||
| 328 | |||
| 329 | check_snmp_state_entry result_state = { | ||
| 330 | .timestamp = query_timestamp, | ||
| 331 | .oid_length = response.oid_length, | ||
| 332 | .type = response.type, | ||
| 333 | }; | ||
| 334 | |||
| 335 | for (size_t i = 0; i < response.oid_length; i++) { | ||
| 336 | result_state.oid[i] = response.oid[i]; | ||
| 337 | } | ||
| 338 | |||
| 339 | if (have_previous_state) { | ||
| 340 | if (query_timestamp == prev_state.timestamp) { | ||
| 341 | // somehow we have the same timestamp again, that can't be good | ||
| 342 | sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_UNKNOWN); | ||
| 343 | xasprintf(&sc_oid_test.output, "Time duration between plugin calls is invalid"); | ||
| 344 | |||
| 345 | check_snmp_evaluation result = { | ||
| 346 | .sc = sc_oid_test, | ||
| 347 | .state = result_state, | ||
| 348 | }; | ||
| 349 | |||
| 350 | return result; | ||
| 351 | } | ||
| 352 | } | ||
| 353 | // compute rate time difference | ||
| 354 | double timeDiff = 0; | ||
| 355 | if (have_previous_state) { | ||
| 356 | if (verbose) { | ||
| 357 | printf("Previous timestamp: %s", ctime(&prev_state.timestamp)); | ||
| 358 | printf("Current timestamp: %s", ctime(&query_timestamp)); | ||
| 359 | } | ||
| 360 | timeDiff = difftime(query_timestamp, prev_state.timestamp) / eval_params.rate_multiplier; | ||
| 361 | } | ||
| 362 | |||
| 363 | mp_perfdata pd_num_val = {}; | ||
| 364 | |||
| 365 | switch (response.type) { | ||
| 366 | case ASN_OCTET_STR: { | ||
| 367 | char *tmp = response.string_response; | ||
| 368 | if (strchr(tmp, '"') != NULL) { | ||
| 369 | // got double quote in the string | ||
| 370 | if (strchr(tmp, '\'') != NULL) { | ||
| 371 | // got single quote in the string too | ||
| 372 | // dont quote that at all to avoid even more confusion | ||
| 373 | xasprintf(&sc_oid_test.output, "%s - Value: %s", sc_oid_test.output, tmp); | ||
| 374 | } else { | ||
| 375 | // quote with single quotes | ||
| 376 | xasprintf(&sc_oid_test.output, "%s - Value: '%s'", sc_oid_test.output, tmp); | ||
| 377 | } | ||
| 378 | } else { | ||
| 379 | // quote with double quotes | ||
| 380 | xasprintf(&sc_oid_test.output, "%s - Value: \"%s\"", sc_oid_test.output, tmp); | ||
| 381 | } | ||
| 382 | |||
| 383 | if (strlen(tmp) == 0) { | ||
| 384 | sc_oid_test = mp_set_subcheck_state(sc_oid_test, eval_params.nulloid_result); | ||
| 385 | } | ||
| 386 | |||
| 387 | // String matching test | ||
| 388 | if ((test_unit.eval_mthd.crit_string)) { | ||
| 389 | if (strcmp(tmp, eval_params.string_cmp_value)) { | ||
| 390 | sc_oid_test = mp_set_subcheck_state( | ||
| 391 | sc_oid_test, (eval_params.invert_search) ? STATE_CRITICAL : STATE_OK); | ||
| 392 | } else { | ||
| 393 | sc_oid_test = mp_set_subcheck_state( | ||
| 394 | sc_oid_test, (eval_params.invert_search) ? STATE_OK : STATE_CRITICAL); | ||
| 395 | } | ||
| 396 | } else if (test_unit.eval_mthd.crit_regex) { | ||
| 397 | const size_t nmatch = eval_params.regex_cmp_value.re_nsub + 1; | ||
| 398 | regmatch_t pmatch[nmatch]; | ||
| 399 | memset(pmatch, '\0', sizeof(regmatch_t) * nmatch); | ||
| 400 | |||
| 401 | int excode = regexec(&eval_params.regex_cmp_value, tmp, nmatch, pmatch, 0); | ||
| 402 | if (excode == 0) { | ||
| 403 | sc_oid_test = mp_set_subcheck_state( | ||
| 404 | sc_oid_test, (eval_params.invert_search) ? STATE_OK : STATE_CRITICAL); | ||
| 405 | } else if (excode != REG_NOMATCH) { | ||
| 406 | char errbuf[MAX_INPUT_BUFFER] = ""; | ||
| 407 | regerror(excode, &eval_params.regex_cmp_value, errbuf, MAX_INPUT_BUFFER); | ||
| 408 | printf(_("Execute Error: %s\n"), errbuf); | ||
| 409 | exit(STATE_CRITICAL); | ||
| 410 | } else { // REG_NOMATCH | ||
| 411 | sc_oid_test = mp_set_subcheck_state( | ||
| 412 | sc_oid_test, eval_params.invert_search ? STATE_CRITICAL : STATE_OK); | ||
| 413 | } | ||
| 414 | } | ||
| 415 | } break; | ||
| 416 | case ASN_COUNTER64: | ||
| 417 | got_a_numerical_value = true; | ||
| 418 | |||
| 419 | result_state.value.uIntVal = response.value.uIntVal; | ||
| 420 | result_state.type = response.type; | ||
| 421 | |||
| 422 | // TODO: perfdata unit counter | ||
| 423 | if (eval_params.calculate_rate && have_previous_state) { | ||
| 424 | if (prev_state.value.uIntVal > response.value.uIntVal) { | ||
| 425 | // overflow | ||
| 426 | unsigned long long tmp = | ||
| 427 | (UINT64_MAX - prev_state.value.uIntVal) + response.value.uIntVal; | ||
| 428 | |||
| 429 | tmp /= timeDiff; | ||
| 430 | pd_result_val = mp_create_pd_value(tmp); | ||
| 431 | } else { | ||
| 432 | pd_result_val = mp_create_pd_value( | ||
| 433 | (response.value.uIntVal - prev_state.value.uIntVal) / timeDiff); | ||
| 434 | } | ||
| 435 | } else { | ||
| 436 | // It's only a counter if we cont compute rate | ||
| 437 | pd_num_val.uom = "c"; | ||
| 438 | pd_result_val = mp_create_pd_value(response.value.uIntVal); | ||
| 439 | } | ||
| 440 | break; | ||
| 441 | case ASN_GAUGE: // same as ASN_UNSIGNED | ||
| 442 | case ASN_TIMETICKS: | ||
| 443 | case ASN_COUNTER: | ||
| 444 | case ASN_UINTEGER: { | ||
| 445 | got_a_numerical_value = true; | ||
| 446 | long long treated_value = (long long)response.value.uIntVal; | ||
| 447 | |||
| 448 | if (eval_params.multiplier_set || eval_params.offset_set) { | ||
| 449 | double processed = (double)response.value.uIntVal; | ||
| 450 | |||
| 451 | if (eval_params.offset_set) { | ||
| 452 | processed += eval_params.offset; | ||
| 453 | } | ||
| 454 | |||
| 455 | if (eval_params.multiplier_set) { | ||
| 456 | processed = processed * eval_params.multiplier; | ||
| 457 | } | ||
| 458 | |||
| 459 | treated_value = lround(processed); | ||
| 460 | } | ||
| 461 | |||
| 462 | result_state.value.intVal = treated_value; | ||
| 463 | |||
| 464 | if (eval_params.calculate_rate && have_previous_state) { | ||
| 465 | if (verbose > 2) { | ||
| 466 | printf("%s: Rate calculation (int/counter/gauge): prev: %lli\n", __FUNCTION__, | ||
| 467 | prev_state.value.intVal); | ||
| 468 | printf("%s: Rate calculation (int/counter/gauge): current: %lli\n", __FUNCTION__, | ||
| 469 | treated_value); | ||
| 470 | } | ||
| 471 | double rate = (treated_value - prev_state.value.intVal) / timeDiff; | ||
| 472 | pd_result_val = mp_create_pd_value(rate); | ||
| 473 | } else { | ||
| 474 | pd_result_val = mp_create_pd_value(treated_value); | ||
| 475 | |||
| 476 | if (response.type == ASN_COUNTER) { | ||
| 477 | pd_num_val.uom = "c"; | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | } break; | ||
| 482 | case ASN_INTEGER: { | ||
| 483 | if (eval_params.multiplier_set || eval_params.offset_set) { | ||
| 484 | double processed = (double)response.value.intVal; | ||
| 485 | |||
| 486 | if (eval_params.offset_set) { | ||
| 487 | processed += eval_params.offset; | ||
| 488 | } | ||
| 489 | |||
| 490 | if (eval_params.multiplier_set) { | ||
| 491 | processed *= eval_params.multiplier; | ||
| 492 | } | ||
| 493 | |||
| 494 | result_state.value.doubleVal = processed; | ||
| 495 | |||
| 496 | if (eval_params.calculate_rate && have_previous_state) { | ||
| 497 | pd_result_val = | ||
| 498 | mp_create_pd_value((processed - prev_state.value.doubleVal) / timeDiff); | ||
| 499 | } else { | ||
| 500 | pd_result_val = mp_create_pd_value(processed); | ||
| 501 | } | ||
| 502 | } else { | ||
| 503 | result_state.value.intVal = response.value.intVal; | ||
| 504 | |||
| 505 | if (eval_params.calculate_rate && have_previous_state) { | ||
| 506 | pd_result_val = mp_create_pd_value( | ||
| 507 | (response.value.intVal - prev_state.value.intVal) / timeDiff); | ||
| 508 | } else { | ||
| 509 | pd_result_val = mp_create_pd_value(response.value.intVal); | ||
| 510 | } | ||
| 511 | } | ||
| 512 | |||
| 513 | got_a_numerical_value = true; | ||
| 514 | } break; | ||
| 515 | case ASN_FLOAT: // fallthrough | ||
| 516 | case ASN_DOUBLE: { | ||
| 517 | got_a_numerical_value = true; | ||
| 518 | double tmp = response.value.doubleVal; | ||
| 519 | if (eval_params.offset_set) { | ||
| 520 | tmp += eval_params.offset; | ||
| 521 | } | ||
| 522 | |||
| 523 | if (eval_params.multiplier_set) { | ||
| 524 | tmp *= eval_params.multiplier; | ||
| 525 | } | ||
| 526 | |||
| 527 | if (eval_params.calculate_rate && have_previous_state) { | ||
| 528 | pd_result_val = mp_create_pd_value((tmp - prev_state.value.doubleVal) / timeDiff); | ||
| 529 | } else { | ||
| 530 | pd_result_val = mp_create_pd_value(tmp); | ||
| 531 | } | ||
| 532 | got_a_numerical_value = true; | ||
| 533 | |||
| 534 | result_state.value.doubleVal = tmp; | ||
| 535 | } break; | ||
| 536 | case ASN_IPADDRESS: | ||
| 537 | // TODO | ||
| 538 | break; | ||
| 539 | } | ||
| 540 | |||
| 541 | if (got_a_numerical_value) { | ||
| 542 | if (eval_params.use_oid_as_perf_data_label) { | ||
| 543 | // Use oid for perdata label | ||
| 544 | pd_num_val.label = strdup(oid_string); | ||
| 545 | // TODO strdup error checking | ||
| 546 | } else if (test_unit.label != NULL && strcmp(test_unit.label, "") != 0) { | ||
| 547 | pd_num_val.label = strdup(test_unit.label); | ||
| 548 | } else { | ||
| 549 | pd_num_val.label = strdup(test_unit.oid); | ||
| 550 | } | ||
| 551 | |||
| 552 | if (!(eval_params.calculate_rate && !have_previous_state)) { | ||
| 553 | // some kind of numerical value | ||
| 554 | if (test_unit.unit_value != NULL && strcmp(test_unit.unit_value, "") != 0) { | ||
| 555 | pd_num_val.uom = test_unit.unit_value; | ||
| 556 | } | ||
| 557 | |||
| 558 | pd_num_val.value = pd_result_val; | ||
| 559 | |||
| 560 | xasprintf(&sc_oid_test.output, "%s Value: %s", sc_oid_test.output, | ||
| 561 | pd_value_to_string(pd_result_val)); | ||
| 562 | |||
| 563 | if (test_unit.unit_value != NULL && strcmp(test_unit.unit_value, "") != 0) { | ||
| 564 | xasprintf(&sc_oid_test.output, "%s%s", sc_oid_test.output, test_unit.unit_value); | ||
| 565 | } | ||
| 566 | |||
| 567 | if (test_unit.threshold.warning_is_set || test_unit.threshold.critical_is_set) { | ||
| 568 | pd_num_val = mp_pd_set_thresholds(pd_num_val, test_unit.threshold); | ||
| 569 | mp_state_enum tmp_state = mp_get_pd_status(pd_num_val); | ||
| 570 | |||
| 571 | if (tmp_state == STATE_WARNING) { | ||
| 572 | sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_WARNING); | ||
| 573 | xasprintf(&sc_oid_test.output, "%s - number violates warning threshold", | ||
| 574 | sc_oid_test.output); | ||
| 575 | } else if (tmp_state == STATE_CRITICAL) { | ||
| 576 | sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_CRITICAL); | ||
| 577 | xasprintf(&sc_oid_test.output, "%s - number violates critical threshold", | ||
| 578 | sc_oid_test.output); | ||
| 579 | } | ||
| 580 | } | ||
| 581 | |||
| 582 | mp_add_perfdata_to_subcheck(&sc_oid_test, pd_num_val); | ||
| 583 | } else { | ||
| 584 | // should calculate rate, but there is no previous state, so first run | ||
| 585 | // exit with ok now | ||
| 586 | sc_oid_test = mp_set_subcheck_state(sc_oid_test, STATE_OK); | ||
| 587 | xasprintf(&sc_oid_test.output, "%s - No previous data to calculate rate - assume okay", | ||
| 588 | sc_oid_test.output); | ||
| 589 | } | ||
| 590 | } | ||
| 591 | |||
| 592 | check_snmp_evaluation result = { | ||
| 593 | .sc = sc_oid_test, | ||
| 594 | .state = result_state, | ||
| 595 | }; | ||
| 596 | |||
| 597 | return result; | ||
| 598 | } | ||
| 599 | |||
| 600 | char *_np_state_generate_key(int argc, char **argv); | ||
| 601 | |||
| 602 | /* | ||
| 603 | * If time=NULL, use current time. Create state file, with state format | ||
| 604 | * version, default text. Writes version, time, and data. Avoid locking | ||
| 605 | * problems - use mv to write and then swap. Possible loss of state data if | ||
| 606 | * two things writing to same key at same time. | ||
| 607 | * Will die with UNKNOWN if errors | ||
| 608 | */ | ||
| 609 | void np_state_write_string(state_key stateKey, time_t timestamp, char *stringToStore) { | ||
| 610 | time_t current_time; | ||
| 611 | if (timestamp == 0) { | ||
| 612 | time(¤t_time); | ||
| 613 | } else { | ||
| 614 | current_time = timestamp; | ||
| 615 | } | ||
| 616 | |||
| 617 | int result = 0; | ||
| 618 | |||
| 619 | /* If file doesn't currently exist, create directories */ | ||
| 620 | if (access(stateKey._filename, F_OK) != 0) { | ||
| 621 | char *directories = NULL; | ||
| 622 | result = asprintf(&directories, "%s", stateKey._filename); | ||
| 623 | if (result < 0) { | ||
| 624 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 625 | } | ||
| 626 | |||
| 627 | for (char *p = directories + 1; *p; p++) { | ||
| 628 | if (*p == '/') { | ||
| 629 | *p = '\0'; | ||
| 630 | if ((access(directories, F_OK) != 0) && (mkdir(directories, S_IRWXU) != 0)) { | ||
| 631 | /* Can't free this! Otherwise error message is wrong! */ | ||
| 632 | /* np_free(directories); */ | ||
| 633 | die(STATE_UNKNOWN, _("Cannot create directory: %s"), directories); | ||
| 634 | } | ||
| 635 | *p = '/'; | ||
| 636 | } | ||
| 637 | } | ||
| 638 | |||
| 639 | if (directories) { | ||
| 640 | free(directories); | ||
| 641 | } | ||
| 642 | } | ||
| 643 | |||
| 644 | char *temp_file = NULL; | ||
| 645 | result = asprintf(&temp_file, "%s.XXXXXX", stateKey._filename); | ||
| 646 | if (result < 0) { | ||
| 647 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 648 | } | ||
| 649 | |||
| 650 | int temp_file_desc = 0; | ||
| 651 | if ((temp_file_desc = mkstemp(temp_file)) == -1) { | ||
| 652 | if (temp_file) { | ||
| 653 | free(temp_file); | ||
| 654 | } | ||
| 655 | die(STATE_UNKNOWN, _("Cannot create temporary filename")); | ||
| 656 | } | ||
| 657 | |||
| 658 | FILE *temp_file_pointer = fdopen(temp_file_desc, "w"); | ||
| 659 | if (temp_file_pointer == NULL) { | ||
| 660 | close(temp_file_desc); | ||
| 661 | unlink(temp_file); | ||
| 662 | if (temp_file) { | ||
| 663 | free(temp_file); | ||
| 664 | } | ||
| 665 | die(STATE_UNKNOWN, _("Unable to open temporary state file")); | ||
| 666 | } | ||
| 667 | |||
| 668 | fprintf(temp_file_pointer, "# NP State file\n"); | ||
| 669 | fprintf(temp_file_pointer, "%d\n", NP_STATE_FORMAT_VERSION); | ||
| 670 | fprintf(temp_file_pointer, "%d\n", stateKey.data_version); | ||
| 671 | fprintf(temp_file_pointer, "%lu\n", current_time); | ||
| 672 | fprintf(temp_file_pointer, "%s\n", stringToStore); | ||
| 673 | |||
| 674 | fchmod(temp_file_desc, S_IRUSR | S_IWUSR | S_IRGRP); | ||
| 675 | |||
| 676 | fflush(temp_file_pointer); | ||
| 677 | |||
| 678 | result = fclose(temp_file_pointer); | ||
| 679 | |||
| 680 | fsync(temp_file_desc); | ||
| 681 | |||
| 682 | if (result != 0) { | ||
| 683 | unlink(temp_file); | ||
| 684 | if (temp_file) { | ||
| 685 | free(temp_file); | ||
| 686 | } | ||
| 687 | die(STATE_UNKNOWN, _("Error writing temp file")); | ||
| 688 | } | ||
| 689 | |||
| 690 | if (rename(temp_file, stateKey._filename) != 0) { | ||
| 691 | unlink(temp_file); | ||
| 692 | if (temp_file) { | ||
| 693 | free(temp_file); | ||
| 694 | } | ||
| 695 | die(STATE_UNKNOWN, _("Cannot rename state temp file")); | ||
| 696 | } | ||
| 697 | |||
| 698 | if (temp_file) { | ||
| 699 | free(temp_file); | ||
| 700 | } | ||
| 701 | } | ||
| 702 | |||
| 703 | /* | ||
| 704 | * Read the state file | ||
| 705 | */ | ||
| 706 | bool _np_state_read_file(FILE *state_file, state_key stateKey) { | ||
| 707 | time_t current_time; | ||
| 708 | time(¤t_time); | ||
| 709 | |||
| 710 | /* Note: This introduces a limit of 8192 bytes in the string data */ | ||
| 711 | char *line = (char *)calloc(1, 8192); | ||
| 712 | if (line == NULL) { | ||
| 713 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 714 | } | ||
| 715 | |||
| 716 | bool status = false; | ||
| 717 | enum { | ||
| 718 | STATE_FILE_VERSION, | ||
| 719 | STATE_DATA_VERSION, | ||
| 720 | STATE_DATA_TIME, | ||
| 721 | STATE_DATA_TEXT, | ||
| 722 | STATE_DATA_END | ||
| 723 | } expected = STATE_FILE_VERSION; | ||
| 724 | |||
| 725 | int failure = 0; | ||
| 726 | while (!failure && (fgets(line, 8192, state_file)) != NULL) { | ||
| 727 | size_t pos = strlen(line); | ||
| 728 | if (line[pos - 1] == '\n') { | ||
| 729 | line[pos - 1] = '\0'; | ||
| 730 | } | ||
| 731 | |||
| 732 | if (line[0] == '#') { | ||
| 733 | continue; | ||
| 734 | } | ||
| 735 | |||
| 736 | switch (expected) { | ||
| 737 | case STATE_FILE_VERSION: { | ||
| 738 | int i = atoi(line); | ||
| 739 | if (i != NP_STATE_FORMAT_VERSION) { | ||
| 740 | failure++; | ||
| 741 | } else { | ||
| 742 | expected = STATE_DATA_VERSION; | ||
| 743 | } | ||
| 744 | } break; | ||
| 745 | case STATE_DATA_VERSION: { | ||
| 746 | int i = atoi(line); | ||
| 747 | if (i != stateKey.data_version) { | ||
| 748 | failure++; | ||
| 749 | } else { | ||
| 750 | expected = STATE_DATA_TIME; | ||
| 751 | } | ||
| 752 | } break; | ||
| 753 | case STATE_DATA_TIME: { | ||
| 754 | /* If time > now, error */ | ||
| 755 | time_t data_time = strtoul(line, NULL, 10); | ||
| 756 | if (data_time > current_time) { | ||
| 757 | failure++; | ||
| 758 | } else { | ||
| 759 | stateKey.state_data->time = data_time; | ||
| 760 | expected = STATE_DATA_TEXT; | ||
| 761 | } | ||
| 762 | } break; | ||
| 763 | case STATE_DATA_TEXT: | ||
| 764 | stateKey.state_data->data = strdup(line); | ||
| 765 | if (stateKey.state_data->data == NULL) { | ||
| 766 | die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); | ||
| 767 | } | ||
| 768 | stateKey.state_data->length = strlen(line); | ||
| 769 | expected = STATE_DATA_END; | ||
| 770 | status = true; | ||
| 771 | break; | ||
| 772 | case STATE_DATA_END:; | ||
| 773 | } | ||
| 774 | } | ||
| 775 | |||
| 776 | if (line) { | ||
| 777 | free(line); | ||
| 778 | } | ||
| 779 | return status; | ||
| 780 | } | ||
| 781 | /* | ||
| 782 | * Will return NULL if no data is available (first run). If key currently | ||
| 783 | * exists, read data. If state file format version is not expected, return | ||
| 784 | * as if no data. Get state data version number and compares to expected. | ||
| 785 | * If numerically lower, then return as no previous state. die with UNKNOWN | ||
| 786 | * if exceptional error. | ||
| 787 | */ | ||
| 788 | state_data *np_state_read(state_key stateKey) { | ||
| 789 | /* Open file. If this fails, no previous state found */ | ||
| 790 | FILE *statefile = fopen(stateKey._filename, "r"); | ||
| 791 | state_data *this_state_data = (state_data *)calloc(1, sizeof(state_data)); | ||
| 792 | if (statefile != NULL) { | ||
| 793 | |||
| 794 | if (this_state_data == NULL) { | ||
| 795 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 796 | } | ||
| 797 | |||
| 798 | this_state_data->data = NULL; | ||
| 799 | stateKey.state_data = this_state_data; | ||
| 800 | |||
| 801 | if (_np_state_read_file(statefile, stateKey)) { | ||
| 802 | this_state_data->errorcode = OK; | ||
| 803 | } else { | ||
| 804 | this_state_data->errorcode = ERROR; | ||
| 805 | } | ||
| 806 | |||
| 807 | fclose(statefile); | ||
| 808 | } else { | ||
| 809 | // Failed to open state file | ||
| 810 | this_state_data->errorcode = ERROR; | ||
| 811 | } | ||
| 812 | |||
| 813 | return stateKey.state_data; | ||
| 814 | } | ||
| 815 | |||
| 816 | /* | ||
| 817 | * Internal function. Returns either: | ||
| 818 | * envvar NAGIOS_PLUGIN_STATE_DIRECTORY | ||
| 819 | * statically compiled shared state directory | ||
| 820 | */ | ||
| 821 | char *_np_state_calculate_location_prefix(void) { | ||
| 822 | char *env_dir; | ||
| 823 | |||
| 824 | /* Do not allow passing MP_STATE_PATH in setuid plugins | ||
| 825 | * for security reasons */ | ||
| 826 | if (!mp_suid()) { | ||
| 827 | env_dir = getenv("MP_STATE_PATH"); | ||
| 828 | if (env_dir && env_dir[0] != '\0') { | ||
| 829 | return env_dir; | ||
| 830 | } | ||
| 831 | /* This is the former ENV, for backward-compatibility */ | ||
| 832 | env_dir = getenv("NAGIOS_PLUGIN_STATE_DIRECTORY"); | ||
| 833 | if (env_dir && env_dir[0] != '\0') { | ||
| 834 | return env_dir; | ||
| 835 | } | ||
| 836 | } | ||
| 837 | |||
| 838 | return NP_STATE_DIR_PREFIX; | ||
| 839 | } | ||
| 840 | |||
| 841 | /* | ||
| 842 | * Initiatializer for state routines. | ||
| 843 | * Sets variables. Generates filename. Returns np_state_key. die with | ||
| 844 | * UNKNOWN if exception | ||
| 845 | */ | ||
| 846 | state_key np_enable_state(char *keyname, int expected_data_version, char *plugin_name, int argc, | ||
| 847 | char **argv) { | ||
| 848 | state_key *this_state = (state_key *)calloc(1, sizeof(state_key)); | ||
| 849 | if (this_state == NULL) { | ||
| 850 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 851 | } | ||
| 852 | |||
| 853 | char *temp_keyname = NULL; | ||
| 854 | if (keyname == NULL) { | ||
| 855 | temp_keyname = _np_state_generate_key(argc, argv); | ||
| 856 | } else { | ||
| 857 | temp_keyname = strdup(keyname); | ||
| 858 | if (temp_keyname == NULL) { | ||
| 859 | die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); | ||
| 860 | } | ||
| 861 | } | ||
| 862 | |||
| 863 | /* Die if invalid characters used for keyname */ | ||
| 864 | char *tmp_char = temp_keyname; | ||
| 865 | while (*tmp_char != '\0') { | ||
| 866 | if (!(isalnum(*tmp_char) || *tmp_char == '_')) { | ||
| 867 | die(STATE_UNKNOWN, _("Invalid character for keyname - only alphanumerics or '_'")); | ||
| 868 | } | ||
| 869 | tmp_char++; | ||
| 870 | } | ||
| 871 | this_state->name = temp_keyname; | ||
| 872 | this_state->plugin_name = plugin_name; | ||
| 873 | this_state->data_version = expected_data_version; | ||
| 874 | this_state->state_data = NULL; | ||
| 875 | |||
| 876 | /* Calculate filename */ | ||
| 877 | char *temp_filename = NULL; | ||
| 878 | int error = asprintf(&temp_filename, "%s/%lu/%s/%s", _np_state_calculate_location_prefix(), | ||
| 879 | (unsigned long)geteuid(), plugin_name, this_state->name); | ||
| 880 | if (error < 0) { | ||
| 881 | die(STATE_UNKNOWN, _("Cannot allocate memory: %s"), strerror(errno)); | ||
| 882 | } | ||
| 883 | |||
| 884 | this_state->_filename = temp_filename; | ||
| 885 | |||
| 886 | return *this_state; | ||
| 887 | } | ||
| 888 | |||
| 889 | /* | ||
| 890 | * Returns a string to use as a keyname, based on an md5 hash of argv, thus | ||
| 891 | * hopefully a unique key per service/plugin invocation. Use the extra-opts | ||
| 892 | * parse of argv, so that uniqueness in parameters are reflected there. | ||
| 893 | */ | ||
| 894 | char *_np_state_generate_key(int argc, char **argv) { | ||
| 895 | unsigned char result[256]; | ||
| 896 | |||
| 897 | #ifdef USE_OPENSSL | ||
| 898 | /* | ||
| 899 | * This code path is chosen if openssl is available (which should be the most common | ||
| 900 | * scenario). Alternatively, the gnulib implementation/ | ||
| 901 | * | ||
| 902 | */ | ||
| 903 | EVP_MD_CTX *ctx = EVP_MD_CTX_new(); | ||
| 904 | |||
| 905 | EVP_DigestInit(ctx, EVP_sha256()); | ||
| 906 | |||
| 907 | for (int i = 0; i < argc; i++) { | ||
| 908 | EVP_DigestUpdate(ctx, argv[i], strlen(argv[i])); | ||
| 909 | } | ||
| 910 | |||
| 911 | EVP_DigestFinal(ctx, result, NULL); | ||
| 912 | #else | ||
| 913 | |||
| 914 | struct sha256_ctx ctx; | ||
| 915 | |||
| 916 | for (int i = 0; i < this_monitoring_plugin->argc; i++) { | ||
| 917 | sha256_process_bytes(argv[i], strlen(argv[i]), &ctx); | ||
| 918 | } | ||
| 919 | |||
| 920 | sha256_finish_ctx(&ctx, result); | ||
| 921 | #endif // FOUNDOPENSSL | ||
| 922 | |||
| 923 | char keyname[41]; | ||
| 924 | for (int i = 0; i < 20; ++i) { | ||
| 925 | sprintf(&keyname[2 * i], "%02x", result[i]); | ||
| 926 | } | ||
| 927 | |||
| 928 | keyname[40] = '\0'; | ||
| 929 | |||
| 930 | char *keyname_copy = strdup(keyname); | ||
| 931 | if (keyname_copy == NULL) { | ||
| 932 | die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); | ||
| 933 | } | ||
| 934 | |||
| 935 | return keyname_copy; | ||
| 936 | } | ||
diff --git a/plugins/check_snmp.d/check_snmp_helpers.h b/plugins/check_snmp.d/check_snmp_helpers.h new file mode 100644 index 00000000..0f7780b1 --- /dev/null +++ b/plugins/check_snmp.d/check_snmp_helpers.h | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "./config.h" | ||
| 4 | #include <net-snmp/library/asn1.h> | ||
| 5 | |||
| 6 | check_snmp_test_unit check_snmp_test_unit_init(); | ||
| 7 | int check_snmp_set_thresholds(const char *, check_snmp_test_unit[], size_t, bool); | ||
| 8 | check_snmp_config check_snmp_config_init(); | ||
| 9 | |||
| 10 | typedef struct { | ||
| 11 | oid oid[MAX_OID_LEN]; | ||
| 12 | size_t oid_length; | ||
| 13 | unsigned char type; | ||
| 14 | union { | ||
| 15 | uint64_t uIntVal; | ||
| 16 | int64_t intVal; | ||
| 17 | double doubleVal; | ||
| 18 | } value; | ||
| 19 | char *string_response; | ||
| 20 | } response_value; | ||
| 21 | |||
| 22 | typedef struct { | ||
| 23 | int errorcode; | ||
| 24 | response_value *response_values; | ||
| 25 | } snmp_responces; | ||
| 26 | snmp_responces do_snmp_query(check_snmp_config_snmp_parameters parameters); | ||
| 27 | |||
| 28 | // state is similar to response, but only numerics and a timestamp | ||
| 29 | typedef struct { | ||
| 30 | time_t timestamp; | ||
| 31 | oid oid[MAX_OID_LEN]; | ||
| 32 | size_t oid_length; | ||
| 33 | unsigned char type; | ||
| 34 | union { | ||
| 35 | unsigned long long uIntVal; | ||
| 36 | long long intVal; | ||
| 37 | double doubleVal; | ||
| 38 | } value; | ||
| 39 | } check_snmp_state_entry; | ||
| 40 | |||
| 41 | typedef struct { | ||
| 42 | check_snmp_state_entry state; | ||
| 43 | mp_subcheck sc; | ||
| 44 | } check_snmp_evaluation; | ||
| 45 | check_snmp_evaluation evaluate_single_unit(response_value response, | ||
| 46 | check_snmp_evaluation_parameters eval_params, | ||
| 47 | check_snmp_test_unit test_unit, time_t query_timestamp, | ||
| 48 | check_snmp_state_entry prev_state, | ||
| 49 | bool have_previous_state); | ||
| 50 | |||
| 51 | #define NP_STATE_FORMAT_VERSION 1 | ||
| 52 | |||
| 53 | typedef struct state_data_struct { | ||
| 54 | time_t time; | ||
| 55 | void *data; | ||
| 56 | size_t length; /* Of binary data */ | ||
| 57 | int errorcode; | ||
| 58 | } state_data; | ||
| 59 | |||
| 60 | typedef struct state_key_struct { | ||
| 61 | char *name; | ||
| 62 | char *plugin_name; | ||
| 63 | int data_version; | ||
| 64 | char *_filename; | ||
| 65 | state_data *state_data; | ||
| 66 | } state_key; | ||
| 67 | |||
| 68 | state_data *np_state_read(state_key stateKey); | ||
| 69 | state_key np_enable_state(char *keyname, int expected_data_version, char *plugin_name, int argc, | ||
| 70 | char **argv); | ||
| 71 | void np_state_write_string(state_key stateKey, time_t timestamp, char *stringToStore); | ||
diff --git a/plugins/check_snmp.d/config.h b/plugins/check_snmp.d/config.h new file mode 100644 index 00000000..e7b6d1b3 --- /dev/null +++ b/plugins/check_snmp.d/config.h | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../lib/thresholds.h" | ||
| 4 | #include "../../lib/states.h" | ||
| 5 | #include <stdlib.h> | ||
| 6 | #include <stdbool.h> | ||
| 7 | #include <regex.h> | ||
| 8 | #include "../common.h" | ||
| 9 | |||
| 10 | // defines for snmp libs | ||
| 11 | #define u_char unsigned char | ||
| 12 | #define u_long unsigned long | ||
| 13 | #define u_short unsigned short | ||
| 14 | #define u_int unsigned int | ||
| 15 | |||
| 16 | #include <net-snmp/net-snmp-config.h> | ||
| 17 | #include <net-snmp/net-snmp-includes.h> | ||
| 18 | #include <net-snmp/library/snmp.h> | ||
| 19 | #include <net-snmp/session_api.h> | ||
| 20 | |||
| 21 | #define DEFAULT_PORT "161" | ||
| 22 | #define DEFAULT_RETRIES 5 | ||
| 23 | |||
| 24 | typedef struct eval_method { | ||
| 25 | bool crit_string; | ||
| 26 | bool crit_regex; | ||
| 27 | } eval_method; | ||
| 28 | |||
| 29 | typedef struct check_snmp_test_unit { | ||
| 30 | char *oid; | ||
| 31 | char *label; | ||
| 32 | char *unit_value; | ||
| 33 | eval_method eval_mthd; | ||
| 34 | mp_thresholds threshold; | ||
| 35 | } check_snmp_test_unit; | ||
| 36 | |||
| 37 | typedef struct { | ||
| 38 | struct snmp_session snmp_session; | ||
| 39 | // use getnet instead of get | ||
| 40 | bool use_getnext; | ||
| 41 | |||
| 42 | // TODO actually make these useful | ||
| 43 | bool ignore_mib_parsing_errors; | ||
| 44 | bool need_mibs; | ||
| 45 | |||
| 46 | check_snmp_test_unit *test_units; | ||
| 47 | size_t num_of_test_units; | ||
| 48 | } check_snmp_config_snmp_parameters; | ||
| 49 | |||
| 50 | typedef struct { | ||
| 51 | // State if an empty value is encountered | ||
| 52 | mp_state_enum nulloid_result; | ||
| 53 | |||
| 54 | // String evaluation stuff | ||
| 55 | bool invert_search; | ||
| 56 | regex_t regex_cmp_value; // regex to match query results against | ||
| 57 | char string_cmp_value[MAX_INPUT_BUFFER]; | ||
| 58 | |||
| 59 | // Modify data | ||
| 60 | double multiplier; | ||
| 61 | bool multiplier_set; | ||
| 62 | double offset; | ||
| 63 | bool offset_set; | ||
| 64 | |||
| 65 | // Modify output | ||
| 66 | bool use_oid_as_perf_data_label; | ||
| 67 | |||
| 68 | // activate rate calculation | ||
| 69 | bool calculate_rate; | ||
| 70 | unsigned int rate_multiplier; | ||
| 71 | } check_snmp_evaluation_parameters; | ||
| 72 | |||
| 73 | typedef struct check_snmp_config { | ||
| 74 | // SNMP session to use | ||
| 75 | check_snmp_config_snmp_parameters snmp_params; | ||
| 76 | |||
| 77 | check_snmp_evaluation_parameters evaluation_params; | ||
| 78 | |||
| 79 | mp_output_format output_format; | ||
| 80 | bool output_format_is_set; | ||
| 81 | } check_snmp_config; | ||
diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 9d0d7cde..f6c8d551 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c | |||
| @@ -57,7 +57,8 @@ static process_arguments_wrapper process_arguments(int /*argc*/, char ** /*argv* | |||
| 57 | static void print_help(void); | 57 | static void print_help(void); |
| 58 | void print_usage(void); | 58 | void print_usage(void); |
| 59 | 59 | ||
| 60 | static int ssh_connect(mp_check *overall, char *haddr, int hport, char *remote_version, char *remote_protocol); | 60 | static int ssh_connect(mp_check *overall, char *haddr, int hport, char *remote_version, |
| 61 | char *remote_protocol); | ||
| 61 | 62 | ||
| 62 | int main(int argc, char **argv) { | 63 | int main(int argc, char **argv) { |
| 63 | setlocale(LC_ALL, ""); | 64 | setlocale(LC_ALL, ""); |
| @@ -85,7 +86,8 @@ int main(int argc, char **argv) { | |||
| 85 | alarm(socket_timeout); | 86 | alarm(socket_timeout); |
| 86 | 87 | ||
| 87 | /* ssh_connect exits if error is found */ | 88 | /* ssh_connect exits if error is found */ |
| 88 | ssh_connect(&overall, config.server_name, config.port, config.remote_version, config.remote_protocol); | 89 | ssh_connect(&overall, config.server_name, config.port, config.remote_version, |
| 90 | config.remote_protocol); | ||
| 89 | 91 | ||
| 90 | alarm(0); | 92 | alarm(0); |
| 91 | 93 | ||
| @@ -96,19 +98,20 @@ int main(int argc, char **argv) { | |||
| 96 | 98 | ||
| 97 | /* process command-line arguments */ | 99 | /* process command-line arguments */ |
| 98 | process_arguments_wrapper process_arguments(int argc, char **argv) { | 100 | process_arguments_wrapper process_arguments(int argc, char **argv) { |
| 99 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, | 101 | static struct option longopts[] = { |
| 100 | {"version", no_argument, 0, 'V'}, | 102 | {"help", no_argument, 0, 'h'}, |
| 101 | {"host", required_argument, 0, 'H'}, /* backward compatibility */ | 103 | {"version", no_argument, 0, 'V'}, |
| 102 | {"hostname", required_argument, 0, 'H'}, | 104 | {"host", required_argument, 0, 'H'}, /* backward compatibility */ |
| 103 | {"port", required_argument, 0, 'p'}, | 105 | {"hostname", required_argument, 0, 'H'}, |
| 104 | {"use-ipv4", no_argument, 0, '4'}, | 106 | {"port", required_argument, 0, 'p'}, |
| 105 | {"use-ipv6", no_argument, 0, '6'}, | 107 | {"use-ipv4", no_argument, 0, '4'}, |
| 106 | {"timeout", required_argument, 0, 't'}, | 108 | {"use-ipv6", no_argument, 0, '6'}, |
| 107 | {"verbose", no_argument, 0, 'v'}, | 109 | {"timeout", required_argument, 0, 't'}, |
| 108 | {"remote-version", required_argument, 0, 'r'}, | 110 | {"verbose", no_argument, 0, 'v'}, |
| 109 | {"remote-protocol", required_argument, 0, 'P'}, | 111 | {"remote-version", required_argument, 0, 'r'}, |
| 110 | {"output-format", required_argument, 0, output_format_index}, | 112 | {"remote-protocol", required_argument, 0, 'P'}, |
| 111 | {0, 0, 0, 0}}; | 113 | {"output-format", required_argument, 0, output_format_index}, |
| 114 | {0, 0, 0, 0}}; | ||
| 112 | 115 | ||
| 113 | process_arguments_wrapper result = { | 116 | process_arguments_wrapper result = { |
| 114 | .config = check_ssh_config_init(), | 117 | .config = check_ssh_config_init(), |
| @@ -228,7 +231,8 @@ process_arguments_wrapper process_arguments(int argc, char **argv) { | |||
| 228 | * | 231 | * |
| 229 | *-----------------------------------------------------------------------*/ | 232 | *-----------------------------------------------------------------------*/ |
| 230 | 233 | ||
| 231 | int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_version, char *desired_remote_protocol) { | 234 | int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_version, |
| 235 | char *desired_remote_protocol) { | ||
| 232 | struct timeval tv; | 236 | struct timeval tv; |
| 233 | gettimeofday(&tv, NULL); | 237 | gettimeofday(&tv, NULL); |
| 234 | 238 | ||
| @@ -238,32 +242,34 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ | |||
| 238 | mp_subcheck connection_sc = mp_subcheck_init(); | 242 | mp_subcheck connection_sc = mp_subcheck_init(); |
| 239 | if (result != STATE_OK) { | 243 | if (result != STATE_OK) { |
| 240 | connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); | 244 | connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); |
| 241 | xasprintf(&connection_sc.output, "Failed to establish TCP connection to Host %s and Port %d", haddr, hport); | 245 | xasprintf(&connection_sc.output, |
| 246 | "Failed to establish TCP connection to Host %s and Port %d", haddr, hport); | ||
| 242 | mp_add_subcheck_to_check(overall, connection_sc); | 247 | mp_add_subcheck_to_check(overall, connection_sc); |
| 243 | return result; | 248 | return result; |
| 244 | } | 249 | } |
| 245 | 250 | ||
| 246 | char *output = (char *)calloc(BUFF_SZ + 1, sizeof(char)); | 251 | char *output = (char *)calloc(BUFF_SZ + 1, sizeof(char)); |
| 247 | char *buffer = NULL; | 252 | char *buffer = NULL; |
| 248 | size_t recv_ret = 0; | 253 | ssize_t recv_ret = 0; |
| 249 | char *version_control_string = NULL; | 254 | char *version_control_string = NULL; |
| 250 | size_t byte_offset = 0; | 255 | size_t byte_offset = 0; |
| 251 | while ((version_control_string == NULL) && | 256 | while ((version_control_string == NULL) && |
| 252 | (recv_ret = recv(socket, output + byte_offset, (unsigned long)(BUFF_SZ - byte_offset), 0) > 0)) { | 257 | (recv_ret = recv(socket, output + byte_offset, (unsigned long)(BUFF_SZ - byte_offset), |
| 258 | 0) > 0)) { | ||
| 253 | 259 | ||
| 254 | if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/ | 260 | if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/ |
| 255 | byte_offset = 0; | 261 | byte_offset = 0; |
| 256 | 262 | ||
| 257 | char *index = NULL; | 263 | char *index = NULL; |
| 258 | unsigned long len = 0; | ||
| 259 | while ((index = strchr(output + byte_offset, '\n')) != NULL) { | 264 | while ((index = strchr(output + byte_offset, '\n')) != NULL) { |
| 260 | /*Partition the buffer so that this line is a separate string, | 265 | /*Partition the buffer so that this line is a separate string, |
| 261 | * by replacing the newline with NUL*/ | 266 | * by replacing the newline with NUL*/ |
| 262 | output[(index - output)] = '\0'; | 267 | output[(index - output)] = '\0'; |
| 263 | len = strlen(output + byte_offset); | 268 | size_t len = strlen(output + byte_offset); |
| 264 | 269 | ||
| 265 | if ((len >= 4) && (strncmp(output + byte_offset, "SSH-", 4) == 0)) { | 270 | if ((len >= 4) && (strncmp(output + byte_offset, "SSH-", 4) == 0)) { |
| 266 | /*if the string starts with SSH-, this _should_ be a valid version control string*/ | 271 | /*if the string starts with SSH-, this _should_ be a valid version control |
| 272 | * string*/ | ||
| 267 | version_control_string = output + byte_offset; | 273 | version_control_string = output + byte_offset; |
| 268 | break; | 274 | break; |
| 269 | } | 275 | } |
| @@ -273,21 +279,23 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ | |||
| 273 | } | 279 | } |
| 274 | 280 | ||
| 275 | if (version_control_string == NULL) { | 281 | if (version_control_string == NULL) { |
| 276 | /* move unconsumed data to beginning of buffer, null rest */ | 282 | /* move unconsumed data to beginning of buffer */ |
| 277 | memmove((void *)output, (void *)(output + byte_offset + 1), BUFF_SZ - len + 1); | 283 | memmove((void *)output, (void *)(output + byte_offset), BUFF_SZ - byte_offset); |
| 278 | memset(output + byte_offset + 1, 0, BUFF_SZ - byte_offset + 1); | ||
| 279 | 284 | ||
| 280 | /*start reading from end of current line chunk on next recv*/ | 285 | /*start reading from end of current line chunk on next recv*/ |
| 281 | byte_offset = strlen(output); | 286 | byte_offset = strlen(output); |
| 287 | |||
| 288 | /* NUL the rest of the buffer */ | ||
| 289 | memset(output + byte_offset, 0, BUFF_SZ - byte_offset); | ||
| 282 | } | 290 | } |
| 283 | } else { | 291 | } else { |
| 284 | byte_offset += recv_ret; | 292 | byte_offset += (size_t)recv_ret; |
| 285 | } | 293 | } |
| 286 | } | 294 | } |
| 287 | 295 | ||
| 288 | if (recv_ret < 0) { | 296 | if (recv_ret < 0) { |
| 289 | connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); | 297 | connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); |
| 290 | xasprintf(&connection_sc.output, "%s", "SSH CRITICAL - %s", strerror(errno)); | 298 | xasprintf(&connection_sc.output, "%s - %s", "SSH CRITICAL - ", strerror(errno)); |
| 291 | mp_add_subcheck_to_check(overall, connection_sc); | 299 | mp_add_subcheck_to_check(overall, connection_sc); |
| 292 | return OK; | 300 | return OK; |
| 293 | } | 301 | } |
| @@ -333,7 +341,8 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ | |||
| 333 | * "1.x" (e.g., "1.5" or "1.3")." | 341 | * "1.x" (e.g., "1.5" or "1.3")." |
| 334 | * - RFC 4253:5 | 342 | * - RFC 4253:5 |
| 335 | */ | 343 | */ |
| 336 | char *ssh_server = ssh_proto + strspn(ssh_proto, "0123456789.") + 1; /* (+1 for the '-' separating protoversion from softwareversion) */ | 344 | char *ssh_server = ssh_proto + strspn(ssh_proto, "0123456789.") + |
| 345 | 1; /* (+1 for the '-' separating protoversion from softwareversion) */ | ||
| 337 | 346 | ||
| 338 | /* If there's a space in the version string, whatever's after the space is a comment | 347 | /* If there's a space in the version string, whatever's after the space is a comment |
| 339 | * (which is NOT part of the server name/version)*/ | 348 | * (which is NOT part of the server name/version)*/ |
| @@ -345,13 +354,15 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ | |||
| 345 | mp_subcheck protocol_validity_sc = mp_subcheck_init(); | 354 | mp_subcheck protocol_validity_sc = mp_subcheck_init(); |
| 346 | if (strlen(ssh_proto) == 0 || strlen(ssh_server) == 0) { | 355 | if (strlen(ssh_proto) == 0 || strlen(ssh_server) == 0) { |
| 347 | protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_CRITICAL); | 356 | protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_CRITICAL); |
| 348 | xasprintf(&protocol_validity_sc.output, "Invalid protocol version control string %s", version_control_string); | 357 | xasprintf(&protocol_validity_sc.output, "Invalid protocol version control string %s", |
| 358 | version_control_string); | ||
| 349 | mp_add_subcheck_to_check(overall, protocol_validity_sc); | 359 | mp_add_subcheck_to_check(overall, protocol_validity_sc); |
| 350 | return OK; | 360 | return OK; |
| 351 | } | 361 | } |
| 352 | 362 | ||
| 353 | protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_OK); | 363 | protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_OK); |
| 354 | xasprintf(&protocol_validity_sc.output, "Valid protocol version control string %s", version_control_string); | 364 | xasprintf(&protocol_validity_sc.output, "Valid protocol version control string %s", |
| 365 | version_control_string); | ||
| 355 | mp_add_subcheck_to_check(overall, protocol_validity_sc); | 366 | mp_add_subcheck_to_check(overall, protocol_validity_sc); |
| 356 | 367 | ||
| 357 | ssh_proto[strspn(ssh_proto, "0123456789. ")] = 0; | 368 | ssh_proto[strspn(ssh_proto, "0123456789. ")] = 0; |
| @@ -366,8 +377,8 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ | |||
| 366 | if (desired_remote_version && strcmp(desired_remote_version, ssh_server)) { | 377 | if (desired_remote_version && strcmp(desired_remote_version, ssh_server)) { |
| 367 | mp_subcheck remote_version_sc = mp_subcheck_init(); | 378 | mp_subcheck remote_version_sc = mp_subcheck_init(); |
| 368 | remote_version_sc = mp_set_subcheck_state(remote_version_sc, STATE_CRITICAL); | 379 | remote_version_sc = mp_set_subcheck_state(remote_version_sc, STATE_CRITICAL); |
| 369 | xasprintf(&remote_version_sc.output, _("%s (protocol %s) version mismatch, expected '%s'"), ssh_server, ssh_proto, | 380 | xasprintf(&remote_version_sc.output, _("%s (protocol %s) version mismatch, expected '%s'"), |
| 370 | desired_remote_version); | 381 | ssh_server, ssh_proto, desired_remote_version); |
| 371 | close(socket); | 382 | close(socket); |
| 372 | mp_add_subcheck_to_check(overall, remote_version_sc); | 383 | mp_add_subcheck_to_check(overall, remote_version_sc); |
| 373 | return OK; | 384 | return OK; |
| @@ -385,11 +396,13 @@ int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_ | |||
| 385 | 396 | ||
| 386 | if (desired_remote_protocol && strcmp(desired_remote_protocol, ssh_proto)) { | 397 | if (desired_remote_protocol && strcmp(desired_remote_protocol, ssh_proto)) { |
| 387 | protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_CRITICAL); | 398 | protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_CRITICAL); |
| 388 | xasprintf(&protocol_version_sc.output, _("%s (protocol %s) protocol version mismatch, expected '%s'"), ssh_server, ssh_proto, | 399 | xasprintf(&protocol_version_sc.output, |
| 389 | desired_remote_protocol); | 400 | _("%s (protocol %s) protocol version mismatch, expected '%s'"), ssh_server, |
| 401 | ssh_proto, desired_remote_protocol); | ||
| 390 | } else { | 402 | } else { |
| 391 | protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_OK); | 403 | protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_OK); |
| 392 | xasprintf(&protocol_version_sc.output, "SSH server version: %s (protocol version: %s)", ssh_server, ssh_proto); | 404 | xasprintf(&protocol_version_sc.output, "SSH server version: %s (protocol version: %s)", |
| 405 | ssh_server, ssh_proto); | ||
| 393 | } | 406 | } |
| 394 | 407 | ||
| 395 | mp_add_subcheck_to_check(overall, protocol_version_sc); | 408 | mp_add_subcheck_to_check(overall, protocol_version_sc); |
| @@ -422,7 +435,8 @@ void print_help(void) { | |||
| 422 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 435 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 423 | 436 | ||
| 424 | printf(" %s\n", "-r, --remote-version=STRING"); | 437 | printf(" %s\n", "-r, --remote-version=STRING"); |
| 425 | printf(" %s\n", _("Alert if string doesn't match expected server version (ex: OpenSSH_3.9p1)")); | 438 | printf(" %s\n", |
| 439 | _("Alert if string doesn't match expected server version (ex: OpenSSH_3.9p1)")); | ||
| 426 | 440 | ||
| 427 | printf(" %s\n", "-P, --remote-protocol=STRING"); | 441 | printf(" %s\n", "-P, --remote-protocol=STRING"); |
| 428 | printf(" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)")); | 442 | printf(" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)")); |
| @@ -435,5 +449,6 @@ void print_help(void) { | |||
| 435 | 449 | ||
| 436 | void print_usage(void) { | 450 | void print_usage(void) { |
| 437 | printf("%s\n", _("Usage:")); | 451 | printf("%s\n", _("Usage:")); |
| 438 | printf("%s [-4|-6] [-t <timeout>] [-r <remote version>] [-p <port>] --hostname <host>\n", progname); | 452 | printf("%s [-4|-6] [-t <timeout>] [-r <remote version>] [-p <port>] --hostname <host>\n", |
| 453 | progname); | ||
| 439 | } | 454 | } |
diff --git a/plugins/check_swap.c b/plugins/check_swap.c index cb95949a..dbf53a00 100644 --- a/plugins/check_swap.c +++ b/plugins/check_swap.c | |||
| @@ -90,6 +90,14 @@ int main(int argc, char **argv) { | |||
| 90 | exit(STATE_UNKNOWN); | 90 | exit(STATE_UNKNOWN); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | if (verbose) { | ||
| 94 | printf("Swap retrieval result:\n" | ||
| 95 | "\tFree: %llu\n" | ||
| 96 | "\tUsed: %llu\n" | ||
| 97 | "\tTotal: %llu\n", | ||
| 98 | data.metrics.free, data.metrics.used, data.metrics.total); | ||
| 99 | } | ||
| 100 | |||
| 93 | double percent_used; | 101 | double percent_used; |
| 94 | mp_check overall = mp_check_init(); | 102 | mp_check overall = mp_check_init(); |
| 95 | if (config.output_format_is_set) { | 103 | if (config.output_format_is_set) { |
| @@ -164,7 +172,8 @@ int main(int argc, char **argv) { | |||
| 164 | } | 172 | } |
| 165 | 173 | ||
| 166 | if (config.warn_is_set) { | 174 | if (config.warn_is_set) { |
| 167 | if ((config.warn.is_percentage && (percent_used >= (100 - (double)config.warn.value))) || config.warn.value >= data.metrics.free) { | 175 | if ((config.warn.is_percentage && (percent_used >= (100 - (double)config.warn.value))) || |
| 176 | config.warn.value >= data.metrics.free) { | ||
| 168 | sc1 = mp_set_subcheck_state(sc1, STATE_WARNING); | 177 | sc1 = mp_set_subcheck_state(sc1, STATE_WARNING); |
| 169 | } | 178 | } |
| 170 | } | 179 | } |
| @@ -174,13 +183,14 @@ int main(int argc, char **argv) { | |||
| 174 | } | 183 | } |
| 175 | 184 | ||
| 176 | if (config.crit_is_set) { | 185 | if (config.crit_is_set) { |
| 177 | if ((config.crit.is_percentage && (percent_used >= (100 - (double)config.crit.value))) || config.crit.value >= data.metrics.free) { | 186 | if ((config.crit.is_percentage && (percent_used >= (100 - (double)config.crit.value))) || |
| 187 | config.crit.value >= data.metrics.free) { | ||
| 178 | sc1 = mp_set_subcheck_state(sc1, STATE_CRITICAL); | 188 | sc1 = mp_set_subcheck_state(sc1, STATE_CRITICAL); |
| 179 | } | 189 | } |
| 180 | } | 190 | } |
| 181 | 191 | ||
| 182 | xasprintf(&sc1.output, _("%g%% free (%lluMiB out of %lluMiB)"), (100 - percent_used), data.metrics.free >> 20, | 192 | xasprintf(&sc1.output, _("%g%% free (%lluMiB out of %lluMiB)"), (100 - percent_used), |
| 183 | data.metrics.total >> 20); | 193 | data.metrics.free >> 20, data.metrics.total >> 20); |
| 184 | 194 | ||
| 185 | overall.summary = "Swap"; | 195 | overall.summary = "Swap"; |
| 186 | mp_add_subcheck_to_check(&overall, sc1); | 196 | mp_add_subcheck_to_check(&overall, sc1); |
| @@ -193,7 +203,9 @@ int check_swap(float free_swap_mb, float total_swap_mb, swap_config config) { | |||
| 193 | return config.no_swap_state; | 203 | return config.no_swap_state; |
| 194 | } | 204 | } |
| 195 | 205 | ||
| 196 | uint64_t free_swap = (uint64_t)(free_swap_mb * (1024 * 1024)); /* Convert back to bytes as warn and crit specified in bytes */ | 206 | uint64_t free_swap = |
| 207 | (uint64_t)(free_swap_mb * | ||
| 208 | (1024 * 1024)); /* Convert back to bytes as warn and crit specified in bytes */ | ||
| 197 | 209 | ||
| 198 | if (!config.crit.is_percentage && config.crit.value >= free_swap) { | 210 | if (!config.crit.is_percentage && config.crit.value >= free_swap) { |
| 199 | return STATE_CRITICAL; | 211 | return STATE_CRITICAL; |
| @@ -202,13 +214,16 @@ int check_swap(float free_swap_mb, float total_swap_mb, swap_config config) { | |||
| 202 | return STATE_WARNING; | 214 | return STATE_WARNING; |
| 203 | } | 215 | } |
| 204 | 216 | ||
| 205 | uint64_t usage_percentage = (uint64_t)((total_swap_mb - free_swap_mb) / total_swap_mb) * HUNDRED_PERCENT; | 217 | uint64_t usage_percentage = |
| 218 | (uint64_t)((total_swap_mb - free_swap_mb) / total_swap_mb) * HUNDRED_PERCENT; | ||
| 206 | 219 | ||
| 207 | if (config.crit.is_percentage && config.crit.value != 0 && usage_percentage >= (HUNDRED_PERCENT - config.crit.value)) { | 220 | if (config.crit.is_percentage && config.crit.value != 0 && |
| 221 | usage_percentage >= (HUNDRED_PERCENT - config.crit.value)) { | ||
| 208 | return STATE_CRITICAL; | 222 | return STATE_CRITICAL; |
| 209 | } | 223 | } |
| 210 | 224 | ||
| 211 | if (config.warn.is_percentage && config.warn.value != 0 && usage_percentage >= (HUNDRED_PERCENT - config.warn.value)) { | 225 | if (config.warn.is_percentage && config.warn.value != 0 && |
| 226 | usage_percentage >= (HUNDRED_PERCENT - config.warn.value)) { | ||
| 212 | return STATE_WARNING; | 227 | return STATE_WARNING; |
| 213 | } | 228 | } |
| 214 | 229 | ||
diff --git a/plugins/check_swap.d/check_swap.h b/plugins/check_swap.d/check_swap.h index 1000fc9e..8d3c7fcf 100644 --- a/plugins/check_swap.d/check_swap.h +++ b/plugins/check_swap.d/check_swap.h | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include "../common.h" | 3 | #include "../common.h" |
| 4 | #include "output.h" | 4 | #include "../../lib/output.h" |
| 5 | #include "../../lib/states.h" | ||
| 5 | 6 | ||
| 6 | #ifndef SWAP_CONVERSION | 7 | #ifndef SWAP_CONVERSION |
| 7 | # define SWAP_CONVERSION 1 | 8 | # define SWAP_CONVERSION 1 |
| @@ -26,7 +27,7 @@ typedef struct { | |||
| 26 | 27 | ||
| 27 | typedef struct { | 28 | typedef struct { |
| 28 | bool allswaps; | 29 | bool allswaps; |
| 29 | int no_swap_state; | 30 | mp_state_enum no_swap_state; |
| 30 | bool warn_is_set; | 31 | bool warn_is_set; |
| 31 | check_swap_threshold warn; | 32 | check_swap_threshold warn; |
| 32 | bool crit_is_set; | 33 | bool crit_is_set; |
| @@ -42,6 +43,7 @@ swap_config swap_config_init(void); | |||
| 42 | 43 | ||
| 43 | swap_result get_swap_data(swap_config config); | 44 | swap_result get_swap_data(swap_config config); |
| 44 | swap_result getSwapFromProcMeminfo(char path_to_proc_meminfo[]); | 45 | swap_result getSwapFromProcMeminfo(char path_to_proc_meminfo[]); |
| 45 | swap_result getSwapFromSwapCommand(swap_config config, const char swap_command[], const char swap_format[]); | 46 | swap_result getSwapFromSwapCommand(swap_config config, const char swap_command[], |
| 47 | const char swap_format[]); | ||
| 46 | swap_result getSwapFromSwapctl_BSD(swap_config config); | 48 | swap_result getSwapFromSwapctl_BSD(swap_config config); |
| 47 | swap_result getSwapFromSwap_SRV4(swap_config config); | 49 | swap_result getSwapFromSwap_SRV4(swap_config config); |
diff --git a/plugins/check_swap.d/swap.c b/plugins/check_swap.d/swap.c index 180d5037..58213a3c 100644 --- a/plugins/check_swap.d/swap.c +++ b/plugins/check_swap.d/swap.c | |||
| @@ -52,10 +52,10 @@ swap_result get_swap_data(swap_config config) { | |||
| 52 | } | 52 | } |
| 53 | # else // HAVE_SWAP | 53 | # else // HAVE_SWAP |
| 54 | # ifdef CHECK_SWAP_SWAPCTL_SVR4 | 54 | # ifdef CHECK_SWAP_SWAPCTL_SVR4 |
| 55 | return getSwapFromSwapctl_SRV4(); | 55 | return getSwapFromSwapctl_SRV4(config); |
| 56 | # else // CHECK_SWAP_SWAPCTL_SVR4 | 56 | # else // CHECK_SWAP_SWAPCTL_SVR4 |
| 57 | # ifdef CHECK_SWAP_SWAPCTL_BSD | 57 | # ifdef CHECK_SWAP_SWAPCTL_BSD |
| 58 | return getSwapFromSwapctl_BSD(); | 58 | return getSwapFromSwapctl_BSD(config); |
| 59 | # else // CHECK_SWAP_SWAPCTL_BSD | 59 | # else // CHECK_SWAP_SWAPCTL_BSD |
| 60 | # error No way found to retrieve swap | 60 | # error No way found to retrieve swap |
| 61 | # endif /* CHECK_SWAP_SWAPCTL_BSD */ | 61 | # endif /* CHECK_SWAP_SWAPCTL_BSD */ |
| @@ -68,7 +68,7 @@ swap_result getSwapFromProcMeminfo(char proc_meminfo[]) { | |||
| 68 | FILE *meminfo_file_ptr; | 68 | FILE *meminfo_file_ptr; |
| 69 | meminfo_file_ptr = fopen(proc_meminfo, "r"); | 69 | meminfo_file_ptr = fopen(proc_meminfo, "r"); |
| 70 | 70 | ||
| 71 | swap_result result = {0}; | 71 | swap_result result = {}; |
| 72 | result.errorcode = STATE_UNKNOWN; | 72 | result.errorcode = STATE_UNKNOWN; |
| 73 | 73 | ||
| 74 | if (meminfo_file_ptr == NULL) { | 74 | if (meminfo_file_ptr == NULL) { |
| @@ -78,90 +78,81 @@ swap_result getSwapFromProcMeminfo(char proc_meminfo[]) { | |||
| 78 | return result; | 78 | return result; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | uint64_t swap_total = 0; | 81 | unsigned long swap_total = 0; |
| 82 | uint64_t swap_used = 0; | 82 | unsigned long swap_used = 0; |
| 83 | uint64_t swap_free = 0; | 83 | unsigned long swap_free = 0; |
| 84 | 84 | ||
| 85 | bool found_total = false; | 85 | bool found_total = false; |
| 86 | bool found_used = false; | ||
| 87 | bool found_free = false; | 86 | bool found_free = false; |
| 88 | 87 | ||
| 89 | char input_buffer[MAX_INPUT_BUFFER]; | 88 | char input_buffer[MAX_INPUT_BUFFER]; |
| 90 | char str[32]; | 89 | char str[32]; |
| 91 | 90 | ||
| 92 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, meminfo_file_ptr)) { | 91 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, meminfo_file_ptr)) { |
| 93 | uint64_t tmp_KB = 0; | ||
| 94 | 92 | ||
| 95 | /* | 93 | /* |
| 96 | * The following sscanf call looks for a line looking like: "Swap: 123 | 94 | * The following sscanf call looks for a line looking like: "Swap: 123 |
| 97 | * 123 123" On which kind of system this format exists, I can not say, | 95 | * 123 123" which exists on NetBSD (at least), |
| 98 | * but I wanted to document this for people who are not adapt with | 96 | * The unit should be Bytes |
| 99 | * sscanf anymore, like me | ||
| 100 | * Also the units used here are unclear and probably wrong | ||
| 101 | */ | 97 | */ |
| 102 | if (sscanf(input_buffer, "%*[S]%*[w]%*[a]%*[p]%*[:] %lu %lu %lu", &swap_total, &swap_used, &swap_free) == 3) { | 98 | if (sscanf(input_buffer, "%*[S]%*[w]%*[a]%*[p]%*[:] %lu %lu %lu", &swap_total, &swap_used, |
| 103 | 99 | &swap_free) == 3) { | |
| 104 | result.metrics.total += swap_total; | ||
| 105 | result.metrics.used += swap_used; | ||
| 106 | result.metrics.free += swap_free; | ||
| 107 | |||
| 108 | found_total = true; | 100 | found_total = true; |
| 109 | found_free = true; | 101 | found_free = true; |
| 110 | found_used = true; | ||
| 111 | |||
| 112 | // Set error | 102 | // Set error |
| 113 | result.errorcode = STATE_OK; | 103 | result.errorcode = STATE_OK; |
| 104 | // Break out of fgets here, since both scanf expressions might match (NetBSD for | ||
| 105 | // example) | ||
| 106 | break; | ||
| 107 | } | ||
| 108 | |||
| 109 | /* | ||
| 110 | * The following sscanf call looks for lines looking like: | ||
| 111 | * "SwapTotal: 123" and "SwapFree: 123" This format exists at least | ||
| 112 | * on Debian Linux with a 5.* kernel | ||
| 113 | */ | ||
| 114 | unsigned long tmp_KB = 0; | ||
| 115 | int sscanf_result = sscanf(input_buffer, | ||
| 116 | "%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %lu " | ||
| 117 | "%*[k]%*[B]", | ||
| 118 | str, &tmp_KB); | ||
| 119 | |||
| 120 | if (sscanf_result == 2) { | ||
| 121 | |||
| 122 | if (verbose >= 3) { | ||
| 123 | printf("Got %s with %lu\n", str, tmp_KB); | ||
| 124 | } | ||
| 114 | 125 | ||
| 115 | /* | 126 | /* I think this part is always in Kb, so convert to bytes */ |
| 116 | * The following sscanf call looks for lines looking like: | 127 | if (strcmp("Total", str) == 0) { |
| 117 | * "SwapTotal: 123" and "SwapFree: 123" This format exists at least | 128 | swap_total = tmp_KB * 1000; |
| 118 | * on Debian Linux with a 5.* kernel | 129 | found_total = true; |
| 119 | */ | 130 | } else if (strcmp("Free", str) == 0) { |
| 120 | } else { | 131 | swap_free += tmp_KB * 1000; |
| 121 | int sscanf_result = sscanf(input_buffer, | 132 | found_free = true; |
| 122 | "%*[S]%*[w]%*[a]%*[p]%[TotalFreCchd]%*[:] %lu " | 133 | } else if (strcmp("Cached", str) == 0) { |
| 123 | "%*[k]%*[B]", | 134 | swap_free += tmp_KB * 1000; |
| 124 | str, &tmp_KB); | ||
| 125 | |||
| 126 | if (sscanf_result == 2) { | ||
| 127 | |||
| 128 | if (verbose >= 3) { | ||
| 129 | printf("Got %s with %lu\n", str, tmp_KB); | ||
| 130 | } | ||
| 131 | |||
| 132 | /* I think this part is always in Kb, so convert to bytes */ | ||
| 133 | if (strcmp("Total", str) == 0) { | ||
| 134 | swap_total = tmp_KB * 1000; | ||
| 135 | found_total = true; | ||
| 136 | } else if (strcmp("Free", str) == 0) { | ||
| 137 | swap_free = swap_free + tmp_KB * 1000; | ||
| 138 | found_free = true; | ||
| 139 | found_used = true; // No explicit used metric available | ||
| 140 | } else if (strcmp("Cached", str) == 0) { | ||
| 141 | swap_free = swap_free + tmp_KB * 1000; | ||
| 142 | found_free = true; | ||
| 143 | found_used = true; // No explicit used metric available | ||
| 144 | } | ||
| 145 | |||
| 146 | result.errorcode = STATE_OK; | ||
| 147 | } | 135 | } |
| 136 | |||
| 137 | result.errorcode = STATE_OK; | ||
| 148 | } | 138 | } |
| 149 | } | 139 | } |
| 150 | 140 | ||
| 151 | fclose(meminfo_file_ptr); | 141 | fclose(meminfo_file_ptr); |
| 152 | 142 | ||
| 153 | result.metrics.total = swap_total; | 143 | result.metrics.total = swap_total; |
| 154 | result.metrics.used = swap_total - swap_free; | ||
| 155 | result.metrics.free = swap_free; | 144 | result.metrics.free = swap_free; |
| 145 | result.metrics.used = swap_total - swap_free; | ||
| 156 | 146 | ||
| 157 | if (!found_free || !found_total || !found_used) { | 147 | if (!found_free || !found_total) { |
| 158 | result.errorcode = STATE_UNKNOWN; | 148 | result.errorcode = STATE_UNKNOWN; |
| 159 | } | 149 | } |
| 160 | 150 | ||
| 161 | return result; | 151 | return result; |
| 162 | } | 152 | } |
| 163 | 153 | ||
| 164 | swap_result getSwapFromSwapCommand(swap_config config, const char swap_command[], const char swap_format[]) { | 154 | swap_result getSwapFromSwapCommand(swap_config config, const char swap_command[], |
| 155 | const char swap_format[]) { | ||
| 165 | swap_result result = {0}; | 156 | swap_result result = {0}; |
| 166 | 157 | ||
| 167 | char *temp_buffer; | 158 | char *temp_buffer; |
| @@ -224,7 +215,8 @@ swap_result getSwapFromSwapCommand(swap_config config, const char swap_command[] | |||
| 224 | used_swap_mb = total_swap_mb - free_swap_mb; | 215 | used_swap_mb = total_swap_mb - free_swap_mb; |
| 225 | 216 | ||
| 226 | if (verbose >= 3) { | 217 | if (verbose >= 3) { |
| 227 | printf(_("total=%.0f, used=%.0f, free=%.0f\n"), total_swap_mb, used_swap_mb, free_swap_mb); | 218 | printf(_("total=%.0f, used=%.0f, free=%.0f\n"), total_swap_mb, used_swap_mb, |
| 219 | free_swap_mb); | ||
| 228 | } | 220 | } |
| 229 | } else { | 221 | } else { |
| 230 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | 222 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { |
| @@ -297,8 +289,14 @@ struct swapent { | |||
| 297 | }; | 289 | }; |
| 298 | 290 | ||
| 299 | #else | 291 | #else |
| 292 | |||
| 293 | // Includes for NetBSD | ||
| 294 | # include <unistd.h> | ||
| 295 | # include <sys/swap.h> | ||
| 296 | |||
| 300 | # define bsd_swapctl swapctl | 297 | # define bsd_swapctl swapctl |
| 301 | #endif | 298 | |
| 299 | #endif // CHECK_SWAP_SWAPCTL_BSD | ||
| 302 | 300 | ||
| 303 | swap_result getSwapFromSwapctl_BSD(swap_config config) { | 301 | swap_result getSwapFromSwapctl_BSD(swap_config config) { |
| 304 | /* get the number of active swap devices */ | 302 | /* get the number of active swap devices */ |
| @@ -322,8 +320,8 @@ swap_result getSwapFromSwapctl_BSD(swap_config config) { | |||
| 322 | unsigned long long used_swap_mb = 0; | 320 | unsigned long long used_swap_mb = 0; |
| 323 | 321 | ||
| 324 | for (int i = 0; i < nswaps; i++) { | 322 | for (int i = 0; i < nswaps; i++) { |
| 325 | dsktotal_mb = (float)ent[i].se_nblks / (float)config.conversion_factor; | 323 | dsktotal_mb = (double)ent[i].se_nblks / (double)config.conversion_factor; |
| 326 | dskused_mb = (float)ent[i].se_inuse / (float)config.conversion_factor; | 324 | dskused_mb = (double)ent[i].se_inuse / (double)config.conversion_factor; |
| 327 | dskfree_mb = (dsktotal_mb - dskused_mb); | 325 | dskfree_mb = (dsktotal_mb - dskused_mb); |
| 328 | 326 | ||
| 329 | if (config.allswaps && dsktotal_mb > 0) { | 327 | if (config.allswaps && dsktotal_mb > 0) { |
| @@ -404,7 +402,8 @@ swap_result getSwapFromSwap_SRV4(swap_config config) { | |||
| 404 | } | 402 | } |
| 405 | 403 | ||
| 406 | /* initialize swap table + entries */ | 404 | /* initialize swap table + entries */ |
| 407 | swaptbl_t *tbl = (swaptbl_t *)malloc(sizeof(swaptbl_t) + (sizeof(swapent_t) * (unsigned long)nswaps)); | 405 | swaptbl_t *tbl = |
| 406 | (swaptbl_t *)malloc(sizeof(swaptbl_t) + (sizeof(swapent_t) * (unsigned long)nswaps)); | ||
| 408 | 407 | ||
| 409 | if (tbl == NULL) { | 408 | if (tbl == NULL) { |
| 410 | die(STATE_UNKNOWN, _("malloc() failed!\n")); | 409 | die(STATE_UNKNOWN, _("malloc() failed!\n")); |
| @@ -439,7 +438,8 @@ swap_result getSwapFromSwap_SRV4(swap_config config) { | |||
| 439 | dskused_mb = (dsktotal_mb - dskfree_mb); | 438 | dskused_mb = (dsktotal_mb - dskfree_mb); |
| 440 | 439 | ||
| 441 | if (verbose >= 3) { | 440 | if (verbose >= 3) { |
| 442 | printf("dsktotal_mb=%.0f dskfree_mb=%.0f dskused_mb=%.0f\n", dsktotal_mb, dskfree_mb, dskused_mb); | 441 | printf("dsktotal_mb=%.0f dskfree_mb=%.0f dskused_mb=%.0f\n", dsktotal_mb, dskfree_mb, |
| 442 | dskused_mb); | ||
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | if (config.allswaps && dsktotal_mb > 0) { | 445 | if (config.allswaps && dsktotal_mb > 0) { |
diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c index 49ad096c..09806373 100644 --- a/plugins/check_tcp.c +++ b/plugins/check_tcp.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * Monitoring check_tcp plugin | 3 | * Monitoring check_tcp plugin |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 1999-2024 Monitoring Plugins Development Team | 6 | * Copyright (c) 1999-2025 Monitoring Plugins Development Team |
| 7 | * | 7 | * |
| 8 | * Description: | 8 | * Description: |
| 9 | * | 9 | * |
| @@ -29,74 +29,64 @@ | |||
| 29 | 29 | ||
| 30 | /* progname "check_tcp" changes depending on symlink called */ | 30 | /* progname "check_tcp" changes depending on symlink called */ |
| 31 | char *progname; | 31 | char *progname; |
| 32 | const char *copyright = "1999-2024"; | 32 | const char *copyright = "1999-2025"; |
| 33 | const char *email = "devel@monitoring-plugins.org"; | 33 | const char *email = "devel@monitoring-plugins.org"; |
| 34 | 34 | ||
| 35 | #include "common.h" | 35 | #include "./common.h" |
| 36 | #include "netutils.h" | 36 | #include "./netutils.h" |
| 37 | #include "utils.h" | 37 | #include "./utils.h" |
| 38 | #include "utils_tcp.h" | 38 | #include "./check_tcp.d/config.h" |
| 39 | #include "output.h" | ||
| 40 | #include "states.h" | ||
| 39 | 41 | ||
| 42 | #include <sys/types.h> | ||
| 40 | #include <ctype.h> | 43 | #include <ctype.h> |
| 41 | #include <sys/select.h> | 44 | #include <sys/select.h> |
| 42 | 45 | ||
| 46 | ssize_t my_recv(int socket_descriptor, char *buf, size_t len, bool use_tls) { | ||
| 43 | #ifdef HAVE_SSL | 47 | #ifdef HAVE_SSL |
| 44 | static bool check_cert = false; | 48 | if (use_tls) { |
| 45 | static int days_till_exp_warn, days_till_exp_crit; | 49 | return np_net_ssl_read(buf, (int)len); |
| 46 | # define my_recv(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) | 50 | } |
| 47 | # define my_send(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) | 51 | #endif |
| 48 | #else | 52 | return read(socket_descriptor, buf, len); |
| 49 | # define my_recv(buf, len) read(sd, buf, len) | 53 | } |
| 50 | # define my_send(buf, len) send(sd, buf, len, 0) | 54 | |
| 55 | ssize_t my_send(int socket_descriptor, char *buf, size_t len, bool use_tls) { | ||
| 56 | #ifdef HAVE_SSL | ||
| 57 | if (use_tls) { | ||
| 58 | return np_net_ssl_write(buf, (int)len); | ||
| 59 | } | ||
| 51 | #endif | 60 | #endif |
| 61 | return write(socket_descriptor, buf, len); | ||
| 62 | } | ||
| 52 | 63 | ||
| 53 | /* int my_recv(char *, size_t); */ | 64 | typedef struct { |
| 54 | static int process_arguments(int /*argc*/, char ** /*argv*/); | 65 | int errorcode; |
| 55 | static void print_help(void); | 66 | check_tcp_config config; |
| 67 | } check_tcp_config_wrapper; | ||
| 68 | static check_tcp_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/, | ||
| 69 | check_tcp_config /*config*/); | ||
| 70 | void print_help(const char *service); | ||
| 56 | void print_usage(void); | 71 | void print_usage(void); |
| 57 | 72 | ||
| 58 | #define EXPECT server_expect[0] | 73 | int verbosity = 0; |
| 59 | static char *SERVICE = "TCP"; | ||
| 60 | static char *SEND = NULL; | ||
| 61 | static char *QUIT = NULL; | ||
| 62 | static int PROTOCOL = IPPROTO_TCP; /* most common is default */ | ||
| 63 | static int PORT = 0; | ||
| 64 | static int READ_TIMEOUT = 2; | ||
| 65 | |||
| 66 | static int server_port = 0; | ||
| 67 | static char *server_address = NULL; | ||
| 68 | static bool host_specified = false; | ||
| 69 | static char *server_send = NULL; | ||
| 70 | static char *server_quit = NULL; | ||
| 71 | static char **server_expect; | ||
| 72 | static size_t server_expect_count = 0; | ||
| 73 | static ssize_t maxbytes = 0; | ||
| 74 | static char **warn_codes = NULL; | ||
| 75 | static size_t warn_codes_count = 0; | ||
| 76 | static char **crit_codes = NULL; | ||
| 77 | static size_t crit_codes_count = 0; | ||
| 78 | static unsigned int delay = 0; | ||
| 79 | static double warning_time = 0; | ||
| 80 | static double critical_time = 0; | ||
| 81 | static double elapsed_time = 0; | ||
| 82 | static long microsec; | ||
| 83 | static int sd = 0; | ||
| 84 | #define MAXBUF 1024 | ||
| 85 | static char buffer[MAXBUF]; | ||
| 86 | static int expect_mismatch_state = STATE_WARNING; | ||
| 87 | static int match_flags = NP_MATCH_EXACT; | ||
| 88 | 74 | ||
| 89 | #ifdef HAVE_SSL | 75 | static const int READ_TIMEOUT = 2; |
| 90 | static char *sni = NULL; | 76 | |
| 91 | static bool sni_specified = false; | 77 | const int MAXBUF = 1024; |
| 92 | #endif | ||
| 93 | 78 | ||
| 94 | #define FLAG_SSL 0x01 | 79 | const int DEFAULT_FTP_PORT = 21; |
| 95 | #define FLAG_VERBOSE 0x02 | 80 | const int DEFAULT_POP_PORT = 110; |
| 96 | #define FLAG_TIME_WARN 0x04 | 81 | const int DEFAULT_SPOP_PORT = 995; |
| 97 | #define FLAG_TIME_CRIT 0x08 | 82 | const int DEFAULT_SMTP_PORT = 25; |
| 98 | #define FLAG_HIDE_OUTPUT 0x10 | 83 | const int DEFAULT_SSMTP_PORT = 465; |
| 99 | static size_t flags; | 84 | const int DEFAULT_IMAP_PORT = 143; |
| 85 | const int DEFAULT_SIMAP_PORT = 993; | ||
| 86 | const int DEFAULT_XMPP_C2S_PORT = 5222; | ||
| 87 | const int DEFAULT_NNTP_PORT = 119; | ||
| 88 | const int DEFAULT_NNTPS_PORT = 563; | ||
| 89 | const int DEFAULT_CLAMD_PORT = 3310; | ||
| 100 | 90 | ||
| 101 | int main(int argc, char **argv) { | 91 | int main(int argc, char **argv) { |
| 102 | setlocale(LC_ALL, ""); | 92 | setlocale(LC_ALL, ""); |
| @@ -105,353 +95,482 @@ int main(int argc, char **argv) { | |||
| 105 | 95 | ||
| 106 | /* determine program- and service-name quickly */ | 96 | /* determine program- and service-name quickly */ |
| 107 | progname = strrchr(argv[0], '/'); | 97 | progname = strrchr(argv[0], '/'); |
| 108 | if (progname != NULL) | 98 | if (progname != NULL) { |
| 109 | progname++; | 99 | progname++; |
| 110 | else | 100 | } else { |
| 111 | progname = argv[0]; | 101 | progname = argv[0]; |
| 102 | } | ||
| 103 | |||
| 104 | // Initialize config here with values from above, | ||
| 105 | // might be changed by on disk config or cli commands | ||
| 106 | check_tcp_config config = check_tcp_config_init(); | ||
| 112 | 107 | ||
| 113 | size_t prog_name_len = strlen(progname); | 108 | size_t prog_name_len = strlen(progname); |
| 114 | if (prog_name_len > 6 && !memcmp(progname, "check_", 6)) { | 109 | const size_t prefix_length = strlen("check_"); |
| 115 | SERVICE = strdup(progname + 6); | 110 | |
| 116 | for (size_t i = 0; i < prog_name_len - 6; i++) | 111 | if (prog_name_len <= prefix_length) { |
| 117 | SERVICE[i] = toupper(SERVICE[i]); | 112 | die(STATE_UNKNOWN, _("Weird progname")); |
| 113 | } | ||
| 114 | |||
| 115 | if (!memcmp(progname, "check_", prefix_length)) { | ||
| 116 | config.service = strdup(progname + prefix_length); | ||
| 117 | if (config.service == NULL) { | ||
| 118 | die(STATE_UNKNOWN, _("Allocation failed")); | ||
| 119 | } | ||
| 120 | |||
| 121 | for (size_t i = 0; i < prog_name_len - prefix_length; i++) { | ||
| 122 | config.service[i] = toupper(config.service[i]); | ||
| 123 | } | ||
| 118 | } | 124 | } |
| 119 | 125 | ||
| 120 | /* set up a reasonable buffer at first (will be realloc()'ed if | 126 | /* set up a reasonable buffer at first (will be realloc()'ed if |
| 121 | * user specifies other options) */ | 127 | * user specifies other options) */ |
| 122 | server_expect = calloc(2, sizeof(char *)); | 128 | config.server_expect = calloc(2, sizeof(char *)); |
| 129 | |||
| 130 | if (config.server_expect == NULL) { | ||
| 131 | die(STATE_UNKNOWN, _("Allocation failed")); | ||
| 132 | } | ||
| 123 | 133 | ||
| 124 | /* determine defaults for this service's protocol */ | 134 | /* determine defaults for this service's protocol */ |
| 125 | if (!strncmp(SERVICE, "UDP", 3)) { | 135 | if (!strncmp(config.service, "UDP", strlen("UDP"))) { |
| 126 | PROTOCOL = IPPROTO_UDP; | 136 | config.protocol = IPPROTO_UDP; |
| 127 | } else if (!strncmp(SERVICE, "FTP", 3)) { | 137 | } else if (!strncmp(config.service, "FTP", strlen("FTP"))) { |
| 128 | EXPECT = "220"; | 138 | config.server_expect[0] = "220"; |
| 129 | QUIT = "QUIT\r\n"; | 139 | config.quit = "QUIT\r\n"; |
| 130 | PORT = 21; | 140 | config.server_port = DEFAULT_FTP_PORT; |
| 131 | } else if (!strncmp(SERVICE, "POP", 3) || !strncmp(SERVICE, "POP3", 4)) { | 141 | } else if (!strncmp(config.service, "POP", strlen("POP")) || |
| 132 | EXPECT = "+OK"; | 142 | !strncmp(config.service, "POP3", strlen("POP3"))) { |
| 133 | QUIT = "QUIT\r\n"; | 143 | config.server_expect[0] = "+OK"; |
| 134 | PORT = 110; | 144 | config.quit = "QUIT\r\n"; |
| 135 | } else if (!strncmp(SERVICE, "SMTP", 4)) { | 145 | config.server_port = DEFAULT_POP_PORT; |
| 136 | EXPECT = "220"; | 146 | } else if (!strncmp(config.service, "SMTP", strlen("SMTP"))) { |
| 137 | QUIT = "QUIT\r\n"; | 147 | config.server_expect[0] = "220"; |
| 138 | PORT = 25; | 148 | config.quit = "QUIT\r\n"; |
| 139 | } else if (!strncmp(SERVICE, "IMAP", 4)) { | 149 | config.server_port = DEFAULT_SMTP_PORT; |
| 140 | EXPECT = "* OK"; | 150 | } else if (!strncmp(config.service, "IMAP", strlen("IMAP"))) { |
| 141 | QUIT = "a1 LOGOUT\r\n"; | 151 | config.server_expect[0] = "* OK"; |
| 142 | PORT = 143; | 152 | config.quit = "a1 LOGOUT\r\n"; |
| 153 | config.server_port = DEFAULT_IMAP_PORT; | ||
| 143 | } | 154 | } |
| 144 | #ifdef HAVE_SSL | 155 | #ifdef HAVE_SSL |
| 145 | else if (!strncmp(SERVICE, "SIMAP", 5)) { | 156 | else if (!strncmp(config.service, "SIMAP", strlen("SIMAP"))) { |
| 146 | EXPECT = "* OK"; | 157 | config.server_expect[0] = "* OK"; |
| 147 | QUIT = "a1 LOGOUT\r\n"; | 158 | config.quit = "a1 LOGOUT\r\n"; |
| 148 | flags |= FLAG_SSL; | 159 | config.use_tls = true; |
| 149 | PORT = 993; | 160 | config.server_port = DEFAULT_SIMAP_PORT; |
| 150 | } else if (!strncmp(SERVICE, "SPOP", 4)) { | 161 | } else if (!strncmp(config.service, "SPOP", strlen("SPOP"))) { |
| 151 | EXPECT = "+OK"; | 162 | config.server_expect[0] = "+OK"; |
| 152 | QUIT = "QUIT\r\n"; | 163 | config.quit = "QUIT\r\n"; |
| 153 | flags |= FLAG_SSL; | 164 | config.use_tls = true; |
| 154 | PORT = 995; | 165 | config.server_port = DEFAULT_SPOP_PORT; |
| 155 | } else if (!strncmp(SERVICE, "SSMTP", 5)) { | 166 | } else if (!strncmp(config.service, "SSMTP", strlen("SSMTP"))) { |
| 156 | EXPECT = "220"; | 167 | config.server_expect[0] = "220"; |
| 157 | QUIT = "QUIT\r\n"; | 168 | config.quit = "QUIT\r\n"; |
| 158 | flags |= FLAG_SSL; | 169 | config.use_tls = true; |
| 159 | PORT = 465; | 170 | config.server_port = DEFAULT_SSMTP_PORT; |
| 160 | } else if (!strncmp(SERVICE, "JABBER", 6)) { | 171 | } else if (!strncmp(config.service, "JABBER", strlen("JABBER"))) { |
| 161 | SEND = "<stream:stream to=\'host\' xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'>\n"; | 172 | config.send = "<stream:stream to=\'host\' xmlns=\'jabber:client\' " |
| 162 | EXPECT = "<?xml version=\'1.0\'"; | 173 | "xmlns:stream=\'http://etherx.jabber.org/streams\'>\n"; |
| 163 | QUIT = "</stream:stream>\n"; | 174 | config.server_expect[0] = "<?xml version=\'1.0\'"; |
| 164 | flags |= FLAG_HIDE_OUTPUT; | 175 | config.quit = "</stream:stream>\n"; |
| 165 | PORT = 5222; | 176 | config.hide_output = true; |
| 166 | } else if (!strncmp(SERVICE, "NNTPS", 5)) { | 177 | config.server_port = DEFAULT_XMPP_C2S_PORT; |
| 167 | server_expect_count = 2; | 178 | } else if (!strncmp(config.service, "NNTPS", strlen("NNTPS"))) { |
| 168 | server_expect[0] = "200"; | 179 | config.server_expect_count = 2; |
| 169 | server_expect[1] = "201"; | 180 | config.server_expect[0] = "200"; |
| 170 | QUIT = "QUIT\r\n"; | 181 | config.server_expect[1] = "201"; |
| 171 | flags |= FLAG_SSL; | 182 | config.quit = "QUIT\r\n"; |
| 172 | PORT = 563; | 183 | config.use_tls = true; |
| 184 | config.server_port = DEFAULT_NNTPS_PORT; | ||
| 173 | } | 185 | } |
| 174 | #endif | 186 | #endif |
| 175 | else if (!strncmp(SERVICE, "NNTP", 4)) { | 187 | else if (!strncmp(config.service, "NNTP", strlen("NNTP"))) { |
| 176 | server_expect_count = 2; | 188 | config.server_expect_count = 2; |
| 177 | server_expect = malloc(sizeof(char *) * server_expect_count); | 189 | char **tmp = realloc(config.server_expect, config.server_expect_count * sizeof(char *)); |
| 178 | server_expect[0] = strdup("200"); | 190 | if (tmp == NULL) { |
| 179 | server_expect[1] = strdup("201"); | 191 | free(config.server_expect); |
| 180 | QUIT = "QUIT\r\n"; | 192 | die(STATE_UNKNOWN, _("Allocation failed")); |
| 181 | PORT = 119; | 193 | } |
| 182 | } else if (!strncmp(SERVICE, "CLAMD", 5)) { | 194 | config.server_expect = tmp; |
| 183 | SEND = "PING"; | 195 | |
| 184 | EXPECT = "PONG"; | 196 | config.server_expect[0] = strdup("200"); |
| 185 | QUIT = NULL; | 197 | config.server_expect[1] = strdup("201"); |
| 186 | PORT = 3310; | 198 | config.quit = "QUIT\r\n"; |
| 199 | config.server_port = DEFAULT_NNTP_PORT; | ||
| 200 | } else if (!strncmp(config.service, "CLAMD", strlen("CLAMD"))) { | ||
| 201 | config.send = "PING"; | ||
| 202 | config.server_expect[0] = "PONG"; | ||
| 203 | config.quit = NULL; | ||
| 204 | config.server_port = DEFAULT_CLAMD_PORT; | ||
| 187 | } | 205 | } |
| 188 | /* fallthrough check, so it's supposed to use reverse matching */ | 206 | /* fallthrough check, so it's supposed to use reverse matching */ |
| 189 | else if (strcmp(SERVICE, "TCP")) | 207 | else if (strcmp(config.service, "TCP")) { |
| 190 | usage(_("CRITICAL - Generic check_tcp called with unknown service\n")); | 208 | usage(_("CRITICAL - Generic check_tcp called with unknown service\n")); |
| 191 | 209 | } | |
| 192 | server_address = "127.0.0.1"; | ||
| 193 | server_port = PORT; | ||
| 194 | server_send = SEND; | ||
| 195 | server_quit = QUIT; | ||
| 196 | char *status = NULL; | ||
| 197 | 210 | ||
| 198 | /* Parse extra opts if any */ | 211 | /* Parse extra opts if any */ |
| 199 | argv = np_extra_opts(&argc, argv, progname); | 212 | argv = np_extra_opts(&argc, argv, progname); |
| 200 | 213 | ||
| 201 | if (process_arguments(argc, argv) == ERROR) | 214 | check_tcp_config_wrapper paw = process_arguments(argc, argv, config); |
| 215 | if (paw.errorcode == ERROR) { | ||
| 202 | usage4(_("Could not parse arguments")); | 216 | usage4(_("Could not parse arguments")); |
| 217 | } | ||
| 218 | |||
| 219 | config = paw.config; | ||
| 203 | 220 | ||
| 204 | if (flags & FLAG_VERBOSE) { | 221 | if (verbosity > 0) { |
| 205 | printf("Using service %s\n", SERVICE); | 222 | printf("Using service %s\n", config.service); |
| 206 | printf("Port: %d\n", server_port); | 223 | printf("Port: %d\n", config.server_port); |
| 207 | printf("flags: 0x%x\n", (int)flags); | ||
| 208 | } | 224 | } |
| 209 | 225 | ||
| 210 | if (EXPECT && !server_expect_count) | 226 | if ((config.server_expect_count == 0) && config.server_expect[0]) { |
| 211 | server_expect_count++; | 227 | config.server_expect_count++; |
| 228 | } | ||
| 212 | 229 | ||
| 213 | if (PROTOCOL == IPPROTO_UDP && !(server_expect_count && server_send)) { | 230 | if (config.protocol == IPPROTO_UDP && !(config.server_expect_count && config.send)) { |
| 214 | usage(_("With UDP checks, a send/expect string must be specified.")); | 231 | usage(_("With UDP checks, a send/expect string must be specified.")); |
| 215 | } | 232 | } |
| 216 | 233 | ||
| 234 | // Initialize check stuff before setting timers | ||
| 235 | mp_check overall = mp_check_init(); | ||
| 236 | if (config.output_format_set) { | ||
| 237 | mp_set_format(config.output_format); | ||
| 238 | } | ||
| 239 | |||
| 217 | /* set up the timer */ | 240 | /* set up the timer */ |
| 218 | signal(SIGALRM, socket_timeout_alarm_handler); | 241 | signal(SIGALRM, socket_timeout_alarm_handler); |
| 219 | alarm(socket_timeout); | 242 | alarm(socket_timeout); |
| 220 | 243 | ||
| 221 | /* try to connect to the host at the given port number */ | 244 | /* try to connect to the host at the given port number */ |
| 222 | struct timeval tv; | 245 | struct timeval start_time; |
| 223 | gettimeofday(&tv, NULL); | 246 | gettimeofday(&start_time, NULL); |
| 224 | 247 | ||
| 225 | int result = STATE_UNKNOWN; | 248 | int socket_descriptor = 0; |
| 226 | result = np_net_connect(server_address, server_port, &sd, PROTOCOL); | 249 | mp_subcheck inital_connect_result = mp_subcheck_init(); |
| 227 | if (result == STATE_CRITICAL) | 250 | |
| 228 | return econn_refuse_state; | 251 | // Try initial connection |
| 252 | if (np_net_connect(config.server_address, config.server_port, &socket_descriptor, | ||
| 253 | config.protocol) == STATE_CRITICAL) { | ||
| 254 | // Early exit here, we got connection refused | ||
| 255 | inital_connect_result = | ||
| 256 | mp_set_subcheck_state(inital_connect_result, config.econn_refuse_state); | ||
| 257 | xasprintf(&inital_connect_result.output, "Connection to %s on port %i was REFUSED", | ||
| 258 | config.server_address, config.server_port); | ||
| 259 | mp_add_subcheck_to_check(&overall, inital_connect_result); | ||
| 260 | mp_exit(overall); | ||
| 261 | } else { | ||
| 262 | inital_connect_result = mp_set_subcheck_state(inital_connect_result, STATE_OK); | ||
| 263 | xasprintf(&inital_connect_result.output, "Connection to %s on port %i was a SUCCESS", | ||
| 264 | config.server_address, config.server_port); | ||
| 265 | mp_add_subcheck_to_check(&overall, inital_connect_result); | ||
| 266 | } | ||
| 229 | 267 | ||
| 230 | #ifdef HAVE_SSL | 268 | #ifdef HAVE_SSL |
| 231 | if (flags & FLAG_SSL) { | 269 | if (config.use_tls) { |
| 232 | result = np_net_ssl_init_with_hostname(sd, (sni_specified ? sni : NULL)); | 270 | mp_subcheck tls_connection_result = mp_subcheck_init(); |
| 233 | if (result == STATE_OK && check_cert) { | 271 | mp_state_enum result = np_net_ssl_init_with_hostname( |
| 234 | result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); | 272 | socket_descriptor, (config.sni_specified ? config.sni : NULL)); |
| 273 | tls_connection_result = mp_set_subcheck_default_state(tls_connection_result, result); | ||
| 274 | |||
| 275 | if (result == STATE_OK) { | ||
| 276 | xasprintf(&tls_connection_result.output, "TLS connection succeeded"); | ||
| 277 | |||
| 278 | if (config.check_cert) { | ||
| 279 | result = | ||
| 280 | np_net_ssl_check_cert(config.days_till_exp_warn, config.days_till_exp_crit); | ||
| 281 | |||
| 282 | mp_subcheck tls_certificate_lifetime_result = mp_subcheck_init(); | ||
| 283 | tls_certificate_lifetime_result = | ||
| 284 | mp_set_subcheck_state(tls_certificate_lifetime_result, result); | ||
| 285 | |||
| 286 | if (result == STATE_OK) { | ||
| 287 | xasprintf(&tls_certificate_lifetime_result.output, | ||
| 288 | "Certificate lifetime is within thresholds"); | ||
| 289 | } else if (result == STATE_WARNING) { | ||
| 290 | xasprintf(&tls_certificate_lifetime_result.output, | ||
| 291 | "Certificate lifetime is violating warning threshold (%i)", | ||
| 292 | config.days_till_exp_warn); | ||
| 293 | } else if (result == STATE_CRITICAL) { | ||
| 294 | xasprintf(&tls_certificate_lifetime_result.output, | ||
| 295 | "Certificate lifetime is violating critical threshold (%i)", | ||
| 296 | config.days_till_exp_crit); | ||
| 297 | } else { | ||
| 298 | xasprintf(&tls_certificate_lifetime_result.output, | ||
| 299 | "Certificate lifetime is somehow unknown"); | ||
| 300 | } | ||
| 301 | |||
| 302 | mp_add_subcheck_to_subcheck(&tls_connection_result, | ||
| 303 | tls_certificate_lifetime_result); | ||
| 304 | } | ||
| 305 | |||
| 306 | mp_add_subcheck_to_check(&overall, tls_connection_result); | ||
| 307 | } else { | ||
| 308 | xasprintf(&tls_connection_result.output, "TLS connection failed"); | ||
| 309 | mp_add_subcheck_to_check(&overall, tls_connection_result); | ||
| 310 | |||
| 311 | if (socket_descriptor) { | ||
| 312 | close(socket_descriptor); | ||
| 313 | } | ||
| 314 | np_net_ssl_cleanup(); | ||
| 315 | |||
| 316 | mp_exit(overall); | ||
| 235 | } | 317 | } |
| 236 | } | 318 | } |
| 237 | if (result != STATE_OK) { | ||
| 238 | if (sd) | ||
| 239 | close(sd); | ||
| 240 | np_net_ssl_cleanup(); | ||
| 241 | return result; | ||
| 242 | } | ||
| 243 | #endif /* HAVE_SSL */ | 319 | #endif /* HAVE_SSL */ |
| 244 | 320 | ||
| 245 | if (server_send != NULL) { /* Something to send? */ | 321 | if (config.send != NULL) { /* Something to send? */ |
| 246 | my_send(server_send, strlen(server_send)); | 322 | my_send(socket_descriptor, config.send, strlen(config.send), config.use_tls); |
| 247 | } | 323 | } |
| 248 | 324 | ||
| 249 | if (delay > 0) { | 325 | if (config.delay > 0) { |
| 250 | tv.tv_sec += delay; | 326 | start_time.tv_sec += config.delay; |
| 251 | sleep(delay); | 327 | sleep(config.delay); |
| 252 | } | 328 | } |
| 253 | 329 | ||
| 254 | if (flags & FLAG_VERBOSE) { | 330 | if (verbosity > 0) { |
| 255 | if (server_send) { | 331 | if (config.send) { |
| 256 | printf("Send string: %s\n", server_send); | 332 | printf("Send string: %s\n", config.send); |
| 333 | } | ||
| 334 | if (config.quit) { | ||
| 335 | printf("Quit string: %s\n", config.quit); | ||
| 257 | } | 336 | } |
| 258 | if (server_quit) { | 337 | printf("server_expect_count: %d\n", (int)config.server_expect_count); |
| 259 | printf("Quit string: %s\n", server_quit); | 338 | for (size_t i = 0; i < config.server_expect_count; i++) { |
| 339 | printf("\t%zd: %s\n", i, config.server_expect[i]); | ||
| 260 | } | 340 | } |
| 261 | printf("server_expect_count: %d\n", (int)server_expect_count); | ||
| 262 | for (size_t i = 0; i < server_expect_count; i++) | ||
| 263 | printf("\t%zd: %s\n", i, server_expect[i]); | ||
| 264 | } | 341 | } |
| 265 | 342 | ||
| 266 | /* if(len) later on, we know we have a non-NULL response */ | 343 | /* if(len) later on, we know we have a non-NULL response */ |
| 267 | ssize_t len = 0; | 344 | ssize_t len = 0; |
| 345 | char *received_buffer = NULL; | ||
| 346 | enum np_match_result match = NP_MATCH_NONE; | ||
| 347 | mp_subcheck expected_data_result = mp_subcheck_init(); | ||
| 268 | 348 | ||
| 269 | int match = -1; | 349 | if (config.server_expect_count) { |
| 270 | struct timeval timeout; | ||
| 271 | fd_set rfds; | ||
| 272 | FD_ZERO(&rfds); | ||
| 273 | if (server_expect_count) { | ||
| 274 | ssize_t received = 0; | 350 | ssize_t received = 0; |
| 351 | char buffer[MAXBUF]; | ||
| 275 | 352 | ||
| 276 | /* watch for the expect string */ | 353 | /* watch for the expect string */ |
| 277 | while ((received = my_recv(buffer, sizeof(buffer))) > 0) { | 354 | while ((received = my_recv(socket_descriptor, buffer, sizeof(buffer), config.use_tls)) > |
| 278 | status = realloc(status, len + received + 1); | 355 | 0) { |
| 279 | memcpy(&status[len], buffer, received); | 356 | received_buffer = realloc(received_buffer, len + received + 1); |
| 357 | |||
| 358 | if (received_buffer == NULL) { | ||
| 359 | die(STATE_UNKNOWN, _("Allocation failed")); | ||
| 360 | } | ||
| 361 | |||
| 362 | memcpy(&received_buffer[len], buffer, received); | ||
| 280 | len += received; | 363 | len += received; |
| 281 | status[len] = '\0'; | 364 | received_buffer[len] = '\0'; |
| 282 | 365 | ||
| 283 | /* stop reading if user-forced */ | 366 | /* stop reading if user-forced */ |
| 284 | if (maxbytes && len >= maxbytes) | 367 | if (config.maxbytes && len >= config.maxbytes) { |
| 285 | break; | 368 | break; |
| 369 | } | ||
| 286 | 370 | ||
| 287 | if ((match = np_expect_match(status, server_expect, server_expect_count, match_flags)) != NP_MATCH_RETRY) | 371 | if ((match = np_expect_match(received_buffer, config.server_expect, |
| 372 | config.server_expect_count, config.match_flags)) != | ||
| 373 | NP_MATCH_RETRY) { | ||
| 288 | break; | 374 | break; |
| 375 | } | ||
| 376 | |||
| 377 | fd_set rfds; | ||
| 378 | FD_ZERO(&rfds); | ||
| 379 | FD_SET(socket_descriptor, &rfds); | ||
| 289 | 380 | ||
| 290 | /* some protocols wait for further input, so make sure we don't wait forever */ | 381 | /* some protocols wait for further input, so make sure we don't wait forever */ |
| 291 | FD_SET(sd, &rfds); | 382 | struct timeval timeout; |
| 292 | timeout.tv_sec = READ_TIMEOUT; | 383 | timeout.tv_sec = READ_TIMEOUT; |
| 293 | timeout.tv_usec = 0; | 384 | timeout.tv_usec = 0; |
| 294 | if (select(sd + 1, &rfds, NULL, NULL, &timeout) <= 0) | 385 | |
| 386 | if (select(socket_descriptor + 1, &rfds, NULL, NULL, &timeout) <= 0) { | ||
| 295 | break; | 387 | break; |
| 388 | } | ||
| 296 | } | 389 | } |
| 297 | 390 | ||
| 298 | if (match == NP_MATCH_RETRY) | 391 | if (match == NP_MATCH_RETRY) { |
| 299 | match = NP_MATCH_FAILURE; | 392 | match = NP_MATCH_FAILURE; |
| 393 | } | ||
| 300 | 394 | ||
| 301 | /* no data when expected, so return critical */ | 395 | /* no data when expected, so return critical */ |
| 302 | if (len == 0) | 396 | if (len == 0) { |
| 303 | die(STATE_CRITICAL, _("No data received from host\n")); | 397 | xasprintf(&expected_data_result.output, "Received no data when some was expected"); |
| 398 | expected_data_result = mp_set_subcheck_state(expected_data_result, STATE_CRITICAL); | ||
| 399 | mp_add_subcheck_to_check(&overall, expected_data_result); | ||
| 400 | mp_exit(overall); | ||
| 401 | } | ||
| 304 | 402 | ||
| 305 | /* print raw output if we're debugging */ | 403 | /* print raw output if we're debugging */ |
| 306 | if (flags & FLAG_VERBOSE) | 404 | if (verbosity > 0) { |
| 307 | printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n", (int)len + 1, status); | 405 | printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n", |
| 406 | (int)len + 1, received_buffer); | ||
| 407 | } | ||
| 308 | /* strip whitespace from end of output */ | 408 | /* strip whitespace from end of output */ |
| 309 | while (--len > 0 && isspace(status[len])) | 409 | while (--len > 0 && isspace(received_buffer[len])) { |
| 310 | status[len] = '\0'; | 410 | received_buffer[len] = '\0'; |
| 411 | } | ||
| 311 | } | 412 | } |
| 312 | 413 | ||
| 313 | if (server_quit != NULL) { | 414 | if (config.quit != NULL) { |
| 314 | my_send(server_quit, strlen(server_quit)); | 415 | my_send(socket_descriptor, config.quit, strlen(config.quit), config.use_tls); |
| 416 | } | ||
| 417 | |||
| 418 | if (socket_descriptor) { | ||
| 419 | close(socket_descriptor); | ||
| 315 | } | 420 | } |
| 316 | if (sd) | ||
| 317 | close(sd); | ||
| 318 | #ifdef HAVE_SSL | 421 | #ifdef HAVE_SSL |
| 319 | np_net_ssl_cleanup(); | 422 | np_net_ssl_cleanup(); |
| 320 | #endif | 423 | #endif |
| 321 | 424 | ||
| 322 | microsec = deltime(tv); | 425 | long microsec = deltime(start_time); |
| 323 | elapsed_time = (double)microsec / 1.0e6; | 426 | double elapsed_time = (double)microsec / 1.0e6; |
| 427 | |||
| 428 | mp_subcheck elapsed_time_result = mp_subcheck_init(); | ||
| 429 | |||
| 430 | mp_perfdata time_pd = perfdata_init(); | ||
| 431 | time_pd = mp_set_pd_value(time_pd, elapsed_time); | ||
| 432 | time_pd.label = "time"; | ||
| 433 | time_pd.uom = "s"; | ||
| 434 | |||
| 435 | if (config.critical_time_set && elapsed_time > config.critical_time) { | ||
| 436 | xasprintf(&elapsed_time_result.output, | ||
| 437 | "Connection time %fs exceeded critical threshold (%f)", elapsed_time, | ||
| 438 | config.critical_time); | ||
| 439 | |||
| 440 | elapsed_time_result = mp_set_subcheck_state(elapsed_time_result, STATE_CRITICAL); | ||
| 441 | time_pd.crit_present = true; | ||
| 442 | mp_range crit_val = mp_range_init(); | ||
| 443 | |||
| 444 | crit_val.end = mp_create_pd_value(config.critical_time); | ||
| 445 | crit_val.end_infinity = false; | ||
| 446 | |||
| 447 | time_pd.crit = crit_val; | ||
| 448 | } else if (config.warning_time_set && elapsed_time > config.warning_time) { | ||
| 449 | xasprintf(&elapsed_time_result.output, | ||
| 450 | "Connection time %fs exceeded warning threshold (%f)", elapsed_time, | ||
| 451 | config.critical_time); | ||
| 452 | |||
| 453 | elapsed_time_result = mp_set_subcheck_state(elapsed_time_result, STATE_WARNING); | ||
| 454 | time_pd.warn_present = true; | ||
| 455 | mp_range warn_val = mp_range_init(); | ||
| 456 | warn_val.end = mp_create_pd_value(config.critical_time); | ||
| 457 | warn_val.end_infinity = false; | ||
| 458 | |||
| 459 | time_pd.warn = warn_val; | ||
| 460 | } else { | ||
| 461 | elapsed_time_result = mp_set_subcheck_state(elapsed_time_result, STATE_OK); | ||
| 462 | xasprintf(&elapsed_time_result.output, "Connection time %fs is within thresholds", | ||
| 463 | elapsed_time); | ||
| 464 | } | ||
| 324 | 465 | ||
| 325 | if (flags & FLAG_TIME_CRIT && elapsed_time > critical_time) | 466 | mp_add_perfdata_to_subcheck(&elapsed_time_result, time_pd); |
| 326 | result = STATE_CRITICAL; | 467 | mp_add_subcheck_to_check(&overall, elapsed_time_result); |
| 327 | else if (flags & FLAG_TIME_WARN && elapsed_time > warning_time) | ||
| 328 | result = STATE_WARNING; | ||
| 329 | 468 | ||
| 330 | /* did we get the response we hoped? */ | 469 | /* did we get the response we hoped? */ |
| 331 | if (match == NP_MATCH_FAILURE && result != STATE_CRITICAL) | 470 | if (match == NP_MATCH_FAILURE) { |
| 332 | result = expect_mismatch_state; | 471 | expected_data_result = |
| 472 | mp_set_subcheck_state(expected_data_result, config.expect_mismatch_state); | ||
| 473 | xasprintf(&expected_data_result.output, "Answer failed to match expectation"); | ||
| 474 | mp_add_subcheck_to_check(&overall, expected_data_result); | ||
| 475 | } else if (match == NP_MATCH_SUCCESS) { | ||
| 476 | expected_data_result = mp_set_subcheck_state(expected_data_result, STATE_OK); | ||
| 477 | xasprintf(&expected_data_result.output, "The answer of the server matched the expectation"); | ||
| 478 | mp_add_subcheck_to_check(&overall, expected_data_result); | ||
| 479 | } | ||
| 333 | 480 | ||
| 334 | /* reset the alarm */ | 481 | /* reset the alarm */ |
| 335 | alarm(0); | 482 | alarm(0); |
| 336 | 483 | ||
| 337 | /* this is a bit stupid, because we don't want to print the | 484 | mp_exit(overall); |
| 338 | * response time (which can look ok to the user) if we didn't get | ||
| 339 | * the response we were looking for. if-else */ | ||
| 340 | printf("%s %s - ", SERVICE, state_text(result)); | ||
| 341 | |||
| 342 | if (match == NP_MATCH_FAILURE && len && !(flags & FLAG_HIDE_OUTPUT)) | ||
| 343 | printf("Unexpected response from host/socket: %s", status); | ||
| 344 | else { | ||
| 345 | if (match == NP_MATCH_FAILURE) | ||
| 346 | printf("Unexpected response from host/socket on "); | ||
| 347 | else | ||
| 348 | printf("%.3f second response time on ", elapsed_time); | ||
| 349 | if (server_address[0] != '/') { | ||
| 350 | if (host_specified) | ||
| 351 | printf("%s port %d", server_address, server_port); | ||
| 352 | else | ||
| 353 | printf("port %d", server_port); | ||
| 354 | } else | ||
| 355 | printf("socket %s", server_address); | ||
| 356 | } | ||
| 357 | |||
| 358 | if (match != NP_MATCH_FAILURE && !(flags & FLAG_HIDE_OUTPUT) && len) | ||
| 359 | printf(" [%s]", status); | ||
| 360 | |||
| 361 | /* perf-data doesn't apply when server doesn't talk properly, | ||
| 362 | * so print all zeroes on warn and crit. Use fperfdata since | ||
| 363 | * localisation settings can make different outputs */ | ||
| 364 | if (match == NP_MATCH_FAILURE) | ||
| 365 | printf("|%s", fperfdata("time", elapsed_time, "s", (flags & FLAG_TIME_WARN ? true : false), 0, | ||
| 366 | (flags & FLAG_TIME_CRIT ? true : false), 0, true, 0, true, socket_timeout)); | ||
| 367 | else | ||
| 368 | printf("|%s", fperfdata("time", elapsed_time, "s", (flags & FLAG_TIME_WARN ? true : false), warning_time, | ||
| 369 | (flags & FLAG_TIME_CRIT ? true : false), critical_time, true, 0, true, socket_timeout)); | ||
| 370 | |||
| 371 | putchar('\n'); | ||
| 372 | return result; | ||
| 373 | } | 485 | } |
| 374 | 486 | ||
| 375 | /* process command-line arguments */ | 487 | /* process command-line arguments */ |
| 376 | static int process_arguments(int argc, char **argv) { | 488 | static check_tcp_config_wrapper process_arguments(int argc, char **argv, check_tcp_config config) { |
| 377 | enum { | 489 | enum { |
| 378 | SNI_OPTION = CHAR_MAX + 1 | 490 | SNI_OPTION = CHAR_MAX + 1, |
| 491 | output_format_index, | ||
| 379 | }; | 492 | }; |
| 380 | 493 | ||
| 381 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, | 494 | static struct option longopts[] = { |
| 382 | {"critical", required_argument, 0, 'c'}, | 495 | {"hostname", required_argument, 0, 'H'}, |
| 383 | {"warning", required_argument, 0, 'w'}, | 496 | {"critical", required_argument, 0, 'c'}, |
| 384 | {"critical-codes", required_argument, 0, 'C'}, | 497 | {"warning", required_argument, 0, 'w'}, |
| 385 | {"warning-codes", required_argument, 0, 'W'}, | 498 | {"critical-codes", required_argument, 0, 'C'}, |
| 386 | {"timeout", required_argument, 0, 't'}, | 499 | {"warning-codes", required_argument, 0, 'W'}, |
| 387 | {"protocol", required_argument, 0, 'P'}, /* FIXME: Unhandled */ | 500 | {"timeout", required_argument, 0, 't'}, |
| 388 | {"port", required_argument, 0, 'p'}, | 501 | {"protocol", required_argument, 0, 'P'}, /* FIXME: Unhandled */ |
| 389 | {"escape", no_argument, 0, 'E'}, | 502 | {"port", required_argument, 0, 'p'}, |
| 390 | {"all", no_argument, 0, 'A'}, | 503 | {"escape", no_argument, 0, 'E'}, |
| 391 | {"send", required_argument, 0, 's'}, | 504 | {"all", no_argument, 0, 'A'}, |
| 392 | {"expect", required_argument, 0, 'e'}, | 505 | {"send", required_argument, 0, 's'}, |
| 393 | {"maxbytes", required_argument, 0, 'm'}, | 506 | {"expect", required_argument, 0, 'e'}, |
| 394 | {"quit", required_argument, 0, 'q'}, | 507 | {"maxbytes", required_argument, 0, 'm'}, |
| 395 | {"jail", no_argument, 0, 'j'}, | 508 | {"quit", required_argument, 0, 'q'}, |
| 396 | {"delay", required_argument, 0, 'd'}, | 509 | {"jail", no_argument, 0, 'j'}, |
| 397 | {"refuse", required_argument, 0, 'r'}, | 510 | {"delay", required_argument, 0, 'd'}, |
| 398 | {"mismatch", required_argument, 0, 'M'}, | 511 | {"refuse", required_argument, 0, 'r'}, |
| 399 | {"use-ipv4", no_argument, 0, '4'}, | 512 | {"mismatch", required_argument, 0, 'M'}, |
| 400 | {"use-ipv6", no_argument, 0, '6'}, | 513 | {"use-ipv4", no_argument, 0, '4'}, |
| 401 | {"verbose", no_argument, 0, 'v'}, | 514 | {"use-ipv6", no_argument, 0, '6'}, |
| 402 | {"version", no_argument, 0, 'V'}, | 515 | {"verbose", no_argument, 0, 'v'}, |
| 403 | {"help", no_argument, 0, 'h'}, | 516 | {"version", no_argument, 0, 'V'}, |
| 404 | {"ssl", no_argument, 0, 'S'}, | 517 | {"help", no_argument, 0, 'h'}, |
| 405 | {"sni", required_argument, 0, SNI_OPTION}, | 518 | {"ssl", no_argument, 0, 'S'}, |
| 406 | {"certificate", required_argument, 0, 'D'}, | 519 | {"sni", required_argument, 0, SNI_OPTION}, |
| 407 | {0, 0, 0, 0}}; | 520 | {"certificate", required_argument, 0, 'D'}, |
| 408 | 521 | {"output-format", required_argument, 0, output_format_index}, | |
| 409 | if (argc < 2) | 522 | {0, 0, 0, 0}}; |
| 523 | |||
| 524 | if (argc < 2) { | ||
| 410 | usage4(_("No arguments found")); | 525 | usage4(_("No arguments found")); |
| 526 | } | ||
| 411 | 527 | ||
| 412 | /* backwards compatibility */ | 528 | /* backwards compatibility */ |
| 413 | for (int i = 1; i < argc; i++) { | 529 | for (int i = 1; i < argc; i++) { |
| 414 | if (strcmp("-to", argv[i]) == 0) | 530 | if (strcmp("-to", argv[i]) == 0) { |
| 415 | strcpy(argv[i], "-t"); | 531 | strcpy(argv[i], "-t"); |
| 416 | else if (strcmp("-wt", argv[i]) == 0) | 532 | } else if (strcmp("-wt", argv[i]) == 0) { |
| 417 | strcpy(argv[i], "-w"); | 533 | strcpy(argv[i], "-w"); |
| 418 | else if (strcmp("-ct", argv[i]) == 0) | 534 | } else if (strcmp("-ct", argv[i]) == 0) { |
| 419 | strcpy(argv[i], "-c"); | 535 | strcpy(argv[i], "-c"); |
| 536 | } | ||
| 420 | } | 537 | } |
| 421 | 538 | ||
| 422 | if (!is_option(argv[1])) { | 539 | if (!is_option(argv[1])) { |
| 423 | server_address = argv[1]; | 540 | config.server_address = argv[1]; |
| 424 | argv[1] = argv[0]; | 541 | argv[1] = argv[0]; |
| 425 | argv = &argv[1]; | 542 | argv = &argv[1]; |
| 426 | argc--; | 543 | argc--; |
| 427 | } | 544 | } |
| 428 | 545 | ||
| 429 | int option_char; | ||
| 430 | bool escape = false; | 546 | bool escape = false; |
| 547 | |||
| 431 | while (true) { | 548 | while (true) { |
| 432 | int option = 0; | 549 | int option = 0; |
| 433 | option_char = getopt_long(argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:", longopts, &option); | 550 | int option_index = |
| 551 | getopt_long(argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:", longopts, &option); | ||
| 434 | 552 | ||
| 435 | if (option_char == -1 || option_char == EOF || option_char == 1) | 553 | if (option_index == -1 || option_index == EOF || option_index == 1) { |
| 436 | break; | 554 | break; |
| 555 | } | ||
| 437 | 556 | ||
| 438 | switch (option_char) { | 557 | switch (option_index) { |
| 439 | case '?': /* print short usage statement if args not parsable */ | 558 | case '?': /* print short usage statement if args not parsable */ |
| 440 | usage5(); | 559 | usage5(); |
| 441 | case 'h': /* help */ | 560 | case 'h': /* help */ |
| 442 | print_help(); | 561 | print_help(config.service); |
| 443 | exit(STATE_UNKNOWN); | 562 | exit(STATE_UNKNOWN); |
| 444 | case 'V': /* version */ | 563 | case 'V': /* version */ |
| 445 | print_revision(progname, NP_VERSION); | 564 | print_revision(progname, NP_VERSION); |
| 446 | exit(STATE_UNKNOWN); | 565 | exit(STATE_UNKNOWN); |
| 447 | case 'v': /* verbose mode */ | 566 | case 'v': /* verbose mode */ |
| 448 | flags |= FLAG_VERBOSE; | 567 | verbosity++; |
| 449 | match_flags |= NP_MATCH_VERBOSE; | 568 | config.match_flags |= NP_MATCH_VERBOSE; |
| 450 | break; | 569 | break; |
| 451 | case '4': | 570 | case '4': // Apparently unused TODO |
| 452 | address_family = AF_INET; | 571 | address_family = AF_INET; |
| 453 | break; | 572 | break; |
| 454 | case '6': | 573 | case '6': // Apparently unused TODO |
| 455 | #ifdef USE_IPV6 | 574 | #ifdef USE_IPV6 |
| 456 | address_family = AF_INET6; | 575 | address_family = AF_INET6; |
| 457 | #else | 576 | #else |
| @@ -459,163 +578,192 @@ static int process_arguments(int argc, char **argv) { | |||
| 459 | #endif | 578 | #endif |
| 460 | break; | 579 | break; |
| 461 | case 'H': /* hostname */ | 580 | case 'H': /* hostname */ |
| 462 | host_specified = true; | 581 | config.host_specified = true; |
| 463 | server_address = optarg; | 582 | config.server_address = optarg; |
| 464 | break; | 583 | break; |
| 465 | case 'c': /* critical */ | 584 | case 'c': /* critical */ |
| 466 | critical_time = strtod(optarg, NULL); | 585 | config.critical_time = strtod(optarg, NULL); |
| 467 | flags |= FLAG_TIME_CRIT; | 586 | config.critical_time_set = true; |
| 468 | break; | 587 | break; |
| 469 | case 'j': /* hide output */ | 588 | case 'j': /* hide output */ |
| 470 | flags |= FLAG_HIDE_OUTPUT; | 589 | config.hide_output = true; |
| 471 | break; | 590 | break; |
| 472 | case 'w': /* warning */ | 591 | case 'w': /* warning */ |
| 473 | warning_time = strtod(optarg, NULL); | 592 | config.warning_time = strtod(optarg, NULL); |
| 474 | flags |= FLAG_TIME_WARN; | 593 | config.warning_time_set = true; |
| 475 | break; | ||
| 476 | case 'C': | ||
| 477 | crit_codes = realloc(crit_codes, ++crit_codes_count); | ||
| 478 | crit_codes[crit_codes_count - 1] = optarg; | ||
| 479 | break; | ||
| 480 | case 'W': | ||
| 481 | warn_codes = realloc(warn_codes, ++warn_codes_count); | ||
| 482 | warn_codes[warn_codes_count - 1] = optarg; | ||
| 483 | break; | 594 | break; |
| 484 | case 't': /* timeout */ | 595 | case 't': /* timeout */ |
| 485 | if (!is_intpos(optarg)) | 596 | if (!is_intpos(optarg)) { |
| 486 | usage4(_("Timeout interval must be a positive integer")); | 597 | usage4(_("Timeout interval must be a positive integer")); |
| 487 | else | 598 | } else { |
| 488 | socket_timeout = atoi(optarg); | 599 | socket_timeout = atoi(optarg); |
| 600 | } | ||
| 489 | break; | 601 | break; |
| 490 | case 'p': /* port */ | 602 | case 'p': /* port */ |
| 491 | if (!is_intpos(optarg)) | 603 | if (!is_intpos(optarg)) { |
| 492 | usage4(_("Port must be a positive integer")); | 604 | usage4(_("Port must be a positive integer")); |
| 493 | else | 605 | } else { |
| 494 | server_port = atoi(optarg); | 606 | config.server_port = atoi(optarg); |
| 607 | } | ||
| 495 | break; | 608 | break; |
| 496 | case 'E': | 609 | case 'E': |
| 497 | escape = true; | 610 | escape = true; |
| 498 | break; | 611 | break; |
| 499 | case 's': | 612 | case 's': |
| 500 | if (escape) | 613 | if (escape) { |
| 501 | server_send = np_escaped_string(optarg); | 614 | config.send = np_escaped_string(optarg); |
| 502 | else | 615 | } else { |
| 503 | xasprintf(&server_send, "%s", optarg); | 616 | xasprintf(&config.send, "%s", optarg); |
| 617 | } | ||
| 504 | break; | 618 | break; |
| 505 | case 'e': /* expect string (may be repeated) */ | 619 | case 'e': /* expect string (may be repeated) */ |
| 506 | match_flags &= ~NP_MATCH_EXACT; | 620 | config.match_flags &= ~NP_MATCH_EXACT; |
| 507 | if (server_expect_count == 0) | 621 | if (config.server_expect_count == 0) { |
| 508 | server_expect = malloc(sizeof(char *) * (++server_expect_count)); | 622 | config.server_expect = malloc(sizeof(char *) * (++config.server_expect_count)); |
| 509 | else | 623 | } else { |
| 510 | server_expect = realloc(server_expect, sizeof(char *) * (++server_expect_count)); | 624 | config.server_expect = |
| 511 | server_expect[server_expect_count - 1] = optarg; | 625 | realloc(config.server_expect, sizeof(char *) * (++config.server_expect_count)); |
| 626 | } | ||
| 627 | |||
| 628 | if (config.server_expect == NULL) { | ||
| 629 | die(STATE_UNKNOWN, _("Allocation failed")); | ||
| 630 | } | ||
| 631 | config.server_expect[config.server_expect_count - 1] = optarg; | ||
| 512 | break; | 632 | break; |
| 513 | case 'm': | 633 | case 'm': |
| 514 | if (!is_intpos(optarg)) | 634 | if (!is_intpos(optarg)) { |
| 515 | usage4(_("Maxbytes must be a positive integer")); | 635 | usage4(_("Maxbytes must be a positive integer")); |
| 516 | else | 636 | } else { |
| 517 | maxbytes = strtol(optarg, NULL, 0); | 637 | config.maxbytes = strtol(optarg, NULL, 0); |
| 638 | } | ||
| 518 | break; | 639 | break; |
| 519 | case 'q': | 640 | case 'q': |
| 520 | if (escape) | 641 | if (escape) { |
| 521 | server_quit = np_escaped_string(optarg); | 642 | config.quit = np_escaped_string(optarg); |
| 522 | else | 643 | } else { |
| 523 | xasprintf(&server_quit, "%s\r\n", optarg); | 644 | xasprintf(&config.quit, "%s\r\n", optarg); |
| 645 | } | ||
| 524 | break; | 646 | break; |
| 525 | case 'r': | 647 | case 'r': |
| 526 | if (!strncmp(optarg, "ok", 2)) | 648 | if (!strncmp(optarg, "ok", 2)) { |
| 527 | econn_refuse_state = STATE_OK; | 649 | config.econn_refuse_state = STATE_OK; |
| 528 | else if (!strncmp(optarg, "warn", 4)) | 650 | } else if (!strncmp(optarg, "warn", 4)) { |
| 529 | econn_refuse_state = STATE_WARNING; | 651 | config.econn_refuse_state = STATE_WARNING; |
| 530 | else if (!strncmp(optarg, "crit", 4)) | 652 | } else if (!strncmp(optarg, "crit", 4)) { |
| 531 | econn_refuse_state = STATE_CRITICAL; | 653 | config.econn_refuse_state = STATE_CRITICAL; |
| 532 | else | 654 | } else { |
| 533 | usage4(_("Refuse must be one of ok, warn, crit")); | 655 | usage4(_("Refuse must be one of ok, warn, crit")); |
| 656 | } | ||
| 534 | break; | 657 | break; |
| 535 | case 'M': | 658 | case 'M': |
| 536 | if (!strncmp(optarg, "ok", 2)) | 659 | if (!strncmp(optarg, "ok", 2)) { |
| 537 | expect_mismatch_state = STATE_OK; | 660 | config.expect_mismatch_state = STATE_OK; |
| 538 | else if (!strncmp(optarg, "warn", 4)) | 661 | } else if (!strncmp(optarg, "warn", 4)) { |
| 539 | expect_mismatch_state = STATE_WARNING; | 662 | config.expect_mismatch_state = STATE_WARNING; |
| 540 | else if (!strncmp(optarg, "crit", 4)) | 663 | } else if (!strncmp(optarg, "crit", 4)) { |
| 541 | expect_mismatch_state = STATE_CRITICAL; | 664 | config.expect_mismatch_state = STATE_CRITICAL; |
| 542 | else | 665 | } else { |
| 543 | usage4(_("Mismatch must be one of ok, warn, crit")); | 666 | usage4(_("Mismatch must be one of ok, warn, crit")); |
| 667 | } | ||
| 544 | break; | 668 | break; |
| 545 | case 'd': | 669 | case 'd': |
| 546 | if (is_intpos(optarg)) | 670 | if (is_intpos(optarg)) { |
| 547 | delay = atoi(optarg); | 671 | config.delay = atoi(optarg); |
| 548 | else | 672 | } else { |
| 549 | usage4(_("Delay must be a positive integer")); | 673 | usage4(_("Delay must be a positive integer")); |
| 674 | } | ||
| 550 | break; | 675 | break; |
| 551 | case 'D': { /* Check SSL cert validity - days 'til certificate expiration */ | 676 | case 'D': /* Check SSL cert validity - days 'til certificate expiration */ |
| 552 | #ifdef HAVE_SSL | 677 | #ifdef HAVE_SSL |
| 553 | # ifdef USE_OPENSSL /* XXX */ | 678 | # ifdef USE_OPENSSL /* XXX */ |
| 679 | { | ||
| 554 | char *temp; | 680 | char *temp; |
| 555 | if ((temp = strchr(optarg, ',')) != NULL) { | 681 | if ((temp = strchr(optarg, ',')) != NULL) { |
| 556 | *temp = '\0'; | 682 | *temp = '\0'; |
| 557 | if (!is_intnonneg(optarg)) | 683 | if (!is_intnonneg(optarg)) { |
| 558 | usage2(_("Invalid certificate expiration period"), optarg); | 684 | usage2(_("Invalid certificate expiration period"), optarg); |
| 559 | days_till_exp_warn = atoi(optarg); | 685 | } |
| 686 | config.days_till_exp_warn = atoi(optarg); | ||
| 560 | *temp = ','; | 687 | *temp = ','; |
| 561 | temp++; | 688 | temp++; |
| 562 | if (!is_intnonneg(temp)) | 689 | if (!is_intnonneg(temp)) { |
| 563 | usage2(_("Invalid certificate expiration period"), temp); | 690 | usage2(_("Invalid certificate expiration period"), temp); |
| 564 | days_till_exp_crit = atoi(temp); | 691 | } |
| 692 | config.days_till_exp_crit = atoi(temp); | ||
| 565 | } else { | 693 | } else { |
| 566 | days_till_exp_crit = 0; | 694 | config.days_till_exp_crit = 0; |
| 567 | if (!is_intnonneg(optarg)) | 695 | if (!is_intnonneg(optarg)) { |
| 568 | usage2(_("Invalid certificate expiration period"), optarg); | 696 | usage2(_("Invalid certificate expiration period"), optarg); |
| 569 | days_till_exp_warn = atoi(optarg); | 697 | } |
| 698 | config.days_till_exp_warn = atoi(optarg); | ||
| 570 | } | 699 | } |
| 571 | check_cert = true; | 700 | config.check_cert = true; |
| 572 | flags |= FLAG_SSL; | 701 | config.use_tls = true; |
| 573 | } break; | 702 | } break; |
| 574 | # endif /* USE_OPENSSL */ | 703 | # endif /* USE_OPENSSL */ |
| 575 | #endif | 704 | #endif |
| 576 | /* fallthrough if we don't have ssl */ | 705 | /* fallthrough if we don't have ssl */ |
| 577 | case 'S': | 706 | case 'S': |
| 578 | #ifdef HAVE_SSL | 707 | #ifdef HAVE_SSL |
| 579 | flags |= FLAG_SSL; | 708 | config.use_tls = true; |
| 580 | #else | 709 | #else |
| 581 | die(STATE_UNKNOWN, _("Invalid option - SSL is not available")); | 710 | die(STATE_UNKNOWN, _("Invalid option - SSL is not available")); |
| 582 | #endif | 711 | #endif |
| 583 | break; | 712 | break; |
| 584 | case SNI_OPTION: | 713 | case SNI_OPTION: |
| 585 | #ifdef HAVE_SSL | 714 | #ifdef HAVE_SSL |
| 586 | flags |= FLAG_SSL; | 715 | config.use_tls = true; |
| 587 | sni_specified = true; | 716 | config.sni_specified = true; |
| 588 | sni = optarg; | 717 | config.sni = optarg; |
| 589 | #else | 718 | #else |
| 590 | die(STATE_UNKNOWN, _("Invalid option - SSL is not available")); | 719 | die(STATE_UNKNOWN, _("Invalid option - SSL is not available")); |
| 591 | #endif | 720 | #endif |
| 592 | break; | 721 | break; |
| 593 | case 'A': | 722 | case 'A': |
| 594 | match_flags |= NP_MATCH_ALL; | 723 | config.match_flags |= NP_MATCH_ALL; |
| 724 | break; | ||
| 725 | case output_format_index: { | ||
| 726 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 727 | if (!parser.parsing_success) { | ||
| 728 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 729 | printf("Invalid output format: %s\n", optarg); | ||
| 730 | exit(STATE_UNKNOWN); | ||
| 731 | } | ||
| 732 | |||
| 733 | config.output_format_set = true; | ||
| 734 | config.output_format = parser.output_format; | ||
| 595 | break; | 735 | break; |
| 596 | } | 736 | } |
| 737 | } | ||
| 597 | } | 738 | } |
| 598 | 739 | ||
| 599 | option_char = optind; | 740 | int index = optind; |
| 600 | if (!host_specified && option_char < argc) | 741 | if (!config.host_specified && index < argc) { |
| 601 | server_address = strdup(argv[option_char++]); | 742 | config.server_address = strdup(argv[index++]); |
| 743 | } | ||
| 602 | 744 | ||
| 603 | if (server_address == NULL) | 745 | if (config.server_address == NULL) { |
| 604 | usage4(_("You must provide a server address")); | 746 | usage4(_("You must provide a server address")); |
| 605 | else if (server_address[0] != '/' && !is_host(server_address)) | 747 | } else if (config.server_address[0] != '/' && !is_host(config.server_address)) { |
| 606 | die(STATE_CRITICAL, "%s %s - %s: %s\n", SERVICE, state_text(STATE_CRITICAL), _("Invalid hostname, address or socket"), | 748 | die(STATE_CRITICAL, "%s %s - %s: %s\n", config.service, state_text(STATE_CRITICAL), |
| 607 | server_address); | 749 | _("Invalid hostname, address or socket"), config.server_address); |
| 750 | } | ||
| 608 | 751 | ||
| 609 | return OK; | 752 | check_tcp_config_wrapper result = { |
| 753 | .config = config, | ||
| 754 | .errorcode = OK, | ||
| 755 | }; | ||
| 756 | return result; | ||
| 610 | } | 757 | } |
| 611 | 758 | ||
| 612 | void print_help(void) { | 759 | void print_help(const char *service) { |
| 613 | print_revision(progname, NP_VERSION); | 760 | print_revision(progname, NP_VERSION); |
| 614 | 761 | ||
| 615 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); | 762 | printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); |
| 616 | printf(COPYRIGHT, copyright, email); | 763 | printf(COPYRIGHT, copyright, email); |
| 617 | 764 | ||
| 618 | printf(_("This plugin tests %s connections with the specified host (or unix socket).\n\n"), SERVICE); | 765 | printf(_("This plugin tests %s connections with the specified host (or unix socket).\n\n"), |
| 766 | service); | ||
| 619 | 767 | ||
| 620 | print_usage(); | 768 | print_usage(); |
| 621 | 769 | ||
| @@ -627,7 +775,8 @@ void print_help(void) { | |||
| 627 | printf(UT_IPv46); | 775 | printf(UT_IPv46); |
| 628 | 776 | ||
| 629 | printf(" %s\n", "-E, --escape"); | 777 | printf(" %s\n", "-E, --escape"); |
| 630 | printf(" %s\n", _("Can use \\n, \\r, \\t or \\\\ in send or quit string. Must come before send or quit option")); | 778 | printf(" %s\n", _("Can use \\n, \\r, \\t or \\\\ in send or quit string. Must come before " |
| 779 | "send or quit option")); | ||
| 631 | printf(" %s\n", _("Default: nothing added to send, \\r\\n added to end of quit")); | 780 | printf(" %s\n", _("Default: nothing added to send, \\r\\n added to end of quit")); |
| 632 | printf(" %s\n", "-s, --send=STRING"); | 781 | printf(" %s\n", "-s, --send=STRING"); |
| 633 | printf(" %s\n", _("String to send to the server")); | 782 | printf(" %s\n", _("String to send to the server")); |
| @@ -640,7 +789,8 @@ void print_help(void) { | |||
| 640 | printf(" %s\n", "-r, --refuse=ok|warn|crit"); | 789 | printf(" %s\n", "-r, --refuse=ok|warn|crit"); |
| 641 | printf(" %s\n", _("Accept TCP refusals with states ok, warn, crit (default: crit)")); | 790 | printf(" %s\n", _("Accept TCP refusals with states ok, warn, crit (default: crit)")); |
| 642 | printf(" %s\n", "-M, --mismatch=ok|warn|crit"); | 791 | printf(" %s\n", "-M, --mismatch=ok|warn|crit"); |
| 643 | printf(" %s\n", _("Accept expected string mismatches with states ok, warn, crit (default: warn)")); | 792 | printf(" %s\n", |
| 793 | _("Accept expected string mismatches with states ok, warn, crit (default: warn)")); | ||
| 644 | printf(" %s\n", "-j, --jail"); | 794 | printf(" %s\n", "-j, --jail"); |
| 645 | printf(" %s\n", _("Hide output from TCP socket")); | 795 | printf(" %s\n", _("Hide output from TCP socket")); |
| 646 | printf(" %s\n", "-m, --maxbytes=INTEGER"); | 796 | printf(" %s\n", "-m, --maxbytes=INTEGER"); |
| @@ -662,6 +812,7 @@ void print_help(void) { | |||
| 662 | 812 | ||
| 663 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 813 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
| 664 | 814 | ||
| 815 | printf(UT_OUTPUT_FORMAT); | ||
| 665 | printf(UT_VERBOSE); | 816 | printf(UT_VERBOSE); |
| 666 | 817 | ||
| 667 | printf(UT_SUPPORT); | 818 | printf(UT_SUPPORT); |
| @@ -669,7 +820,8 @@ void print_help(void) { | |||
| 669 | 820 | ||
| 670 | void print_usage(void) { | 821 | void print_usage(void) { |
| 671 | printf("%s\n", _("Usage:")); | 822 | printf("%s\n", _("Usage:")); |
| 672 | printf("%s -H host -p port [-w <warning time>] [-c <critical time>] [-s <send string>]\n", progname); | 823 | printf("%s -H host -p port [-w <warning time>] [-c <critical time>] [-s <send string>]\n", |
| 824 | progname); | ||
| 673 | printf("[-e <expect string>] [-q <quit string>][-m <maximum bytes>] [-d <delay>]\n"); | 825 | printf("[-e <expect string>] [-q <quit string>][-m <maximum bytes>] [-d <delay>]\n"); |
| 674 | printf("[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]\n"); | 826 | printf("[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]\n"); |
| 675 | printf("[-D <warn days cert expire>[,<crit days cert expire>]] [-S <use SSL>] [-E]\n"); | 827 | printf("[-D <warn days cert expire>[,<crit days cert expire>]] [-S <use SSL>] [-E]\n"); |
diff --git a/plugins/check_tcp.d/config.h b/plugins/check_tcp.d/config.h new file mode 100644 index 00000000..dc25d79e --- /dev/null +++ b/plugins/check_tcp.d/config.h | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../lib/utils_tcp.h" | ||
| 4 | #include "output.h" | ||
| 5 | #include "states.h" | ||
| 6 | #include <netinet/in.h> | ||
| 7 | |||
| 8 | typedef struct { | ||
| 9 | char *server_address; | ||
| 10 | bool host_specified; | ||
| 11 | int server_port; // TODO can this be a uint16? | ||
| 12 | |||
| 13 | int protocol; /* most common is default */ | ||
| 14 | char *service; | ||
| 15 | char *send; | ||
| 16 | char *quit; | ||
| 17 | char **server_expect; | ||
| 18 | size_t server_expect_count; | ||
| 19 | bool use_tls; | ||
| 20 | #ifdef HAVE_SSL | ||
| 21 | char *sni; | ||
| 22 | bool sni_specified; | ||
| 23 | bool check_cert; | ||
| 24 | int days_till_exp_warn; | ||
| 25 | int days_till_exp_crit; | ||
| 26 | #endif // HAVE_SSL | ||
| 27 | int match_flags; | ||
| 28 | mp_state_enum expect_mismatch_state; | ||
| 29 | unsigned int delay; | ||
| 30 | |||
| 31 | bool warning_time_set; | ||
| 32 | double warning_time; | ||
| 33 | bool critical_time_set; | ||
| 34 | double critical_time; | ||
| 35 | |||
| 36 | mp_state_enum econn_refuse_state; | ||
| 37 | |||
| 38 | ssize_t maxbytes; | ||
| 39 | |||
| 40 | bool hide_output; | ||
| 41 | |||
| 42 | bool output_format_set; | ||
| 43 | mp_output_format output_format; | ||
| 44 | } check_tcp_config; | ||
| 45 | |||
| 46 | check_tcp_config check_tcp_config_init() { | ||
| 47 | check_tcp_config result = { | ||
| 48 | .server_address = "127.0.0.1", | ||
| 49 | .host_specified = false, | ||
| 50 | .server_port = 0, | ||
| 51 | |||
| 52 | .protocol = IPPROTO_TCP, | ||
| 53 | .service = "TCP", | ||
| 54 | .send = NULL, | ||
| 55 | .quit = NULL, | ||
| 56 | .server_expect = NULL, | ||
| 57 | .server_expect_count = 0, | ||
| 58 | .use_tls = false, | ||
| 59 | #ifdef HAVE_SSL | ||
| 60 | .sni = NULL, | ||
| 61 | .sni_specified = false, | ||
| 62 | .check_cert = false, | ||
| 63 | .days_till_exp_warn = 0, | ||
| 64 | .days_till_exp_crit = 0, | ||
| 65 | #endif // HAVE_SSL | ||
| 66 | .match_flags = NP_MATCH_EXACT, | ||
| 67 | .expect_mismatch_state = STATE_WARNING, | ||
| 68 | .delay = 0, | ||
| 69 | |||
| 70 | .warning_time_set = false, | ||
| 71 | .warning_time = 0, | ||
| 72 | .critical_time_set = false, | ||
| 73 | .critical_time = 0, | ||
| 74 | |||
| 75 | .econn_refuse_state = STATE_CRITICAL, | ||
| 76 | |||
| 77 | .maxbytes = 0, | ||
| 78 | |||
| 79 | .hide_output = false, | ||
| 80 | |||
| 81 | .output_format_set = false, | ||
| 82 | }; | ||
| 83 | return result; | ||
| 84 | } | ||
diff --git a/plugins/check_time.c b/plugins/check_time.c index d1f50683..fc9ba3f9 100644 --- a/plugins/check_time.c +++ b/plugins/check_time.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | * | 28 | * |
| 29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
| 30 | 30 | ||
| 31 | #include "states.h" | ||
| 31 | const char *progname = "check_time"; | 32 | const char *progname = "check_time"; |
| 32 | const char *copyright = "1999-2024"; | 33 | const char *copyright = "1999-2024"; |
| 33 | const char *email = "devel@monitoring-plugins.org"; | 34 | const char *email = "devel@monitoring-plugins.org"; |
| @@ -35,28 +36,15 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 35 | #include "common.h" | 36 | #include "common.h" |
| 36 | #include "netutils.h" | 37 | #include "netutils.h" |
| 37 | #include "utils.h" | 38 | #include "utils.h" |
| 38 | 39 | #include "check_time.d/config.h" | |
| 39 | enum { | ||
| 40 | TIME_PORT = 37 | ||
| 41 | }; | ||
| 42 | 40 | ||
| 43 | #define UNIX_EPOCH 2208988800UL | 41 | #define UNIX_EPOCH 2208988800UL |
| 44 | 42 | ||
| 45 | static uint32_t raw_server_time; | 43 | typedef struct { |
| 46 | static unsigned long server_time, diff_time; | 44 | int errorcode; |
| 47 | static int warning_time = 0; | 45 | check_time_config config; |
| 48 | static bool check_warning_time = false; | 46 | } check_time_config_wrapper; |
| 49 | static int critical_time = 0; | 47 | static check_time_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); |
| 50 | static bool check_critical_time = false; | ||
| 51 | static unsigned long warning_diff = 0; | ||
| 52 | static bool check_warning_diff = false; | ||
| 53 | static unsigned long critical_diff = 0; | ||
| 54 | static bool check_critical_diff = false; | ||
| 55 | static int server_port = TIME_PORT; | ||
| 56 | static char *server_address = NULL; | ||
| 57 | static bool use_udp = false; | ||
| 58 | |||
| 59 | static int process_arguments(int, char **); | ||
| 60 | static void print_help(void); | 48 | static void print_help(void); |
| 61 | void print_usage(void); | 49 | void print_usage(void); |
| 62 | 50 | ||
| @@ -68,8 +56,12 @@ int main(int argc, char **argv) { | |||
| 68 | /* Parse extra opts if any */ | 56 | /* Parse extra opts if any */ |
| 69 | argv = np_extra_opts(&argc, argv, progname); | 57 | argv = np_extra_opts(&argc, argv, progname); |
| 70 | 58 | ||
| 71 | if (process_arguments(argc, argv) == ERROR) | 59 | check_time_config_wrapper tmp_config = process_arguments(argc, argv); |
| 60 | if (tmp_config.errorcode == ERROR) { | ||
| 72 | usage4(_("Could not parse arguments")); | 61 | usage4(_("Could not parse arguments")); |
| 62 | } | ||
| 63 | |||
| 64 | const check_time_config config = tmp_config.config; | ||
| 73 | 65 | ||
| 74 | /* initialize alarm signal handling */ | 66 | /* initialize alarm signal handling */ |
| 75 | signal(SIGALRM, socket_timeout_alarm_handler); | 67 | signal(SIGALRM, socket_timeout_alarm_handler); |
| @@ -79,37 +71,42 @@ int main(int argc, char **argv) { | |||
| 79 | time(&start_time); | 71 | time(&start_time); |
| 80 | 72 | ||
| 81 | int socket; | 73 | int socket; |
| 82 | int result = STATE_UNKNOWN; | 74 | mp_state_enum result = STATE_UNKNOWN; |
| 83 | /* try to connect to the host at the given port number */ | 75 | /* try to connect to the host at the given port number */ |
| 84 | if (use_udp) { | 76 | if (config.use_udp) { |
| 85 | result = my_udp_connect(server_address, server_port, &socket); | 77 | result = my_udp_connect(config.server_address, config.server_port, &socket); |
| 86 | } else { | 78 | } else { |
| 87 | result = my_tcp_connect(server_address, server_port, &socket); | 79 | result = my_tcp_connect(config.server_address, config.server_port, &socket); |
| 88 | } | 80 | } |
| 89 | 81 | ||
| 90 | if (result != STATE_OK) { | 82 | if (result != STATE_OK) { |
| 91 | if (check_critical_time) | 83 | if (config.check_critical_time) { |
| 92 | result = STATE_CRITICAL; | 84 | result = STATE_CRITICAL; |
| 93 | else if (check_warning_time) | 85 | } else if (config.check_warning_time) { |
| 94 | result = STATE_WARNING; | 86 | result = STATE_WARNING; |
| 95 | else | 87 | } else { |
| 96 | result = STATE_UNKNOWN; | 88 | result = STATE_UNKNOWN; |
| 97 | die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), server_address, server_port); | 89 | } |
| 90 | die(result, _("TIME UNKNOWN - could not connect to server %s, port %d\n"), | ||
| 91 | config.server_address, config.server_port); | ||
| 98 | } | 92 | } |
| 99 | 93 | ||
| 100 | if (use_udp) { | 94 | if (config.use_udp) { |
| 101 | if (send(socket, "", 0, 0) < 0) { | 95 | if (send(socket, "", 0, 0) < 0) { |
| 102 | if (check_critical_time) | 96 | if (config.check_critical_time) { |
| 103 | result = STATE_CRITICAL; | 97 | result = STATE_CRITICAL; |
| 104 | else if (check_warning_time) | 98 | } else if (config.check_warning_time) { |
| 105 | result = STATE_WARNING; | 99 | result = STATE_WARNING; |
| 106 | else | 100 | } else { |
| 107 | result = STATE_UNKNOWN; | 101 | result = STATE_UNKNOWN; |
| 108 | die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), server_address, server_port); | 102 | } |
| 103 | die(result, _("TIME UNKNOWN - could not send UDP request to server %s, port %d\n"), | ||
| 104 | config.server_address, config.server_port); | ||
| 109 | } | 105 | } |
| 110 | } | 106 | } |
| 111 | 107 | ||
| 112 | /* watch for the connection string */ | 108 | /* watch for the connection string */ |
| 109 | uint32_t raw_server_time; | ||
| 113 | result = recv(socket, (void *)&raw_server_time, sizeof(raw_server_time), 0); | 110 | result = recv(socket, (void *)&raw_server_time, sizeof(raw_server_time), 0); |
| 114 | 111 | ||
| 115 | /* close the connection */ | 112 | /* close the connection */ |
| @@ -121,48 +118,59 @@ int main(int argc, char **argv) { | |||
| 121 | 118 | ||
| 122 | /* return a WARNING status if we couldn't read any data */ | 119 | /* return a WARNING status if we couldn't read any data */ |
| 123 | if (result <= 0) { | 120 | if (result <= 0) { |
| 124 | if (check_critical_time) | 121 | if (config.check_critical_time) { |
| 125 | result = STATE_CRITICAL; | 122 | result = STATE_CRITICAL; |
| 126 | else if (check_warning_time) | 123 | } else if (config.check_warning_time) { |
| 127 | result = STATE_WARNING; | 124 | result = STATE_WARNING; |
| 128 | else | 125 | } else { |
| 129 | result = STATE_UNKNOWN; | 126 | result = STATE_UNKNOWN; |
| 130 | die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), server_address, server_port); | 127 | } |
| 128 | die(result, _("TIME UNKNOWN - no data received from server %s, port %d\n"), | ||
| 129 | config.server_address, config.server_port); | ||
| 131 | } | 130 | } |
| 132 | 131 | ||
| 133 | result = STATE_OK; | 132 | result = STATE_OK; |
| 134 | 133 | ||
| 135 | time_t conntime = (end_time - start_time); | 134 | time_t conntime = (end_time - start_time); |
| 136 | if (check_critical_time && conntime > critical_time) | 135 | if (config.check_critical_time && conntime > config.critical_time) { |
| 137 | result = STATE_CRITICAL; | 136 | result = STATE_CRITICAL; |
| 138 | else if (check_warning_time && conntime > warning_time) | 137 | } else if (config.check_warning_time && conntime > config.warning_time) { |
| 139 | result = STATE_WARNING; | 138 | result = STATE_WARNING; |
| 139 | } | ||
| 140 | 140 | ||
| 141 | if (result != STATE_OK) | 141 | if (result != STATE_OK) { |
| 142 | die(result, _("TIME %s - %d second response time|%s\n"), state_text(result), (int)conntime, | 142 | die(result, _("TIME %s - %d second response time|%s\n"), state_text(result), (int)conntime, |
| 143 | perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0, | 143 | perfdata("time", (long)conntime, "s", config.check_warning_time, |
| 144 | false, 0)); | 144 | (long)config.warning_time, config.check_critical_time, |
| 145 | (long)config.critical_time, true, 0, false, 0)); | ||
| 146 | } | ||
| 145 | 147 | ||
| 148 | unsigned long server_time; | ||
| 149 | unsigned long diff_time; | ||
| 146 | server_time = ntohl(raw_server_time) - UNIX_EPOCH; | 150 | server_time = ntohl(raw_server_time) - UNIX_EPOCH; |
| 147 | if (server_time > (unsigned long)end_time) | 151 | if (server_time > (unsigned long)end_time) { |
| 148 | diff_time = server_time - (unsigned long)end_time; | 152 | diff_time = server_time - (unsigned long)end_time; |
| 149 | else | 153 | } else { |
| 150 | diff_time = (unsigned long)end_time - server_time; | 154 | diff_time = (unsigned long)end_time - server_time; |
| 155 | } | ||
| 151 | 156 | ||
| 152 | if (check_critical_diff && diff_time > critical_diff) | 157 | if (config.check_critical_diff && diff_time > config.critical_diff) { |
| 153 | result = STATE_CRITICAL; | 158 | result = STATE_CRITICAL; |
| 154 | else if (check_warning_diff && diff_time > warning_diff) | 159 | } else if (config.check_warning_diff && diff_time > config.warning_diff) { |
| 155 | result = STATE_WARNING; | 160 | result = STATE_WARNING; |
| 161 | } | ||
| 156 | 162 | ||
| 157 | printf(_("TIME %s - %lu second time difference|%s %s\n"), state_text(result), diff_time, | 163 | printf(_("TIME %s - %lu second time difference|%s %s\n"), state_text(result), diff_time, |
| 158 | perfdata("time", (long)conntime, "s", check_warning_time, (long)warning_time, check_critical_time, (long)critical_time, true, 0, | 164 | perfdata("time", (long)conntime, "s", config.check_warning_time, |
| 159 | false, 0), | 165 | (long)config.warning_time, config.check_critical_time, |
| 160 | perfdata("offset", diff_time, "s", check_warning_diff, warning_diff, check_critical_diff, critical_diff, true, 0, false, 0)); | 166 | (long)config.critical_time, true, 0, false, 0), |
| 167 | perfdata("offset", diff_time, "s", config.check_warning_diff, config.warning_diff, | ||
| 168 | config.check_critical_diff, config.critical_diff, true, 0, false, 0)); | ||
| 161 | return result; | 169 | return result; |
| 162 | } | 170 | } |
| 163 | 171 | ||
| 164 | /* process command-line arguments */ | 172 | /* process command-line arguments */ |
| 165 | int process_arguments(int argc, char **argv) { | 173 | check_time_config_wrapper process_arguments(int argc, char **argv) { |
| 166 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, | 174 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, |
| 167 | {"warning-variance", required_argument, 0, 'w'}, | 175 | {"warning-variance", required_argument, 0, 'w'}, |
| 168 | {"critical-variance", required_argument, 0, 'c'}, | 176 | {"critical-variance", required_argument, 0, 'c'}, |
| @@ -175,29 +183,37 @@ int process_arguments(int argc, char **argv) { | |||
| 175 | {"help", no_argument, 0, 'h'}, | 183 | {"help", no_argument, 0, 'h'}, |
| 176 | {0, 0, 0, 0}}; | 184 | {0, 0, 0, 0}}; |
| 177 | 185 | ||
| 178 | if (argc < 2) | 186 | if (argc < 2) { |
| 179 | usage("\n"); | 187 | usage("\n"); |
| 188 | } | ||
| 180 | 189 | ||
| 181 | for (int i = 1; i < argc; i++) { | 190 | for (int i = 1; i < argc; i++) { |
| 182 | if (strcmp("-to", argv[i]) == 0) | 191 | if (strcmp("-to", argv[i]) == 0) { |
| 183 | strcpy(argv[i], "-t"); | 192 | strcpy(argv[i], "-t"); |
| 184 | else if (strcmp("-wd", argv[i]) == 0) | 193 | } else if (strcmp("-wd", argv[i]) == 0) { |
| 185 | strcpy(argv[i], "-w"); | 194 | strcpy(argv[i], "-w"); |
| 186 | else if (strcmp("-cd", argv[i]) == 0) | 195 | } else if (strcmp("-cd", argv[i]) == 0) { |
| 187 | strcpy(argv[i], "-c"); | 196 | strcpy(argv[i], "-c"); |
| 188 | else if (strcmp("-wt", argv[i]) == 0) | 197 | } else if (strcmp("-wt", argv[i]) == 0) { |
| 189 | strcpy(argv[i], "-W"); | 198 | strcpy(argv[i], "-W"); |
| 190 | else if (strcmp("-ct", argv[i]) == 0) | 199 | } else if (strcmp("-ct", argv[i]) == 0) { |
| 191 | strcpy(argv[i], "-C"); | 200 | strcpy(argv[i], "-C"); |
| 201 | } | ||
| 192 | } | 202 | } |
| 193 | 203 | ||
| 204 | check_time_config_wrapper result = { | ||
| 205 | .errorcode = OK, | ||
| 206 | .config = check_time_config_init(), | ||
| 207 | }; | ||
| 208 | |||
| 194 | int option_char; | 209 | int option_char; |
| 195 | while (true) { | 210 | while (true) { |
| 196 | int option = 0; | 211 | int option = 0; |
| 197 | option_char = getopt_long(argc, argv, "hVH:w:c:W:C:p:t:u", longopts, &option); | 212 | option_char = getopt_long(argc, argv, "hVH:w:c:W:C:p:t:u", longopts, &option); |
| 198 | 213 | ||
| 199 | if (option_char == -1 || option_char == EOF) | 214 | if (option_char == -1 || option_char == EOF) { |
| 200 | break; | 215 | break; |
| 216 | } | ||
| 201 | 217 | ||
| 202 | switch (option_char) { | 218 | switch (option_char) { |
| 203 | case '?': /* print short usage statement if args not parsable */ | 219 | case '?': /* print short usage statement if args not parsable */ |
| @@ -209,18 +225,20 @@ int process_arguments(int argc, char **argv) { | |||
| 209 | print_revision(progname, NP_VERSION); | 225 | print_revision(progname, NP_VERSION); |
| 210 | exit(STATE_UNKNOWN); | 226 | exit(STATE_UNKNOWN); |
| 211 | case 'H': /* hostname */ | 227 | case 'H': /* hostname */ |
| 212 | if (!is_host(optarg)) | 228 | if (!is_host(optarg)) { |
| 213 | usage2(_("Invalid hostname/address"), optarg); | 229 | usage2(_("Invalid hostname/address"), optarg); |
| 214 | server_address = optarg; | 230 | } |
| 231 | result.config.server_address = optarg; | ||
| 215 | break; | 232 | break; |
| 216 | case 'w': /* warning-variance */ | 233 | case 'w': /* warning-variance */ |
| 217 | if (is_intnonneg(optarg)) { | 234 | if (is_intnonneg(optarg)) { |
| 218 | warning_diff = strtoul(optarg, NULL, 10); | 235 | result.config.warning_diff = strtoul(optarg, NULL, 10); |
| 219 | check_warning_diff = true; | 236 | result.config.check_warning_diff = true; |
| 220 | } else if (strspn(optarg, "0123456789:,") > 0) { | 237 | } else if (strspn(optarg, "0123456789:,") > 0) { |
| 221 | if (sscanf(optarg, "%lu%*[:,]%d", &warning_diff, &warning_time) == 2) { | 238 | if (sscanf(optarg, "%lu%*[:,]%d", &result.config.warning_diff, |
| 222 | check_warning_diff = true; | 239 | &result.config.warning_time) == 2) { |
| 223 | check_warning_time = true; | 240 | result.config.check_warning_diff = true; |
| 241 | result.config.check_warning_time = true; | ||
| 224 | } else { | 242 | } else { |
| 225 | usage4(_("Warning thresholds must be a positive integer")); | 243 | usage4(_("Warning thresholds must be a positive integer")); |
| 226 | } | 244 | } |
| @@ -230,12 +248,13 @@ int process_arguments(int argc, char **argv) { | |||
| 230 | break; | 248 | break; |
| 231 | case 'c': /* critical-variance */ | 249 | case 'c': /* critical-variance */ |
| 232 | if (is_intnonneg(optarg)) { | 250 | if (is_intnonneg(optarg)) { |
| 233 | critical_diff = strtoul(optarg, NULL, 10); | 251 | result.config.critical_diff = strtoul(optarg, NULL, 10); |
| 234 | check_critical_diff = true; | 252 | result.config.check_critical_diff = true; |
| 235 | } else if (strspn(optarg, "0123456789:,") > 0) { | 253 | } else if (strspn(optarg, "0123456789:,") > 0) { |
| 236 | if (sscanf(optarg, "%lu%*[:,]%d", &critical_diff, &critical_time) == 2) { | 254 | if (sscanf(optarg, "%lu%*[:,]%d", &result.config.critical_diff, |
| 237 | check_critical_diff = true; | 255 | &result.config.critical_time) == 2) { |
| 238 | check_critical_time = true; | 256 | result.config.check_critical_diff = true; |
| 257 | result.config.check_critical_time = true; | ||
| 239 | } else { | 258 | } else { |
| 240 | usage4(_("Critical thresholds must be a positive integer")); | 259 | usage4(_("Critical thresholds must be a positive integer")); |
| 241 | } | 260 | } |
| @@ -244,48 +263,53 @@ int process_arguments(int argc, char **argv) { | |||
| 244 | } | 263 | } |
| 245 | break; | 264 | break; |
| 246 | case 'W': /* warning-connect */ | 265 | case 'W': /* warning-connect */ |
| 247 | if (!is_intnonneg(optarg)) | 266 | if (!is_intnonneg(optarg)) { |
| 248 | usage4(_("Warning threshold must be a positive integer")); | 267 | usage4(_("Warning threshold must be a positive integer")); |
| 249 | else | 268 | } else { |
| 250 | warning_time = atoi(optarg); | 269 | result.config.warning_time = atoi(optarg); |
| 251 | check_warning_time = true; | 270 | } |
| 271 | result.config.check_warning_time = true; | ||
| 252 | break; | 272 | break; |
| 253 | case 'C': /* critical-connect */ | 273 | case 'C': /* critical-connect */ |
| 254 | if (!is_intnonneg(optarg)) | 274 | if (!is_intnonneg(optarg)) { |
| 255 | usage4(_("Critical threshold must be a positive integer")); | 275 | usage4(_("Critical threshold must be a positive integer")); |
| 256 | else | 276 | } else { |
| 257 | critical_time = atoi(optarg); | 277 | result.config.critical_time = atoi(optarg); |
| 258 | check_critical_time = true; | 278 | } |
| 279 | result.config.check_critical_time = true; | ||
| 259 | break; | 280 | break; |
| 260 | case 'p': /* port */ | 281 | case 'p': /* port */ |
| 261 | if (!is_intnonneg(optarg)) | 282 | if (!is_intnonneg(optarg)) { |
| 262 | usage4(_("Port must be a positive integer")); | 283 | usage4(_("Port must be a positive integer")); |
| 263 | else | 284 | } else { |
| 264 | server_port = atoi(optarg); | 285 | result.config.server_port = atoi(optarg); |
| 286 | } | ||
| 265 | break; | 287 | break; |
| 266 | case 't': /* timeout */ | 288 | case 't': /* timeout */ |
| 267 | if (!is_intnonneg(optarg)) | 289 | if (!is_intnonneg(optarg)) { |
| 268 | usage2(_("Timeout interval must be a positive integer"), optarg); | 290 | usage2(_("Timeout interval must be a positive integer"), optarg); |
| 269 | else | 291 | } else { |
| 270 | socket_timeout = atoi(optarg); | 292 | socket_timeout = atoi(optarg); |
| 293 | } | ||
| 271 | break; | 294 | break; |
| 272 | case 'u': /* udp */ | 295 | case 'u': /* udp */ |
| 273 | use_udp = true; | 296 | result.config.use_udp = true; |
| 274 | } | 297 | } |
| 275 | } | 298 | } |
| 276 | 299 | ||
| 277 | option_char = optind; | 300 | option_char = optind; |
| 278 | if (server_address == NULL) { | 301 | if (result.config.server_address == NULL) { |
| 279 | if (argc > option_char) { | 302 | if (argc > option_char) { |
| 280 | if (!is_host(argv[option_char])) | 303 | if (!is_host(argv[option_char])) { |
| 281 | usage2(_("Invalid hostname/address"), optarg); | 304 | usage2(_("Invalid hostname/address"), optarg); |
| 282 | server_address = argv[option_char]; | 305 | } |
| 306 | result.config.server_address = argv[option_char]; | ||
| 283 | } else { | 307 | } else { |
| 284 | usage4(_("Hostname was not supplied")); | 308 | usage4(_("Hostname was not supplied")); |
| 285 | } | 309 | } |
| 286 | } | 310 | } |
| 287 | 311 | ||
| 288 | return OK; | 312 | return result; |
| 289 | } | 313 | } |
| 290 | 314 | ||
| 291 | void print_help(void) { | 315 | void print_help(void) { |
diff --git a/plugins/check_time.d/config.h b/plugins/check_time.d/config.h new file mode 100644 index 00000000..09bd7c45 --- /dev/null +++ b/plugins/check_time.d/config.h | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include <stddef.h> | ||
| 5 | |||
| 6 | enum { | ||
| 7 | TIME_PORT = 37 | ||
| 8 | }; | ||
| 9 | |||
| 10 | typedef struct { | ||
| 11 | char *server_address; | ||
| 12 | int server_port; | ||
| 13 | bool use_udp; | ||
| 14 | |||
| 15 | int warning_time; | ||
| 16 | bool check_warning_time; | ||
| 17 | int critical_time; | ||
| 18 | bool check_critical_time; | ||
| 19 | unsigned long warning_diff; | ||
| 20 | bool check_warning_diff; | ||
| 21 | unsigned long critical_diff; | ||
| 22 | bool check_critical_diff; | ||
| 23 | } check_time_config; | ||
| 24 | |||
| 25 | check_time_config check_time_config_init() { | ||
| 26 | check_time_config tmp = { | ||
| 27 | .server_address = NULL, | ||
| 28 | .server_port = TIME_PORT, | ||
| 29 | .use_udp = false, | ||
| 30 | |||
| 31 | .warning_time = 0, | ||
| 32 | .check_warning_time = false, | ||
| 33 | .critical_time = 0, | ||
| 34 | .check_critical_time = false, | ||
| 35 | |||
| 36 | .warning_diff = 0, | ||
| 37 | .check_warning_diff = false, | ||
| 38 | .critical_diff = 0, | ||
| 39 | .check_critical_diff = false, | ||
| 40 | }; | ||
| 41 | return tmp; | ||
| 42 | } | ||
diff --git a/plugins/check_ups.c b/plugins/check_ups.c index 526a29df..54decce3 100644 --- a/plugins/check_ups.c +++ b/plugins/check_ups.c | |||
| @@ -39,69 +39,29 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 39 | #include "common.h" | 39 | #include "common.h" |
| 40 | #include "netutils.h" | 40 | #include "netutils.h" |
| 41 | #include "utils.h" | 41 | #include "utils.h" |
| 42 | 42 | #include "check_ups.d/config.h" | |
| 43 | enum { | 43 | #include "states.h" |
| 44 | PORT = 3493 | ||
| 45 | }; | ||
| 46 | |||
| 47 | #define UPS_NONE 0 /* no supported options */ | ||
| 48 | #define UPS_UTILITY 1 /* supports utility line */ | ||
| 49 | #define UPS_BATTPCT 2 /* supports percent battery remaining */ | ||
| 50 | #define UPS_STATUS 4 /* supports UPS status */ | ||
| 51 | #define UPS_TEMP 8 /* supports UPS temperature */ | ||
| 52 | #define UPS_LOADPCT 16 /* supports load percent */ | ||
| 53 | #define UPS_REALPOWER 32 /* supports real power */ | ||
| 54 | |||
| 55 | #define UPSSTATUS_NONE 0 | ||
| 56 | #define UPSSTATUS_OFF 1 | ||
| 57 | #define UPSSTATUS_OL 2 | ||
| 58 | #define UPSSTATUS_OB 4 | ||
| 59 | #define UPSSTATUS_LB 8 | ||
| 60 | #define UPSSTATUS_CAL 16 | ||
| 61 | #define UPSSTATUS_RB 32 /*Replace Battery */ | ||
| 62 | #define UPSSTATUS_BYPASS 64 | ||
| 63 | #define UPSSTATUS_OVER 128 | ||
| 64 | #define UPSSTATUS_TRIM 256 | ||
| 65 | #define UPSSTATUS_BOOST 512 | ||
| 66 | #define UPSSTATUS_CHRG 1024 | ||
| 67 | #define UPSSTATUS_DISCHRG 2048 | ||
| 68 | #define UPSSTATUS_UNKNOWN 4096 | ||
| 69 | #define UPSSTATUS_ALARM 8192 | ||
| 70 | 44 | ||
| 71 | enum { | 45 | enum { |
| 72 | NOSUCHVAR = ERROR - 1 | 46 | NOSUCHVAR = ERROR - 1 |
| 73 | }; | 47 | }; |
| 74 | 48 | ||
| 75 | typedef struct ups_config { | ||
| 76 | unsigned int server_port; | ||
| 77 | char *server_address; | ||
| 78 | char *ups_name; | ||
| 79 | double warning_value; | ||
| 80 | double critical_value; | ||
| 81 | bool check_warn; | ||
| 82 | bool check_crit; | ||
| 83 | int check_variable; | ||
| 84 | int status; | ||
| 85 | bool temp_output_c; | ||
| 86 | } ups_config; | ||
| 87 | |||
| 88 | ups_config ups_config_init(void) { | ||
| 89 | ups_config tmp = {0}; | ||
| 90 | tmp.server_port = PORT; | ||
| 91 | tmp.server_address = NULL; | ||
| 92 | tmp.ups_name = NULL; | ||
| 93 | tmp.check_variable = UPS_NONE; | ||
| 94 | tmp.status = UPSSTATUS_NONE; | ||
| 95 | |||
| 96 | return tmp; | ||
| 97 | } | ||
| 98 | |||
| 99 | // Forward declarations | 49 | // Forward declarations |
| 100 | static int determine_status(ups_config * /*config*/, int *supported_options); | 50 | typedef struct { |
| 101 | static int get_ups_variable(const char * /*varname*/, char * /*buf*/, ups_config config); | 51 | int errorcode; |
| 52 | int ups_status; | ||
| 53 | int supported_options; | ||
| 54 | } determine_status_result; | ||
| 55 | static determine_status_result determine_status(check_ups_config /*config*/); | ||
| 56 | static int get_ups_variable(const char * /*varname*/, char * /*buf*/, check_ups_config config); | ||
| 57 | |||
| 58 | typedef struct { | ||
| 59 | int errorcode; | ||
| 60 | check_ups_config config; | ||
| 61 | } check_ups_config_wrapper; | ||
| 62 | static check_ups_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 63 | static check_ups_config_wrapper validate_arguments(check_ups_config_wrapper /*config_wrapper*/); | ||
| 102 | 64 | ||
| 103 | static int process_arguments(int /*argc*/, char ** /*argv*/, ups_config * /*config*/); | ||
| 104 | static int validate_arguments(ups_config /*config*/); | ||
| 105 | static void print_help(void); | 65 | static void print_help(void); |
| 106 | void print_usage(void); | 66 | void print_usage(void); |
| 107 | 67 | ||
| @@ -109,28 +69,16 @@ int main(int argc, char **argv) { | |||
| 109 | setlocale(LC_ALL, ""); | 69 | setlocale(LC_ALL, ""); |
| 110 | bindtextdomain(PACKAGE, LOCALEDIR); | 70 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 111 | textdomain(PACKAGE); | 71 | textdomain(PACKAGE); |
| 112 | |||
| 113 | char *ups_status; | ||
| 114 | ups_status = strdup("N/A"); | ||
| 115 | |||
| 116 | char *data; | ||
| 117 | data = strdup(""); | ||
| 118 | |||
| 119 | char *message; | ||
| 120 | message = strdup(""); | ||
| 121 | |||
| 122 | // Exit result | ||
| 123 | int result = STATE_UNKNOWN; | ||
| 124 | |||
| 125 | /* Parse extra opts if any */ | 72 | /* Parse extra opts if any */ |
| 126 | argv = np_extra_opts(&argc, argv, progname); | 73 | argv = np_extra_opts(&argc, argv, progname); |
| 127 | 74 | ||
| 128 | // Config from commandline | 75 | check_ups_config_wrapper tmp_config = process_arguments(argc, argv); |
| 129 | ups_config config = ups_config_init(); | ||
| 130 | 76 | ||
| 131 | if (process_arguments(argc, argv, &config) == ERROR) { | 77 | if (tmp_config.errorcode == ERROR) { |
| 132 | usage4(_("Could not parse arguments")); | 78 | usage4(_("Could not parse arguments")); |
| 133 | } | 79 | } |
| 80 | // Config from commandline | ||
| 81 | check_ups_config config = tmp_config.config; | ||
| 134 | 82 | ||
| 135 | /* initialize alarm signal handling */ | 83 | /* initialize alarm signal handling */ |
| 136 | signal(SIGALRM, socket_timeout_alarm_handler); | 84 | signal(SIGALRM, socket_timeout_alarm_handler); |
| @@ -138,71 +86,76 @@ int main(int argc, char **argv) { | |||
| 138 | /* set socket timeout */ | 86 | /* set socket timeout */ |
| 139 | alarm(socket_timeout); | 87 | alarm(socket_timeout); |
| 140 | 88 | ||
| 141 | int supported_options = UPS_NONE; | ||
| 142 | |||
| 143 | /* get the ups status if possible */ | 89 | /* get the ups status if possible */ |
| 144 | if (determine_status(&config, &supported_options) != OK) { | 90 | determine_status_result query_result = determine_status(config); |
| 91 | if (query_result.errorcode != OK) { | ||
| 145 | return STATE_CRITICAL; | 92 | return STATE_CRITICAL; |
| 146 | } | 93 | } |
| 147 | 94 | ||
| 148 | if (supported_options & UPS_STATUS) { | 95 | int ups_status_flags = query_result.ups_status; |
| 96 | int supported_options = query_result.supported_options; | ||
| 149 | 97 | ||
| 150 | ups_status = strdup(""); | 98 | // Exit result |
| 99 | mp_state_enum result = STATE_UNKNOWN; | ||
| 100 | char *message = NULL; | ||
| 151 | 101 | ||
| 102 | if (supported_options & UPS_STATUS) { | ||
| 103 | char *ups_status = strdup(""); | ||
| 152 | result = STATE_OK; | 104 | result = STATE_OK; |
| 153 | 105 | ||
| 154 | if (config.status & UPSSTATUS_OFF) { | 106 | if (ups_status_flags & UPSSTATUS_OFF) { |
| 155 | xasprintf(&ups_status, "Off"); | 107 | xasprintf(&ups_status, "Off"); |
| 156 | result = STATE_CRITICAL; | 108 | result = STATE_CRITICAL; |
| 157 | } else if ((config.status & (UPSSTATUS_OB | UPSSTATUS_LB)) == (UPSSTATUS_OB | UPSSTATUS_LB)) { | 109 | } else if ((ups_status_flags & (UPSSTATUS_OB | UPSSTATUS_LB)) == |
| 110 | (UPSSTATUS_OB | UPSSTATUS_LB)) { | ||
| 158 | xasprintf(&ups_status, _("On Battery, Low Battery")); | 111 | xasprintf(&ups_status, _("On Battery, Low Battery")); |
| 159 | result = STATE_CRITICAL; | 112 | result = STATE_CRITICAL; |
| 160 | } else { | 113 | } else { |
| 161 | if (config.status & UPSSTATUS_OL) { | 114 | if (ups_status_flags & UPSSTATUS_OL) { |
| 162 | xasprintf(&ups_status, "%s%s", ups_status, _("Online")); | 115 | xasprintf(&ups_status, "%s%s", ups_status, _("Online")); |
| 163 | } | 116 | } |
| 164 | if (config.status & UPSSTATUS_OB) { | 117 | if (ups_status_flags & UPSSTATUS_OB) { |
| 165 | xasprintf(&ups_status, "%s%s", ups_status, _("On Battery")); | 118 | xasprintf(&ups_status, "%s%s", ups_status, _("On Battery")); |
| 166 | result = max_state(result, STATE_WARNING); | 119 | result = max_state(result, STATE_WARNING); |
| 167 | } | 120 | } |
| 168 | if (config.status & UPSSTATUS_LB) { | 121 | if (ups_status_flags & UPSSTATUS_LB) { |
| 169 | xasprintf(&ups_status, "%s%s", ups_status, _(", Low Battery")); | 122 | xasprintf(&ups_status, "%s%s", ups_status, _(", Low Battery")); |
| 170 | result = max_state(result, STATE_WARNING); | 123 | result = max_state(result, STATE_WARNING); |
| 171 | } | 124 | } |
| 172 | if (config.status & UPSSTATUS_CAL) { | 125 | if (ups_status_flags & UPSSTATUS_CAL) { |
| 173 | xasprintf(&ups_status, "%s%s", ups_status, _(", Calibrating")); | 126 | xasprintf(&ups_status, "%s%s", ups_status, _(", Calibrating")); |
| 174 | } | 127 | } |
| 175 | if (config.status & UPSSTATUS_RB) { | 128 | if (ups_status_flags & UPSSTATUS_RB) { |
| 176 | xasprintf(&ups_status, "%s%s", ups_status, _(", Replace Battery")); | 129 | xasprintf(&ups_status, "%s%s", ups_status, _(", Replace Battery")); |
| 177 | result = max_state(result, STATE_WARNING); | 130 | result = max_state(result, STATE_WARNING); |
| 178 | } | 131 | } |
| 179 | if (config.status & UPSSTATUS_BYPASS) { | 132 | if (ups_status_flags & UPSSTATUS_BYPASS) { |
| 180 | xasprintf(&ups_status, "%s%s", ups_status, _(", On Bypass")); | 133 | xasprintf(&ups_status, "%s%s", ups_status, _(", On Bypass")); |
| 181 | // Bypassing the battery is likely a bad thing | 134 | // Bypassing the battery is likely a bad thing |
| 182 | result = STATE_CRITICAL; | 135 | result = STATE_CRITICAL; |
| 183 | } | 136 | } |
| 184 | if (config.status & UPSSTATUS_OVER) { | 137 | if (ups_status_flags & UPSSTATUS_OVER) { |
| 185 | xasprintf(&ups_status, "%s%s", ups_status, _(", Overload")); | 138 | xasprintf(&ups_status, "%s%s", ups_status, _(", Overload")); |
| 186 | result = max_state(result, STATE_WARNING); | 139 | result = max_state(result, STATE_WARNING); |
| 187 | } | 140 | } |
| 188 | if (config.status & UPSSTATUS_TRIM) { | 141 | if (ups_status_flags & UPSSTATUS_TRIM) { |
| 189 | xasprintf(&ups_status, "%s%s", ups_status, _(", Trimming")); | 142 | xasprintf(&ups_status, "%s%s", ups_status, _(", Trimming")); |
| 190 | } | 143 | } |
| 191 | if (config.status & UPSSTATUS_BOOST) { | 144 | if (ups_status_flags & UPSSTATUS_BOOST) { |
| 192 | xasprintf(&ups_status, "%s%s", ups_status, _(", Boosting")); | 145 | xasprintf(&ups_status, "%s%s", ups_status, _(", Boosting")); |
| 193 | } | 146 | } |
| 194 | if (config.status & UPSSTATUS_CHRG) { | 147 | if (ups_status_flags & UPSSTATUS_CHRG) { |
| 195 | xasprintf(&ups_status, "%s%s", ups_status, _(", Charging")); | 148 | xasprintf(&ups_status, "%s%s", ups_status, _(", Charging")); |
| 196 | } | 149 | } |
| 197 | if (config.status & UPSSTATUS_DISCHRG) { | 150 | if (ups_status_flags & UPSSTATUS_DISCHRG) { |
| 198 | xasprintf(&ups_status, "%s%s", ups_status, _(", Discharging")); | 151 | xasprintf(&ups_status, "%s%s", ups_status, _(", Discharging")); |
| 199 | result = max_state(result, STATE_WARNING); | 152 | result = max_state(result, STATE_WARNING); |
| 200 | } | 153 | } |
| 201 | if (config.status & UPSSTATUS_ALARM) { | 154 | if (ups_status_flags & UPSSTATUS_ALARM) { |
| 202 | xasprintf(&ups_status, "%s%s", ups_status, _(", ALARM")); | 155 | xasprintf(&ups_status, "%s%s", ups_status, _(", ALARM")); |
| 203 | result = STATE_CRITICAL; | 156 | result = STATE_CRITICAL; |
| 204 | } | 157 | } |
| 205 | if (config.status & UPSSTATUS_UNKNOWN) { | 158 | if (ups_status_flags & UPSSTATUS_UNKNOWN) { |
| 206 | xasprintf(&ups_status, "%s%s", ups_status, _(", Unknown")); | 159 | xasprintf(&ups_status, "%s%s", ups_status, _(", Unknown")); |
| 207 | } | 160 | } |
| 208 | } | 161 | } |
| @@ -211,7 +164,7 @@ int main(int argc, char **argv) { | |||
| 211 | 164 | ||
| 212 | int res; | 165 | int res; |
| 213 | char temp_buffer[MAX_INPUT_BUFFER]; | 166 | char temp_buffer[MAX_INPUT_BUFFER]; |
| 214 | 167 | char *performance_data = strdup(""); | |
| 215 | /* get the ups utility voltage if possible */ | 168 | /* get the ups utility voltage if possible */ |
| 216 | res = get_ups_variable("input.voltage", temp_buffer, config); | 169 | res = get_ups_variable("input.voltage", temp_buffer, config); |
| 217 | if (res == NOSUCHVAR) { | 170 | if (res == NOSUCHVAR) { |
| @@ -239,11 +192,15 @@ int main(int argc, char **argv) { | |||
| 239 | } else if (config.check_warn && ups_utility_deviation >= config.warning_value) { | 192 | } else if (config.check_warn && ups_utility_deviation >= config.warning_value) { |
| 240 | result = max_state(result, STATE_WARNING); | 193 | result = max_state(result, STATE_WARNING); |
| 241 | } | 194 | } |
| 242 | xasprintf(&data, "%s", | 195 | xasprintf(&performance_data, "%s", |
| 243 | perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", config.check_warn, (long)(1000 * config.warning_value), | 196 | perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", |
| 244 | config.check_crit, (long)(1000 * config.critical_value), true, 0, false, 0)); | 197 | config.check_warn, (long)(1000 * config.warning_value), |
| 198 | config.check_crit, (long)(1000 * config.critical_value), true, 0, | ||
| 199 | false, 0)); | ||
| 245 | } else { | 200 | } else { |
| 246 | xasprintf(&data, "%s", perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", false, 0, false, 0, true, 0, false, 0)); | 201 | xasprintf(&performance_data, "%s", |
| 202 | perfdata("voltage", (long)(1000 * ups_utility_voltage), "mV", false, 0, false, | ||
| 203 | 0, true, 0, false, 0)); | ||
| 247 | } | 204 | } |
| 248 | } | 205 | } |
| 249 | 206 | ||
| @@ -266,11 +223,14 @@ int main(int argc, char **argv) { | |||
| 266 | } else if (config.check_warn && ups_battery_percent <= config.warning_value) { | 223 | } else if (config.check_warn && ups_battery_percent <= config.warning_value) { |
| 267 | result = max_state(result, STATE_WARNING); | 224 | result = max_state(result, STATE_WARNING); |
| 268 | } | 225 | } |
| 269 | xasprintf(&data, "%s %s", data, | 226 | xasprintf(&performance_data, "%s %s", performance_data, |
| 270 | perfdata("battery", (long)ups_battery_percent, "%", config.check_warn, (long)(config.warning_value), | 227 | perfdata("battery", (long)ups_battery_percent, "%", config.check_warn, |
| 271 | config.check_crit, (long)(config.critical_value), true, 0, true, 100)); | 228 | (long)(config.warning_value), config.check_crit, |
| 229 | (long)(config.critical_value), true, 0, true, 100)); | ||
| 272 | } else { | 230 | } else { |
| 273 | xasprintf(&data, "%s %s", data, perfdata("battery", (long)ups_battery_percent, "%", false, 0, false, 0, true, 0, true, 100)); | 231 | xasprintf(&performance_data, "%s %s", performance_data, |
| 232 | perfdata("battery", (long)ups_battery_percent, "%", false, 0, false, 0, true, | ||
| 233 | 0, true, 100)); | ||
| 274 | } | 234 | } |
| 275 | } | 235 | } |
| 276 | 236 | ||
| @@ -293,11 +253,14 @@ int main(int argc, char **argv) { | |||
| 293 | } else if (config.check_warn && ups_load_percent >= config.warning_value) { | 253 | } else if (config.check_warn && ups_load_percent >= config.warning_value) { |
| 294 | result = max_state(result, STATE_WARNING); | 254 | result = max_state(result, STATE_WARNING); |
| 295 | } | 255 | } |
| 296 | xasprintf(&data, "%s %s", data, | 256 | xasprintf(&performance_data, "%s %s", performance_data, |
| 297 | perfdata("load", (long)ups_load_percent, "%", config.check_warn, (long)(config.warning_value), config.check_crit, | 257 | perfdata("load", (long)ups_load_percent, "%", config.check_warn, |
| 258 | (long)(config.warning_value), config.check_crit, | ||
| 298 | (long)(config.critical_value), true, 0, true, 100)); | 259 | (long)(config.critical_value), true, 0, true, 100)); |
| 299 | } else { | 260 | } else { |
| 300 | xasprintf(&data, "%s %s", data, perfdata("load", (long)ups_load_percent, "%", false, 0, false, 0, true, 0, true, 100)); | 261 | xasprintf(&performance_data, "%s %s", performance_data, |
| 262 | perfdata("load", (long)ups_load_percent, "%", false, 0, false, 0, true, 0, | ||
| 263 | true, 100)); | ||
| 301 | } | 264 | } |
| 302 | } | 265 | } |
| 303 | 266 | ||
| @@ -329,11 +292,14 @@ int main(int argc, char **argv) { | |||
| 329 | } else if (config.check_warn && ups_temperature >= config.warning_value) { | 292 | } else if (config.check_warn && ups_temperature >= config.warning_value) { |
| 330 | result = max_state(result, STATE_WARNING); | 293 | result = max_state(result, STATE_WARNING); |
| 331 | } | 294 | } |
| 332 | xasprintf(&data, "%s %s", data, | 295 | xasprintf(&performance_data, "%s %s", performance_data, |
| 333 | perfdata("temp", (long)ups_temperature, tunits, config.check_warn, (long)(config.warning_value), config.check_crit, | 296 | perfdata("temp", (long)ups_temperature, tunits, config.check_warn, |
| 297 | (long)(config.warning_value), config.check_crit, | ||
| 334 | (long)(config.critical_value), true, 0, false, 0)); | 298 | (long)(config.critical_value), true, 0, false, 0)); |
| 335 | } else { | 299 | } else { |
| 336 | xasprintf(&data, "%s %s", data, perfdata("temp", (long)ups_temperature, tunits, false, 0, false, 0, true, 0, false, 0)); | 300 | xasprintf(&performance_data, "%s %s", performance_data, |
| 301 | perfdata("temp", (long)ups_temperature, tunits, false, 0, false, 0, true, 0, | ||
| 302 | false, 0)); | ||
| 337 | } | 303 | } |
| 338 | } | 304 | } |
| 339 | 305 | ||
| @@ -355,11 +321,14 @@ int main(int argc, char **argv) { | |||
| 355 | } else if (config.check_warn && ups_realpower >= config.warning_value) { | 321 | } else if (config.check_warn && ups_realpower >= config.warning_value) { |
| 356 | result = max_state(result, STATE_WARNING); | 322 | result = max_state(result, STATE_WARNING); |
| 357 | } | 323 | } |
| 358 | xasprintf(&data, "%s %s", data, | 324 | xasprintf(&performance_data, "%s %s", performance_data, |
| 359 | perfdata("realpower", (long)ups_realpower, "W", config.check_warn, (long)(config.warning_value), config.check_crit, | 325 | perfdata("realpower", (long)ups_realpower, "W", config.check_warn, |
| 326 | (long)(config.warning_value), config.check_crit, | ||
| 360 | (long)(config.critical_value), true, 0, false, 0)); | 327 | (long)(config.critical_value), true, 0, false, 0)); |
| 361 | } else { | 328 | } else { |
| 362 | xasprintf(&data, "%s %s", data, perfdata("realpower", (long)ups_realpower, "W", false, 0, false, 0, true, 0, false, 0)); | 329 | xasprintf(&performance_data, "%s %s", performance_data, |
| 330 | perfdata("realpower", (long)ups_realpower, "W", false, 0, false, 0, true, 0, | ||
| 331 | false, 0)); | ||
| 363 | } | 332 | } |
| 364 | } | 333 | } |
| 365 | 334 | ||
| @@ -373,71 +342,79 @@ int main(int argc, char **argv) { | |||
| 373 | /* reset timeout */ | 342 | /* reset timeout */ |
| 374 | alarm(0); | 343 | alarm(0); |
| 375 | 344 | ||
| 376 | printf("UPS %s - %s|%s\n", state_text(result), message, data); | 345 | printf("UPS %s - %s|%s\n", state_text(result), message, performance_data); |
| 377 | return result; | 346 | exit(result); |
| 378 | } | 347 | } |
| 379 | 348 | ||
| 380 | /* determines what options are supported by the UPS */ | 349 | /* determines what options are supported by the UPS */ |
| 381 | int determine_status(ups_config *config, int *supported_options) { | 350 | determine_status_result determine_status(const check_ups_config config) { |
| 382 | char recv_buffer[MAX_INPUT_BUFFER]; | ||
| 383 | 351 | ||
| 384 | int res = get_ups_variable("ups.status", recv_buffer, *config); | 352 | determine_status_result result = { |
| 353 | .errorcode = OK, | ||
| 354 | .ups_status = UPSSTATUS_NONE, | ||
| 355 | .supported_options = 0, | ||
| 356 | }; | ||
| 357 | |||
| 358 | char recv_buffer[MAX_INPUT_BUFFER]; | ||
| 359 | int res = get_ups_variable("ups.status", recv_buffer, config); | ||
| 385 | if (res == NOSUCHVAR) { | 360 | if (res == NOSUCHVAR) { |
| 386 | return OK; | 361 | return result; |
| 387 | } | 362 | } |
| 388 | 363 | ||
| 389 | if (res != STATE_OK) { | 364 | if (res != STATE_OK) { |
| 390 | printf("%s\n", _("Invalid response received from host")); | 365 | printf("%s\n", _("Invalid response received from host")); |
| 391 | return ERROR; | 366 | result.errorcode = ERROR; |
| 367 | return result; | ||
| 392 | } | 368 | } |
| 393 | 369 | ||
| 394 | *supported_options |= UPS_STATUS; | 370 | result.supported_options |= UPS_STATUS; |
| 395 | 371 | ||
| 396 | char temp_buffer[MAX_INPUT_BUFFER]; | 372 | char temp_buffer[MAX_INPUT_BUFFER]; |
| 397 | 373 | ||
| 398 | strcpy(temp_buffer, recv_buffer); | 374 | strcpy(temp_buffer, recv_buffer); |
| 399 | for (char *ptr = (char *)strtok(temp_buffer, " "); ptr != NULL; ptr = (char *)strtok(NULL, " ")) { | 375 | for (char *ptr = strtok(temp_buffer, " "); ptr != NULL; ptr = strtok(NULL, " ")) { |
| 400 | if (!strcmp(ptr, "OFF")) { | 376 | if (!strcmp(ptr, "OFF")) { |
| 401 | config->status |= UPSSTATUS_OFF; | 377 | result.ups_status |= UPSSTATUS_OFF; |
| 402 | } else if (!strcmp(ptr, "OL")) { | 378 | } else if (!strcmp(ptr, "OL")) { |
| 403 | config->status |= UPSSTATUS_OL; | 379 | result.ups_status |= UPSSTATUS_OL; |
| 404 | } else if (!strcmp(ptr, "OB")) { | 380 | } else if (!strcmp(ptr, "OB")) { |
| 405 | config->status |= UPSSTATUS_OB; | 381 | result.ups_status |= UPSSTATUS_OB; |
| 406 | } else if (!strcmp(ptr, "LB")) { | 382 | } else if (!strcmp(ptr, "LB")) { |
| 407 | config->status |= UPSSTATUS_LB; | 383 | result.ups_status |= UPSSTATUS_LB; |
| 408 | } else if (!strcmp(ptr, "CAL")) { | 384 | } else if (!strcmp(ptr, "CAL")) { |
| 409 | config->status |= UPSSTATUS_CAL; | 385 | result.ups_status |= UPSSTATUS_CAL; |
| 410 | } else if (!strcmp(ptr, "RB")) { | 386 | } else if (!strcmp(ptr, "RB")) { |
| 411 | config->status |= UPSSTATUS_RB; | 387 | result.ups_status |= UPSSTATUS_RB; |
| 412 | } else if (!strcmp(ptr, "BYPASS")) { | 388 | } else if (!strcmp(ptr, "BYPASS")) { |
| 413 | config->status |= UPSSTATUS_BYPASS; | 389 | result.ups_status |= UPSSTATUS_BYPASS; |
| 414 | } else if (!strcmp(ptr, "OVER")) { | 390 | } else if (!strcmp(ptr, "OVER")) { |
| 415 | config->status |= UPSSTATUS_OVER; | 391 | result.ups_status |= UPSSTATUS_OVER; |
| 416 | } else if (!strcmp(ptr, "TRIM")) { | 392 | } else if (!strcmp(ptr, "TRIM")) { |
| 417 | config->status |= UPSSTATUS_TRIM; | 393 | result.ups_status |= UPSSTATUS_TRIM; |
| 418 | } else if (!strcmp(ptr, "BOOST")) { | 394 | } else if (!strcmp(ptr, "BOOST")) { |
| 419 | config->status |= UPSSTATUS_BOOST; | 395 | result.ups_status |= UPSSTATUS_BOOST; |
| 420 | } else if (!strcmp(ptr, "CHRG")) { | 396 | } else if (!strcmp(ptr, "CHRG")) { |
| 421 | config->status |= UPSSTATUS_CHRG; | 397 | result.ups_status |= UPSSTATUS_CHRG; |
| 422 | } else if (!strcmp(ptr, "DISCHRG")) { | 398 | } else if (!strcmp(ptr, "DISCHRG")) { |
| 423 | config->status |= UPSSTATUS_DISCHRG; | 399 | result.ups_status |= UPSSTATUS_DISCHRG; |
| 424 | } else if (!strcmp(ptr, "ALARM")) { | 400 | } else if (!strcmp(ptr, "ALARM")) { |
| 425 | config->status |= UPSSTATUS_ALARM; | 401 | result.ups_status |= UPSSTATUS_ALARM; |
| 426 | } else { | 402 | } else { |
| 427 | config->status |= UPSSTATUS_UNKNOWN; | 403 | result.ups_status |= UPSSTATUS_UNKNOWN; |
| 428 | } | 404 | } |
| 429 | } | 405 | } |
| 430 | 406 | ||
| 431 | return OK; | 407 | return result; |
| 432 | } | 408 | } |
| 433 | 409 | ||
| 434 | /* gets a variable value for a specific UPS */ | 410 | /* gets a variable value for a specific UPS */ |
| 435 | int get_ups_variable(const char *varname, char *buf, const ups_config config) { | 411 | int get_ups_variable(const char *varname, char *buf, const check_ups_config config) { |
| 436 | char send_buffer[MAX_INPUT_BUFFER]; | 412 | char send_buffer[MAX_INPUT_BUFFER]; |
| 437 | 413 | ||
| 438 | /* create the command string to send to the UPS daemon */ | 414 | /* create the command string to send to the UPS daemon */ |
| 439 | /* Add LOGOUT to avoid read failure logs */ | 415 | /* Add LOGOUT to avoid read failure logs */ |
| 440 | int res = snprintf(send_buffer, sizeof(send_buffer), "GET VAR %s %s\nLOGOUT\n", config.ups_name, varname); | 416 | int res = snprintf(send_buffer, sizeof(send_buffer), "GET VAR %s %s\nLOGOUT\n", config.ups_name, |
| 417 | varname); | ||
| 441 | if ((res > 0) && ((size_t)res >= sizeof(send_buffer))) { | 418 | if ((res > 0) && ((size_t)res >= sizeof(send_buffer))) { |
| 442 | printf("%s\n", _("UPS name to long for buffer")); | 419 | printf("%s\n", _("UPS name to long for buffer")); |
| 443 | return ERROR; | 420 | return ERROR; |
| @@ -446,7 +423,8 @@ int get_ups_variable(const char *varname, char *buf, const ups_config config) { | |||
| 446 | char temp_buffer[MAX_INPUT_BUFFER]; | 423 | char temp_buffer[MAX_INPUT_BUFFER]; |
| 447 | 424 | ||
| 448 | /* send the command to the daemon and get a response back */ | 425 | /* send the command to the daemon and get a response back */ |
| 449 | if (process_tcp_request(config.server_address, config.server_port, send_buffer, temp_buffer, sizeof(temp_buffer)) != STATE_OK) { | 426 | if (process_tcp_request(config.server_address, config.server_port, send_buffer, temp_buffer, |
| 427 | sizeof(temp_buffer)) != STATE_OK) { | ||
| 450 | printf("%s\n", _("Invalid response received from host")); | 428 | printf("%s\n", _("Invalid response received from host")); |
| 451 | return ERROR; | 429 | return ERROR; |
| 452 | } | 430 | } |
| @@ -500,7 +478,7 @@ int get_ups_variable(const char *varname, char *buf, const ups_config config) { | |||
| 500 | [-wv warn_value] [-cv crit_value] [-to to_sec] */ | 478 | [-wv warn_value] [-cv crit_value] [-to to_sec] */ |
| 501 | 479 | ||
| 502 | /* process command-line arguments */ | 480 | /* process command-line arguments */ |
| 503 | int process_arguments(int argc, char **argv, ups_config *config) { | 481 | check_ups_config_wrapper process_arguments(int argc, char **argv) { |
| 504 | 482 | ||
| 505 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, | 483 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, |
| 506 | {"ups", required_argument, 0, 'u'}, | 484 | {"ups", required_argument, 0, 'u'}, |
| @@ -514,8 +492,14 @@ int process_arguments(int argc, char **argv, ups_config *config) { | |||
| 514 | {"help", no_argument, 0, 'h'}, | 492 | {"help", no_argument, 0, 'h'}, |
| 515 | {0, 0, 0, 0}}; | 493 | {0, 0, 0, 0}}; |
| 516 | 494 | ||
| 495 | check_ups_config_wrapper result = { | ||
| 496 | .errorcode = OK, | ||
| 497 | .config = check_ups_config_init(), | ||
| 498 | }; | ||
| 499 | |||
| 517 | if (argc < 2) { | 500 | if (argc < 2) { |
| 518 | return ERROR; | 501 | result.errorcode = ERROR; |
| 502 | return result; | ||
| 519 | } | 503 | } |
| 520 | 504 | ||
| 521 | int c; | 505 | int c; |
| @@ -542,52 +526,52 @@ int process_arguments(int argc, char **argv, ups_config *config) { | |||
| 542 | usage5(); | 526 | usage5(); |
| 543 | case 'H': /* hostname */ | 527 | case 'H': /* hostname */ |
| 544 | if (is_host(optarg)) { | 528 | if (is_host(optarg)) { |
| 545 | config->server_address = optarg; | 529 | result.config.server_address = optarg; |
| 546 | } else { | 530 | } else { |
| 547 | usage2(_("Invalid hostname/address"), optarg); | 531 | usage2(_("Invalid hostname/address"), optarg); |
| 548 | } | 532 | } |
| 549 | break; | 533 | break; |
| 550 | case 'T': /* FIXME: to be improved (ie "-T C" for Celsius or "-T F" for | 534 | case 'T': /* FIXME: to be improved (ie "-T C" for Celsius or "-T F" for |
| 551 | Fahrenheit) */ | 535 | Fahrenheit) */ |
| 552 | config->temp_output_c = true; | 536 | result.config.temp_output_c = true; |
| 553 | break; | 537 | break; |
| 554 | case 'u': /* ups name */ | 538 | case 'u': /* ups name */ |
| 555 | config->ups_name = optarg; | 539 | result.config.ups_name = optarg; |
| 556 | break; | 540 | break; |
| 557 | case 'p': /* port */ | 541 | case 'p': /* port */ |
| 558 | if (is_intpos(optarg)) { | 542 | if (is_intpos(optarg)) { |
| 559 | config->server_port = atoi(optarg); | 543 | result.config.server_port = atoi(optarg); |
| 560 | } else { | 544 | } else { |
| 561 | usage2(_("Port must be a positive integer"), optarg); | 545 | usage2(_("Port must be a positive integer"), optarg); |
| 562 | } | 546 | } |
| 563 | break; | 547 | break; |
| 564 | case 'c': /* critical time threshold */ | 548 | case 'c': /* critical time threshold */ |
| 565 | if (is_intnonneg(optarg)) { | 549 | if (is_intnonneg(optarg)) { |
| 566 | config->critical_value = atoi(optarg); | 550 | result.config.critical_value = atoi(optarg); |
| 567 | config->check_crit = true; | 551 | result.config.check_crit = true; |
| 568 | } else { | 552 | } else { |
| 569 | usage2(_("Critical time must be a positive integer"), optarg); | 553 | usage2(_("Critical time must be a positive integer"), optarg); |
| 570 | } | 554 | } |
| 571 | break; | 555 | break; |
| 572 | case 'w': /* warning time threshold */ | 556 | case 'w': /* warning time threshold */ |
| 573 | if (is_intnonneg(optarg)) { | 557 | if (is_intnonneg(optarg)) { |
| 574 | config->warning_value = atoi(optarg); | 558 | result.config.warning_value = atoi(optarg); |
| 575 | config->check_warn = true; | 559 | result.config.check_warn = true; |
| 576 | } else { | 560 | } else { |
| 577 | usage2(_("Warning time must be a positive integer"), optarg); | 561 | usage2(_("Warning time must be a positive integer"), optarg); |
| 578 | } | 562 | } |
| 579 | break; | 563 | break; |
| 580 | case 'v': /* variable */ | 564 | case 'v': /* variable */ |
| 581 | if (!strcmp(optarg, "LINE")) { | 565 | if (!strcmp(optarg, "LINE")) { |
| 582 | config->check_variable = UPS_UTILITY; | 566 | result.config.check_variable = UPS_UTILITY; |
| 583 | } else if (!strcmp(optarg, "TEMP")) { | 567 | } else if (!strcmp(optarg, "TEMP")) { |
| 584 | config->check_variable = UPS_TEMP; | 568 | result.config.check_variable = UPS_TEMP; |
| 585 | } else if (!strcmp(optarg, "BATTPCT")) { | 569 | } else if (!strcmp(optarg, "BATTPCT")) { |
| 586 | config->check_variable = UPS_BATTPCT; | 570 | result.config.check_variable = UPS_BATTPCT; |
| 587 | } else if (!strcmp(optarg, "LOADPCT")) { | 571 | } else if (!strcmp(optarg, "LOADPCT")) { |
| 588 | config->check_variable = UPS_LOADPCT; | 572 | result.config.check_variable = UPS_LOADPCT; |
| 589 | } else if (!strcmp(optarg, "REALPOWER")) { | 573 | } else if (!strcmp(optarg, "REALPOWER")) { |
| 590 | config->check_variable = UPS_REALPOWER; | 574 | result.config.check_variable = UPS_REALPOWER; |
| 591 | } else { | 575 | } else { |
| 592 | usage2(_("Unrecognized UPS variable"), optarg); | 576 | usage2(_("Unrecognized UPS variable"), optarg); |
| 593 | } | 577 | } |
| @@ -608,27 +592,27 @@ int process_arguments(int argc, char **argv, ups_config *config) { | |||
| 608 | } | 592 | } |
| 609 | } | 593 | } |
| 610 | 594 | ||
| 611 | if (config->server_address == NULL && argc > optind) { | 595 | if (result.config.server_address == NULL && argc > optind) { |
| 612 | if (is_host(argv[optind])) { | 596 | if (is_host(argv[optind])) { |
| 613 | config->server_address = argv[optind++]; | 597 | result.config.server_address = argv[optind++]; |
| 614 | } else { | 598 | } else { |
| 615 | usage2(_("Invalid hostname/address"), optarg); | 599 | usage2(_("Invalid hostname/address"), optarg); |
| 616 | } | 600 | } |
| 617 | } | 601 | } |
| 618 | 602 | ||
| 619 | if (config->server_address == NULL) { | 603 | if (result.config.server_address == NULL) { |
| 620 | config->server_address = strdup("127.0.0.1"); | 604 | result.config.server_address = strdup("127.0.0.1"); |
| 621 | } | 605 | } |
| 622 | 606 | ||
| 623 | return validate_arguments(*config); | 607 | return validate_arguments(result); |
| 624 | } | 608 | } |
| 625 | 609 | ||
| 626 | int validate_arguments(ups_config config) { | 610 | check_ups_config_wrapper validate_arguments(check_ups_config_wrapper config_wrapper) { |
| 627 | if (!config.ups_name) { | 611 | if (config_wrapper.config.ups_name) { |
| 628 | printf("%s\n", _("Error : no UPS indicated")); | 612 | printf("%s\n", _("Error : no UPS indicated")); |
| 629 | return ERROR; | 613 | config_wrapper.errorcode = ERROR; |
| 630 | } | 614 | } |
| 631 | return OK; | 615 | return config_wrapper; |
| 632 | } | 616 | } |
| 633 | 617 | ||
| 634 | void print_help(void) { | 618 | void print_help(void) { |
| @@ -660,7 +644,8 @@ void print_help(void) { | |||
| 660 | printf(" %s\n", "-T, --temperature"); | 644 | printf(" %s\n", "-T, --temperature"); |
| 661 | printf(" %s\n", _("Output of temperatures in Celsius")); | 645 | printf(" %s\n", _("Output of temperatures in Celsius")); |
| 662 | printf(" %s\n", "-v, --variable=STRING"); | 646 | printf(" %s\n", "-v, --variable=STRING"); |
| 663 | printf(" %s %s\n", _("Valid values for STRING are"), "LINE, TEMP, BATTPCT, LOADPCT or REALPOWER"); | 647 | printf(" %s %s\n", _("Valid values for STRING are"), |
| 648 | "LINE, TEMP, BATTPCT, LOADPCT or REALPOWER"); | ||
| 664 | 649 | ||
| 665 | printf(UT_WARN_CRIT); | 650 | printf(UT_WARN_CRIT); |
| 666 | 651 | ||
diff --git a/plugins/check_ups.d/config.h b/plugins/check_ups.d/config.h new file mode 100644 index 00000000..e05edceb --- /dev/null +++ b/plugins/check_ups.d/config.h | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "../../config.h" | ||
| 4 | #include <stddef.h> | ||
| 5 | |||
| 6 | #define UPS_NONE 0 /* no supported options */ | ||
| 7 | #define UPS_UTILITY 1 /* supports utility line */ | ||
| 8 | #define UPS_BATTPCT 2 /* supports percent battery remaining */ | ||
| 9 | #define UPS_STATUS 4 /* supports UPS status */ | ||
| 10 | #define UPS_TEMP 8 /* supports UPS temperature */ | ||
| 11 | #define UPS_LOADPCT 16 /* supports load percent */ | ||
| 12 | #define UPS_REALPOWER 32 /* supports real power */ | ||
| 13 | |||
| 14 | #define UPSSTATUS_NONE 0 | ||
| 15 | #define UPSSTATUS_OFF 1 | ||
| 16 | #define UPSSTATUS_OL 2 | ||
| 17 | #define UPSSTATUS_OB 4 | ||
| 18 | #define UPSSTATUS_LB 8 | ||
| 19 | #define UPSSTATUS_CAL 16 | ||
| 20 | #define UPSSTATUS_RB 32 /*Replace Battery */ | ||
| 21 | #define UPSSTATUS_BYPASS 64 | ||
| 22 | #define UPSSTATUS_OVER 128 | ||
| 23 | #define UPSSTATUS_TRIM 256 | ||
| 24 | #define UPSSTATUS_BOOST 512 | ||
| 25 | #define UPSSTATUS_CHRG 1024 | ||
| 26 | #define UPSSTATUS_DISCHRG 2048 | ||
| 27 | #define UPSSTATUS_UNKNOWN 4096 | ||
| 28 | #define UPSSTATUS_ALARM 8192 | ||
| 29 | |||
| 30 | enum { | ||
| 31 | PORT = 3493 | ||
| 32 | }; | ||
| 33 | |||
| 34 | typedef struct ups_config { | ||
| 35 | unsigned int server_port; | ||
| 36 | char *server_address; | ||
| 37 | char *ups_name; | ||
| 38 | double warning_value; | ||
| 39 | double critical_value; | ||
| 40 | bool check_warn; | ||
| 41 | bool check_crit; | ||
| 42 | int check_variable; | ||
| 43 | bool temp_output_c; | ||
| 44 | } check_ups_config; | ||
| 45 | |||
| 46 | check_ups_config check_ups_config_init(void) { | ||
| 47 | check_ups_config tmp = {0}; | ||
| 48 | tmp.server_port = PORT; | ||
| 49 | tmp.server_address = NULL; | ||
| 50 | tmp.ups_name = NULL; | ||
| 51 | tmp.check_variable = UPS_NONE; | ||
| 52 | |||
| 53 | return tmp; | ||
| 54 | } | ||
diff --git a/plugins/check_users.c b/plugins/check_users.c index f1e1c39d..3b2e265e 100644 --- a/plugins/check_users.c +++ b/plugins/check_users.c | |||
| @@ -34,8 +34,15 @@ const char *progname = "check_users"; | |||
| 34 | const char *copyright = "2000-2024"; | 34 | const char *copyright = "2000-2024"; |
| 35 | const char *email = "devel@monitoring-plugins.org"; | 35 | const char *email = "devel@monitoring-plugins.org"; |
| 36 | 36 | ||
| 37 | #include "common.h" | 37 | #include "check_users.d/users.h" |
| 38 | #include "utils.h" | 38 | #include "output.h" |
| 39 | #include "perfdata.h" | ||
| 40 | #include "states.h" | ||
| 41 | #include "utils_base.h" | ||
| 42 | #include "./common.h" | ||
| 43 | #include "./utils.h" | ||
| 44 | #include "check_users.d/config.h" | ||
| 45 | #include "thresholds.h" | ||
| 39 | 46 | ||
| 40 | #if HAVE_WTSAPI32_H | 47 | #if HAVE_WTSAPI32_H |
| 41 | # include <windows.h> | 48 | # include <windows.h> |
| @@ -44,8 +51,6 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 44 | # define ERROR -1 | 51 | # define ERROR -1 |
| 45 | #elif HAVE_UTMPX_H | 52 | #elif HAVE_UTMPX_H |
| 46 | # include <utmpx.h> | 53 | # include <utmpx.h> |
| 47 | #else | ||
| 48 | # include "popen.h" | ||
| 49 | #endif | 54 | #endif |
| 50 | 55 | ||
| 51 | #ifdef HAVE_LIBSYSTEMD | 56 | #ifdef HAVE_LIBSYSTEMD |
| @@ -53,29 +58,16 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 53 | # include <systemd/sd-login.h> | 58 | # include <systemd/sd-login.h> |
| 54 | #endif | 59 | #endif |
| 55 | 60 | ||
| 56 | #define possibly_set(a, b) ((a) == 0 ? (b) : 0) | 61 | typedef struct process_argument_wrapper { |
| 62 | int errorcode; | ||
| 63 | check_users_config config; | ||
| 64 | } check_users_config_wrapper; | ||
| 65 | check_users_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 57 | 66 | ||
| 58 | static int process_arguments(int, char **); | 67 | void print_help(void); |
| 59 | static void print_help(void); | ||
| 60 | void print_usage(void); | 68 | void print_usage(void); |
| 61 | 69 | ||
| 62 | static char *warning_range = NULL; | ||
| 63 | static char *critical_range = NULL; | ||
| 64 | static thresholds *thlds = NULL; | ||
| 65 | |||
| 66 | int main(int argc, char **argv) { | 70 | int main(int argc, char **argv) { |
| 67 | int users = -1; | ||
| 68 | int result = STATE_UNKNOWN; | ||
| 69 | #if HAVE_WTSAPI32_H | ||
| 70 | WTS_SESSION_INFO *wtsinfo; | ||
| 71 | DWORD wtscount; | ||
| 72 | DWORD index; | ||
| 73 | #elif HAVE_UTMPX_H | ||
| 74 | struct utmpx *putmpx; | ||
| 75 | #else | ||
| 76 | char input_buffer[MAX_INPUT_BUFFER]; | ||
| 77 | #endif | ||
| 78 | |||
| 79 | setlocale(LC_ALL, ""); | 71 | setlocale(LC_ALL, ""); |
| 80 | bindtextdomain(PACKAGE, LOCALEDIR); | 72 | bindtextdomain(PACKAGE, LOCALEDIR); |
| 81 | textdomain(PACKAGE); | 73 | textdomain(PACKAGE); |
| @@ -83,121 +75,104 @@ int main(int argc, char **argv) { | |||
| 83 | /* Parse extra opts if any */ | 75 | /* Parse extra opts if any */ |
| 84 | argv = np_extra_opts(&argc, argv, progname); | 76 | argv = np_extra_opts(&argc, argv, progname); |
| 85 | 77 | ||
| 86 | if (process_arguments(argc, argv) == ERROR) | 78 | check_users_config_wrapper tmp_config = process_arguments(argc, argv); |
| 87 | usage4(_("Could not parse arguments")); | ||
| 88 | |||
| 89 | users = 0; | ||
| 90 | |||
| 91 | #ifdef HAVE_LIBSYSTEMD | ||
| 92 | if (sd_booted() > 0) | ||
| 93 | users = sd_get_sessions(NULL); | ||
| 94 | else { | ||
| 95 | #endif | ||
| 96 | #if HAVE_WTSAPI32_H | ||
| 97 | if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) { | ||
| 98 | printf(_("Could not enumerate RD sessions: %d\n"), GetLastError()); | ||
| 99 | return STATE_UNKNOWN; | ||
| 100 | } | ||
| 101 | |||
| 102 | for (index = 0; index < wtscount; index++) { | ||
| 103 | LPTSTR username; | ||
| 104 | DWORD size; | ||
| 105 | int len; | ||
| 106 | |||
| 107 | if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, WTSUserName, &username, &size)) | ||
| 108 | continue; | ||
| 109 | |||
| 110 | len = lstrlen(username); | ||
| 111 | |||
| 112 | WTSFreeMemory(username); | ||
| 113 | |||
| 114 | if (len == 0) | ||
| 115 | continue; | ||
| 116 | |||
| 117 | if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) | ||
| 118 | users++; | ||
| 119 | } | ||
| 120 | |||
| 121 | WTSFreeMemory(wtsinfo); | ||
| 122 | #elif HAVE_UTMPX_H | ||
| 123 | /* get currently logged users from utmpx */ | ||
| 124 | setutxent(); | ||
| 125 | |||
| 126 | while ((putmpx = getutxent()) != NULL) | ||
| 127 | if (putmpx->ut_type == USER_PROCESS) | ||
| 128 | users++; | ||
| 129 | 79 | ||
| 130 | endutxent(); | 80 | if (tmp_config.errorcode == ERROR) { |
| 131 | #else | 81 | usage4(_("Could not parse arguments")); |
| 132 | /* run the command */ | ||
| 133 | child_process = spopen(WHO_COMMAND); | ||
| 134 | if (child_process == NULL) { | ||
| 135 | printf(_("Could not open pipe: %s\n"), WHO_COMMAND); | ||
| 136 | return STATE_UNKNOWN; | ||
| 137 | } | 82 | } |
| 138 | 83 | ||
| 139 | child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); | 84 | check_users_config config = tmp_config.config; |
| 140 | if (child_stderr == NULL) | ||
| 141 | printf(_("Could not open stderr for %s\n"), WHO_COMMAND); | ||
| 142 | |||
| 143 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | ||
| 144 | /* increment 'users' on all lines except total user count */ | ||
| 145 | if (input_buffer[0] != '#') { | ||
| 146 | users++; | ||
| 147 | continue; | ||
| 148 | } | ||
| 149 | 85 | ||
| 150 | /* get total logged in users */ | 86 | #ifdef _WIN32 |
| 151 | if (sscanf(input_buffer, _("# users=%d"), &users) == 1) | 87 | # if HAVE_WTSAPI32_H |
| 152 | break; | 88 | get_num_of_users_wrapper user_wrapper = get_num_of_users_windows(); |
| 89 | # else | ||
| 90 | # error Did not find WTSAPI32 | ||
| 91 | # endif // HAVE_WTSAPI32_H | ||
| 92 | #else | ||
| 93 | # ifdef HAVE_LIBSYSTEMD | ||
| 94 | get_num_of_users_wrapper user_wrapper = get_num_of_users_systemd(); | ||
| 95 | # elif HAVE_UTMPX_H | ||
| 96 | get_num_of_users_wrapper user_wrapper = get_num_of_users_utmp(); | ||
| 97 | # else // !HAVE_LIBSYSTEMD && !HAVE_UTMPX_H | ||
| 98 | get_num_of_users_wrapper user_wrapper = get_num_of_users_who_command(); | ||
| 99 | # endif // HAVE_LIBSYSTEMD | ||
| 100 | #endif // _WIN32 | ||
| 101 | |||
| 102 | mp_check overall = mp_check_init(); | ||
| 103 | if (config.output_format_is_set) { | ||
| 104 | mp_set_format(config.output_format); | ||
| 153 | } | 105 | } |
| 106 | mp_subcheck sc_users = mp_subcheck_init(); | ||
| 154 | 107 | ||
| 155 | /* check STDERR */ | 108 | if (user_wrapper.errorcode != 0) { |
| 156 | if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) | 109 | sc_users = mp_set_subcheck_state(sc_users, STATE_UNKNOWN); |
| 157 | result = possibly_set(result, STATE_UNKNOWN); | 110 | sc_users.output = "Failed to retrieve number of users"; |
| 158 | (void)fclose(child_stderr); | 111 | mp_add_subcheck_to_check(&overall, sc_users); |
| 159 | 112 | mp_exit(overall); | |
| 160 | /* close the pipe */ | ||
| 161 | if (spclose(child_process)) | ||
| 162 | result = possibly_set(result, STATE_UNKNOWN); | ||
| 163 | #endif | ||
| 164 | #ifdef HAVE_LIBSYSTEMD | ||
| 165 | } | 113 | } |
| 166 | #endif | ||
| 167 | |||
| 168 | /* check the user count against warning and critical thresholds */ | 114 | /* check the user count against warning and critical thresholds */ |
| 169 | result = get_status((double)users, thlds); | ||
| 170 | 115 | ||
| 171 | if (result == STATE_UNKNOWN) | 116 | mp_perfdata users_pd = { |
| 172 | printf("%s\n", _("Unable to read output")); | 117 | .label = "users", |
| 173 | else { | 118 | .value = mp_create_pd_value(user_wrapper.users), |
| 174 | printf(_("USERS %s - %d users currently logged in |%s\n"), state_text(result), users, | 119 | }; |
| 175 | sperfdata_int("users", users, "", warning_range, critical_range, true, 0, false, 0)); | 120 | |
| 121 | users_pd = mp_pd_set_thresholds(users_pd, config.thresholds); | ||
| 122 | mp_add_perfdata_to_subcheck(&sc_users, users_pd); | ||
| 123 | |||
| 124 | int tmp_status = mp_get_pd_status(users_pd); | ||
| 125 | sc_users = mp_set_subcheck_state(sc_users, tmp_status); | ||
| 126 | |||
| 127 | switch (tmp_status) { | ||
| 128 | case STATE_WARNING: | ||
| 129 | xasprintf(&sc_users.output, | ||
| 130 | "%d users currently logged in. This violates the warning threshold", | ||
| 131 | user_wrapper.users); | ||
| 132 | break; | ||
| 133 | case STATE_CRITICAL: | ||
| 134 | xasprintf(&sc_users.output, | ||
| 135 | "%d users currently logged in. This violates the critical threshold", | ||
| 136 | user_wrapper.users); | ||
| 137 | break; | ||
| 138 | default: | ||
| 139 | xasprintf(&sc_users.output, "%d users currently logged in", user_wrapper.users); | ||
| 176 | } | 140 | } |
| 177 | 141 | ||
| 178 | return result; | 142 | mp_add_subcheck_to_check(&overall, sc_users); |
| 143 | mp_exit(overall); | ||
| 179 | } | 144 | } |
| 180 | 145 | ||
| 146 | #define output_format_index CHAR_MAX + 1 | ||
| 147 | |||
| 181 | /* process command-line arguments */ | 148 | /* process command-line arguments */ |
| 182 | int process_arguments(int argc, char **argv) { | 149 | check_users_config_wrapper process_arguments(int argc, char **argv) { |
| 183 | static struct option longopts[] = {{"critical", required_argument, 0, 'c'}, | 150 | static struct option longopts[] = {{"critical", required_argument, 0, 'c'}, |
| 184 | {"warning", required_argument, 0, 'w'}, | 151 | {"warning", required_argument, 0, 'w'}, |
| 185 | {"version", no_argument, 0, 'V'}, | 152 | {"version", no_argument, 0, 'V'}, |
| 186 | {"help", no_argument, 0, 'h'}, | 153 | {"help", no_argument, 0, 'h'}, |
| 154 | {"output-format", required_argument, 0, output_format_index}, | ||
| 187 | {0, 0, 0, 0}}; | 155 | {0, 0, 0, 0}}; |
| 188 | 156 | ||
| 189 | if (argc < 2) | 157 | if (argc < 2) { |
| 190 | usage("\n"); | 158 | usage(progname); |
| 159 | } | ||
| 160 | |||
| 161 | char *warning_range = NULL; | ||
| 162 | char *critical_range = NULL; | ||
| 163 | check_users_config_wrapper result = { | ||
| 164 | .config = check_users_config_init(), | ||
| 165 | .errorcode = OK, | ||
| 166 | }; | ||
| 191 | 167 | ||
| 192 | int option_char; | ||
| 193 | while (true) { | 168 | while (true) { |
| 194 | int option = 0; | 169 | int counter = getopt_long(argc, argv, "+hVvc:w:", longopts, NULL); |
| 195 | option_char = getopt_long(argc, argv, "+hVvc:w:", longopts, &option); | ||
| 196 | 170 | ||
| 197 | if (option_char == -1 || option_char == EOF || option_char == 1) | 171 | if (counter == -1 || counter == EOF || counter == 1) { |
| 198 | break; | 172 | break; |
| 173 | } | ||
| 199 | 174 | ||
| 200 | switch (option_char) { | 175 | switch (counter) { |
| 201 | case '?': /* print short usage statement if args not parsable */ | 176 | case '?': /* print short usage statement if args not parsable */ |
| 202 | usage5(); | 177 | usage5(); |
| 203 | case 'h': /* help */ | 178 | case 'h': /* help */ |
| @@ -212,29 +187,66 @@ int process_arguments(int argc, char **argv) { | |||
| 212 | case 'w': /* warning */ | 187 | case 'w': /* warning */ |
| 213 | warning_range = optarg; | 188 | warning_range = optarg; |
| 214 | break; | 189 | break; |
| 190 | case output_format_index: { | ||
| 191 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
| 192 | if (!parser.parsing_success) { | ||
| 193 | // TODO List all available formats here, maybe add anothoer usage function | ||
| 194 | printf("Invalid output format: %s\n", optarg); | ||
| 195 | exit(STATE_UNKNOWN); | ||
| 196 | } | ||
| 197 | |||
| 198 | result.config.output_format_is_set = true; | ||
| 199 | result.config.output_format = parser.output_format; | ||
| 200 | break; | ||
| 201 | } | ||
| 215 | } | 202 | } |
| 216 | } | 203 | } |
| 217 | 204 | ||
| 218 | option_char = optind; | 205 | int option_char = optind; |
| 219 | 206 | ||
| 220 | if (warning_range == NULL && argc > option_char) | 207 | if (warning_range == NULL && argc > option_char) { |
| 221 | warning_range = argv[option_char++]; | 208 | warning_range = argv[option_char++]; |
| 209 | } | ||
| 222 | 210 | ||
| 223 | if (critical_range == NULL && argc > option_char) | 211 | if (critical_range == NULL && argc > option_char) { |
| 224 | critical_range = argv[option_char++]; | 212 | critical_range = argv[option_char++]; |
| 213 | } | ||
| 214 | |||
| 215 | // TODO add proper verification for ranges here! | ||
| 216 | mp_range_parsed tmp; | ||
| 217 | if (warning_range) { | ||
| 218 | tmp = mp_parse_range_string(warning_range); | ||
| 219 | } else { | ||
| 220 | printf("Warning threshold missing\n"); | ||
| 221 | print_usage(); | ||
| 222 | exit(STATE_UNKNOWN); | ||
| 223 | } | ||
| 225 | 224 | ||
| 226 | /* this will abort in case of invalid ranges */ | 225 | if (tmp.error == MP_PARSING_SUCCES) { |
| 227 | set_thresholds(&thlds, warning_range, critical_range); | 226 | result.config.thresholds.warning = tmp.range; |
| 227 | result.config.thresholds.warning_is_set = true; | ||
| 228 | } else { | ||
| 229 | printf("Failed to parse warning range: %s", warning_range); | ||
| 230 | exit(STATE_UNKNOWN); | ||
| 231 | } | ||
| 228 | 232 | ||
| 229 | if (!thlds->warning) { | 233 | if (critical_range) { |
| 230 | usage4(_("Warning threshold must be a valid range expression")); | 234 | tmp = mp_parse_range_string(critical_range); |
| 235 | } else { | ||
| 236 | printf("Critical threshold missing\n"); | ||
| 237 | print_usage(); | ||
| 238 | exit(STATE_UNKNOWN); | ||
| 231 | } | 239 | } |
| 232 | 240 | ||
| 233 | if (!thlds->critical) { | 241 | if (tmp.error == MP_PARSING_SUCCES) { |
| 234 | usage4(_("Critical threshold must be a valid range expression")); | 242 | result.config.thresholds.critical = tmp.range; |
| 243 | result.config.thresholds.critical_is_set = true; | ||
| 244 | } else { | ||
| 245 | printf("Failed to parse critical range: %s", critical_range); | ||
| 246 | exit(STATE_UNKNOWN); | ||
| 235 | } | 247 | } |
| 236 | 248 | ||
| 237 | return OK; | 249 | return result; |
| 238 | } | 250 | } |
| 239 | 251 | ||
| 240 | void print_help(void) { | 252 | void print_help(void) { |
| @@ -244,7 +256,8 @@ void print_help(void) { | |||
| 244 | printf(COPYRIGHT, copyright, email); | 256 | printf(COPYRIGHT, copyright, email); |
| 245 | 257 | ||
| 246 | printf("%s\n", _("This plugin checks the number of users currently logged in on the local")); | 258 | printf("%s\n", _("This plugin checks the number of users currently logged in on the local")); |
| 247 | printf("%s\n", _("system and generates an error if the number exceeds the thresholds specified.")); | 259 | printf("%s\n", |
| 260 | _("system and generates an error if the number exceeds the thresholds specified.")); | ||
| 248 | 261 | ||
| 249 | printf("\n\n"); | 262 | printf("\n\n"); |
| 250 | 263 | ||
| @@ -254,9 +267,12 @@ void print_help(void) { | |||
| 254 | printf(UT_EXTRA_OPTS); | 267 | printf(UT_EXTRA_OPTS); |
| 255 | 268 | ||
| 256 | printf(" %s\n", "-w, --warning=RANGE_EXPRESSION"); | 269 | printf(" %s\n", "-w, --warning=RANGE_EXPRESSION"); |
| 257 | printf(" %s\n", _("Set WARNING status if number of logged in users violates RANGE_EXPRESSION")); | 270 | printf(" %s\n", |
| 271 | _("Set WARNING status if number of logged in users violates RANGE_EXPRESSION")); | ||
| 258 | printf(" %s\n", "-c, --critical=RANGE_EXPRESSION"); | 272 | printf(" %s\n", "-c, --critical=RANGE_EXPRESSION"); |
| 259 | printf(" %s\n", _("Set CRITICAL status if number of logged in users violates RANGE_EXPRESSION")); | 273 | printf(" %s\n", |
| 274 | _("Set CRITICAL status if number of logged in users violates RANGE_EXPRESSION")); | ||
| 275 | printf(UT_OUTPUT_FORMAT); | ||
| 260 | 276 | ||
| 261 | printf(UT_SUPPORT); | 277 | printf(UT_SUPPORT); |
| 262 | } | 278 | } |
diff --git a/plugins/check_users.d/config.h b/plugins/check_users.d/config.h new file mode 100644 index 00000000..26d3ee70 --- /dev/null +++ b/plugins/check_users.d/config.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "output.h" | ||
| 4 | #include "thresholds.h" | ||
| 5 | |||
| 6 | typedef struct check_users_config { | ||
| 7 | mp_thresholds thresholds; | ||
| 8 | |||
| 9 | bool output_format_is_set; | ||
| 10 | mp_output_format output_format; | ||
| 11 | } check_users_config; | ||
| 12 | |||
| 13 | check_users_config check_users_config_init() { | ||
| 14 | check_users_config tmp = { | ||
| 15 | .thresholds = mp_thresholds_init(), | ||
| 16 | |||
| 17 | .output_format_is_set = false, | ||
| 18 | }; | ||
| 19 | return tmp; | ||
| 20 | } | ||
diff --git a/plugins/check_users.d/users.c b/plugins/check_users.d/users.c new file mode 100644 index 00000000..a08f79c5 --- /dev/null +++ b/plugins/check_users.d/users.c | |||
| @@ -0,0 +1,169 @@ | |||
| 1 | #include "./users.h" | ||
| 2 | |||
| 3 | #ifdef _WIN32 | ||
| 4 | # ifdef HAVE_WTSAPI32_H | ||
| 5 | # include <windows.h> | ||
| 6 | # include <wtsapi32.h> | ||
| 7 | # undef ERROR | ||
| 8 | # define ERROR -1 | ||
| 9 | |||
| 10 | get_num_of_users_wrapper get_num_of_users_windows() { | ||
| 11 | WTS_SESSION_INFO *wtsinfo; | ||
| 12 | DWORD wtscount; | ||
| 13 | |||
| 14 | get_num_of_users_wrapper result = {}; | ||
| 15 | |||
| 16 | if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &wtsinfo, &wtscount)) { | ||
| 17 | // printf(_("Could not enumerate RD sessions: %d\n"), GetLastError()); | ||
| 18 | result.error = WINDOWS_COULD_NOT_ENUMERATE_SESSIONS; | ||
| 19 | return result; | ||
| 20 | } | ||
| 21 | |||
| 22 | for (DWORD index = 0; index < wtscount; index++) { | ||
| 23 | LPTSTR username; | ||
| 24 | DWORD size; | ||
| 25 | |||
| 26 | if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wtsinfo[index].SessionId, | ||
| 27 | WTSUserName, &username, &size)) { | ||
| 28 | continue; | ||
| 29 | } | ||
| 30 | |||
| 31 | int len = lstrlen(username); | ||
| 32 | |||
| 33 | WTSFreeMemory(username); | ||
| 34 | |||
| 35 | if (len == 0) { | ||
| 36 | continue; | ||
| 37 | } | ||
| 38 | |||
| 39 | if (wtsinfo[index].State == WTSActive || wtsinfo[index].State == WTSDisconnected) { | ||
| 40 | result.users++; | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | WTSFreeMemory(wtsinfo); | ||
| 45 | return result; | ||
| 46 | } | ||
| 47 | # else // HAVE_WTSAPI32_H | ||
| 48 | # error On windows but without the WTSAPI32 lib | ||
| 49 | # endif // HAVE_WTSAPI32_H | ||
| 50 | |||
| 51 | #else // _WIN32 | ||
| 52 | |||
| 53 | # include "../../config.h" | ||
| 54 | # include <stddef.h> | ||
| 55 | |||
| 56 | # ifdef HAVE_LIBSYSTEMD | ||
| 57 | # include <systemd/sd-daemon.h> | ||
| 58 | # include <systemd/sd-login.h> | ||
| 59 | |||
| 60 | get_num_of_users_wrapper get_num_of_users_systemd() { | ||
| 61 | get_num_of_users_wrapper result = {}; | ||
| 62 | |||
| 63 | // Test whether we booted with systemd | ||
| 64 | if (sd_booted() > 0) { | ||
| 65 | int users = sd_get_uids(NULL); | ||
| 66 | if (users >= 0) { | ||
| 67 | // Success | ||
| 68 | result.users = users; | ||
| 69 | return result; | ||
| 70 | } | ||
| 71 | |||
| 72 | // Failure! return the error code | ||
| 73 | result.errorcode = users; | ||
| 74 | return result; | ||
| 75 | } | ||
| 76 | |||
| 77 | // Looks like we are not running systemd, | ||
| 78 | // return with error here | ||
| 79 | result.errorcode = NO_SYSTEMD_ERROR; | ||
| 80 | return result; | ||
| 81 | } | ||
| 82 | # endif | ||
| 83 | |||
| 84 | # ifdef HAVE_UTMPX_H | ||
| 85 | # include <utmpx.h> | ||
| 86 | |||
| 87 | get_num_of_users_wrapper get_num_of_users_utmp() { | ||
| 88 | int users = 0; | ||
| 89 | |||
| 90 | /* get currently logged users from utmpx */ | ||
| 91 | setutxent(); | ||
| 92 | |||
| 93 | struct utmpx *putmpx; | ||
| 94 | while ((putmpx = getutxent()) != NULL) { | ||
| 95 | if (putmpx->ut_type == USER_PROCESS) { | ||
| 96 | users++; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | endutxent(); | ||
| 101 | |||
| 102 | get_num_of_users_wrapper result = { | ||
| 103 | .errorcode = 0, | ||
| 104 | .users = users, | ||
| 105 | }; | ||
| 106 | |||
| 107 | return result; | ||
| 108 | } | ||
| 109 | # endif | ||
| 110 | |||
| 111 | # ifndef HAVE_WTSAPI32_H | ||
| 112 | # ifndef HAVE_LIBSYSTEMD | ||
| 113 | # ifndef HAVE_UTMPX_H | ||
| 114 | // Fall back option here for the others (probably still not on windows) | ||
| 115 | |||
| 116 | # include "../common.h" | ||
| 117 | # include "../popen.h" | ||
| 118 | # include "../utils.h" | ||
| 119 | |||
| 120 | get_num_of_users_wrapper get_num_of_users_who_command() { | ||
| 121 | /* run the command */ | ||
| 122 | child_process = spopen(WHO_COMMAND); | ||
| 123 | if (child_process == NULL) { | ||
| 124 | // printf(_("Could not open pipe: %s\n"), WHO_COMMAND); | ||
| 125 | get_num_of_users_wrapper result = { | ||
| 126 | .errorcode = COULD_NOT_OPEN_PIPE, | ||
| 127 | }; | ||
| 128 | return result; | ||
| 129 | } | ||
| 130 | |||
| 131 | child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); | ||
| 132 | if (child_stderr == NULL) { | ||
| 133 | // printf(_("Could not open stderr for %s\n"), WHO_COMMAND); | ||
| 134 | // TODO this error should probably be reported | ||
| 135 | } | ||
| 136 | |||
| 137 | get_num_of_users_wrapper result = {}; | ||
| 138 | char input_buffer[MAX_INPUT_BUFFER]; | ||
| 139 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | ||
| 140 | /* increment 'users' on all lines except total user count */ | ||
| 141 | if (input_buffer[0] != '#') { | ||
| 142 | result.users++; | ||
| 143 | continue; | ||
| 144 | } | ||
| 145 | |||
| 146 | /* get total logged in users */ | ||
| 147 | if (sscanf(input_buffer, _("# users=%d"), &result.users) == 1) { | ||
| 148 | break; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | /* check STDERR */ | ||
| 153 | if (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { | ||
| 154 | // if this fails, something broke and the result can not be relied upon or so is the theorie | ||
| 155 | // here | ||
| 156 | result.errorcode = STDERR_COULD_NOT_BE_READ; | ||
| 157 | } | ||
| 158 | (void)fclose(child_stderr); | ||
| 159 | |||
| 160 | /* close the pipe */ | ||
| 161 | spclose(child_process); | ||
| 162 | |||
| 163 | return result; | ||
| 164 | } | ||
| 165 | |||
| 166 | # endif | ||
| 167 | # endif | ||
| 168 | # endif | ||
| 169 | #endif | ||
diff --git a/plugins/check_users.d/users.h b/plugins/check_users.d/users.h new file mode 100644 index 00000000..aacba775 --- /dev/null +++ b/plugins/check_users.d/users.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | typedef struct get_num_of_users_wrapper { | ||
| 4 | int errorcode; | ||
| 5 | int users; | ||
| 6 | } get_num_of_users_wrapper; | ||
| 7 | |||
| 8 | enum { | ||
| 9 | NO_SYSTEMD_ERROR = 64, | ||
| 10 | WINDOWS_COULD_NOT_ENUMERATE_SESSIONS, | ||
| 11 | COULD_NOT_OPEN_PIPE, | ||
| 12 | STDERR_COULD_NOT_BE_READ, | ||
| 13 | }; | ||
| 14 | |||
| 15 | get_num_of_users_wrapper get_num_of_users_systemd(); | ||
| 16 | get_num_of_users_wrapper get_num_of_users_utmp(); | ||
| 17 | get_num_of_users_wrapper get_num_of_users_windows(); | ||
| 18 | get_num_of_users_wrapper get_num_of_users_who_command(); | ||
diff --git a/plugins/common.h b/plugins/common.h index 603bae55..ef888d08 100644 --- a/plugins/common.h +++ b/plugins/common.h | |||
| @@ -1,121 +1,122 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Monitoring Plugins common include file | 3 | * Monitoring Plugins common include file |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) | 6 | * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) |
| 7 | * Copyright (c) 2003-2007 Monitoring Plugins Development Team | 7 | * Copyright (c) 2003-2007 Monitoring Plugins Development Team |
| 8 | * | 8 | * |
| 9 | * Description: | 9 | * Description: |
| 10 | * | 10 | * |
| 11 | * This file contains common include files and defines used in many of | 11 | * This file contains common include files and defines used in many of |
| 12 | * the plugins. | 12 | * the plugins. |
| 13 | * | 13 | * |
| 14 | * | 14 | * |
| 15 | * This program is free software: you can redistribute it and/or modify | 15 | * This program is free software: you can redistribute it and/or modify |
| 16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
| 17 | * the Free Software Foundation, either version 3 of the License, or | 17 | * the Free Software Foundation, either version 3 of the License, or |
| 18 | * (at your option) any later version. | 18 | * (at your option) any later version. |
| 19 | * | 19 | * |
| 20 | * This program is distributed in the hope that it will be useful, | 20 | * This program is distributed in the hope that it will be useful, |
| 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 23 | * GNU General Public License for more details. | 23 | * GNU General Public License for more details. |
| 24 | * | 24 | * |
| 25 | * You should have received a copy of the GNU General Public License | 25 | * You should have received a copy of the GNU General Public License |
| 26 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 26 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 27 | * | 27 | * |
| 28 | * | 28 | * |
| 29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
| 30 | 30 | ||
| 31 | #ifndef _COMMON_H_ | 31 | #ifndef _COMMON_H_ |
| 32 | #define _COMMON_H_ | 32 | #define _COMMON_H_ |
| 33 | 33 | ||
| 34 | #include "config.h" | 34 | #include "../config.h" |
| 35 | #include "../lib/monitoringplug.h" | 35 | #include "../lib/monitoringplug.h" |
| 36 | 36 | ||
| 37 | #ifdef HAVE_FEATURES_H | 37 | #ifdef HAVE_FEATURES_H |
| 38 | #include <features.h> | 38 | # include <features.h> |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | #include <stdio.h> /* obligatory includes */ | 41 | #include <stdio.h> /* obligatory includes */ |
| 42 | #include <stdlib.h> | 42 | #include <stdlib.h> |
| 43 | #include <errno.h> | 43 | #include <errno.h> |
| 44 | 44 | ||
| 45 | /* This block provides uintmax_t - should be reported to coreutils that this should be added to fsuage.h */ | 45 | /* This block provides uintmax_t - should be reported to coreutils that this should be added to |
| 46 | * fsuage.h */ | ||
| 46 | #if HAVE_INTTYPES_H | 47 | #if HAVE_INTTYPES_H |
| 47 | # include <inttypes.h> | 48 | # include <inttypes.h> |
| 48 | #endif | 49 | #endif |
| 49 | #if HAVE_STDINT_H | 50 | #if HAVE_STDINT_H |
| 50 | # include <stdint.h> | 51 | # include <stdint.h> |
| 51 | #endif | 52 | #endif |
| 52 | #include <unistd.h> | 53 | #include <unistd.h> |
| 53 | #ifndef UINTMAX_MAX | 54 | #ifndef UINTMAX_MAX |
| 54 | # define UINTMAX_MAX ((uintmax_t) -1) | 55 | # define UINTMAX_MAX ((uintmax_t) - 1) |
| 55 | #endif | 56 | #endif |
| 56 | 57 | ||
| 57 | #include <limits.h> /* This is assumed true, because coreutils assume it too */ | 58 | #include <limits.h> /* This is assumed true, because coreutils assume it too */ |
| 58 | 59 | ||
| 59 | #ifdef HAVE_MATH_H | 60 | #ifdef HAVE_MATH_H |
| 60 | #include <math.h> | 61 | # include <math.h> |
| 61 | #endif | 62 | #endif |
| 62 | 63 | ||
| 63 | #ifdef _AIX | 64 | #ifdef _AIX |
| 64 | #ifdef HAVE_MP_H | 65 | # ifdef HAVE_MP_H |
| 65 | #include <mp.h> | 66 | # include <mp.h> |
| 66 | #endif | 67 | # endif |
| 67 | #endif | 68 | #endif |
| 68 | 69 | ||
| 69 | #ifdef HAVE_STRINGS_H | 70 | #ifdef HAVE_STRINGS_H |
| 70 | #include <strings.h> | 71 | # include <strings.h> |
| 71 | #endif | 72 | #endif |
| 72 | #ifdef HAVE_STRING_H | 73 | #ifdef HAVE_STRING_H |
| 73 | #include <string.h> | 74 | # include <string.h> |
| 74 | #endif | 75 | #endif |
| 75 | 76 | ||
| 76 | #ifdef HAVE_UNISTD_H | 77 | #ifdef HAVE_UNISTD_H |
| 77 | #include <unistd.h> | 78 | # include <unistd.h> |
| 78 | #endif | 79 | #endif |
| 79 | 80 | ||
| 80 | /* GET_NUMBER_OF_CPUS is a macro to return | 81 | /* GET_NUMBER_OF_CPUS is a macro to return |
| 81 | number of CPUs, if we can get that data. | 82 | number of CPUs, if we can get that data. |
| 82 | Use configure.in to test for various OS ways of | 83 | Use configure.in to test for various OS ways of |
| 83 | getting that data | 84 | getting that data |
| 84 | Will return -1 if cannot get data | 85 | Will return -1 if cannot get data |
| 85 | */ | 86 | */ |
| 86 | #if defined(HAVE_SYSCONF__SC_NPROCESSORS_ONLN) | 87 | #if defined(HAVE_SYSCONF__SC_NPROCESSORS_ONLN) |
| 87 | # define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_ONLN) | 88 | # define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_ONLN) |
| 88 | #elif defined (HAVE_SYSCONF__SC_NPROCESSORS_CONF) | 89 | #elif defined(HAVE_SYSCONF__SC_NPROCESSORS_CONF) |
| 89 | # define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_CONF) | 90 | # define GET_NUMBER_OF_CPUS() sysconf(_SC_NPROCESSORS_CONF) |
| 90 | #else | 91 | #else |
| 91 | # define GET_NUMBER_OF_CPUS() -1 | 92 | # define GET_NUMBER_OF_CPUS() -1 |
| 92 | #endif | 93 | #endif |
| 93 | 94 | ||
| 94 | #ifdef HAVE_SYS_TIME_H | 95 | #ifdef HAVE_SYS_TIME_H |
| 95 | # include <sys/time.h> | 96 | # include <sys/time.h> |
| 96 | #endif | 97 | #endif |
| 97 | #include <time.h> | 98 | #include <time.h> |
| 98 | 99 | ||
| 99 | #ifdef HAVE_SYS_TYPES_H | 100 | #ifdef HAVE_SYS_TYPES_H |
| 100 | #include <sys/types.h> | 101 | # include <sys/types.h> |
| 101 | #endif | 102 | #endif |
| 102 | 103 | ||
| 103 | #ifdef HAVE_SYS_SOCKET_H | 104 | #ifdef HAVE_SYS_SOCKET_H |
| 104 | #include <sys/socket.h> | 105 | # include <sys/socket.h> |
| 105 | #endif | 106 | #endif |
| 106 | 107 | ||
| 107 | #ifdef HAVE_SIGNAL_H | 108 | #ifdef HAVE_SIGNAL_H |
| 108 | #include <signal.h> | 109 | # include <signal.h> |
| 109 | #endif | 110 | #endif |
| 110 | 111 | ||
| 111 | /* GNU Libraries */ | 112 | /* GNU Libraries */ |
| 112 | #include <getopt.h> | 113 | #include <getopt.h> |
| 113 | #include "dirname.h" | 114 | #include "../gl/dirname.h" |
| 114 | 115 | ||
| 115 | #include <locale.h> | 116 | #include <locale.h> |
| 116 | 117 | ||
| 117 | #ifdef HAVE_SYS_POLL_H | 118 | #ifdef HAVE_SYS_POLL_H |
| 118 | # include "sys/poll.h" | 119 | # include "sys/poll.h" |
| 119 | #endif | 120 | #endif |
| 120 | 121 | ||
| 121 | /* | 122 | /* |
| @@ -125,42 +126,42 @@ | |||
| 125 | */ | 126 | */ |
| 126 | 127 | ||
| 127 | #ifndef HAVE_STRTOL | 128 | #ifndef HAVE_STRTOL |
| 128 | # define strtol(a,b,c) atol((a)) | 129 | # define strtol(a, b, c) atol((a)) |
| 129 | #endif | 130 | #endif |
| 130 | 131 | ||
| 131 | #ifndef HAVE_STRTOUL | 132 | #ifndef HAVE_STRTOUL |
| 132 | # define strtoul(a,b,c) (unsigned long)atol((a)) | 133 | # define strtoul(a, b, c) (unsigned long)atol((a)) |
| 133 | #endif | 134 | #endif |
| 134 | 135 | ||
| 135 | /* SSL implementations */ | 136 | /* SSL implementations */ |
| 136 | #ifdef HAVE_GNUTLS_OPENSSL_H | 137 | #ifdef HAVE_GNUTLS_OPENSSL_H |
| 137 | # include <gnutls/openssl.h> | 138 | # include <gnutls/openssl.h> |
| 138 | #else | 139 | #else |
| 139 | # define OPENSSL_LOAD_CONF /* See the OPENSSL_config(3) man page. */ | 140 | # define OPENSSL_LOAD_CONF /* See the OPENSSL_config(3) man page. */ |
| 140 | # ifdef HAVE_SSL_H | 141 | # ifdef HAVE_SSL_H |
| 141 | # include <rsa.h> | 142 | # include <rsa.h> |
| 142 | # include <crypto.h> | 143 | # include <crypto.h> |
| 143 | # include <x509.h> | 144 | # include <x509.h> |
| 144 | # include <pem.h> | 145 | # include <pem.h> |
| 145 | # include <ssl.h> | 146 | # include <ssl.h> |
| 146 | # include <err.h> | 147 | # include <err.h> |
| 147 | # else | 148 | # else |
| 148 | # ifdef HAVE_OPENSSL_SSL_H | 149 | # ifdef HAVE_OPENSSL_SSL_H |
| 149 | # include <openssl/rsa.h> | 150 | # include <openssl/rsa.h> |
| 150 | # include <openssl/crypto.h> | 151 | # include <openssl/crypto.h> |
| 151 | # include <openssl/x509.h> | 152 | # include <openssl/x509.h> |
| 152 | # include <openssl/pem.h> | 153 | # include <openssl/pem.h> |
| 153 | # include <openssl/ssl.h> | 154 | # include <openssl/ssl.h> |
| 154 | # include <openssl/err.h> | 155 | # include <openssl/err.h> |
| 155 | # endif | 156 | # endif |
| 156 | # endif | 157 | # endif |
| 157 | #endif | 158 | #endif |
| 158 | 159 | ||
| 159 | /* openssl 1.1 does not set OPENSSL_NO_SSL2 by default but ships without ssl2 */ | 160 | /* openssl 1.1 does not set OPENSSL_NO_SSL2 by default but ships without ssl2 */ |
| 160 | #ifdef OPENSSL_VERSION_NUMBER | 161 | #ifdef OPENSSL_VERSION_NUMBER |
| 161 | # if OPENSSL_VERSION_NUMBER >= 0x10100000 | 162 | # if OPENSSL_VERSION_NUMBER >= 0x10100000 |
| 162 | # define OPENSSL_NO_SSL2 | 163 | # define OPENSSL_NO_SSL2 |
| 163 | # endif | 164 | # endif |
| 164 | #endif | 165 | #endif |
| 165 | 166 | ||
| 166 | /* | 167 | /* |
| @@ -171,7 +172,7 @@ | |||
| 171 | 172 | ||
| 172 | /* MariaDB 10.2 client does not set MYSQL_PORT */ | 173 | /* MariaDB 10.2 client does not set MYSQL_PORT */ |
| 173 | #ifndef MYSQL_PORT | 174 | #ifndef MYSQL_PORT |
| 174 | # define MYSQL_PORT 3306 | 175 | # define MYSQL_PORT 3306 |
| 175 | #endif | 176 | #endif |
| 176 | 177 | ||
| 177 | enum { | 178 | enum { |
| @@ -180,9 +181,9 @@ enum { | |||
| 180 | }; | 181 | }; |
| 181 | 182 | ||
| 182 | enum { | 183 | enum { |
| 183 | DEFAULT_SOCKET_TIMEOUT = 10, /* timeout after 10 seconds */ | 184 | DEFAULT_SOCKET_TIMEOUT = 10, /* timeout after 10 seconds */ |
| 184 | MAX_INPUT_BUFFER = 8192, /* max size of most buffers we use */ | 185 | MAX_INPUT_BUFFER = 8192, /* max size of most buffers we use */ |
| 185 | MAX_HOST_ADDRESS_LENGTH = 256 /* max size of a host address */ | 186 | MAX_HOST_ADDRESS_LENGTH = 256 /* max size of a host address */ |
| 186 | }; | 187 | }; |
| 187 | 188 | ||
| 188 | /* | 189 | /* |
| @@ -190,18 +191,18 @@ enum { | |||
| 190 | * Internationalization | 191 | * Internationalization |
| 191 | * | 192 | * |
| 192 | */ | 193 | */ |
| 193 | #include "gettext.h" | 194 | #include "../gl/gettext.h" |
| 194 | #define _(String) gettext (String) | 195 | #define _(String) gettext(String) |
| 195 | #if ! ENABLE_NLS | 196 | #if !ENABLE_NLS |
| 196 | # undef textdomain | 197 | # undef textdomain |
| 197 | # define textdomain(Domainname) /* empty */ | 198 | # define textdomain(Domainname) /* empty */ |
| 198 | # undef bindtextdomain | 199 | # undef bindtextdomain |
| 199 | # define bindtextdomain(Domainname, Dirname) /* empty */ | 200 | # define bindtextdomain(Domainname, Dirname) /* empty */ |
| 200 | #endif | 201 | #endif |
| 201 | 202 | ||
| 202 | /* For non-GNU compilers to ignore __attribute__ */ | 203 | /* For non-GNU compilers to ignore __attribute__ */ |
| 203 | #ifndef __GNUC__ | 204 | #ifndef __GNUC__ |
| 204 | # define __attribute__(x) /* do nothing */ | 205 | # define __attribute__(x) /* do nothing */ |
| 205 | #endif | 206 | #endif |
| 206 | 207 | ||
| 207 | #endif /* _COMMON_H_ */ | 208 | #endif /* _COMMON_H_ */ |
diff --git a/plugins/negate.c b/plugins/negate.c index 750c0bfb..a42a6c59 100644 --- a/plugins/negate.c +++ b/plugins/negate.c | |||
| @@ -38,21 +38,18 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 38 | #include "common.h" | 38 | #include "common.h" |
| 39 | #include "utils.h" | 39 | #include "utils.h" |
| 40 | #include "utils_cmd.h" | 40 | #include "utils_cmd.h" |
| 41 | #include "negate.d/config.h" | ||
| 42 | #include "../lib/states.h" | ||
| 41 | 43 | ||
| 42 | #include <ctype.h> | 44 | typedef struct { |
| 45 | int errorcode; | ||
| 46 | negate_config config; | ||
| 47 | } negate_config_wrapper; | ||
| 48 | static negate_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 49 | static negate_config_wrapper validate_arguments(negate_config_wrapper /*config_wrapper*/); | ||
| 43 | 50 | ||
| 44 | static const char **process_arguments(int /*argc*/, char ** /*argv*/); | ||
| 45 | static void validate_arguments(char ** /*command_line*/); | ||
| 46 | static void print_help(void); | 51 | static void print_help(void); |
| 47 | void print_usage(void); | 52 | void print_usage(void); |
| 48 | static bool subst_text = false; | ||
| 49 | |||
| 50 | static int state[4] = { | ||
| 51 | STATE_OK, | ||
| 52 | STATE_WARNING, | ||
| 53 | STATE_CRITICAL, | ||
| 54 | STATE_UNKNOWN, | ||
| 55 | }; | ||
| 56 | 53 | ||
| 57 | int main(int argc, char **argv) { | 54 | int main(int argc, char **argv) { |
| 58 | setlocale(LC_ALL, ""); | 55 | setlocale(LC_ALL, ""); |
| @@ -61,15 +58,24 @@ int main(int argc, char **argv) { | |||
| 61 | 58 | ||
| 62 | timeout_interval = DEFAULT_TIMEOUT; | 59 | timeout_interval = DEFAULT_TIMEOUT; |
| 63 | 60 | ||
| 64 | char **command_line = (char **)process_arguments(argc, argv); | 61 | negate_config_wrapper tmp_config = process_arguments(argc, argv); |
| 62 | |||
| 63 | if (tmp_config.errorcode == ERROR) { | ||
| 64 | die(STATE_UNKNOWN, _("negate: Failed to parse input")); | ||
| 65 | } | ||
| 66 | |||
| 67 | negate_config config = tmp_config.config; | ||
| 68 | |||
| 69 | char **command_line = config.command_line; | ||
| 65 | 70 | ||
| 66 | /* Set signal handling and alarm */ | 71 | /* Set signal handling and alarm */ |
| 67 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) | 72 | if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) { |
| 68 | die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); | 73 | die(STATE_UNKNOWN, _("Cannot catch SIGALRM")); |
| 74 | } | ||
| 69 | 75 | ||
| 70 | (void)alarm((unsigned)timeout_interval); | 76 | (void)alarm(timeout_interval); |
| 71 | 77 | ||
| 72 | int result = STATE_UNKNOWN; | 78 | mp_state_enum result = STATE_UNKNOWN; |
| 73 | output chld_out; | 79 | output chld_out; |
| 74 | output chld_err; | 80 | output chld_err; |
| 75 | 81 | ||
| @@ -86,46 +92,54 @@ int main(int argc, char **argv) { | |||
| 86 | } | 92 | } |
| 87 | 93 | ||
| 88 | /* Return UNKNOWN or worse if no output is returned */ | 94 | /* Return UNKNOWN or worse if no output is returned */ |
| 89 | if (chld_out.lines == 0) | 95 | if (chld_out.lines == 0) { |
| 90 | die(max_state_alt(result, STATE_UNKNOWN), _("No data returned from command\n")); | 96 | die(max_state_alt(result, STATE_UNKNOWN), _("No data returned from command\n")); |
| 97 | } | ||
| 91 | 98 | ||
| 92 | char *sub; | 99 | char *sub; |
| 93 | for (size_t i = 0; i < chld_out.lines; i++) { | 100 | for (size_t i = 0; i < chld_out.lines; i++) { |
| 94 | if (subst_text && result >= 0 && result <= 4 && result != state[result]) { | 101 | if (config.subst_text && result >= 0 && result <= 4 && result != config.state[result]) { |
| 95 | /* Loop over each match found */ | 102 | /* Loop over each match found */ |
| 96 | while ((sub = strstr(chld_out.line[i], state_text(result)))) { | 103 | while ((sub = strstr(chld_out.line[i], state_text(result)))) { |
| 97 | /* Terminate the first part and skip over the string we'll substitute */ | 104 | /* Terminate the first part and skip over the string we'll substitute */ |
| 98 | *sub = '\0'; | 105 | *sub = '\0'; |
| 99 | sub += strlen(state_text(result)); | 106 | sub += strlen(state_text(result)); |
| 100 | /* then put everything back together */ | 107 | /* then put everything back together */ |
| 101 | xasprintf(&chld_out.line[i], "%s%s%s", chld_out.line[i], state_text(state[result]), sub); | 108 | xasprintf(&chld_out.line[i], "%s%s%s", chld_out.line[i], |
| 109 | state_text(config.state[result]), sub); | ||
| 102 | } | 110 | } |
| 103 | } | 111 | } |
| 104 | printf("%s\n", chld_out.line[i]); | 112 | printf("%s\n", chld_out.line[i]); |
| 105 | } | 113 | } |
| 106 | 114 | ||
| 107 | if (result >= 0 && result <= 4) { | 115 | if (result >= 0 && result <= 4) { |
| 108 | exit(state[result]); | 116 | exit(config.state[result]); |
| 109 | } else { | 117 | } else { |
| 110 | exit(result); | 118 | exit(result); |
| 111 | } | 119 | } |
| 112 | } | 120 | } |
| 113 | 121 | ||
| 114 | /* process command-line arguments */ | 122 | /* process command-line arguments */ |
| 115 | static const char **process_arguments(int argc, char **argv) { | 123 | static negate_config_wrapper process_arguments(int argc, char **argv) { |
| 116 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, | 124 | static struct option longopts[] = { |
| 117 | {"timeout", required_argument, 0, 't'}, {"timeout-result", required_argument, 0, 'T'}, | 125 | {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, |
| 118 | {"ok", required_argument, 0, 'o'}, {"warning", required_argument, 0, 'w'}, | 126 | {"timeout", required_argument, 0, 't'}, {"timeout-result", required_argument, 0, 'T'}, |
| 119 | {"critical", required_argument, 0, 'c'}, {"unknown", required_argument, 0, 'u'}, | 127 | {"ok", required_argument, 0, 'o'}, {"warning", required_argument, 0, 'w'}, |
| 120 | {"substitute", no_argument, 0, 's'}, {0, 0, 0, 0}}; | 128 | {"critical", required_argument, 0, 'c'}, {"unknown", required_argument, 0, 'u'}, |
| 121 | 129 | {"substitute", no_argument, 0, 's'}, {0, 0, 0, 0}}; | |
| 130 | |||
| 131 | negate_config_wrapper result = { | ||
| 132 | .errorcode = OK, | ||
| 133 | .config = negate_config_init(), | ||
| 134 | }; | ||
| 122 | bool permute = true; | 135 | bool permute = true; |
| 123 | while (true) { | 136 | while (true) { |
| 124 | int option = 0; | 137 | int option = 0; |
| 125 | int option_char = getopt_long(argc, argv, "+hVt:T:o:w:c:u:s", longopts, &option); | 138 | int option_char = getopt_long(argc, argv, "+hVt:T:o:w:c:u:s", longopts, &option); |
| 126 | 139 | ||
| 127 | if (option_char == -1 || option_char == EOF) | 140 | if (option_char == -1 || option_char == EOF) { |
| 128 | break; | 141 | break; |
| 142 | } | ||
| 129 | 143 | ||
| 130 | switch (option_char) { | 144 | switch (option_char) { |
| 131 | case '?': /* help */ | 145 | case '?': /* help */ |
| @@ -139,58 +153,74 @@ static const char **process_arguments(int argc, char **argv) { | |||
| 139 | print_revision(progname, NP_VERSION); | 153 | print_revision(progname, NP_VERSION); |
| 140 | exit(STATE_UNKNOWN); | 154 | exit(STATE_UNKNOWN); |
| 141 | case 't': /* timeout period */ | 155 | case 't': /* timeout period */ |
| 142 | if (!is_integer(optarg)) | 156 | if (!is_integer(optarg)) { |
| 143 | usage2(_("Timeout interval must be a positive integer"), optarg); | 157 | usage2(_("Timeout interval must be a positive integer"), optarg); |
| 144 | else | 158 | } else { |
| 145 | timeout_interval = atoi(optarg); | 159 | timeout_interval = atoi(optarg); |
| 160 | } | ||
| 146 | break; | 161 | break; |
| 147 | case 'T': /* Result to return on timeouts */ | 162 | case 'T': /* Result to return on timeouts */ |
| 148 | if ((timeout_state = mp_translate_state(optarg)) == ERROR) | 163 | if ((timeout_state = mp_translate_state(optarg)) == ERROR) { |
| 149 | usage4(_("Timeout result must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); | 164 | usage4(_("Timeout result must be a valid state name (OK, WARNING, CRITICAL, " |
| 165 | "UNKNOWN) or integer (0-3).")); | ||
| 166 | } | ||
| 150 | break; | 167 | break; |
| 151 | case 'o': /* replacement for OK */ | 168 | case 'o': /* replacement for OK */ |
| 152 | if ((state[STATE_OK] = mp_translate_state(optarg)) == ERROR) | 169 | if ((result.config.state[STATE_OK] = mp_translate_state(optarg)) == ERROR) { |
| 153 | usage4(_("Ok must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); | 170 | usage4(_("Ok must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or " |
| 171 | "integer (0-3).")); | ||
| 172 | } | ||
| 154 | permute = false; | 173 | permute = false; |
| 155 | break; | 174 | break; |
| 156 | 175 | ||
| 157 | case 'w': /* replacement for WARNING */ | 176 | case 'w': /* replacement for WARNING */ |
| 158 | if ((state[STATE_WARNING] = mp_translate_state(optarg)) == ERROR) | 177 | if ((result.config.state[STATE_WARNING] = mp_translate_state(optarg)) == ERROR) { |
| 159 | usage4(_("Warning must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); | 178 | usage4(_("Warning must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or " |
| 179 | "integer (0-3).")); | ||
| 180 | } | ||
| 160 | permute = false; | 181 | permute = false; |
| 161 | break; | 182 | break; |
| 162 | case 'c': /* replacement for CRITICAL */ | 183 | case 'c': /* replacement for CRITICAL */ |
| 163 | if ((state[STATE_CRITICAL] = mp_translate_state(optarg)) == ERROR) | 184 | if ((result.config.state[STATE_CRITICAL] = mp_translate_state(optarg)) == ERROR) { |
| 164 | usage4(_("Critical must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); | 185 | usage4(_("Critical must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or " |
| 186 | "integer (0-3).")); | ||
| 187 | } | ||
| 165 | permute = false; | 188 | permute = false; |
| 166 | break; | 189 | break; |
| 167 | case 'u': /* replacement for UNKNOWN */ | 190 | case 'u': /* replacement for UNKNOWN */ |
| 168 | if ((state[STATE_UNKNOWN] = mp_translate_state(optarg)) == ERROR) | 191 | if ((result.config.state[STATE_UNKNOWN] = mp_translate_state(optarg)) == ERROR) { |
| 169 | usage4(_("Unknown must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or integer (0-3).")); | 192 | usage4(_("Unknown must be a valid state name (OK, WARNING, CRITICAL, UNKNOWN) or " |
| 193 | "integer (0-3).")); | ||
| 194 | } | ||
| 170 | permute = false; | 195 | permute = false; |
| 171 | break; | 196 | break; |
| 172 | case 's': /* Substitute status text */ | 197 | case 's': /* Substitute status text */ |
| 173 | subst_text = true; | 198 | result.config.subst_text = true; |
| 174 | break; | 199 | break; |
| 175 | } | 200 | } |
| 176 | } | 201 | } |
| 177 | 202 | ||
| 178 | validate_arguments(&argv[optind]); | ||
| 179 | |||
| 180 | if (permute) { /* No [owcu] switch specified, default to this */ | 203 | if (permute) { /* No [owcu] switch specified, default to this */ |
| 181 | state[STATE_OK] = STATE_CRITICAL; | 204 | result.config.state[STATE_OK] = STATE_CRITICAL; |
| 182 | state[STATE_CRITICAL] = STATE_OK; | 205 | result.config.state[STATE_CRITICAL] = STATE_OK; |
| 183 | } | 206 | } |
| 184 | 207 | ||
| 185 | return (const char **)&argv[optind]; | 208 | result.config.command_line = &argv[optind]; |
| 209 | |||
| 210 | return validate_arguments(result); | ||
| 186 | } | 211 | } |
| 187 | 212 | ||
| 188 | void validate_arguments(char **command_line) { | 213 | negate_config_wrapper validate_arguments(negate_config_wrapper config_wrapper) { |
| 189 | if (command_line[0] == NULL) | 214 | if (config_wrapper.config.command_line[0] == NULL) { |
| 190 | usage4(_("Could not parse arguments")); | 215 | usage4(_("Could not parse arguments")); |
| 216 | } | ||
| 191 | 217 | ||
| 192 | if (strncmp(command_line[0], "/", 1) != 0 && strncmp(command_line[0], "./", 2) != 0) | 218 | if (strncmp(config_wrapper.config.command_line[0], "/", 1) != 0 && |
| 219 | strncmp(config_wrapper.config.command_line[0], "./", 2) != 0) { | ||
| 193 | usage4(_("Require path to command")); | 220 | usage4(_("Require path to command")); |
| 221 | } | ||
| 222 | |||
| 223 | return config_wrapper; | ||
| 194 | } | 224 | } |
| 195 | 225 | ||
| 196 | void print_help(void) { | 226 | void print_help(void) { |
| @@ -198,7 +228,8 @@ void print_help(void) { | |||
| 198 | 228 | ||
| 199 | printf(COPYRIGHT, copyright, email); | 229 | printf(COPYRIGHT, copyright, email); |
| 200 | 230 | ||
| 201 | printf("%s\n", _("Negates only the return code of a plugin (returns OK for CRITICAL and vice-versa) by default.")); | 231 | printf("%s\n", _("Negates only the return code of a plugin (returns OK for CRITICAL and " |
| 232 | "vice-versa) by default.")); | ||
| 202 | printf("%s\n", _("Additional switches can be used to control:\n")); | 233 | printf("%s\n", _("Additional switches can be used to control:\n")); |
| 203 | printf("\t - which state becomes what\n"); | 234 | printf("\t - which state becomes what\n"); |
| 204 | printf("\t - changing the plugin output text to match the return code"); | 235 | printf("\t - changing the plugin output text to match the return code"); |
| @@ -228,17 +259,20 @@ void print_help(void) { | |||
| 228 | printf("%s\n", _("Examples:")); | 259 | printf("%s\n", _("Examples:")); |
| 229 | printf(" %s\n", "negate /usr/local/nagios/libexec/check_ping -H host"); | 260 | printf(" %s\n", "negate /usr/local/nagios/libexec/check_ping -H host"); |
| 230 | printf(" %s\n", _("Run check_ping and invert result. Must use full path to plugin")); | 261 | printf(" %s\n", _("Run check_ping and invert result. Must use full path to plugin")); |
| 231 | printf(" %s\n", "negate -w OK -c UNKNOWN /usr/local/nagios/libexec/check_procs -a 'vi negate.c'"); | 262 | printf(" %s\n", |
| 263 | "negate -w OK -c UNKNOWN /usr/local/nagios/libexec/check_procs -a 'vi negate.c'"); | ||
| 232 | printf(" %s\n", _("This will return OK instead of WARNING and UNKNOWN instead of CRITICAL")); | 264 | printf(" %s\n", _("This will return OK instead of WARNING and UNKNOWN instead of CRITICAL")); |
| 233 | printf("\n"); | 265 | printf("\n"); |
| 234 | printf("%s\n", _("Notes:")); | 266 | printf("%s\n", _("Notes:")); |
| 235 | printf(" %s\n", _("This plugin is a wrapper to take the output of another plugin and invert it.")); | 267 | printf(" %s\n", |
| 268 | _("This plugin is a wrapper to take the output of another plugin and invert it.")); | ||
| 236 | printf(" %s\n", _("The full path of the plugin must be provided.")); | 269 | printf(" %s\n", _("The full path of the plugin must be provided.")); |
| 237 | printf(" %s\n", _("If the wrapped plugin returns OK, the wrapper will return CRITICAL.")); | 270 | printf(" %s\n", _("If the wrapped plugin returns OK, the wrapper will return CRITICAL.")); |
| 238 | printf(" %s\n", _("If the wrapped plugin returns CRITICAL, the wrapper will return OK.")); | 271 | printf(" %s\n", _("If the wrapped plugin returns CRITICAL, the wrapper will return OK.")); |
| 239 | printf(" %s\n", _("Otherwise, the output state of the wrapped plugin is unchanged.")); | 272 | printf(" %s\n", _("Otherwise, the output state of the wrapped plugin is unchanged.")); |
| 240 | printf("\n"); | 273 | printf("\n"); |
| 241 | printf(" %s\n", _("Using timeout-result, it is possible to override the timeout behaviour or a")); | 274 | printf(" %s\n", |
| 275 | _("Using timeout-result, it is possible to override the timeout behaviour or a")); | ||
| 242 | printf(" %s\n", _("plugin by setting the negate timeout a bit lower.")); | 276 | printf(" %s\n", _("plugin by setting the negate timeout a bit lower.")); |
| 243 | 277 | ||
| 244 | printf(UT_SUPPORT); | 278 | printf(UT_SUPPORT); |
diff --git a/plugins/negate.d/config.h b/plugins/negate.d/config.h new file mode 100644 index 00000000..0cf30cd4 --- /dev/null +++ b/plugins/negate.d/config.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "states.h" | ||
| 4 | |||
| 5 | typedef struct { | ||
| 6 | mp_state_enum state[4]; | ||
| 7 | bool subst_text; | ||
| 8 | char **command_line; | ||
| 9 | } negate_config; | ||
| 10 | |||
| 11 | negate_config negate_config_init() { | ||
| 12 | negate_config tmp = { | ||
| 13 | .state = | ||
| 14 | { | ||
| 15 | STATE_OK, | ||
| 16 | STATE_WARNING, | ||
| 17 | STATE_CRITICAL, | ||
| 18 | STATE_UNKNOWN, | ||
| 19 | }, | ||
| 20 | .subst_text = false, | ||
| 21 | .command_line = NULL, | ||
| 22 | }; | ||
| 23 | return tmp; | ||
| 24 | } | ||
diff --git a/plugins/netutils.c b/plugins/netutils.c index e2916c65..b4c6ff0a 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c | |||
| @@ -30,13 +30,14 @@ | |||
| 30 | #include "common.h" | 30 | #include "common.h" |
| 31 | #include "output.h" | 31 | #include "output.h" |
| 32 | #include "states.h" | 32 | #include "states.h" |
| 33 | #include <sys/types.h> | ||
| 33 | #include "netutils.h" | 34 | #include "netutils.h" |
| 34 | 35 | ||
| 35 | unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT; | 36 | unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT; |
| 36 | unsigned int socket_timeout_state = STATE_CRITICAL; | 37 | mp_state_enum socket_timeout_state = STATE_CRITICAL; |
| 37 | 38 | mp_state_enum econn_refuse_state = STATE_CRITICAL; | |
| 38 | int econn_refuse_state = STATE_CRITICAL; | ||
| 39 | bool was_refused = false; | 39 | bool was_refused = false; |
| 40 | |||
| 40 | #if USE_IPV6 | 41 | #if USE_IPV6 |
| 41 | int address_family = AF_UNSPEC; | 42 | int address_family = AF_UNSPEC; |
| 42 | #else | 43 | #else |
| @@ -63,38 +64,40 @@ void socket_timeout_alarm_handler(int sig) { | |||
| 63 | /* connects to a host on a specified tcp port, sends a string, and gets a | 64 | /* connects to a host on a specified tcp port, sends a string, and gets a |
| 64 | response. loops on select-recv until timeout or eof to get all of a | 65 | response. loops on select-recv until timeout or eof to get all of a |
| 65 | multi-packet answer */ | 66 | multi-packet answer */ |
| 66 | int process_tcp_request2(const char *server_address, int server_port, const char *send_buffer, char *recv_buffer, int recv_size) { | 67 | mp_state_enum process_tcp_request2(const char *server_address, const int server_port, |
| 68 | const char *send_buffer, char *recv_buffer, | ||
| 69 | const int recv_size) { | ||
| 67 | 70 | ||
| 68 | int result; | 71 | int socket; |
| 69 | int send_result; | ||
| 70 | int recv_result; | ||
| 71 | int sd; | ||
| 72 | struct timeval tv; | ||
| 73 | fd_set readfds; | ||
| 74 | int recv_length = 0; | ||
| 75 | 72 | ||
| 76 | result = np_net_connect(server_address, server_port, &sd, IPPROTO_TCP); | 73 | mp_state_enum connect_result = |
| 77 | if (result != STATE_OK) { | 74 | np_net_connect(server_address, server_port, &socket, IPPROTO_TCP); |
| 75 | if (connect_result != STATE_OK) { | ||
| 78 | return STATE_CRITICAL; | 76 | return STATE_CRITICAL; |
| 79 | } | 77 | } |
| 80 | 78 | ||
| 81 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); | 79 | mp_state_enum result; |
| 80 | ssize_t send_result = send(socket, send_buffer, strlen(send_buffer), 0); | ||
| 82 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { | 81 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
| 83 | // printf("%s\n", _("Send failed")); | 82 | // printf("%s\n", _("Send failed")); |
| 84 | result = STATE_WARNING; | 83 | result = STATE_WARNING; |
| 85 | } | 84 | } |
| 86 | 85 | ||
| 87 | while (1) { | 86 | fd_set readfds; |
| 87 | ssize_t recv_length = 0; | ||
| 88 | while (true) { | ||
| 88 | /* wait up to the number of seconds for socket timeout | 89 | /* wait up to the number of seconds for socket timeout |
| 89 | minus one for data from the host */ | 90 | minus one for data from the host */ |
| 90 | tv.tv_sec = socket_timeout - 1; | 91 | struct timeval timeout = { |
| 91 | tv.tv_usec = 0; | 92 | .tv_sec = socket_timeout - 1, |
| 93 | .tv_usec = 0, | ||
| 94 | }; | ||
| 92 | FD_ZERO(&readfds); | 95 | FD_ZERO(&readfds); |
| 93 | FD_SET(sd, &readfds); | 96 | FD_SET(socket, &readfds); |
| 94 | select(sd + 1, &readfds, NULL, NULL, &tv); | 97 | select(socket + 1, &readfds, NULL, NULL, &timeout); |
| 95 | 98 | ||
| 96 | /* make sure some data has arrived */ | 99 | /* make sure some data has arrived */ |
| 97 | if (!FD_ISSET(sd, &readfds)) { /* it hasn't */ | 100 | if (!FD_ISSET(socket, &readfds)) { /* it hasn't */ |
| 98 | if (!recv_length) { | 101 | if (!recv_length) { |
| 99 | strcpy(recv_buffer, ""); | 102 | strcpy(recv_buffer, ""); |
| 100 | // printf("%s\n", _("No data was received from host!")); | 103 | // printf("%s\n", _("No data was received from host!")); |
| @@ -103,70 +106,69 @@ int process_tcp_request2(const char *server_address, int server_port, const char | |||
| 103 | recv_buffer[recv_length] = 0; | 106 | recv_buffer[recv_length] = 0; |
| 104 | } | 107 | } |
| 105 | break; | 108 | break; |
| 106 | } else { /* it has */ | 109 | } /* it has */ |
| 107 | recv_result = recv(sd, recv_buffer + recv_length, (size_t)recv_size - recv_length - 1, 0); | 110 | |
| 108 | if (recv_result == -1) { | 111 | ssize_t recv_result = |
| 109 | /* recv failed, bail out */ | 112 | recv(socket, recv_buffer + recv_length, (size_t)(recv_size - recv_length - 1), 0); |
| 110 | strcpy(recv_buffer + recv_length, ""); | 113 | if (recv_result == -1) { |
| 111 | result = STATE_WARNING; | 114 | /* recv failed, bail out */ |
| 112 | break; | 115 | strcpy(recv_buffer + recv_length, ""); |
| 113 | } else if (recv_result == 0) { | 116 | result = STATE_WARNING; |
| 114 | /* end of file ? */ | 117 | break; |
| 115 | recv_buffer[recv_length] = 0; | 118 | } |
| 116 | break; | 119 | |
| 117 | } else { /* we got data! */ | 120 | if (recv_result == 0) { |
| 118 | recv_length += recv_result; | 121 | /* end of file ? */ |
| 119 | if (recv_length >= recv_size - 1) { | 122 | recv_buffer[recv_length] = 0; |
| 120 | /* buffer full, we're done */ | 123 | break; |
| 121 | recv_buffer[recv_size - 1] = 0; | 124 | } |
| 122 | break; | 125 | |
| 123 | } | 126 | /* we got data! */ |
| 124 | } | 127 | recv_length += recv_result; |
| 128 | if (recv_length >= recv_size - 1) { | ||
| 129 | /* buffer full, we're done */ | ||
| 130 | recv_buffer[recv_size - 1] = 0; | ||
| 131 | break; | ||
| 125 | } | 132 | } |
| 126 | /* end if(!FD_ISSET(sd,&readfds)) */ | 133 | /* end if(!FD_ISSET(sd,&readfds)) */ |
| 127 | } | 134 | } |
| 128 | /* end while(1) */ | ||
| 129 | 135 | ||
| 130 | close(sd); | 136 | close(socket); |
| 131 | return result; | 137 | return result; |
| 132 | } | 138 | } |
| 133 | 139 | ||
| 134 | /* connects to a host on a specified port, sends a string, and gets a | 140 | /* connects to a host on a specified port, sends a string, and gets a |
| 135 | response */ | 141 | response */ |
| 136 | int process_request(const char *server_address, int server_port, int proto, const char *send_buffer, char *recv_buffer, int recv_size) { | 142 | mp_state_enum process_request(const char *server_address, const int server_port, const int proto, |
| 137 | int result; | 143 | const char *send_buffer, char *recv_buffer, const int recv_size) { |
| 138 | int sd; | ||
| 139 | 144 | ||
| 140 | result = STATE_OK; | 145 | mp_state_enum result = STATE_OK; |
| 141 | 146 | int socket; | |
| 142 | result = np_net_connect(server_address, server_port, &sd, proto); | 147 | result = np_net_connect(server_address, server_port, &socket, proto); |
| 143 | if (result != STATE_OK) { | 148 | if (result != STATE_OK) { |
| 144 | return STATE_CRITICAL; | 149 | return STATE_CRITICAL; |
| 145 | } | 150 | } |
| 146 | 151 | ||
| 147 | result = send_request(sd, proto, send_buffer, recv_buffer, recv_size); | 152 | result = send_request(socket, proto, send_buffer, recv_buffer, recv_size); |
| 148 | 153 | ||
| 149 | close(sd); | 154 | close(socket); |
| 150 | 155 | ||
| 151 | return result; | 156 | return result; |
| 152 | } | 157 | } |
| 153 | 158 | ||
| 154 | /* opens a tcp or udp connection to a remote host or local socket */ | 159 | /* opens a tcp or udp connection to a remote host or local socket */ |
| 155 | int np_net_connect(const char *host_name, int port, int *sd, int proto) { | 160 | mp_state_enum np_net_connect(const char *host_name, int port, int *socketDescriptor, |
| 161 | const int proto) { | ||
| 156 | /* send back STATE_UNKOWN if there's an error | 162 | /* send back STATE_UNKOWN if there's an error |
| 157 | send back STATE_OK if we connect | 163 | send back STATE_OK if we connect |
| 158 | send back STATE_CRITICAL if we can't connect. | 164 | send back STATE_CRITICAL if we can't connect. |
| 159 | Let upstream figure out what to send to the user. */ | 165 | Let upstream figure out what to send to the user. */ |
| 160 | struct addrinfo hints; | 166 | bool is_socket = (host_name[0] == '/'); |
| 161 | struct addrinfo *r, *res; | 167 | int socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; |
| 162 | struct sockaddr_un su; | ||
| 163 | char port_str[6], host[MAX_HOST_ADDRESS_LENGTH]; | ||
| 164 | size_t len; | ||
| 165 | int socktype, result; | ||
| 166 | short is_socket = (host_name[0] == '/'); | ||
| 167 | |||
| 168 | socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; | ||
| 169 | 168 | ||
| 169 | struct addrinfo hints = {}; | ||
| 170 | struct addrinfo *res = NULL; | ||
| 171 | int result; | ||
| 170 | /* as long as it doesn't start with a '/', it's assumed a host or ip */ | 172 | /* as long as it doesn't start with a '/', it's assumed a host or ip */ |
| 171 | if (!is_socket) { | 173 | if (!is_socket) { |
| 172 | memset(&hints, 0, sizeof(hints)); | 174 | memset(&hints, 0, sizeof(hints)); |
| @@ -174,38 +176,46 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
| 174 | hints.ai_protocol = proto; | 176 | hints.ai_protocol = proto; |
| 175 | hints.ai_socktype = socktype; | 177 | hints.ai_socktype = socktype; |
| 176 | 178 | ||
| 177 | len = strlen(host_name); | 179 | size_t len = strlen(host_name); |
| 178 | /* check for an [IPv6] address (and strip the brackets) */ | 180 | /* check for an [IPv6] address (and strip the brackets) */ |
| 179 | if (len >= 2 && host_name[0] == '[' && host_name[len - 1] == ']') { | 181 | if (len >= 2 && host_name[0] == '[' && host_name[len - 1] == ']') { |
| 180 | host_name++; | 182 | host_name++; |
| 181 | len -= 2; | 183 | len -= 2; |
| 182 | } | 184 | } |
| 185 | |||
| 186 | char host[MAX_HOST_ADDRESS_LENGTH]; | ||
| 187 | |||
| 183 | if (len >= sizeof(host)) { | 188 | if (len >= sizeof(host)) { |
| 184 | return STATE_UNKNOWN; | 189 | return STATE_UNKNOWN; |
| 185 | } | 190 | } |
| 191 | |||
| 186 | memcpy(host, host_name, len); | 192 | memcpy(host, host_name, len); |
| 187 | host[len] = '\0'; | 193 | host[len] = '\0'; |
| 194 | |||
| 195 | char port_str[6]; | ||
| 188 | snprintf(port_str, sizeof(port_str), "%d", port); | 196 | snprintf(port_str, sizeof(port_str), "%d", port); |
| 189 | result = getaddrinfo(host, port_str, &hints, &res); | 197 | int getaddrinfo_err = getaddrinfo(host, port_str, &hints, &res); |
| 190 | 198 | ||
| 191 | if (result != 0) { | 199 | if (getaddrinfo_err != 0) { |
| 192 | // printf("%s\n", gai_strerror(result)); | 200 | // printf("%s\n", gai_strerror(result)); |
| 193 | return STATE_UNKNOWN; | 201 | return STATE_UNKNOWN; |
| 194 | } | 202 | } |
| 195 | 203 | ||
| 196 | r = res; | 204 | struct addrinfo *addressPointer = res; |
| 197 | while (r) { | 205 | while (addressPointer) { |
| 198 | /* attempt to create a socket */ | 206 | /* attempt to create a socket */ |
| 199 | *sd = socket(r->ai_family, socktype, r->ai_protocol); | 207 | *socketDescriptor = |
| 208 | socket(addressPointer->ai_family, socktype, addressPointer->ai_protocol); | ||
| 200 | 209 | ||
| 201 | if (*sd < 0) { | 210 | if (*socketDescriptor < 0) { |
| 202 | // printf("%s\n", _("Socket creation failed")); | 211 | // printf("%s\n", _("Socket creation failed")); |
| 203 | freeaddrinfo(r); | 212 | freeaddrinfo(addressPointer); |
| 204 | return STATE_UNKNOWN; | 213 | return STATE_UNKNOWN; |
| 205 | } | 214 | } |
| 206 | 215 | ||
| 207 | /* attempt to open a connection */ | 216 | /* attempt to open a connection */ |
| 208 | result = connect(*sd, r->ai_addr, r->ai_addrlen); | 217 | result = |
| 218 | connect(*socketDescriptor, addressPointer->ai_addr, addressPointer->ai_addrlen); | ||
| 209 | 219 | ||
| 210 | if (result == 0) { | 220 | if (result == 0) { |
| 211 | was_refused = false; | 221 | was_refused = false; |
| @@ -220,24 +230,28 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
| 220 | } | 230 | } |
| 221 | } | 231 | } |
| 222 | 232 | ||
| 223 | close(*sd); | 233 | close(*socketDescriptor); |
| 224 | r = r->ai_next; | 234 | addressPointer = addressPointer->ai_next; |
| 225 | } | 235 | } |
| 236 | |||
| 226 | freeaddrinfo(res); | 237 | freeaddrinfo(res); |
| 227 | } | 238 | |
| 228 | /* else the hostname is interpreted as a path to a unix socket */ | 239 | } else { |
| 229 | else { | 240 | /* else the hostname is interpreted as a path to a unix socket */ |
| 230 | if (strlen(host_name) >= UNIX_PATH_MAX) { | 241 | if (strlen(host_name) >= UNIX_PATH_MAX) { |
| 231 | die(STATE_UNKNOWN, _("Supplied path too long unix domain socket")); | 242 | die(STATE_UNKNOWN, _("Supplied path too long unix domain socket")); |
| 232 | } | 243 | } |
| 233 | memset(&su, 0, sizeof(su)); | 244 | |
| 245 | struct sockaddr_un su = {}; | ||
| 234 | su.sun_family = AF_UNIX; | 246 | su.sun_family = AF_UNIX; |
| 235 | strncpy(su.sun_path, host_name, UNIX_PATH_MAX); | 247 | strncpy(su.sun_path, host_name, UNIX_PATH_MAX); |
| 236 | *sd = socket(PF_UNIX, SOCK_STREAM, 0); | 248 | *socketDescriptor = socket(PF_UNIX, SOCK_STREAM, 0); |
| 237 | if (*sd < 0) { | 249 | |
| 250 | if (*socketDescriptor < 0) { | ||
| 238 | die(STATE_UNKNOWN, _("Socket creation failed")); | 251 | die(STATE_UNKNOWN, _("Socket creation failed")); |
| 239 | } | 252 | } |
| 240 | result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); | 253 | |
| 254 | result = connect(*socketDescriptor, (struct sockaddr *)&su, sizeof(su)); | ||
| 241 | if (result < 0 && errno == ECONNREFUSED) { | 255 | if (result < 0 && errno == ECONNREFUSED) { |
| 242 | was_refused = true; | 256 | was_refused = true; |
| 243 | } | 257 | } |
| @@ -245,7 +259,9 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
| 245 | 259 | ||
| 246 | if (result == 0) { | 260 | if (result == 0) { |
| 247 | return STATE_OK; | 261 | return STATE_OK; |
| 248 | } else if (was_refused) { | 262 | } |
| 263 | |||
| 264 | if (was_refused) { | ||
| 249 | switch (econn_refuse_state) { /* a user-defined expected outcome */ | 265 | switch (econn_refuse_state) { /* a user-defined expected outcome */ |
| 250 | case STATE_OK: | 266 | case STATE_OK: |
| 251 | case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ | 267 | case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ |
| @@ -253,7 +269,8 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
| 253 | if (is_socket) { | 269 | if (is_socket) { |
| 254 | // printf("connect to file socket %s: %s\n", host_name, strerror(errno)); | 270 | // printf("connect to file socket %s: %s\n", host_name, strerror(errno)); |
| 255 | } else { | 271 | } else { |
| 256 | // printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); | 272 | // printf("connect to address %s and port %d: %s\n", host_name, port, |
| 273 | // strerror(errno)); | ||
| 257 | } | 274 | } |
| 258 | return STATE_CRITICAL; | 275 | return STATE_CRITICAL; |
| 259 | break; | 276 | break; |
| @@ -271,14 +288,11 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
| 271 | } | 288 | } |
| 272 | } | 289 | } |
| 273 | 290 | ||
| 274 | int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, int recv_size) { | 291 | mp_state_enum send_request(const int socket, const int proto, const char *send_buffer, |
| 275 | int result = STATE_OK; | 292 | char *recv_buffer, const int recv_size) { |
| 276 | int send_result; | 293 | mp_state_enum result = STATE_OK; |
| 277 | int recv_result; | ||
| 278 | struct timeval tv; | ||
| 279 | fd_set readfds; | ||
| 280 | 294 | ||
| 281 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); | 295 | ssize_t send_result = send(socket, send_buffer, strlen(send_buffer), 0); |
| 282 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { | 296 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
| 283 | // printf("%s\n", _("Send failed")); | 297 | // printf("%s\n", _("Send failed")); |
| 284 | result = STATE_WARNING; | 298 | result = STATE_WARNING; |
| @@ -286,21 +300,22 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, | |||
| 286 | 300 | ||
| 287 | /* wait up to the number of seconds for socket timeout minus one | 301 | /* wait up to the number of seconds for socket timeout minus one |
| 288 | for data from the host */ | 302 | for data from the host */ |
| 289 | tv.tv_sec = socket_timeout - 1; | 303 | struct timeval timestamp = { |
| 290 | tv.tv_usec = 0; | 304 | .tv_sec = socket_timeout - 1, |
| 305 | .tv_usec = 0, | ||
| 306 | }; | ||
| 307 | fd_set readfds; | ||
| 291 | FD_ZERO(&readfds); | 308 | FD_ZERO(&readfds); |
| 292 | FD_SET(sd, &readfds); | 309 | FD_SET(socket, &readfds); |
| 293 | select(sd + 1, &readfds, NULL, NULL, &tv); | 310 | select(socket + 1, &readfds, NULL, NULL, ×tamp); |
| 294 | 311 | ||
| 295 | /* make sure some data has arrived */ | 312 | /* make sure some data has arrived */ |
| 296 | if (!FD_ISSET(sd, &readfds)) { | 313 | if (!FD_ISSET(socket, &readfds)) { |
| 297 | strcpy(recv_buffer, ""); | 314 | strcpy(recv_buffer, ""); |
| 298 | // printf("%s\n", _("No data was received from host!")); | 315 | // printf("%s\n", _("No data was received from host!")); |
| 299 | result = STATE_WARNING; | 316 | result = STATE_WARNING; |
| 300 | } | 317 | } else { |
| 301 | 318 | ssize_t recv_result = recv(socket, recv_buffer, (size_t)(recv_size - 1), 0); | |
| 302 | else { | ||
| 303 | recv_result = recv(sd, recv_buffer, (size_t)recv_size - 1, 0); | ||
| 304 | if (recv_result == -1) { | 319 | if (recv_result == -1) { |
| 305 | strcpy(recv_buffer, ""); | 320 | strcpy(recv_buffer, ""); |
| 306 | if (proto != IPPROTO_TCP) { | 321 | if (proto != IPPROTO_TCP) { |
| @@ -314,6 +329,7 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, | |||
| 314 | /* die returned string */ | 329 | /* die returned string */ |
| 315 | recv_buffer[recv_size - 1] = 0; | 330 | recv_buffer[recv_size - 1] = 0; |
| 316 | } | 331 | } |
| 332 | |||
| 317 | return result; | 333 | return result; |
| 318 | } | 334 | } |
| 319 | 335 | ||
| @@ -335,27 +351,27 @@ bool is_addr(const char *address) { | |||
| 335 | #ifdef USE_IPV6 | 351 | #ifdef USE_IPV6 |
| 336 | if (address_family == AF_INET && is_inet_addr(address)) { | 352 | if (address_family == AF_INET && is_inet_addr(address)) { |
| 337 | return true; | 353 | return true; |
| 338 | } else if (address_family == AF_INET6 && is_inet6_addr(address)) { | 354 | } |
| 355 | |||
| 356 | if (address_family == AF_INET6 && is_inet6_addr(address)) { | ||
| 339 | return true; | 357 | return true; |
| 340 | } | 358 | } |
| 341 | #else | 359 | #else |
| 342 | if (is_inet_addr(address)) { | 360 | if (is_inet_addr(address)) { |
| 343 | return (true); | 361 | return true; |
| 344 | } | 362 | } |
| 345 | #endif | 363 | #endif |
| 346 | 364 | ||
| 347 | return (false); | 365 | return false; |
| 348 | } | 366 | } |
| 349 | 367 | ||
| 350 | int dns_lookup(const char *in, struct sockaddr_storage *ss, int family) { | 368 | bool dns_lookup(const char *node_string, struct sockaddr_storage *ss, const int family) { |
| 351 | struct addrinfo hints; | 369 | struct addrinfo hints; |
| 352 | struct addrinfo *res; | ||
| 353 | int retval; | ||
| 354 | |||
| 355 | memset(&hints, 0, sizeof(struct addrinfo)); | 370 | memset(&hints, 0, sizeof(struct addrinfo)); |
| 356 | hints.ai_family = family; | 371 | hints.ai_family = family; |
| 357 | 372 | ||
| 358 | retval = getaddrinfo(in, NULL, &hints, &res); | 373 | struct addrinfo *res; |
| 374 | int retval = getaddrinfo(node_string, NULL, &hints, &res); | ||
| 359 | if (retval != 0) { | 375 | if (retval != 0) { |
| 360 | return false; | 376 | return false; |
| 361 | } | 377 | } |
| @@ -363,6 +379,8 @@ int dns_lookup(const char *in, struct sockaddr_storage *ss, int family) { | |||
| 363 | if (ss != NULL) { | 379 | if (ss != NULL) { |
| 364 | memcpy(ss, res->ai_addr, res->ai_addrlen); | 380 | memcpy(ss, res->ai_addr, res->ai_addrlen); |
| 365 | } | 381 | } |
| 382 | |||
| 366 | freeaddrinfo(res); | 383 | freeaddrinfo(res); |
| 384 | |||
| 367 | return true; | 385 | return true; |
| 368 | } | 386 | } |
diff --git a/plugins/netutils.h b/plugins/netutils.h index a95057e0..dbd22398 100644 --- a/plugins/netutils.h +++ b/plugins/netutils.h | |||
| @@ -1,120 +1,140 @@ | |||
| 1 | /***************************************************************************** | 1 | /***************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Monitoring Plugins net utilities include file | 3 | * Monitoring Plugins net utilities include file |
| 4 | * | 4 | * |
| 5 | * License: GPL | 5 | * License: GPL |
| 6 | * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) | 6 | * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) |
| 7 | * Copyright (c) 2003-2007 Monitoring Plugins Development Team | 7 | * Copyright (c) 2003-2007 Monitoring Plugins Development Team |
| 8 | * | 8 | * |
| 9 | * Description: | 9 | * Description: |
| 10 | * | 10 | * |
| 11 | * This file contains common include files and function definitions | 11 | * This file contains common include files and function definitions |
| 12 | * used in many of the plugins. | 12 | * used in many of the plugins. |
| 13 | * | 13 | * |
| 14 | * | 14 | * |
| 15 | * This program is free software: you can redistribute it and/or modify | 15 | * This program is free software: you can redistribute it and/or modify |
| 16 | * it under the terms of the GNU General Public License as published by | 16 | * it under the terms of the GNU General Public License as published by |
| 17 | * the Free Software Foundation, either version 3 of the License, or | 17 | * the Free Software Foundation, either version 3 of the License, or |
| 18 | * (at your option) any later version. | 18 | * (at your option) any later version. |
| 19 | * | 19 | * |
| 20 | * This program is distributed in the hope that it will be useful, | 20 | * This program is distributed in the hope that it will be useful, |
| 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 23 | * GNU General Public License for more details. | 23 | * GNU General Public License for more details. |
| 24 | * | 24 | * |
| 25 | * You should have received a copy of the GNU General Public License | 25 | * You should have received a copy of the GNU General Public License |
| 26 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 26 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 27 | * | 27 | * |
| 28 | * | 28 | * |
| 29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
| 30 | 30 | ||
| 31 | #ifndef _NETUTILS_H_ | 31 | #ifndef _NETUTILS_H_ |
| 32 | #define _NETUTILS_H_ | 32 | #define _NETUTILS_H_ |
| 33 | 33 | ||
| 34 | #include "common.h" | 34 | #include "output.h" |
| 35 | #include "states.h" | ||
| 35 | #include "utils.h" | 36 | #include "utils.h" |
| 36 | #include <netinet/in.h> | 37 | #include <netinet/in.h> |
| 37 | #include <arpa/inet.h> | 38 | #include <arpa/inet.h> |
| 38 | #include <netdb.h> | 39 | #include <netdb.h> |
| 39 | 40 | ||
| 40 | #ifdef HAVE_SYS_UN_H | 41 | #ifdef HAVE_SYS_UN_H |
| 41 | # include <sys/un.h> | 42 | # include <sys/un.h> |
| 42 | # ifndef UNIX_PATH_MAX | 43 | # ifndef UNIX_PATH_MAX |
| 43 | /* linux uses this, on sun it's hard-coded at 108 without a define, on BSD at 104 */ | 44 | /* linux uses this, on sun it's hard-coded at 108 without a define, on BSD at 104 */ |
| 44 | # define UNIX_PATH_MAX 104 | 45 | # define UNIX_PATH_MAX 104 |
| 45 | # endif /* UNIX_PATH_MAX */ | 46 | # endif /* UNIX_PATH_MAX */ |
| 46 | #endif /* HAVE_SYS_UN_H */ | 47 | #endif /* HAVE_SYS_UN_H */ |
| 47 | 48 | ||
| 48 | #ifndef HOST_MAX_BYTES | 49 | #ifndef HOST_MAX_BYTES |
| 49 | # define HOST_MAX_BYTES 255 | 50 | # define HOST_MAX_BYTES 255 |
| 50 | #endif | 51 | #endif |
| 51 | 52 | ||
| 52 | /* process_request and wrapper macros */ | 53 | /* process_request and wrapper macros */ |
| 53 | #define process_tcp_request(addr, port, sbuf, rbuf, rsize) \ | 54 | #define process_tcp_request(addr, port, sbuf, rbuf, rsize) \ |
| 54 | process_request(addr, port, IPPROTO_TCP, sbuf, rbuf, rsize) | 55 | process_request(addr, port, IPPROTO_TCP, sbuf, rbuf, rsize) |
| 55 | #define process_udp_request(addr, port, sbuf, rbuf, rsize) \ | 56 | #define process_udp_request(addr, port, sbuf, rbuf, rsize) \ |
| 56 | process_request(addr, port, IPPROTO_UDP, sbuf, rbuf, rsize) | 57 | process_request(addr, port, IPPROTO_UDP, sbuf, rbuf, rsize) |
| 57 | int process_tcp_request2 (const char *address, int port, | 58 | mp_state_enum process_tcp_request2(const char *server_address, int server_port, |
| 58 | const char *sbuffer, char *rbuffer, int rsize); | 59 | const char *send_buffer, char *recv_buffer, int recv_size); |
| 59 | int process_request (const char *address, int port, int proto, | 60 | mp_state_enum process_request(const char *server_address, int server_port, int proto, |
| 60 | const char *sbuffer, char *rbuffer, int rsize); | 61 | const char *send_buffer, char *recv_buffer, int recv_size); |
| 61 | 62 | ||
| 62 | /* my_connect and wrapper macros */ | 63 | /* my_connect and wrapper macros */ |
| 63 | #define my_tcp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_TCP) | 64 | #define my_tcp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_TCP) |
| 64 | #define my_udp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_UDP) | 65 | #define my_udp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_UDP) |
| 65 | int np_net_connect(const char *address, int port, int *sd, int proto); | 66 | mp_state_enum np_net_connect(const char *host_name, int port, int *socketDescriptor, int proto); |
| 66 | 67 | ||
| 67 | /* send_request and wrapper macros */ | 68 | /* send_request and wrapper macros */ |
| 68 | #define send_tcp_request(s, sbuf, rbuf, rsize) \ | 69 | #define send_tcp_request(s, sbuf, rbuf, rsize) send_request(s, IPPROTO_TCP, sbuf, rbuf, rsize) |
| 69 | send_request(s, IPPROTO_TCP, sbuf, rbuf, rsize) | 70 | #define send_udp_request(s, sbuf, rbuf, rsize) send_request(s, IPPROTO_UDP, sbuf, rbuf, rsize) |
| 70 | #define send_udp_request(s, sbuf, rbuf, rsize) \ | 71 | mp_state_enum send_request(int socket, int proto, const char *send_buffer, char *recv_buffer, |
| 71 | send_request(s, IPPROTO_UDP, sbuf, rbuf, rsize) | 72 | int recv_size); |
| 72 | int send_request (int sd, int proto, const char *send_buffer, char *recv_buffer, int recv_size); | ||
| 73 | |||
| 74 | 73 | ||
| 75 | /* "is_*" wrapper macros and functions */ | 74 | /* "is_*" wrapper macros and functions */ |
| 76 | bool is_host (const char *); | 75 | bool is_host(const char *); |
| 77 | bool is_addr (const char *); | 76 | bool is_addr(const char *); |
| 78 | int dns_lookup (const char *, struct sockaddr_storage *, int); | 77 | bool dns_lookup(const char *, struct sockaddr_storage *, int); |
| 79 | void host_or_die(const char *str); | 78 | void host_or_die(const char *str); |
| 80 | #define resolve_host_or_addr(addr, family) dns_lookup(addr, NULL, family) | 79 | #define resolve_host_or_addr(addr, family) dns_lookup(addr, NULL, family) |
| 81 | #define is_inet_addr(addr) resolve_host_or_addr(addr, AF_INET) | 80 | #define is_inet_addr(addr) resolve_host_or_addr(addr, AF_INET) |
| 82 | #ifdef USE_IPV6 | 81 | #ifdef USE_IPV6 |
| 83 | # define is_inet6_addr(addr) resolve_host_or_addr(addr, AF_INET6) | 82 | # define is_inet6_addr(addr) resolve_host_or_addr(addr, AF_INET6) |
| 84 | # define is_hostname(addr) resolve_host_or_addr(addr, address_family) | 83 | # define is_hostname(addr) resolve_host_or_addr(addr, address_family) |
| 85 | #else | 84 | #else |
| 86 | # define is_hostname(addr) resolve_host_or_addr(addr, AF_INET) | 85 | # define is_hostname(addr) resolve_host_or_addr(addr, AF_INET) |
| 87 | #endif | 86 | #endif |
| 88 | 87 | ||
| 89 | extern unsigned int socket_timeout; | 88 | extern unsigned int socket_timeout; |
| 90 | extern unsigned int socket_timeout_state; | 89 | extern mp_state_enum socket_timeout_state; |
| 91 | extern int econn_refuse_state; | 90 | extern mp_state_enum econn_refuse_state; |
| 92 | extern bool was_refused; | 91 | extern bool was_refused; |
| 93 | extern int address_family; | 92 | extern int address_family; |
| 94 | 93 | ||
| 95 | void socket_timeout_alarm_handler (int) __attribute__((noreturn)); | 94 | void socket_timeout_alarm_handler(int) __attribute__((noreturn)); |
| 96 | 95 | ||
| 97 | /* SSL-Related functionality */ | 96 | /* SSL-Related functionality */ |
| 98 | #ifdef HAVE_SSL | 97 | #ifdef HAVE_SSL |
| 99 | # define MP_SSLv2 1 | 98 | # define MP_SSLv2 1 |
| 100 | # define MP_SSLv3 2 | 99 | # define MP_SSLv3 2 |
| 101 | # define MP_TLSv1 3 | 100 | # define MP_TLSv1 3 |
| 102 | # define MP_TLSv1_1 4 | 101 | # define MP_TLSv1_1 4 |
| 103 | # define MP_TLSv1_2 5 | 102 | # define MP_TLSv1_2 5 |
| 104 | # define MP_SSLv2_OR_NEWER 6 | 103 | # define MP_SSLv2_OR_NEWER 6 |
| 105 | # define MP_SSLv3_OR_NEWER 7 | 104 | # define MP_SSLv3_OR_NEWER 7 |
| 106 | # define MP_TLSv1_OR_NEWER 8 | 105 | # define MP_TLSv1_OR_NEWER 8 |
| 107 | # define MP_TLSv1_1_OR_NEWER 9 | 106 | # define MP_TLSv1_1_OR_NEWER 9 |
| 108 | # define MP_TLSv1_2_OR_NEWER 10 | 107 | # define MP_TLSv1_2_OR_NEWER 10 |
| 109 | /* maybe this could be merged with the above np_net_connect, via some flags */ | 108 | /* maybe this could be merged with the above np_net_connect, via some flags */ |
| 110 | int np_net_ssl_init(int sd); | 109 | int np_net_ssl_init(int socket); |
| 111 | int np_net_ssl_init_with_hostname(int sd, char *host_name); | 110 | int np_net_ssl_init_with_hostname(int socket, char *host_name); |
| 112 | int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version); | 111 | int np_net_ssl_init_with_hostname_and_version(int socket, char *host_name, int version); |
| 113 | int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey); | 112 | int np_net_ssl_init_with_hostname_version_and_cert(int socket, char *host_name, int version, |
| 114 | void np_net_ssl_cleanup(); | 113 | char *cert, char *privkey); |
| 114 | void np_net_ssl_cleanup(void); | ||
| 115 | int np_net_ssl_write(const void *buf, int num); | 115 | int np_net_ssl_write(const void *buf, int num); |
| 116 | int np_net_ssl_read(void *buf, int num); | 116 | int np_net_ssl_read(void *buf, int num); |
| 117 | int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); | ||
| 118 | #endif /* HAVE_SSL */ | ||
| 119 | 117 | ||
| 118 | typedef enum { | ||
| 119 | ALL_OK, | ||
| 120 | NO_SERVER_CERTIFICATE_PRESENT, | ||
| 121 | UNABLE_TO_RETRIEVE_CERTIFICATE_SUBJECT, | ||
| 122 | WRONG_TIME_FORMAT_IN_CERTIFICATE, | ||
| 123 | } retrieve_expiration_date_errors; | ||
| 124 | |||
| 125 | typedef struct { | ||
| 126 | double remaining_seconds; | ||
| 127 | retrieve_expiration_date_errors errors; | ||
| 128 | } retrieve_expiration_time_result; | ||
| 129 | |||
| 130 | typedef struct { | ||
| 131 | mp_state_enum result_state; | ||
| 132 | double remaining_seconds; | ||
| 133 | retrieve_expiration_date_errors errors; | ||
| 134 | } net_ssl_check_cert_result; | ||
| 135 | net_ssl_check_cert_result np_net_ssl_check_cert2(int days_till_exp_warn, int days_till_exp_crit); | ||
| 136 | |||
| 137 | mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); | ||
| 138 | mp_subcheck mp_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); | ||
| 139 | #endif /* HAVE_SSL */ | ||
| 120 | #endif /* _NETUTILS_H_ */ | 140 | #endif /* _NETUTILS_H_ */ |
diff --git a/plugins/picohttpparser/picohttpparser.c b/plugins/picohttpparser/picohttpparser.c index 2ae92d66..e87388b0 100644 --- a/plugins/picohttpparser/picohttpparser.c +++ b/plugins/picohttpparser/picohttpparser.c | |||
| @@ -50,59 +50,61 @@ | |||
| 50 | # define ALIGNED(n) __attribute__((aligned(n))) | 50 | # define ALIGNED(n) __attribute__((aligned(n))) |
| 51 | #endif | 51 | #endif |
| 52 | 52 | ||
| 53 | #define IS_PRINTABLE_ASCII(c) ((unsigned char)(c)-040u < 0137u) | 53 | #define IS_PRINTABLE_ASCII(c) ((unsigned char)(c) - 040u < 0137u) |
| 54 | 54 | ||
| 55 | #define CHECK_EOF() \ | 55 | #define CHECK_EOF() \ |
| 56 | if (buf == buf_end) { \ | 56 | if (buf == buf_end) { \ |
| 57 | *ret = -2; \ | 57 | *ret = -2; \ |
| 58 | return NULL; \ | 58 | return NULL; \ |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | #define EXPECT_CHAR_NO_CHECK(ch) \ | 61 | #define EXPECT_CHAR_NO_CHECK(ch) \ |
| 62 | if (*buf++ != ch) { \ | 62 | if (*buf++ != ch) { \ |
| 63 | *ret = -1; \ | 63 | *ret = -1; \ |
| 64 | return NULL; \ | 64 | return NULL; \ |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | #define EXPECT_CHAR(ch) \ | 67 | #define EXPECT_CHAR(ch) \ |
| 68 | CHECK_EOF(); \ | 68 | CHECK_EOF(); \ |
| 69 | EXPECT_CHAR_NO_CHECK(ch); | 69 | EXPECT_CHAR_NO_CHECK(ch); |
| 70 | 70 | ||
| 71 | #define ADVANCE_TOKEN(tok, toklen) \ | 71 | #define ADVANCE_TOKEN(tok, toklen) \ |
| 72 | do { \ | 72 | do { \ |
| 73 | const char *tok_start = buf; \ | 73 | const char *tok_start = buf; \ |
| 74 | static const char ALIGNED(16) ranges2[16] = "\000\040\177\177"; \ | 74 | static const char ALIGNED(16) ranges2[16] = "\000\040\177\177"; \ |
| 75 | int found2; \ | 75 | int found2; \ |
| 76 | buf = findchar_fast(buf, buf_end, ranges2, 4, &found2); \ | 76 | buf = findchar_fast(buf, buf_end, ranges2, 4, &found2); \ |
| 77 | if (!found2) { \ | 77 | if (!found2) { \ |
| 78 | CHECK_EOF(); \ | 78 | CHECK_EOF(); \ |
| 79 | } \ | 79 | } \ |
| 80 | while (1) { \ | 80 | while (1) { \ |
| 81 | if (*buf == ' ') { \ | 81 | if (*buf == ' ') { \ |
| 82 | break; \ | 82 | break; \ |
| 83 | } else if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { \ | 83 | } else if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { \ |
| 84 | if ((unsigned char)*buf < '\040' || *buf == '\177') { \ | 84 | if ((unsigned char)*buf < '\040' || *buf == '\177') { \ |
| 85 | *ret = -1; \ | 85 | *ret = -1; \ |
| 86 | return NULL; \ | 86 | return NULL; \ |
| 87 | } \ | 87 | } \ |
| 88 | } \ | 88 | } \ |
| 89 | ++buf; \ | 89 | ++buf; \ |
| 90 | CHECK_EOF(); \ | 90 | CHECK_EOF(); \ |
| 91 | } \ | 91 | } \ |
| 92 | tok = tok_start; \ | 92 | tok = tok_start; \ |
| 93 | toklen = buf - tok_start; \ | 93 | toklen = buf - tok_start; \ |
| 94 | } while (0) | 94 | } while (0) |
| 95 | 95 | ||
| 96 | static const char *token_char_map = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 96 | static const char *token_char_map = |
| 97 | "\0\1\0\1\1\1\1\1\0\0\1\1\0\1\1\0\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0" | 97 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
| 98 | "\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\1\1" | 98 | "\0\1\0\1\1\1\1\1\0\0\1\1\0\1\1\0\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0" |
| 99 | "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\1\0\1\0" | 99 | "\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\1\1" |
| 100 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 100 | "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\1\0\1\0" |
| 101 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 101 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
| 102 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 102 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
| 103 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; | 103 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
| 104 | 104 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; | |
| 105 | static const char *findchar_fast(const char *buf, const char *buf_end, const char *ranges, size_t ranges_size, int *found) { | 105 | |
| 106 | static const char *findchar_fast(const char *buf, const char *buf_end, const char *ranges, | ||
| 107 | size_t ranges_size, int *found) { | ||
| 106 | *found = 0; | 108 | *found = 0; |
| 107 | #if __SSE4_2__ | 109 | #if __SSE4_2__ |
| 108 | if (likely(buf_end - buf >= 16)) { | 110 | if (likely(buf_end - buf >= 16)) { |
| @@ -111,7 +113,8 @@ static const char *findchar_fast(const char *buf, const char *buf_end, const cha | |||
| 111 | size_t left = (buf_end - buf) & ~15; | 113 | size_t left = (buf_end - buf) & ~15; |
| 112 | do { | 114 | do { |
| 113 | __m128i b16 = _mm_loadu_si128((const __m128i *)buf); | 115 | __m128i b16 = _mm_loadu_si128((const __m128i *)buf); |
| 114 | int r = _mm_cmpestri(ranges16, ranges_size, b16, 16, _SIDD_LEAST_SIGNIFICANT | _SIDD_CMP_RANGES | _SIDD_UBYTE_OPS); | 116 | int r = _mm_cmpestri(ranges16, ranges_size, b16, 16, |
| 117 | _SIDD_LEAST_SIGNIFICANT | _SIDD_CMP_RANGES | _SIDD_UBYTE_OPS); | ||
| 115 | if (unlikely(r != 16)) { | 118 | if (unlikely(r != 16)) { |
| 116 | buf += r; | 119 | buf += r; |
| 117 | *found = 1; | 120 | *found = 1; |
| @@ -130,25 +133,29 @@ static const char *findchar_fast(const char *buf, const char *buf_end, const cha | |||
| 130 | return buf; | 133 | return buf; |
| 131 | } | 134 | } |
| 132 | 135 | ||
| 133 | static const char *get_token_to_eol(const char *buf, const char *buf_end, const char **token, size_t *token_len, int *ret) { | 136 | static const char *get_token_to_eol(const char *buf, const char *buf_end, const char **token, |
| 137 | size_t *token_len, int *ret) { | ||
| 134 | const char *token_start = buf; | 138 | const char *token_start = buf; |
| 135 | 139 | ||
| 136 | #ifdef __SSE4_2__ | 140 | #ifdef __SSE4_2__ |
| 137 | static const char ALIGNED(16) ranges1[16] = "\0\010" /* allow HT */ | 141 | static const char ALIGNED(16) ranges1[16] = |
| 138 | "\012\037" /* allow SP and up to but not including DEL */ | 142 | "\0\010" /* allow HT */ |
| 139 | "\177\177"; /* allow chars w. MSB set */ | 143 | "\012\037" /* allow SP and up to but not including DEL */ |
| 144 | "\177\177"; /* allow chars w. MSB set */ | ||
| 140 | int found; | 145 | int found; |
| 141 | buf = findchar_fast(buf, buf_end, ranges1, 6, &found); | 146 | buf = findchar_fast(buf, buf_end, ranges1, 6, &found); |
| 142 | if (found) | 147 | if (found) { |
| 143 | goto FOUND_CTL; | 148 | goto FOUND_CTL; |
| 149 | } | ||
| 144 | #else | 150 | #else |
| 145 | /* find non-printable char within the next 8 bytes, this is the hottest code; manually inlined */ | 151 | /* find non-printable char within the next 8 bytes, this is the hottest code; manually inlined |
| 152 | */ | ||
| 146 | while (likely(buf_end - buf >= 8)) { | 153 | while (likely(buf_end - buf >= 8)) { |
| 147 | # define DOIT() \ | 154 | # define DOIT() \ |
| 148 | do { \ | 155 | do { \ |
| 149 | if (unlikely(!IS_PRINTABLE_ASCII(*buf))) \ | 156 | if (unlikely(!IS_PRINTABLE_ASCII(*buf))) \ |
| 150 | goto NonPrintable; \ | 157 | goto NonPrintable; \ |
| 151 | ++buf; \ | 158 | ++buf; \ |
| 152 | } while (0) | 159 | } while (0) |
| 153 | DOIT(); | 160 | DOIT(); |
| 154 | DOIT(); | 161 | DOIT(); |
| @@ -161,7 +168,8 @@ static const char *get_token_to_eol(const char *buf, const char *buf_end, const | |||
| 161 | # undef DOIT | 168 | # undef DOIT |
| 162 | continue; | 169 | continue; |
| 163 | NonPrintable: | 170 | NonPrintable: |
| 164 | if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) { | 171 | if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || |
| 172 | unlikely(*buf == '\177')) { | ||
| 165 | goto FOUND_CTL; | 173 | goto FOUND_CTL; |
| 166 | } | 174 | } |
| 167 | ++buf; | 175 | ++buf; |
| @@ -170,7 +178,8 @@ static const char *get_token_to_eol(const char *buf, const char *buf_end, const | |||
| 170 | for (;; ++buf) { | 178 | for (;; ++buf) { |
| 171 | CHECK_EOF(); | 179 | CHECK_EOF(); |
| 172 | if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { | 180 | if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { |
| 173 | if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) { | 181 | if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || |
| 182 | unlikely(*buf == '\177')) { | ||
| 174 | goto FOUND_CTL; | 183 | goto FOUND_CTL; |
| 175 | } | 184 | } |
| 176 | } | 185 | } |
| @@ -219,27 +228,28 @@ static const char *is_complete(const char *buf, const char *buf_end, size_t last | |||
| 219 | return NULL; | 228 | return NULL; |
| 220 | } | 229 | } |
| 221 | 230 | ||
| 222 | #define PARSE_INT(valp_, mul_) \ | 231 | #define PARSE_INT(valp_, mul_) \ |
| 223 | if (*buf < '0' || '9' < *buf) { \ | 232 | if (*buf < '0' || '9' < *buf) { \ |
| 224 | buf++; \ | 233 | buf++; \ |
| 225 | *ret = -1; \ | 234 | *ret = -1; \ |
| 226 | return NULL; \ | 235 | return NULL; \ |
| 227 | } \ | 236 | } \ |
| 228 | *(valp_) = (mul_) * (*buf++ - '0'); | 237 | *(valp_) = (mul_) * (*buf++ - '0'); |
| 229 | 238 | ||
| 230 | #define PARSE_INT_3(valp_) \ | 239 | #define PARSE_INT_3(valp_) \ |
| 231 | do { \ | 240 | do { \ |
| 232 | int res_ = 0; \ | 241 | int res_ = 0; \ |
| 233 | PARSE_INT(&res_, 100) \ | 242 | PARSE_INT(&res_, 100) \ |
| 234 | *valp_ = res_; \ | 243 | *valp_ = res_; \ |
| 235 | PARSE_INT(&res_, 10) \ | 244 | PARSE_INT(&res_, 10) \ |
| 236 | *valp_ += res_; \ | 245 | *valp_ += res_; \ |
| 237 | PARSE_INT(&res_, 1) \ | 246 | PARSE_INT(&res_, 1) \ |
| 238 | *valp_ += res_; \ | 247 | *valp_ += res_; \ |
| 239 | } while (0) | 248 | } while (0) |
| 240 | 249 | ||
| 241 | /* returned pointer is always within [buf, buf_end), or null */ | 250 | /* returned pointer is always within [buf, buf_end), or null */ |
| 242 | static const char *parse_http_version(const char *buf, const char *buf_end, int *major_version, int *minor_version, int *ret) { | 251 | static const char *parse_http_version(const char *buf, const char *buf_end, int *major_version, |
| 252 | int *minor_version, int *ret) { | ||
| 243 | /* we want at least [HTTP/1.<two chars>] to try to parse */ | 253 | /* we want at least [HTTP/1.<two chars>] to try to parse */ |
| 244 | if (buf_end - buf < 9) { | 254 | if (buf_end - buf < 9) { |
| 245 | *ret = -2; | 255 | *ret = -2; |
| @@ -260,8 +270,8 @@ static const char *parse_http_version(const char *buf, const char *buf_end, int | |||
| 260 | return buf; | 270 | return buf; |
| 261 | } | 271 | } |
| 262 | 272 | ||
| 263 | static const char *parse_headers(const char *buf, const char *buf_end, struct phr_header *headers, size_t *num_headers, size_t max_headers, | 273 | static const char *parse_headers(const char *buf, const char *buf_end, struct phr_header *headers, |
| 264 | int *ret) { | 274 | size_t *num_headers, size_t max_headers, int *ret) { |
| 265 | for (;; ++*num_headers) { | 275 | for (;; ++*num_headers) { |
| 266 | CHECK_EOF(); | 276 | CHECK_EOF(); |
| 267 | if (*buf == '\015') { | 277 | if (*buf == '\015') { |
| @@ -337,9 +347,10 @@ static const char *parse_headers(const char *buf, const char *buf_end, struct ph | |||
| 337 | return buf; | 347 | return buf; |
| 338 | } | 348 | } |
| 339 | 349 | ||
| 340 | static const char *parse_request(const char *buf, const char *buf_end, const char **method, size_t *method_len, const char **path, | 350 | static const char *parse_request(const char *buf, const char *buf_end, const char **method, |
| 341 | size_t *path_len, int *major_version, int *minor_version, struct phr_header *headers, size_t *num_headers, | 351 | size_t *method_len, const char **path, size_t *path_len, |
| 342 | size_t max_headers, int *ret) { | 352 | int *major_version, int *minor_version, struct phr_header *headers, |
| 353 | size_t *num_headers, size_t max_headers, int *ret) { | ||
| 343 | /* skip first empty line (some clients add CRLF after POST content) */ | 354 | /* skip first empty line (some clients add CRLF after POST content) */ |
| 344 | CHECK_EOF(); | 355 | CHECK_EOF(); |
| 345 | if (*buf == '\015') { | 356 | if (*buf == '\015') { |
| @@ -378,8 +389,9 @@ static const char *parse_request(const char *buf, const char *buf_end, const cha | |||
| 378 | return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); | 389 | return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); |
| 379 | } | 390 | } |
| 380 | 391 | ||
| 381 | int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len, | 392 | int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, |
| 382 | int *major_version, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len) { | 393 | const char **path, size_t *path_len, int *major_version, int *minor_version, |
| 394 | struct phr_header *headers, size_t *num_headers, size_t last_len) { | ||
| 383 | const char *buf = buf_start, *buf_end = buf_start + len; | 395 | const char *buf = buf_start, *buf_end = buf_start + len; |
| 384 | size_t max_headers = *num_headers; | 396 | size_t max_headers = *num_headers; |
| 385 | int r; | 397 | int r; |
| @@ -398,17 +410,18 @@ int phr_parse_request(const char *buf_start, size_t len, const char **method, si | |||
| 398 | return r; | 410 | return r; |
| 399 | } | 411 | } |
| 400 | 412 | ||
| 401 | if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, major_version, minor_version, headers, num_headers, | 413 | if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, major_version, |
| 402 | max_headers, &r)) == NULL) { | 414 | minor_version, headers, num_headers, max_headers, &r)) == NULL) { |
| 403 | return r; | 415 | return r; |
| 404 | } | 416 | } |
| 405 | 417 | ||
| 406 | return (int)(buf - buf_start); | 418 | return (int)(buf - buf_start); |
| 407 | } | 419 | } |
| 408 | 420 | ||
| 409 | static const char *parse_response(const char *buf, const char *buf_end, int *major_version, int *minor_version, int *status, | 421 | static const char *parse_response(const char *buf, const char *buf_end, int *major_version, |
| 410 | const char **msg, size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t max_headers, | 422 | int *minor_version, int *status, const char **msg, |
| 411 | int *ret) { | 423 | size_t *msg_len, struct phr_header *headers, size_t *num_headers, |
| 424 | size_t max_headers, int *ret) { | ||
| 412 | /* parse "HTTP/1.x" */ | 425 | /* parse "HTTP/1.x" */ |
| 413 | if ((buf = parse_http_version(buf, buf_end, major_version, minor_version, ret)) == NULL) { | 426 | if ((buf = parse_http_version(buf, buf_end, major_version, minor_version, ret)) == NULL) { |
| 414 | return NULL; | 427 | return NULL; |
| @@ -421,7 +434,8 @@ static const char *parse_response(const char *buf, const char *buf_end, int *maj | |||
| 421 | do { | 434 | do { |
| 422 | ++buf; | 435 | ++buf; |
| 423 | } while (*buf == ' '); | 436 | } while (*buf == ' '); |
| 424 | /* parse status code, we want at least [:digit:][:digit:][:digit:]<other char> to try to parse */ | 437 | /* parse status code, we want at least [:digit:][:digit:][:digit:]<other char> to try to parse |
| 438 | */ | ||
| 425 | if (buf_end - buf < 4) { | 439 | if (buf_end - buf < 4) { |
| 426 | *ret = -2; | 440 | *ret = -2; |
| 427 | return NULL; | 441 | return NULL; |
| @@ -449,8 +463,9 @@ static const char *parse_response(const char *buf, const char *buf_end, int *maj | |||
| 449 | return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); | 463 | return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); |
| 450 | } | 464 | } |
| 451 | 465 | ||
| 452 | int phr_parse_response(const char *buf_start, size_t len, int *major_version, int *minor_version, int *status, const char **msg, | 466 | int phr_parse_response(const char *buf_start, size_t len, int *major_version, int *minor_version, |
| 453 | size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t last_len) { | 467 | int *status, const char **msg, size_t *msg_len, struct phr_header *headers, |
| 468 | size_t *num_headers, size_t last_len) { | ||
| 454 | const char *buf = buf_start, *buf_end = buf + len; | 469 | const char *buf = buf_start, *buf_end = buf + len; |
| 455 | size_t max_headers = *num_headers; | 470 | size_t max_headers = *num_headers; |
| 456 | int r; | 471 | int r; |
| @@ -468,15 +483,16 @@ int phr_parse_response(const char *buf_start, size_t len, int *major_version, in | |||
| 468 | return r; | 483 | return r; |
| 469 | } | 484 | } |
| 470 | 485 | ||
| 471 | if ((buf = parse_response(buf, buf_end, major_version, minor_version, status, msg, msg_len, headers, num_headers, max_headers, &r)) == | 486 | if ((buf = parse_response(buf, buf_end, major_version, minor_version, status, msg, msg_len, |
| 472 | NULL) { | 487 | headers, num_headers, max_headers, &r)) == NULL) { |
| 473 | return r; | 488 | return r; |
| 474 | } | 489 | } |
| 475 | 490 | ||
| 476 | return (int)(buf - buf_start); | 491 | return (int)(buf - buf_start); |
| 477 | } | 492 | } |
| 478 | 493 | ||
| 479 | int phr_parse_headers(const char *buf_start, size_t len, struct phr_header *headers, size_t *num_headers, size_t last_len) { | 494 | int phr_parse_headers(const char *buf_start, size_t len, struct phr_header *headers, |
| 495 | size_t *num_headers, size_t last_len) { | ||
| 480 | const char *buf = buf_start, *buf_end = buf + len; | 496 | const char *buf = buf_start, *buf_end = buf + len; |
| 481 | size_t max_headers = *num_headers; | 497 | size_t max_headers = *num_headers; |
| 482 | int r; | 498 | int r; |
| @@ -526,8 +542,9 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_ | |||
| 526 | case CHUNKED_IN_CHUNK_SIZE: | 542 | case CHUNKED_IN_CHUNK_SIZE: |
| 527 | for (;; ++src) { | 543 | for (;; ++src) { |
| 528 | int v; | 544 | int v; |
| 529 | if (src == bufsz) | 545 | if (src == bufsz) { |
| 530 | goto Exit; | 546 | goto Exit; |
| 547 | } | ||
| 531 | if ((v = decode_hex(buf[src])) == -1) { | 548 | if ((v = decode_hex(buf[src])) == -1) { |
| 532 | if (decoder->_hex_count == 0) { | 549 | if (decoder->_hex_count == 0) { |
| 533 | ret = -1; | 550 | ret = -1; |
| @@ -548,10 +565,12 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_ | |||
| 548 | case CHUNKED_IN_CHUNK_EXT: | 565 | case CHUNKED_IN_CHUNK_EXT: |
| 549 | /* RFC 7230 A.2 "Line folding in chunk extensions is disallowed" */ | 566 | /* RFC 7230 A.2 "Line folding in chunk extensions is disallowed" */ |
| 550 | for (;; ++src) { | 567 | for (;; ++src) { |
| 551 | if (src == bufsz) | 568 | if (src == bufsz) { |
| 552 | goto Exit; | 569 | goto Exit; |
| 553 | if (buf[src] == '\012') | 570 | } |
| 571 | if (buf[src] == '\012') { | ||
| 554 | break; | 572 | break; |
| 573 | } | ||
| 555 | } | 574 | } |
| 556 | ++src; | 575 | ++src; |
| 557 | if (decoder->bytes_left_in_chunk == 0) { | 576 | if (decoder->bytes_left_in_chunk == 0) { |
| @@ -567,15 +586,17 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_ | |||
| 567 | case CHUNKED_IN_CHUNK_DATA: { | 586 | case CHUNKED_IN_CHUNK_DATA: { |
| 568 | size_t avail = bufsz - src; | 587 | size_t avail = bufsz - src; |
| 569 | if (avail < decoder->bytes_left_in_chunk) { | 588 | if (avail < decoder->bytes_left_in_chunk) { |
| 570 | if (dst != src) | 589 | if (dst != src) { |
| 571 | memmove(buf + dst, buf + src, avail); | 590 | memmove(buf + dst, buf + src, avail); |
| 591 | } | ||
| 572 | src += avail; | 592 | src += avail; |
| 573 | dst += avail; | 593 | dst += avail; |
| 574 | decoder->bytes_left_in_chunk -= avail; | 594 | decoder->bytes_left_in_chunk -= avail; |
| 575 | goto Exit; | 595 | goto Exit; |
| 576 | } | 596 | } |
| 577 | if (dst != src) | 597 | if (dst != src) { |
| 578 | memmove(buf + dst, buf + src, decoder->bytes_left_in_chunk); | 598 | memmove(buf + dst, buf + src, decoder->bytes_left_in_chunk); |
| 599 | } | ||
| 579 | src += decoder->bytes_left_in_chunk; | 600 | src += decoder->bytes_left_in_chunk; |
| 580 | dst += decoder->bytes_left_in_chunk; | 601 | dst += decoder->bytes_left_in_chunk; |
| 581 | decoder->bytes_left_in_chunk = 0; | 602 | decoder->bytes_left_in_chunk = 0; |
| @@ -584,10 +605,12 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_ | |||
| 584 | /* fallthru */ | 605 | /* fallthru */ |
| 585 | case CHUNKED_IN_CHUNK_CRLF: | 606 | case CHUNKED_IN_CHUNK_CRLF: |
| 586 | for (;; ++src) { | 607 | for (;; ++src) { |
| 587 | if (src == bufsz) | 608 | if (src == bufsz) { |
| 588 | goto Exit; | 609 | goto Exit; |
| 589 | if (buf[src] != '\015') | 610 | } |
| 611 | if (buf[src] != '\015') { | ||
| 590 | break; | 612 | break; |
| 613 | } | ||
| 591 | } | 614 | } |
| 592 | if (buf[src] != '\012') { | 615 | if (buf[src] != '\012') { |
| 593 | ret = -1; | 616 | ret = -1; |
| @@ -598,21 +621,26 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_ | |||
| 598 | break; | 621 | break; |
| 599 | case CHUNKED_IN_TRAILERS_LINE_HEAD: | 622 | case CHUNKED_IN_TRAILERS_LINE_HEAD: |
| 600 | for (;; ++src) { | 623 | for (;; ++src) { |
| 601 | if (src == bufsz) | 624 | if (src == bufsz) { |
| 602 | goto Exit; | 625 | goto Exit; |
| 603 | if (buf[src] != '\015') | 626 | } |
| 627 | if (buf[src] != '\015') { | ||
| 604 | break; | 628 | break; |
| 629 | } | ||
| 605 | } | 630 | } |
| 606 | if (buf[src++] == '\012') | 631 | if (buf[src++] == '\012') { |
| 607 | goto Complete; | 632 | goto Complete; |
| 633 | } | ||
| 608 | decoder->_state = CHUNKED_IN_TRAILERS_LINE_MIDDLE; | 634 | decoder->_state = CHUNKED_IN_TRAILERS_LINE_MIDDLE; |
| 609 | /* fallthru */ | 635 | /* fallthru */ |
| 610 | case CHUNKED_IN_TRAILERS_LINE_MIDDLE: | 636 | case CHUNKED_IN_TRAILERS_LINE_MIDDLE: |
| 611 | for (;; ++src) { | 637 | for (;; ++src) { |
| 612 | if (src == bufsz) | 638 | if (src == bufsz) { |
| 613 | goto Exit; | 639 | goto Exit; |
| 614 | if (buf[src] == '\012') | 640 | } |
| 641 | if (buf[src] == '\012') { | ||
| 615 | break; | 642 | break; |
| 643 | } | ||
| 616 | } | 644 | } |
| 617 | ++src; | 645 | ++src; |
| 618 | decoder->_state = CHUNKED_IN_TRAILERS_LINE_HEAD; | 646 | decoder->_state = CHUNKED_IN_TRAILERS_LINE_HEAD; |
| @@ -625,13 +653,16 @@ ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_ | |||
| 625 | Complete: | 653 | Complete: |
| 626 | ret = bufsz - src; | 654 | ret = bufsz - src; |
| 627 | Exit: | 655 | Exit: |
| 628 | if (dst != src) | 656 | if (dst != src) { |
| 629 | memmove(buf + dst, buf + src, bufsz - src); | 657 | memmove(buf + dst, buf + src, bufsz - src); |
| 658 | } | ||
| 630 | *_bufsz = dst; | 659 | *_bufsz = dst; |
| 631 | return ret; | 660 | return ret; |
| 632 | } | 661 | } |
| 633 | 662 | ||
| 634 | int phr_decode_chunked_is_in_data(struct phr_chunked_decoder *decoder) { return decoder->_state == CHUNKED_IN_CHUNK_DATA; } | 663 | int phr_decode_chunked_is_in_data(struct phr_chunked_decoder *decoder) { |
| 664 | return decoder->_state == CHUNKED_IN_CHUNK_DATA; | ||
| 665 | } | ||
| 635 | 666 | ||
| 636 | #undef CHECK_EOF | 667 | #undef CHECK_EOF |
| 637 | #undef EXPECT_CHAR | 668 | #undef EXPECT_CHAR |
diff --git a/plugins/picohttpparser/picohttpparser.h b/plugins/picohttpparser/picohttpparser.h index 8f13b36f..054c2812 100644 --- a/plugins/picohttpparser/picohttpparser.h +++ b/plugins/picohttpparser/picohttpparser.h | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #include <sys/types.h> | 30 | #include <sys/types.h> |
| 31 | 31 | ||
| 32 | #ifdef _MSC_VER | 32 | #ifdef _MSC_VER |
| 33 | #define ssize_t intptr_t | 33 | # define ssize_t intptr_t |
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| 36 | #ifdef __cplusplus | 36 | #ifdef __cplusplus |
| @@ -40,30 +40,33 @@ extern "C" { | |||
| 40 | /* contains name and value of a header (name == NULL if is a continuing line | 40 | /* contains name and value of a header (name == NULL if is a continuing line |
| 41 | * of a multiline header */ | 41 | * of a multiline header */ |
| 42 | struct phr_header { | 42 | struct phr_header { |
| 43 | const char *name; | 43 | const char *name; |
| 44 | size_t name_len; | 44 | size_t name_len; |
| 45 | const char *value; | 45 | const char *value; |
| 46 | size_t value_len; | 46 | size_t value_len; |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | /* returns number of bytes consumed if successful, -2 if request is partial, | 49 | /* returns number of bytes consumed if successful, -2 if request is partial, |
| 50 | * -1 if failed */ | 50 | * -1 if failed */ |
| 51 | int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len, | 51 | int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, |
| 52 | int *major_version, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len); | 52 | const char **path, size_t *path_len, int *major_version, int *minor_version, |
| 53 | struct phr_header *headers, size_t *num_headers, size_t last_len); | ||
| 53 | 54 | ||
| 54 | /* ditto */ | 55 | /* ditto */ |
| 55 | int phr_parse_response(const char *_buf, size_t len, int *major_version, int *minor_version, int *status, const char **msg, size_t *msg_len, | 56 | int phr_parse_response(const char *_buf, size_t len, int *major_version, int *minor_version, |
| 56 | struct phr_header *headers, size_t *num_headers, size_t last_len); | 57 | int *status, const char **msg, size_t *msg_len, struct phr_header *headers, |
| 58 | size_t *num_headers, size_t last_len); | ||
| 57 | 59 | ||
| 58 | /* ditto */ | 60 | /* ditto */ |
| 59 | int phr_parse_headers(const char *buf, size_t len, struct phr_header *headers, size_t *num_headers, size_t last_len); | 61 | int phr_parse_headers(const char *buf, size_t len, struct phr_header *headers, size_t *num_headers, |
| 62 | size_t last_len); | ||
| 60 | 63 | ||
| 61 | /* should be zero-filled before start */ | 64 | /* should be zero-filled before start */ |
| 62 | struct phr_chunked_decoder { | 65 | struct phr_chunked_decoder { |
| 63 | size_t bytes_left_in_chunk; /* number of bytes left in current chunk */ | 66 | size_t bytes_left_in_chunk; /* number of bytes left in current chunk */ |
| 64 | char consume_trailer; /* if trailing headers should be consumed */ | 67 | char consume_trailer; /* if trailing headers should be consumed */ |
| 65 | char _hex_count; | 68 | char _hex_count; |
| 66 | char _state; | 69 | char _state; |
| 67 | }; | 70 | }; |
| 68 | 71 | ||
| 69 | /* the function rewrites the buffer given as (buf, bufsz) removing the chunked- | 72 | /* the function rewrites the buffer given as (buf, bufsz) removing the chunked- |
diff --git a/plugins/popen.c b/plugins/popen.c index cfe930b6..c596d1e0 100644 --- a/plugins/popen.c +++ b/plugins/popen.c | |||
| @@ -68,7 +68,7 @@ void popen_timeout_alarm_handler(int /*signo*/); | |||
| 68 | #endif | 68 | #endif |
| 69 | 69 | ||
| 70 | #ifndef WIFEXITED | 70 | #ifndef WIFEXITED |
| 71 | # define WIFEXITED(stat_val) (((stat_val)&255) == 0) | 71 | # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) |
| 72 | #endif | 72 | #endif |
| 73 | 73 | ||
| 74 | /* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */ | 74 | /* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */ |
| @@ -96,24 +96,28 @@ FILE *spopen(const char *cmdstring) { | |||
| 96 | env[1] = NULL; | 96 | env[1] = NULL; |
| 97 | 97 | ||
| 98 | /* if no command was passed, return with no error */ | 98 | /* if no command was passed, return with no error */ |
| 99 | if (cmdstring == NULL) | 99 | if (cmdstring == NULL) { |
| 100 | return (NULL); | 100 | return (NULL); |
| 101 | } | ||
| 101 | 102 | ||
| 102 | char *cmd = NULL; | 103 | char *cmd = NULL; |
| 103 | /* make copy of command string so strtok() doesn't silently modify it */ | 104 | /* make copy of command string so strtok() doesn't silently modify it */ |
| 104 | /* (the calling program may want to access it later) */ | 105 | /* (the calling program may want to access it later) */ |
| 105 | cmd = malloc(strlen(cmdstring) + 1); | 106 | cmd = malloc(strlen(cmdstring) + 1); |
| 106 | if (cmd == NULL) | 107 | if (cmd == NULL) { |
| 107 | return NULL; | 108 | return NULL; |
| 109 | } | ||
| 108 | strcpy(cmd, cmdstring); | 110 | strcpy(cmd, cmdstring); |
| 109 | 111 | ||
| 110 | /* This is not a shell, so we don't handle "???" */ | 112 | /* This is not a shell, so we don't handle "???" */ |
| 111 | if (strstr(cmdstring, "\"")) | 113 | if (strstr(cmdstring, "\"")) { |
| 112 | return NULL; | 114 | return NULL; |
| 115 | } | ||
| 113 | 116 | ||
| 114 | /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ | 117 | /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ |
| 115 | if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) | 118 | if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) { |
| 116 | return NULL; | 119 | return NULL; |
| 120 | } | ||
| 117 | 121 | ||
| 118 | int argc; | 122 | int argc; |
| 119 | char **argv = NULL; | 123 | char **argv = NULL; |
| @@ -140,15 +144,17 @@ FILE *spopen(const char *cmdstring) { | |||
| 140 | 144 | ||
| 141 | if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ | 145 | if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ |
| 142 | str++; | 146 | str++; |
| 143 | if (!strstr(str, "'")) | 147 | if (!strstr(str, "'")) { |
| 144 | return NULL; /* balanced? */ | 148 | return NULL; /* balanced? */ |
| 149 | } | ||
| 145 | cmd = 1 + strstr(str, "'"); | 150 | cmd = 1 + strstr(str, "'"); |
| 146 | str[strcspn(str, "'")] = 0; | 151 | str[strcspn(str, "'")] = 0; |
| 147 | } else if (strcspn(str, "'") < strcspn(str, " \t\r\n")) { | 152 | } else if (strcspn(str, "'") < strcspn(str, " \t\r\n")) { |
| 148 | /* handle --option='foo bar' strings */ | 153 | /* handle --option='foo bar' strings */ |
| 149 | char *tmp = str + strcspn(str, "'") + 1; | 154 | char *tmp = str + strcspn(str, "'") + 1; |
| 150 | if (!strstr(tmp, "'")) | 155 | if (!strstr(tmp, "'")) { |
| 151 | return NULL; /* balanced? */ | 156 | return NULL; /* balanced? */ |
| 157 | } | ||
| 152 | tmp += strcspn(tmp, "'") + 1; | 158 | tmp += strcspn(tmp, "'") + 1; |
| 153 | *tmp = 0; | 159 | *tmp = 0; |
| 154 | cmd = tmp + 1; | 160 | cmd = tmp + 1; |
| @@ -161,8 +167,9 @@ FILE *spopen(const char *cmdstring) { | |||
| 161 | } | 167 | } |
| 162 | } | 168 | } |
| 163 | 169 | ||
| 164 | if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) | 170 | if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) { |
| 165 | cmd = NULL; | 171 | cmd = NULL; |
| 172 | } | ||
| 166 | 173 | ||
| 167 | argv[i++] = str; | 174 | argv[i++] = str; |
| 168 | } | 175 | } |
| @@ -171,22 +178,26 @@ FILE *spopen(const char *cmdstring) { | |||
| 171 | long maxfd = mp_open_max(); | 178 | long maxfd = mp_open_max(); |
| 172 | 179 | ||
| 173 | if (childpid == NULL) { /* first time through */ | 180 | if (childpid == NULL) { /* first time through */ |
| 174 | if ((childpid = calloc((size_t)maxfd, sizeof(pid_t))) == NULL) | 181 | if ((childpid = calloc((size_t)maxfd, sizeof(pid_t))) == NULL) { |
| 175 | return (NULL); | 182 | return (NULL); |
| 183 | } | ||
| 176 | } | 184 | } |
| 177 | 185 | ||
| 178 | if (child_stderr_array == NULL) { /* first time through */ | 186 | if (child_stderr_array == NULL) { /* first time through */ |
| 179 | if ((child_stderr_array = calloc((size_t)maxfd, sizeof(int))) == NULL) | 187 | if ((child_stderr_array = calloc((size_t)maxfd, sizeof(int))) == NULL) { |
| 180 | return (NULL); | 188 | return (NULL); |
| 189 | } | ||
| 181 | } | 190 | } |
| 182 | 191 | ||
| 183 | int pfd[2]; | 192 | int pfd[2]; |
| 184 | if (pipe(pfd) < 0) | 193 | if (pipe(pfd) < 0) { |
| 185 | return (NULL); /* errno set by pipe() */ | 194 | return (NULL); /* errno set by pipe() */ |
| 195 | } | ||
| 186 | 196 | ||
| 187 | int pfderr[2]; | 197 | int pfderr[2]; |
| 188 | if (pipe(pfderr) < 0) | 198 | if (pipe(pfderr) < 0) { |
| 189 | return (NULL); /* errno set by pipe() */ | 199 | return (NULL); /* errno set by pipe() */ |
| 200 | } | ||
| 190 | 201 | ||
| 191 | #ifdef REDHAT_SPOPEN_ERROR | 202 | #ifdef REDHAT_SPOPEN_ERROR |
| 192 | if (signal(SIGCHLD, popen_sigchld_handler) == SIG_ERR) { | 203 | if (signal(SIGCHLD, popen_sigchld_handler) == SIG_ERR) { |
| @@ -195,8 +206,9 @@ FILE *spopen(const char *cmdstring) { | |||
| 195 | #endif | 206 | #endif |
| 196 | 207 | ||
| 197 | pid_t pid; | 208 | pid_t pid; |
| 198 | if ((pid = fork()) < 0) | 209 | if ((pid = fork()) < 0) { |
| 199 | return (NULL); /* errno set by fork() */ | 210 | return (NULL); /* errno set by fork() */ |
| 211 | } | ||
| 200 | 212 | ||
| 201 | if (pid == 0) { /* child */ | 213 | if (pid == 0) { /* child */ |
| 202 | close(pfd[0]); | 214 | close(pfd[0]); |
| @@ -210,17 +222,20 @@ FILE *spopen(const char *cmdstring) { | |||
| 210 | close(pfderr[1]); | 222 | close(pfderr[1]); |
| 211 | } | 223 | } |
| 212 | /* close all descriptors in childpid[] */ | 224 | /* close all descriptors in childpid[] */ |
| 213 | for (i = 0; i < maxfd; i++) | 225 | for (i = 0; i < maxfd; i++) { |
| 214 | if (childpid[i] > 0) | 226 | if (childpid[i] > 0) { |
| 215 | close(i); | 227 | close(i); |
| 228 | } | ||
| 229 | } | ||
| 216 | 230 | ||
| 217 | execve(argv[0], argv, env); | 231 | execve(argv[0], argv, env); |
| 218 | _exit(0); | 232 | _exit(0); |
| 219 | } | 233 | } |
| 220 | 234 | ||
| 221 | close(pfd[1]); /* parent */ | 235 | close(pfd[1]); /* parent */ |
| 222 | if ((child_process = fdopen(pfd[0], "r")) == NULL) | 236 | if ((child_process = fdopen(pfd[0], "r")) == NULL) { |
| 223 | return (NULL); | 237 | return (NULL); |
| 238 | } | ||
| 224 | close(pfderr[1]); | 239 | close(pfderr[1]); |
| 225 | 240 | ||
| 226 | childpid[fileno(child_process)] = pid; /* remember child pid for this fd */ | 241 | childpid[fileno(child_process)] = pid; /* remember child pid for this fd */ |
| @@ -229,17 +244,20 @@ FILE *spopen(const char *cmdstring) { | |||
| 229 | } | 244 | } |
| 230 | 245 | ||
| 231 | int spclose(FILE *fp) { | 246 | int spclose(FILE *fp) { |
| 232 | if (childpid == NULL) | 247 | if (childpid == NULL) { |
| 233 | return (1); /* popen() has never been called */ | 248 | return (1); /* popen() has never been called */ |
| 249 | } | ||
| 234 | 250 | ||
| 235 | pid_t pid; | 251 | pid_t pid; |
| 236 | int fd = fileno(fp); | 252 | int fd = fileno(fp); |
| 237 | if ((pid = childpid[fd]) == 0) | 253 | if ((pid = childpid[fd]) == 0) { |
| 238 | return (1); /* fp wasn't opened by popen() */ | 254 | return (1); /* fp wasn't opened by popen() */ |
| 255 | } | ||
| 239 | 256 | ||
| 240 | childpid[fd] = 0; | 257 | childpid[fd] = 0; |
| 241 | if (fclose(fp) == EOF) | 258 | if (fclose(fp) == EOF) { |
| 242 | return (1); | 259 | return (1); |
| 260 | } | ||
| 243 | 261 | ||
| 244 | #ifdef REDHAT_SPOPEN_ERROR | 262 | #ifdef REDHAT_SPOPEN_ERROR |
| 245 | while (!childtermd) | 263 | while (!childtermd) |
| @@ -247,20 +265,24 @@ int spclose(FILE *fp) { | |||
| 247 | #endif | 265 | #endif |
| 248 | 266 | ||
| 249 | int status; | 267 | int status; |
| 250 | while (waitpid(pid, &status, 0) < 0) | 268 | while (waitpid(pid, &status, 0) < 0) { |
| 251 | if (errno != EINTR) | 269 | if (errno != EINTR) { |
| 252 | return (1); /* error other than EINTR from waitpid() */ | 270 | return (1); /* error other than EINTR from waitpid() */ |
| 271 | } | ||
| 272 | } | ||
| 253 | 273 | ||
| 254 | if (WIFEXITED(status)) | 274 | if (WIFEXITED(status)) { |
| 255 | return (WEXITSTATUS(status)); /* return child's termination status */ | 275 | return (WEXITSTATUS(status)); /* return child's termination status */ |
| 276 | } | ||
| 256 | 277 | ||
| 257 | return (1); | 278 | return (1); |
| 258 | } | 279 | } |
| 259 | 280 | ||
| 260 | #ifdef REDHAT_SPOPEN_ERROR | 281 | #ifdef REDHAT_SPOPEN_ERROR |
| 261 | void popen_sigchld_handler(int signo) { | 282 | void popen_sigchld_handler(int signo) { |
| 262 | if (signo == SIGCHLD) | 283 | if (signo == SIGCHLD) { |
| 263 | childtermd = 1; | 284 | childtermd = 1; |
| 285 | } | ||
| 264 | } | 286 | } |
| 265 | #endif | 287 | #endif |
| 266 | 288 | ||
diff --git a/plugins/popen.h b/plugins/popen.h index 1ea69632..e318ce25 100644 --- a/plugins/popen.h +++ b/plugins/popen.h | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /****************************************************************************** | 1 | /****************************************************************************** |
| 2 | * | 2 | * |
| 3 | * | 3 | * |
| 4 | *****************************************************************************/ | 4 | *****************************************************************************/ |
| 5 | 5 | ||
| 6 | FILE *spopen (const char *); | 6 | FILE *spopen(const char *); |
| 7 | int spclose (FILE *); | 7 | int spclose(FILE *); |
| 8 | void popen_timeout_alarm_handler (int); | 8 | void popen_timeout_alarm_handler(int); |
| 9 | 9 | ||
| 10 | pid_t *childpid=NULL; | 10 | pid_t *childpid = NULL; |
| 11 | int *child_stderr_array=NULL; | 11 | int *child_stderr_array = NULL; |
| 12 | FILE *child_process=NULL; | 12 | FILE *child_process = NULL; |
| 13 | FILE *child_stderr=NULL; | 13 | FILE *child_stderr = NULL; |
diff --git a/plugins/runcmd.c b/plugins/runcmd.c index 4429ceb0..be6691d2 100644 --- a/plugins/runcmd.c +++ b/plugins/runcmd.c | |||
| @@ -53,7 +53,7 @@ | |||
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | #ifndef WIFEXITED | 55 | #ifndef WIFEXITED |
| 56 | # define WIFEXITED(stat_val) (((stat_val)&255) == 0) | 56 | # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) |
| 57 | #endif | 57 | #endif |
| 58 | 58 | ||
| 59 | /* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */ | 59 | /* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */ |
| @@ -87,8 +87,9 @@ extern void die(int, const char *, ...) __attribute__((__noreturn__, __format__( | |||
| 87 | * through this api and thus achieve async-safeness throughout the api */ | 87 | * through this api and thus achieve async-safeness throughout the api */ |
| 88 | void np_runcmd_init(void) { | 88 | void np_runcmd_init(void) { |
| 89 | long maxfd = mp_open_max(); | 89 | long maxfd = mp_open_max(); |
| 90 | if (!np_pids) | 90 | if (!np_pids) { |
| 91 | np_pids = calloc(maxfd, sizeof(pid_t)); | 91 | np_pids = calloc(maxfd, sizeof(pid_t)); |
| 92 | } | ||
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | /* Start running a command */ | 95 | /* Start running a command */ |
| @@ -106,8 +107,9 @@ static int np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) { | |||
| 106 | 107 | ||
| 107 | int i = 0; | 108 | int i = 0; |
| 108 | 109 | ||
| 109 | if (!np_pids) | 110 | if (!np_pids) { |
| 110 | NP_RUNCMD_INIT; | 111 | NP_RUNCMD_INIT; |
| 112 | } | ||
| 111 | 113 | ||
| 112 | env[0] = strdup("LC_ALL=C"); | 114 | env[0] = strdup("LC_ALL=C"); |
| 113 | env[1] = NULL; | 115 | env[1] = NULL; |
| @@ -115,18 +117,21 @@ static int np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) { | |||
| 115 | /* make copy of command string so strtok() doesn't silently modify it */ | 117 | /* make copy of command string so strtok() doesn't silently modify it */ |
| 116 | /* (the calling program may want to access it later) */ | 118 | /* (the calling program may want to access it later) */ |
| 117 | cmdlen = strlen(cmdstring); | 119 | cmdlen = strlen(cmdstring); |
| 118 | if ((cmd = malloc(cmdlen + 1)) == NULL) | 120 | if ((cmd = malloc(cmdlen + 1)) == NULL) { |
| 119 | return -1; | 121 | return -1; |
| 122 | } | ||
| 120 | memcpy(cmd, cmdstring, cmdlen); | 123 | memcpy(cmd, cmdstring, cmdlen); |
| 121 | cmd[cmdlen] = '\0'; | 124 | cmd[cmdlen] = '\0'; |
| 122 | 125 | ||
| 123 | /* This is not a shell, so we don't handle "???" */ | 126 | /* This is not a shell, so we don't handle "???" */ |
| 124 | if (strstr(cmdstring, "\"")) | 127 | if (strstr(cmdstring, "\"")) { |
| 125 | return -1; | 128 | return -1; |
| 129 | } | ||
| 126 | 130 | ||
| 127 | /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ | 131 | /* allow single quotes, but only if non-whitesapce doesn't occur on both sides */ |
| 128 | if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) | 132 | if (strstr(cmdstring, " ' ") || strstr(cmdstring, "'''")) { |
| 129 | return -1; | 133 | return -1; |
| 134 | } | ||
| 130 | 135 | ||
| 131 | /* each arg must be whitespace-separated, so args can be a maximum | 136 | /* each arg must be whitespace-separated, so args can be a maximum |
| 132 | * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ | 137 | * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ |
| @@ -145,8 +150,9 @@ static int np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) { | |||
| 145 | 150 | ||
| 146 | if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ | 151 | if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ |
| 147 | str++; | 152 | str++; |
| 148 | if (!strstr(str, "'")) | 153 | if (!strstr(str, "'")) { |
| 149 | return -1; /* balanced? */ | 154 | return -1; /* balanced? */ |
| 155 | } | ||
| 150 | cmd = 1 + strstr(str, "'"); | 156 | cmd = 1 + strstr(str, "'"); |
| 151 | str[strcspn(str, "'")] = 0; | 157 | str[strcspn(str, "'")] = 0; |
| 152 | } else { | 158 | } else { |
| @@ -158,14 +164,16 @@ static int np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) { | |||
| 158 | } | 164 | } |
| 159 | } | 165 | } |
| 160 | 166 | ||
| 161 | if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) | 167 | if (cmd && strlen(cmd) == strspn(cmd, " \t\r\n")) { |
| 162 | cmd = NULL; | 168 | cmd = NULL; |
| 169 | } | ||
| 163 | 170 | ||
| 164 | argv[i++] = str; | 171 | argv[i++] = str; |
| 165 | } | 172 | } |
| 166 | 173 | ||
| 167 | if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) | 174 | if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) { |
| 168 | return -1; /* errno set by the failing function */ | 175 | return -1; /* errno set by the failing function */ |
| 176 | } | ||
| 169 | 177 | ||
| 170 | /* child runs exceve() and _exit. */ | 178 | /* child runs exceve() and _exit. */ |
| 171 | if (pid == 0) { | 179 | if (pid == 0) { |
| @@ -190,9 +198,11 @@ static int np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr) { | |||
| 190 | * This is executed in a separate address space (pure child), | 198 | * This is executed in a separate address space (pure child), |
| 191 | * so we don't have to worry about async safety */ | 199 | * so we don't have to worry about async safety */ |
| 192 | long maxfd = mp_open_max(); | 200 | long maxfd = mp_open_max(); |
| 193 | for (i = 0; i < maxfd; i++) | 201 | for (i = 0; i < maxfd; i++) { |
| 194 | if (np_pids[i] > 0) | 202 | if (np_pids[i] > 0) { |
| 195 | close(i); | 203 | close(i); |
| 204 | } | ||
| 205 | } | ||
| 196 | 206 | ||
| 197 | execve(argv[0], argv, env); | 207 | execve(argv[0], argv, env); |
| 198 | _exit(STATE_UNKNOWN); | 208 | _exit(STATE_UNKNOWN); |
| @@ -215,17 +225,21 @@ static int np_runcmd_close(int fd) { | |||
| 215 | 225 | ||
| 216 | /* make sure this fd was opened by popen() */ | 226 | /* make sure this fd was opened by popen() */ |
| 217 | long maxfd = mp_open_max(); | 227 | long maxfd = mp_open_max(); |
| 218 | if (fd < 0 || fd > maxfd || !np_pids || (pid = np_pids[fd]) == 0) | 228 | if (fd < 0 || fd > maxfd || !np_pids || (pid = np_pids[fd]) == 0) { |
| 219 | return -1; | 229 | return -1; |
| 230 | } | ||
| 220 | 231 | ||
| 221 | np_pids[fd] = 0; | 232 | np_pids[fd] = 0; |
| 222 | if (close(fd) == -1) | 233 | if (close(fd) == -1) { |
| 223 | return -1; | 234 | return -1; |
| 235 | } | ||
| 224 | 236 | ||
| 225 | /* EINTR is ok (sort of), everything else is bad */ | 237 | /* EINTR is ok (sort of), everything else is bad */ |
| 226 | while (waitpid(pid, &status, 0) < 0) | 238 | while (waitpid(pid, &status, 0) < 0) { |
| 227 | if (errno != EINTR) | 239 | if (errno != EINTR) { |
| 228 | return -1; | 240 | return -1; |
| 241 | } | ||
| 242 | } | ||
| 229 | 243 | ||
| 230 | /* return child's termination status */ | 244 | /* return child's termination status */ |
| 231 | return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1; | 245 | return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1; |
| @@ -233,15 +247,18 @@ static int np_runcmd_close(int fd) { | |||
| 233 | 247 | ||
| 234 | void runcmd_timeout_alarm_handler(int signo) { | 248 | void runcmd_timeout_alarm_handler(int signo) { |
| 235 | 249 | ||
| 236 | if (signo == SIGALRM) | 250 | if (signo == SIGALRM) { |
| 237 | puts(_("CRITICAL - Plugin timed out while executing system call")); | 251 | puts(_("CRITICAL - Plugin timed out while executing system call")); |
| 252 | } | ||
| 238 | 253 | ||
| 239 | long maxfd = mp_open_max(); | 254 | long maxfd = mp_open_max(); |
| 240 | if (np_pids) | 255 | if (np_pids) { |
| 241 | for (long int i = 0; i < maxfd; i++) { | 256 | for (long int i = 0; i < maxfd; i++) { |
| 242 | if (np_pids[i] != 0) | 257 | if (np_pids[i] != 0) { |
| 243 | kill(np_pids[i], SIGKILL); | 258 | kill(np_pids[i], SIGKILL); |
| 259 | } | ||
| 244 | } | 260 | } |
| 261 | } | ||
| 245 | 262 | ||
| 246 | exit(STATE_CRITICAL); | 263 | exit(STATE_CRITICAL); |
| 247 | } | 264 | } |
| @@ -270,18 +287,19 @@ static int np_fetch_output(int fd, output *op, int flags) { | |||
| 270 | 287 | ||
| 271 | /* some plugins may want to keep output unbroken, and some commands | 288 | /* some plugins may want to keep output unbroken, and some commands |
| 272 | * will yield no output, so return here for those */ | 289 | * will yield no output, so return here for those */ |
| 273 | if (flags & RUNCMD_NO_ARRAYS || !op->buf || !op->buflen) | 290 | if (flags & RUNCMD_NO_ARRAYS || !op->buf || !op->buflen) { |
| 274 | return op->buflen; | 291 | return op->buflen; |
| 292 | } | ||
| 275 | 293 | ||
| 276 | /* and some may want both */ | 294 | /* and some may want both */ |
| 277 | if (flags & RUNCMD_NO_ASSOC) { | 295 | if (flags & RUNCMD_NO_ASSOC) { |
| 278 | buf = malloc(op->buflen); | 296 | buf = malloc(op->buflen); |
| 279 | memcpy(buf, op->buf, op->buflen); | 297 | memcpy(buf, op->buf, op->buflen); |
| 280 | } else | 298 | } else { |
| 281 | buf = op->buf; | 299 | buf = op->buf; |
| 300 | } | ||
| 282 | 301 | ||
| 283 | op->line = NULL; | 302 | op->line = NULL; |
| 284 | op->lens = NULL; | ||
| 285 | i = 0; | 303 | i = 0; |
| 286 | while (i < op->buflen) { | 304 | while (i < op->buflen) { |
| 287 | /* make sure we have enough memory */ | 305 | /* make sure we have enough memory */ |
| @@ -292,20 +310,17 @@ static int np_fetch_output(int fd, output *op, int flags) { | |||
| 292 | } while (!ary_size); | 310 | } while (!ary_size); |
| 293 | 311 | ||
| 294 | op->line = realloc(op->line, ary_size * sizeof(char *)); | 312 | op->line = realloc(op->line, ary_size * sizeof(char *)); |
| 295 | op->lens = realloc(op->lens, ary_size * sizeof(size_t)); | ||
| 296 | } | 313 | } |
| 297 | 314 | ||
| 298 | /* set the pointer to the string */ | 315 | /* set the pointer to the string */ |
| 299 | op->line[lineno] = &buf[i]; | 316 | op->line[lineno] = &buf[i]; |
| 300 | 317 | ||
| 301 | /* hop to next newline or end of buffer */ | 318 | /* hop to next newline or end of buffer */ |
| 302 | while (buf[i] != '\n' && i < op->buflen) | 319 | while (buf[i] != '\n' && i < op->buflen) { |
| 303 | i++; | 320 | i++; |
| 321 | } | ||
| 304 | buf[i] = '\0'; | 322 | buf[i] = '\0'; |
| 305 | 323 | ||
| 306 | /* calculate the string length using pointer difference */ | ||
| 307 | op->lens[lineno] = (size_t)&buf[i] - (size_t)op->line[lineno]; | ||
| 308 | |||
| 309 | lineno++; | 324 | lineno++; |
| 310 | i++; | 325 | i++; |
| 311 | } | 326 | } |
| @@ -317,18 +332,23 @@ int np_runcmd(const char *cmd, output *out, output *err, int flags) { | |||
| 317 | int fd, pfd_out[2], pfd_err[2]; | 332 | int fd, pfd_out[2], pfd_err[2]; |
| 318 | 333 | ||
| 319 | /* initialize the structs */ | 334 | /* initialize the structs */ |
| 320 | if (out) | 335 | if (out) { |
| 321 | memset(out, 0, sizeof(output)); | 336 | memset(out, 0, sizeof(output)); |
| 322 | if (err) | 337 | } |
| 338 | if (err) { | ||
| 323 | memset(err, 0, sizeof(output)); | 339 | memset(err, 0, sizeof(output)); |
| 340 | } | ||
| 324 | 341 | ||
| 325 | if ((fd = np_runcmd_open(cmd, pfd_out, pfd_err)) == -1) | 342 | if ((fd = np_runcmd_open(cmd, pfd_out, pfd_err)) == -1) { |
| 326 | die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd); | 343 | die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd); |
| 344 | } | ||
| 327 | 345 | ||
| 328 | if (out) | 346 | if (out) { |
| 329 | out->lines = np_fetch_output(pfd_out[0], out, flags); | 347 | out->lines = np_fetch_output(pfd_out[0], out, flags); |
| 330 | if (err) | 348 | } |
| 349 | if (err) { | ||
| 331 | err->lines = np_fetch_output(pfd_err[0], err, flags); | 350 | err->lines = np_fetch_output(pfd_err[0], err, flags); |
| 351 | } | ||
| 332 | 352 | ||
| 333 | return np_runcmd_close(fd); | 353 | return np_runcmd_close(fd); |
| 334 | } | 354 | } |
diff --git a/plugins/runcmd.h b/plugins/runcmd.h index 2dcdadf0..63ce7b12 100644 --- a/plugins/runcmd.h +++ b/plugins/runcmd.h | |||
| @@ -1,25 +1,25 @@ | |||
| 1 | /**************************************************************************** | 1 | /**************************************************************************** |
| 2 | * | 2 | * |
| 3 | * License: GPL | 3 | * License: GPL |
| 4 | * Copyright (c) 2005 Monitoring Plugins Development Team | 4 | * Copyright (c) 2005 Monitoring Plugins Development Team |
| 5 | * Author: Andreas Ericsson <ae@op5.se> | 5 | * Author: Andreas Ericsson <ae@op5.se> |
| 6 | * | 6 | * |
| 7 | * | 7 | * |
| 8 | * This program is free software: you can redistribute it and/or modify | 8 | * This program is free software: you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation, either version 3 of the License, or | 10 | * the Free Software Foundation, either version 3 of the License, or |
| 11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
| 12 | * | 12 | * |
| 13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
| 17 | * | 17 | * |
| 18 | * You should have received a copy of the GNU General Public License | 18 | * You should have received a copy of the GNU General Public License |
| 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 20 | * | 20 | * |
| 21 | * | 21 | * |
| 22 | *****************************************************************************/ | 22 | *****************************************************************************/ |
| 23 | 23 | ||
| 24 | #ifndef NAGIOSPLUG_RUNCMD_H | 24 | #ifndef NAGIOSPLUG_RUNCMD_H |
| 25 | #define NAGIOSPLUG_RUNCMD_H | 25 | #define NAGIOSPLUG_RUNCMD_H |
| @@ -29,8 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | /** prototypes **/ | 30 | /** prototypes **/ |
| 31 | int np_runcmd(const char *, output *, output *, int); | 31 | int np_runcmd(const char *, output *, output *, int); |
| 32 | void runcmd_timeout_alarm_handler(int) | 32 | void runcmd_timeout_alarm_handler(int) __attribute__((__noreturn__)); |
| 33 | __attribute__((__noreturn__)); | ||
| 34 | 33 | ||
| 35 | /* only multi-threaded plugins need to bother with this */ | 34 | /* only multi-threaded plugins need to bother with this */ |
| 36 | void np_runcmd_init(void); | 35 | void np_runcmd_init(void); |
| @@ -38,6 +37,6 @@ void np_runcmd_init(void); | |||
| 38 | 37 | ||
| 39 | /* possible flags for np_runcmd()'s fourth argument */ | 38 | /* possible flags for np_runcmd()'s fourth argument */ |
| 40 | #define RUNCMD_NO_ARRAYS 0x01 /* don't populate arrays at all */ | 39 | #define RUNCMD_NO_ARRAYS 0x01 /* don't populate arrays at all */ |
| 41 | #define RUNCMD_NO_ASSOC 0x02 /* output.line won't point to buf */ | 40 | #define RUNCMD_NO_ASSOC 0x02 /* output.line won't point to buf */ |
| 42 | 41 | ||
| 43 | #endif /* NAGIOSPLUG_RUNCMD_H */ | 42 | #endif /* NAGIOSPLUG_RUNCMD_H */ |
diff --git a/plugins/sslutils.c b/plugins/sslutils.c index 719de575..c58a35ab 100644 --- a/plugins/sslutils.c +++ b/plugins/sslutils.c | |||
| @@ -26,10 +26,12 @@ | |||
| 26 | * | 26 | * |
| 27 | *****************************************************************************/ | 27 | *****************************************************************************/ |
| 28 | 28 | ||
| 29 | #include "output.h" | ||
| 29 | #define MAX_CN_LENGTH 256 | 30 | #define MAX_CN_LENGTH 256 |
| 30 | #include "common.h" | 31 | #include "common.h" |
| 31 | #include "netutils.h" | 32 | #include "netutils.h" |
| 32 | #include "../lib/monitoringplug.h" | 33 | #include "../lib/monitoringplug.h" |
| 34 | #include "states.h" | ||
| 33 | 35 | ||
| 34 | #ifdef HAVE_SSL | 36 | #ifdef HAVE_SSL |
| 35 | static SSL_CTX *ctx = NULL; | 37 | static SSL_CTX *ctx = NULL; |
| @@ -37,13 +39,16 @@ static SSL *s = NULL; | |||
| 37 | 39 | ||
| 38 | int np_net_ssl_init(int sd) { return np_net_ssl_init_with_hostname(sd, NULL); } | 40 | int np_net_ssl_init(int sd) { return np_net_ssl_init_with_hostname(sd, NULL); } |
| 39 | 41 | ||
| 40 | int np_net_ssl_init_with_hostname(int sd, char *host_name) { return np_net_ssl_init_with_hostname_and_version(sd, host_name, 0); } | 42 | int np_net_ssl_init_with_hostname(int sd, char *host_name) { |
| 43 | return np_net_ssl_init_with_hostname_and_version(sd, host_name, 0); | ||
| 44 | } | ||
| 41 | 45 | ||
| 42 | int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) { | 46 | int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version) { |
| 43 | return np_net_ssl_init_with_hostname_version_and_cert(sd, host_name, version, NULL, NULL); | 47 | return np_net_ssl_init_with_hostname_version_and_cert(sd, host_name, version, NULL, NULL); |
| 44 | } | 48 | } |
| 45 | 49 | ||
| 46 | int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey) { | 50 | int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, |
| 51 | char *privkey) { | ||
| 47 | long options = 0; | 52 | long options = 0; |
| 48 | 53 | ||
| 49 | if ((ctx = SSL_CTX_new(TLS_client_method())) == NULL) { | 54 | if ((ctx = SSL_CTX_new(TLS_client_method())) == NULL) { |
| @@ -75,7 +80,8 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int | |||
| 75 | # endif | 80 | # endif |
| 76 | case MP_TLSv1_1: /* TLSv1.1 protocol */ | 81 | case MP_TLSv1_1: /* TLSv1.1 protocol */ |
| 77 | # if !defined(SSL_OP_NO_TLSv1_1) | 82 | # if !defined(SSL_OP_NO_TLSv1_1) |
| 78 | printf("%s\n", _("UNKNOWN - TLS protocol version 1.1 is not supported by your SSL library.")); | 83 | printf("%s\n", |
| 84 | _("UNKNOWN - TLS protocol version 1.1 is not supported by your SSL library.")); | ||
| 79 | return STATE_UNKNOWN; | 85 | return STATE_UNKNOWN; |
| 80 | # else | 86 | # else |
| 81 | SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION); | 87 | SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION); |
| @@ -84,7 +90,8 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int | |||
| 84 | # endif | 90 | # endif |
| 85 | case MP_TLSv1_2: /* TLSv1.2 protocol */ | 91 | case MP_TLSv1_2: /* TLSv1.2 protocol */ |
| 86 | # if !defined(SSL_OP_NO_TLSv1_2) | 92 | # if !defined(SSL_OP_NO_TLSv1_2) |
| 87 | printf("%s\n", _("UNKNOWN - TLS protocol version 1.2 is not supported by your SSL library.")); | 93 | printf("%s\n", |
| 94 | _("UNKNOWN - TLS protocol version 1.2 is not supported by your SSL library.")); | ||
| 88 | return STATE_UNKNOWN; | 95 | return STATE_UNKNOWN; |
| 89 | # else | 96 | # else |
| 90 | SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); | 97 | SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); |
| @@ -145,8 +152,9 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int | |||
| 145 | SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); | 152 | SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); |
| 146 | if ((s = SSL_new(ctx)) != NULL) { | 153 | if ((s = SSL_new(ctx)) != NULL) { |
| 147 | # ifdef SSL_set_tlsext_host_name | 154 | # ifdef SSL_set_tlsext_host_name |
| 148 | if (host_name != NULL) | 155 | if (host_name != NULL) { |
| 149 | SSL_set_tlsext_host_name(s, host_name); | 156 | SSL_set_tlsext_host_name(s, host_name); |
| 157 | } | ||
| 150 | # endif | 158 | # endif |
| 151 | SSL_set_fd(s, sd); | 159 | SSL_set_fd(s, sd); |
| 152 | if (SSL_connect(s) == 1) { | 160 | if (SSL_connect(s) == 1) { |
| @@ -182,63 +190,54 @@ int np_net_ssl_write(const void *buf, int num) { return SSL_write(s, buf, num); | |||
| 182 | 190 | ||
| 183 | int np_net_ssl_read(void *buf, int num) { return SSL_read(s, buf, num); } | 191 | int np_net_ssl_read(void *buf, int num) { return SSL_read(s, buf, num); } |
| 184 | 192 | ||
| 185 | int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit) { | 193 | mp_state_enum np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, |
| 194 | int days_till_exp_crit) { | ||
| 186 | # ifdef USE_OPENSSL | 195 | # ifdef USE_OPENSSL |
| 187 | X509_NAME *subj = NULL; | ||
| 188 | char timestamp[50] = ""; | ||
| 189 | char cn[MAX_CN_LENGTH] = ""; | ||
| 190 | char *tz; | ||
| 191 | |||
| 192 | int cnlen = -1; | ||
| 193 | int status = STATE_UNKNOWN; | ||
| 194 | |||
| 195 | ASN1_STRING *tm; | ||
| 196 | int offset; | ||
| 197 | struct tm stamp; | ||
| 198 | float time_left; | ||
| 199 | int days_left; | ||
| 200 | int time_remaining; | ||
| 201 | time_t tm_t; | ||
| 202 | |||
| 203 | if (!certificate) { | 196 | if (!certificate) { |
| 204 | printf("%s\n", _("CRITICAL - Cannot retrieve server certificate.")); | 197 | printf("%s\n", _("CRITICAL - No server certificate present to inspect.")); |
| 205 | return STATE_CRITICAL; | 198 | return STATE_CRITICAL; |
| 206 | } | 199 | } |
| 207 | 200 | ||
| 208 | /* Extract CN from certificate subject */ | 201 | /* Extract CN from certificate subject */ |
| 209 | subj = X509_get_subject_name(certificate); | 202 | X509_NAME *subj = X509_get_subject_name(certificate); |
| 210 | 203 | ||
| 211 | if (!subj) { | 204 | if (!subj) { |
| 212 | printf("%s\n", _("CRITICAL - Cannot retrieve certificate subject.")); | 205 | printf("%s\n", _("CRITICAL - Cannot retrieve certificate subject.")); |
| 213 | return STATE_CRITICAL; | 206 | return STATE_CRITICAL; |
| 214 | } | 207 | } |
| 215 | cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, cn, sizeof(cn)); | 208 | |
| 216 | if (cnlen == -1) | 209 | char cn[MAX_CN_LENGTH] = ""; |
| 210 | int cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, cn, sizeof(cn)); | ||
| 211 | if (cnlen == -1) { | ||
| 217 | strcpy(cn, _("Unknown CN")); | 212 | strcpy(cn, _("Unknown CN")); |
| 213 | } | ||
| 218 | 214 | ||
| 219 | /* Retrieve timestamp of certificate */ | 215 | /* Retrieve timestamp of certificate */ |
| 220 | tm = X509_get_notAfter(certificate); | 216 | ASN1_STRING *tm = X509_get_notAfter(certificate); |
| 221 | 217 | ||
| 218 | int offset = 0; | ||
| 219 | struct tm stamp = {}; | ||
| 222 | /* Generate tm structure to process timestamp */ | 220 | /* Generate tm structure to process timestamp */ |
| 223 | if (tm->type == V_ASN1_UTCTIME) { | 221 | if (tm->type == V_ASN1_UTCTIME) { |
| 224 | if (tm->length < 10) { | 222 | if (tm->length < 10) { |
| 225 | printf("%s\n", _("CRITICAL - Wrong time format in certificate.")); | 223 | printf("%s\n", _("CRITICAL - Wrong time format in certificate.")); |
| 226 | return STATE_CRITICAL; | 224 | return STATE_CRITICAL; |
| 227 | } else { | ||
| 228 | stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); | ||
| 229 | if (stamp.tm_year < 50) | ||
| 230 | stamp.tm_year += 100; | ||
| 231 | offset = 0; | ||
| 232 | } | 225 | } |
| 226 | stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0'); | ||
| 227 | if (stamp.tm_year < 50) { | ||
| 228 | stamp.tm_year += 100; | ||
| 229 | } | ||
| 230 | offset = 0; | ||
| 231 | |||
| 233 | } else { | 232 | } else { |
| 234 | if (tm->length < 12) { | 233 | if (tm->length < 12) { |
| 235 | printf("%s\n", _("CRITICAL - Wrong time format in certificate.")); | 234 | printf("%s\n", _("CRITICAL - Wrong time format in certificate.")); |
| 236 | return STATE_CRITICAL; | 235 | return STATE_CRITICAL; |
| 237 | } else { | ||
| 238 | stamp.tm_year = (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); | ||
| 239 | stamp.tm_year -= 1900; | ||
| 240 | offset = 2; | ||
| 241 | } | 236 | } |
| 237 | stamp.tm_year = (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 + | ||
| 238 | (tm->data[2] - '0') * 10 + (tm->data[3] - '0'); | ||
| 239 | stamp.tm_year -= 1900; | ||
| 240 | offset = 2; | ||
| 242 | } | 241 | } |
| 243 | stamp.tm_mon = (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1; | 242 | stamp.tm_mon = (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1; |
| 244 | stamp.tm_mday = (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0'); | 243 | stamp.tm_mday = (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0'); |
| @@ -247,48 +246,60 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int | |||
| 247 | stamp.tm_sec = (tm->data[10 + offset] - '0') * 10 + (tm->data[11 + offset] - '0'); | 246 | stamp.tm_sec = (tm->data[10 + offset] - '0') * 10 + (tm->data[11 + offset] - '0'); |
| 248 | stamp.tm_isdst = -1; | 247 | stamp.tm_isdst = -1; |
| 249 | 248 | ||
| 250 | tm_t = timegm(&stamp); | 249 | time_t tm_t = timegm(&stamp); |
| 251 | time_left = difftime(tm_t, time(NULL)); | 250 | float time_left = difftime(tm_t, time(NULL)); |
| 252 | days_left = time_left / 86400; | 251 | int days_left = time_left / 86400; |
| 253 | tz = getenv("TZ"); | 252 | char *tz = getenv("TZ"); |
| 254 | setenv("TZ", "GMT", 1); | 253 | setenv("TZ", "GMT", 1); |
| 255 | tzset(); | 254 | tzset(); |
| 255 | |||
| 256 | char timestamp[50] = ""; | ||
| 256 | strftime(timestamp, 50, "%c %z", localtime(&tm_t)); | 257 | strftime(timestamp, 50, "%c %z", localtime(&tm_t)); |
| 257 | if (tz) | 258 | if (tz) { |
| 258 | setenv("TZ", tz, 1); | 259 | setenv("TZ", tz, 1); |
| 259 | else | 260 | } else { |
| 260 | unsetenv("TZ"); | 261 | unsetenv("TZ"); |
| 262 | } | ||
| 263 | |||
| 261 | tzset(); | 264 | tzset(); |
| 262 | 265 | ||
| 266 | int time_remaining; | ||
| 267 | mp_state_enum status = STATE_UNKNOWN; | ||
| 263 | if (days_left > 0 && days_left <= days_till_exp_warn) { | 268 | if (days_left > 0 && days_left <= days_till_exp_warn) { |
| 264 | printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, | 269 | printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), |
| 265 | days_left, timestamp); | 270 | (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, days_left, timestamp); |
| 266 | if (days_left > days_till_exp_crit) | 271 | if (days_left > days_till_exp_crit) { |
| 267 | status = STATE_WARNING; | 272 | status = STATE_WARNING; |
| 268 | else | 273 | } else { |
| 269 | status = STATE_CRITICAL; | 274 | status = STATE_CRITICAL; |
| 275 | } | ||
| 270 | } else if (days_left == 0 && time_left > 0) { | 276 | } else if (days_left == 0 && time_left > 0) { |
| 271 | if (time_left >= 3600) | 277 | if (time_left >= 3600) { |
| 272 | time_remaining = (int)time_left / 3600; | 278 | time_remaining = (int)time_left / 3600; |
| 273 | else | 279 | } else { |
| 274 | time_remaining = (int)time_left / 60; | 280 | time_remaining = (int)time_left / 60; |
| 281 | } | ||
| 275 | 282 | ||
| 276 | printf(_("%s - Certificate '%s' expires in %u %s (%s)\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, | 283 | printf(_("%s - Certificate '%s' expires in %u %s (%s)\n"), |
| 277 | time_remaining, time_left >= 3600 ? "hours" : "minutes", timestamp); | 284 | (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, time_remaining, |
| 285 | time_left >= 3600 ? "hours" : "minutes", timestamp); | ||
| 278 | 286 | ||
| 279 | if (days_left > days_till_exp_crit) | 287 | if (days_left > days_till_exp_crit) { |
| 280 | status = STATE_WARNING; | 288 | status = STATE_WARNING; |
| 281 | else | 289 | } else { |
| 282 | status = STATE_CRITICAL; | 290 | status = STATE_CRITICAL; |
| 291 | } | ||
| 283 | } else if (time_left < 0) { | 292 | } else if (time_left < 0) { |
| 284 | printf(_("CRITICAL - Certificate '%s' expired on %s.\n"), cn, timestamp); | 293 | printf(_("CRITICAL - Certificate '%s' expired on %s.\n"), cn, timestamp); |
| 285 | status = STATE_CRITICAL; | 294 | status = STATE_CRITICAL; |
| 286 | } else if (days_left == 0) { | 295 | } else if (days_left == 0) { |
| 287 | printf(_("%s - Certificate '%s' just expired (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, timestamp); | 296 | printf(_("%s - Certificate '%s' just expired (%s).\n"), |
| 288 | if (days_left > days_till_exp_crit) | 297 | (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", cn, timestamp); |
| 298 | if (days_left > days_till_exp_crit) { | ||
| 289 | status = STATE_WARNING; | 299 | status = STATE_WARNING; |
| 290 | else | 300 | } else { |
| 291 | status = STATE_CRITICAL; | 301 | status = STATE_CRITICAL; |
| 302 | } | ||
| 292 | } else { | 303 | } else { |
| 293 | printf(_("OK - Certificate '%s' will expire on %s.\n"), cn, timestamp); | 304 | printf(_("OK - Certificate '%s' will expire on %s.\n"), cn, timestamp); |
| 294 | status = STATE_OK; | 305 | status = STATE_OK; |
| @@ -301,7 +312,139 @@ int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int | |||
| 301 | # endif /* USE_OPENSSL */ | 312 | # endif /* USE_OPENSSL */ |
| 302 | } | 313 | } |
| 303 | 314 | ||
| 304 | int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit) { | 315 | retrieve_expiration_time_result np_net_ssl_get_cert_expiration(X509 *certificate) { |
| 316 | # ifdef USE_OPENSSL | ||
| 317 | retrieve_expiration_time_result result = { | ||
| 318 | .errors = ALL_OK, | ||
| 319 | .remaining_seconds = 0, | ||
| 320 | }; | ||
| 321 | |||
| 322 | if (!certificate) { | ||
| 323 | // printf("%s\n", _("CRITICAL - No server certificate present to inspect.")); | ||
| 324 | result.errors = NO_SERVER_CERTIFICATE_PRESENT; | ||
| 325 | return result; | ||
| 326 | } | ||
| 327 | |||
| 328 | /* Extract CN from certificate subject */ | ||
| 329 | X509_NAME *subj = X509_get_subject_name(certificate); | ||
| 330 | |||
| 331 | if (!subj) { | ||
| 332 | // printf("%s\n", _("CRITICAL - Cannot retrieve certificate subject.")); | ||
| 333 | result.errors = UNABLE_TO_RETRIEVE_CERTIFICATE_SUBJECT; | ||
| 334 | return result; | ||
| 335 | } | ||
| 336 | |||
| 337 | char cn[MAX_CN_LENGTH] = ""; | ||
| 338 | int cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, cn, sizeof(cn)); | ||
| 339 | if (cnlen == -1) { | ||
| 340 | strcpy(cn, _("Unknown CN")); | ||
| 341 | } | ||
| 342 | |||
| 343 | /* Retrieve timestamp of certificate */ | ||
| 344 | ASN1_STRING *expiration_timestamp = X509_get_notAfter(certificate); | ||
| 345 | |||
| 346 | int offset = 0; | ||
| 347 | struct tm stamp = {}; | ||
| 348 | /* Generate tm structure to process timestamp */ | ||
| 349 | if (expiration_timestamp->type == V_ASN1_UTCTIME) { | ||
| 350 | if (expiration_timestamp->length < 10) { | ||
| 351 | result.errors = WRONG_TIME_FORMAT_IN_CERTIFICATE; | ||
| 352 | return result; | ||
| 353 | } | ||
| 354 | |||
| 355 | stamp.tm_year = | ||
| 356 | (expiration_timestamp->data[0] - '0') * 10 + (expiration_timestamp->data[1] - '0'); | ||
| 357 | if (stamp.tm_year < 50) { | ||
| 358 | stamp.tm_year += 100; | ||
| 359 | } | ||
| 360 | offset = 0; | ||
| 361 | } else { | ||
| 362 | if (expiration_timestamp->length < 12) { | ||
| 363 | result.errors = WRONG_TIME_FORMAT_IN_CERTIFICATE; | ||
| 364 | return result; | ||
| 365 | } | ||
| 366 | |||
| 367 | stamp.tm_year = (expiration_timestamp->data[0] - '0') * 1000 + | ||
| 368 | (expiration_timestamp->data[1] - '0') * 100 + | ||
| 369 | (expiration_timestamp->data[2] - '0') * 10 + | ||
| 370 | (expiration_timestamp->data[3] - '0'); | ||
| 371 | stamp.tm_year -= 1900; | ||
| 372 | offset = 2; | ||
| 373 | } | ||
| 374 | stamp.tm_mon = (expiration_timestamp->data[2 + offset] - '0') * 10 + | ||
| 375 | (expiration_timestamp->data[3 + offset] - '0') - 1; | ||
| 376 | stamp.tm_mday = (expiration_timestamp->data[4 + offset] - '0') * 10 + | ||
| 377 | (expiration_timestamp->data[5 + offset] - '0'); | ||
| 378 | stamp.tm_hour = (expiration_timestamp->data[6 + offset] - '0') * 10 + | ||
| 379 | (expiration_timestamp->data[7 + offset] - '0'); | ||
| 380 | stamp.tm_min = (expiration_timestamp->data[8 + offset] - '0') * 10 + | ||
| 381 | (expiration_timestamp->data[9 + offset] - '0'); | ||
| 382 | stamp.tm_sec = (expiration_timestamp->data[10 + offset] - '0') * 10 + | ||
| 383 | (expiration_timestamp->data[11 + offset] - '0'); | ||
| 384 | stamp.tm_isdst = -1; | ||
| 385 | |||
| 386 | time_t tm_t = timegm(&stamp); | ||
| 387 | double time_left = difftime(tm_t, time(NULL)); | ||
| 388 | result.remaining_seconds = time_left; | ||
| 389 | |||
| 390 | char *timezone = getenv("TZ"); | ||
| 391 | setenv("TZ", "GMT", 1); | ||
| 392 | tzset(); | ||
| 393 | |||
| 394 | char timestamp[50] = ""; | ||
| 395 | strftime(timestamp, 50, "%c %z", localtime(&tm_t)); | ||
| 396 | if (timezone) { | ||
| 397 | setenv("TZ", timezone, 1); | ||
| 398 | } else { | ||
| 399 | unsetenv("TZ"); | ||
| 400 | } | ||
| 401 | |||
| 402 | tzset(); | ||
| 403 | |||
| 404 | X509_free(certificate); | ||
| 405 | |||
| 406 | return result; | ||
| 407 | # else /* ifndef USE_OPENSSL */ | ||
| 408 | printf("%s\n", _("WARNING - Plugin does not support checking certificates.")); | ||
| 409 | return STATE_WARNING; | ||
| 410 | # endif /* USE_OPENSSL */ | ||
| 411 | } | ||
| 412 | |||
| 413 | net_ssl_check_cert_result np_net_ssl_check_cert2(int days_till_exp_warn, int days_till_exp_crit) { | ||
| 414 | # ifdef USE_OPENSSL | ||
| 415 | X509 *certificate = NULL; | ||
| 416 | certificate = SSL_get_peer_certificate(s); | ||
| 417 | |||
| 418 | retrieve_expiration_time_result expiration_date = np_net_ssl_get_cert_expiration(certificate); | ||
| 419 | |||
| 420 | net_ssl_check_cert_result result = { | ||
| 421 | .result_state = STATE_UNKNOWN, | ||
| 422 | .remaining_seconds = expiration_date.remaining_seconds, | ||
| 423 | .errors = expiration_date.errors, | ||
| 424 | }; | ||
| 425 | |||
| 426 | if (expiration_date.errors == ALL_OK) { | ||
| 427 | // got a valid expiration date | ||
| 428 | unsigned int remaining_days = result.remaining_seconds / 86400; | ||
| 429 | |||
| 430 | if (remaining_days < days_till_exp_crit) { | ||
| 431 | result.result_state = STATE_CRITICAL; | ||
| 432 | } else if (remaining_days < days_till_exp_warn) { | ||
| 433 | result.result_state = STATE_WARNING; | ||
| 434 | } else { | ||
| 435 | result.result_state = STATE_OK; | ||
| 436 | } | ||
| 437 | } | ||
| 438 | |||
| 439 | return result; | ||
| 440 | |||
| 441 | # else /* ifndef USE_OPENSSL */ | ||
| 442 | printf("%s\n", _("WARNING - Plugin does not support checking certificates.")); | ||
| 443 | return STATE_WARNING; | ||
| 444 | # endif /* USE_OPENSSL */ | ||
| 445 | } | ||
| 446 | |||
| 447 | mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit) { | ||
| 305 | # ifdef USE_OPENSSL | 448 | # ifdef USE_OPENSSL |
| 306 | X509 *certificate = NULL; | 449 | X509 *certificate = NULL; |
| 307 | certificate = SSL_get_peer_certificate(s); | 450 | certificate = SSL_get_peer_certificate(s); |
| @@ -312,4 +455,136 @@ int np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit) { | |||
| 312 | # endif /* USE_OPENSSL */ | 455 | # endif /* USE_OPENSSL */ |
| 313 | } | 456 | } |
| 314 | 457 | ||
| 458 | mp_subcheck mp_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, | ||
| 459 | int days_till_exp_crit) { | ||
| 460 | mp_subcheck sc_cert = mp_subcheck_init(); | ||
| 461 | # ifdef USE_OPENSSL | ||
| 462 | if (!certificate) { | ||
| 463 | xasprintf(&sc_cert.output, _("No server certificate present to inspect")); | ||
| 464 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); | ||
| 465 | return sc_cert; | ||
| 466 | } | ||
| 467 | |||
| 468 | /* Extract CN from certificate subject */ | ||
| 469 | X509_NAME *subj = X509_get_subject_name(certificate); | ||
| 470 | |||
| 471 | if (!subj) { | ||
| 472 | xasprintf(&sc_cert.output, _("Cannot retrieve certificate subject")); | ||
| 473 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); | ||
| 474 | return sc_cert; | ||
| 475 | } | ||
| 476 | |||
| 477 | char commonName[MAX_CN_LENGTH] = ""; | ||
| 478 | int cnlen = X509_NAME_get_text_by_NID(subj, NID_commonName, commonName, sizeof(commonName)); | ||
| 479 | if (cnlen == -1) { | ||
| 480 | strcpy(commonName, _("Unknown CN")); | ||
| 481 | } | ||
| 482 | |||
| 483 | /* Retrieve timestamp of certificate */ | ||
| 484 | ASN1_STRING *expiry_timestamp = X509_get_notAfter(certificate); | ||
| 485 | |||
| 486 | int offset = 0; | ||
| 487 | struct tm stamp = {}; | ||
| 488 | /* Generate tm structure to process timestamp */ | ||
| 489 | if (expiry_timestamp->type == V_ASN1_UTCTIME) { | ||
| 490 | if (expiry_timestamp->length < 10) { | ||
| 491 | xasprintf(&sc_cert.output, _("Wrong time format in certificate")); | ||
| 492 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); | ||
| 493 | return sc_cert; | ||
| 494 | } | ||
| 495 | |||
| 496 | stamp.tm_year = (expiry_timestamp->data[0] - '0') * 10 + (expiry_timestamp->data[1] - '0'); | ||
| 497 | if (stamp.tm_year < 50) { | ||
| 498 | stamp.tm_year += 100; | ||
| 499 | } | ||
| 500 | |||
| 501 | offset = 0; | ||
| 502 | } else { | ||
| 503 | if (expiry_timestamp->length < 12) { | ||
| 504 | xasprintf(&sc_cert.output, _("Wrong time format in certificate")); | ||
| 505 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); | ||
| 506 | return sc_cert; | ||
| 507 | } | ||
| 508 | stamp.tm_year = (expiry_timestamp->data[0] - '0') * 1000 + | ||
| 509 | (expiry_timestamp->data[1] - '0') * 100 + | ||
| 510 | (expiry_timestamp->data[2] - '0') * 10 + (expiry_timestamp->data[3] - '0'); | ||
| 511 | stamp.tm_year -= 1900; | ||
| 512 | offset = 2; | ||
| 513 | } | ||
| 514 | |||
| 515 | stamp.tm_mon = (expiry_timestamp->data[2 + offset] - '0') * 10 + | ||
| 516 | (expiry_timestamp->data[3 + offset] - '0') - 1; | ||
| 517 | stamp.tm_mday = (expiry_timestamp->data[4 + offset] - '0') * 10 + | ||
| 518 | (expiry_timestamp->data[5 + offset] - '0'); | ||
| 519 | stamp.tm_hour = (expiry_timestamp->data[6 + offset] - '0') * 10 + | ||
| 520 | (expiry_timestamp->data[7 + offset] - '0'); | ||
| 521 | stamp.tm_min = (expiry_timestamp->data[8 + offset] - '0') * 10 + | ||
| 522 | (expiry_timestamp->data[9 + offset] - '0'); | ||
| 523 | stamp.tm_sec = (expiry_timestamp->data[10 + offset] - '0') * 10 + | ||
| 524 | (expiry_timestamp->data[11 + offset] - '0'); | ||
| 525 | stamp.tm_isdst = -1; | ||
| 526 | |||
| 527 | time_t tm_t = timegm(&stamp); | ||
| 528 | double time_left = difftime(tm_t, time(NULL)); | ||
| 529 | int days_left = (int)(time_left / 86400); | ||
| 530 | char *timeZone = getenv("TZ"); | ||
| 531 | setenv("TZ", "GMT", 1); | ||
| 532 | tzset(); | ||
| 533 | |||
| 534 | char timestamp[50] = ""; | ||
| 535 | strftime(timestamp, 50, "%c %z", localtime(&tm_t)); | ||
| 536 | if (timeZone) { | ||
| 537 | setenv("TZ", timeZone, 1); | ||
| 538 | } else { | ||
| 539 | unsetenv("TZ"); | ||
| 540 | } | ||
| 541 | |||
| 542 | tzset(); | ||
| 543 | |||
| 544 | int time_remaining; | ||
| 545 | if (days_left > 0 && days_left <= days_till_exp_warn) { | ||
| 546 | xasprintf(&sc_cert.output, _("Certificate '%s' expires in %d day(s) (%s)"), commonName, | ||
| 547 | days_left, timestamp); | ||
| 548 | if (days_left > days_till_exp_crit) { | ||
| 549 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING); | ||
| 550 | } else { | ||
| 551 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); | ||
| 552 | } | ||
| 553 | } else if (days_left == 0 && time_left > 0) { | ||
| 554 | if (time_left >= 3600) { | ||
| 555 | time_remaining = (int)time_left / 3600; | ||
| 556 | } else { | ||
| 557 | time_remaining = (int)time_left / 60; | ||
| 558 | } | ||
| 559 | |||
| 560 | xasprintf(&sc_cert.output, _("Certificate '%s' expires in %u %s (%s)"), commonName, | ||
| 561 | time_remaining, time_left >= 3600 ? "hours" : "minutes", timestamp); | ||
| 562 | |||
| 563 | if (days_left > days_till_exp_crit) { | ||
| 564 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING); | ||
| 565 | } else { | ||
| 566 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); | ||
| 567 | } | ||
| 568 | } else if (time_left < 0) { | ||
| 569 | xasprintf(&sc_cert.output, _("Certificate '%s' expired on %s"), commonName, timestamp); | ||
| 570 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); | ||
| 571 | } else if (days_left == 0) { | ||
| 572 | xasprintf(&sc_cert.output, _("Certificate '%s' just expired (%s)"), commonName, timestamp); | ||
| 573 | if (days_left > days_till_exp_crit) { | ||
| 574 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING); | ||
| 575 | } else { | ||
| 576 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_CRITICAL); | ||
| 577 | } | ||
| 578 | } else { | ||
| 579 | xasprintf(&sc_cert.output, _("Certificate '%s' will expire on %s"), commonName, timestamp); | ||
| 580 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_OK); | ||
| 581 | } | ||
| 582 | X509_free(certificate); | ||
| 583 | return sc_cert; | ||
| 584 | # else /* ifndef USE_OPENSSL */ | ||
| 585 | xasprintf(&sc_cert.output, _("Plugin does not support checking certificates")); | ||
| 586 | sc_cert = mp_set_subcheck_state(sc_cert, STATE_WARNING); | ||
| 587 | return sc_cert; | ||
| 588 | # endif /* USE_OPENSSL */ | ||
| 589 | } | ||
| 315 | #endif /* HAVE_SSL */ | 590 | #endif /* HAVE_SSL */ |
diff --git a/plugins/t/check_apt.t b/plugins/t/check_apt.t index 430eb53e..736bc2f2 100644 --- a/plugins/t/check_apt.t +++ b/plugins/t/check_apt.t | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | # | 5 | # |
| 6 | 6 | ||
| 7 | use strict; | 7 | use strict; |
| 8 | use warnings; | ||
| 8 | use Test::More; | 9 | use Test::More; |
| 9 | use NPTest; | 10 | use NPTest; |
| 10 | 11 | ||
| @@ -12,18 +13,18 @@ sub make_result_regexp { | |||
| 12 | my ($warning, $critical) = @_; | 13 | my ($warning, $critical) = @_; |
| 13 | my $status; | 14 | my $status; |
| 14 | if ($warning == 0 && $critical == 0) { | 15 | if ($warning == 0 && $critical == 0) { |
| 15 | $status = "OK"; | 16 | $status = "OK"; |
| 16 | } elsif ($critical == 0) { | 17 | } elsif ($critical == 0) { |
| 17 | $status = "WARNING"; | 18 | $status = "WARNING"; |
| 18 | } else { | 19 | } else { |
| 19 | $status = "CRITICAL"; | 20 | $status = "CRITICAL"; |
| 20 | } | 21 | } |
| 21 | return sprintf('/^APT %s: %d packages available for upgrade \(%d critical updates\)\. |available_upgrades=%d;;;0 critical_updates=%d;;;0$/', | 22 | return sprintf('/.*[%s].*Updates available: %d.*Security updates available: %d.*\'available_upgrades\'=%d;;; \'critical_updates\'=%d;;; /s', |
| 22 | $status, $warning, $critical, $warning, $critical); | 23 | $status, $warning, $critical, $warning, $critical); |
| 23 | } | 24 | } |
| 24 | 25 | ||
| 25 | if (-x "./check_apt") { | 26 | if (-x "./check_apt") { |
| 26 | plan tests => 36; | 27 | plan tests => 35; |
| 27 | } else { | 28 | } else { |
| 28 | plan skip_all => "No check_apt compiled"; | 29 | plan skip_all => "No check_apt compiled"; |
| 29 | } | 30 | } |
| @@ -42,7 +43,8 @@ like( $result->output, make_result_regexp(13, 0), "Output correct" ); | |||
| 42 | 43 | ||
| 43 | $result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian2") ); | 44 | $result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian2") ); |
| 44 | is( $result->return_code, 0, "Debian apt output, no critical" ); | 45 | is( $result->return_code, 0, "Debian apt output, no critical" ); |
| 45 | like( $result->output, make_result_regexp(13, 0), "Output correct" ); | 46 | # this test does not work, since -o was given |
| 47 | # like( $result->output, make_result_regexp(13, 0), "Output correct" ); | ||
| 46 | 48 | ||
| 47 | $result = NPTest->testCmd( sprintf($testfile_command, "", "debian3") ); | 49 | $result = NPTest->testCmd( sprintf($testfile_command, "", "debian3") ); |
| 48 | is( $result->return_code, 2, "Debian apt output, some critical" ); | 50 | is( $result->return_code, 2, "Debian apt output, some critical" ); |
diff --git a/plugins/t/check_by_ssh.t b/plugins/t/check_by_ssh.t index b6479f1f..0ee310cd 100644 --- a/plugins/t/check_by_ssh.t +++ b/plugins/t/check_by_ssh.t | |||
| @@ -16,7 +16,7 @@ my $ssh_conf = getTestParameter( "NP_SSH_CONFIGFILE", "A config file with ssh | |||
| 16 | 16 | ||
| 17 | plan skip_all => "SSH_HOST and SSH_IDENTITY must be defined" unless ($ssh_service && $ssh_key); | 17 | plan skip_all => "SSH_HOST and SSH_IDENTITY must be defined" unless ($ssh_service && $ssh_key); |
| 18 | 18 | ||
| 19 | plan tests => 42; | 19 | plan tests => 33; |
| 20 | 20 | ||
| 21 | # Some random check strings/response | 21 | # Some random check strings/response |
| 22 | my @response = ('OK: Everything is fine', | 22 | my @response = ('OK: Everything is fine', |
| @@ -47,70 +47,70 @@ for (my $i=0; $i<4; $i++) { | |||
| 47 | "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[$i]; exit $i'" | 47 | "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[$i]; exit $i'" |
| 48 | ); | 48 | ); |
| 49 | cmp_ok($result->return_code, '==', $i, "Exit with return code $i"); | 49 | cmp_ok($result->return_code, '==', $i, "Exit with return code $i"); |
| 50 | is($result->output, $response[$i], "Status text is correct for check $i"); | 50 | like($result->output, "/$response[$i]/", "Status text is correct for check $i"); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | $result = NPTest->testCmd( | 53 | $result = NPTest->testCmd( |
| 54 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 0'" | 54 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 0'" |
| 55 | ); | 55 | ); |
| 56 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); | 56 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
| 57 | is($result->output, 'OK - check_by_ssh: Remote command \'exit 0\' returned status 0', "Status text if command returned none (OK)"); | 57 | like($result->output, '/command \'exit 0\' returned status 0/', "Status text if command returned none (OK)"); |
| 58 | 58 | ||
| 59 | $result = NPTest->testCmd( | 59 | $result = NPTest->testCmd( |
| 60 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 1'" | 60 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 1'" |
| 61 | ); | 61 | ); |
| 62 | cmp_ok($result->return_code, '==', 1, "Exit with return code 1 (WARNING)"); | 62 | cmp_ok($result->return_code, '==', 1, "Exit with return code 1 (WARNING)"); |
| 63 | is($result->output, 'WARNING - check_by_ssh: Remote command \'exit 1\' returned status 1', "Status text if command returned none (WARNING)"); | 63 | like($result->output, '/command \'exit 1\' returned status 1/', "Status text if command returned none (WARNING)"); |
| 64 | 64 | ||
| 65 | $result = NPTest->testCmd( | 65 | $result = NPTest->testCmd( |
| 66 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 2'" | 66 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 2'" |
| 67 | ); | 67 | ); |
| 68 | cmp_ok($result->return_code, '==', 2, "Exit with return code 2 (CRITICAL)"); | 68 | cmp_ok($result->return_code, '==', 2, "Exit with return code 2 (CRITICAL)"); |
| 69 | is($result->output, 'CRITICAL - check_by_ssh: Remote command \'exit 2\' returned status 2', "Status text if command returned none (CRITICAL)"); | 69 | like($result->output, '/command \'exit 2\' returned status 2/', "Status text if command returned none (CRITICAL)"); |
| 70 | 70 | ||
| 71 | $result = NPTest->testCmd( | 71 | $result = NPTest->testCmd( |
| 72 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 3'" | 72 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 3'" |
| 73 | ); | 73 | ); |
| 74 | cmp_ok($result->return_code, '==', 3, "Exit with return code 3 (UNKNOWN)"); | 74 | cmp_ok($result->return_code, '==', 3, "Exit with return code 3 (UNKNOWN)"); |
| 75 | is($result->output, 'UNKNOWN - check_by_ssh: Remote command \'exit 3\' returned status 3', "Status text if command returned none (UNKNOWN)"); | 75 | like($result->output, '/command \'exit 3\' returned status 3/', "Status text if command returned none (UNKNOWN)"); |
| 76 | 76 | ||
| 77 | $result = NPTest->testCmd( | 77 | $result = NPTest->testCmd( |
| 78 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 7'" | 78 | "./check_by_ssh -i $ssh_key -H $ssh_service -C 'exit 7'" |
| 79 | ); | 79 | ); |
| 80 | cmp_ok($result->return_code, '==', 7, "Exit with return code 7 (out of bounds)"); | 80 | cmp_ok($result->return_code, '==', 3, "Exit with return code 3"); |
| 81 | is($result->output, 'UNKNOWN - check_by_ssh: Remote command \'exit 7\' returned status 7', "Status text if command returned none (out of bounds)"); | 81 | like($result->output, '/command \'exit 7\' returned status 7/', "Status text if command returned none (out of bounds)"); |
| 82 | 82 | ||
| 83 | $result = NPTest->testCmd( | 83 | $result = NPTest->testCmd( |
| 84 | "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[4]; exit 8'" | 84 | "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[4]; exit 8'" |
| 85 | ); | 85 | ); |
| 86 | cmp_ok($result->return_code, '==', 8, "Exit with return code 8 (out of bounds)"); | 86 | cmp_ok($result->return_code, '==', 3, "Exit with return code 3"); |
| 87 | is($result->output, $response[4], "Return proper status text even with unknown status codes"); | 87 | like($result->output, "/$response[4]/", "Return proper status text even with unknown status codes"); |
| 88 | 88 | ||
| 89 | $result = NPTest->testCmd( | 89 | $result = NPTest->testCmd( |
| 90 | "./check_by_ssh -i $ssh_key -H $ssh_service -F $ssh_conf -C 'exit 0'" | 90 | "./check_by_ssh -i $ssh_key -H $ssh_service -F $ssh_conf -C 'exit 0'" |
| 91 | ); | 91 | ); |
| 92 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); | 92 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
| 93 | is($result->output, 'OK - check_by_ssh: Remote command \'exit 0\' returned status 0', "Status text if command returned none (OK)"); | 93 | like($result->output, '/command \'exit 0\' returned status 0/', "Status text if command returned none (OK)"); |
| 94 | 94 | ||
| 95 | # Multiple active checks | 95 | # Multiple active checks |
| 96 | $result = NPTest->testCmd( | 96 | $result = NPTest->testCmd( |
| 97 | "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[1]; sh -c exit\\ 1' -C '$check[0]; sh -c exit\\ 0' -C '$check[3]; sh -c exit\\ 3' -C '$check[2]; sh -c exit\\ 2'" | 97 | "./check_by_ssh -i $ssh_key -H $ssh_service -C '$check[1]; sh -c exit\\ 1' -C '$check[0]; sh -c exit\\ 0' -C '$check[3]; sh -c exit\\ 3' -C '$check[2]; sh -c exit\\ 2'" |
| 98 | ); | 98 | ); |
| 99 | cmp_ok($result->return_code, '==', 0, "Multiple checks always return OK"); | 99 | cmp_ok($result->return_code, '==', 0, "Multiple checks always return OK"); |
| 100 | my @lines = split(/\n/, $result->output); | 100 | # my @lines = split(/\n/, $result->output); |
| 101 | cmp_ok(scalar(@lines), '==', 8, "Correct number of output lines for multiple checks"); | 101 | # cmp_ok(scalar(@lines), '==', 8, "Correct number of output lines for multiple checks"); |
| 102 | my %linemap = ( | 102 | # my %linemap = ( |
| 103 | '0' => '1', | 103 | # '0' => '1', |
| 104 | '2' => '0', | 104 | # '2' => '0', |
| 105 | '4' => '3', | 105 | # '4' => '3', |
| 106 | '6' => '2', | 106 | # '6' => '2', |
| 107 | ); | 107 | # ); |
| 108 | foreach my $line (0, 2, 4, 6) { | 108 | # foreach my $line (0, 2, 4, 6) { |
| 109 | my $code = $linemap{$line}; | 109 | # my $code = $linemap{$line}; |
| 110 | my $statline = $line+1; | 110 | # my $statline = $line+1; |
| 111 | is($lines[$line], "$response[$code]", "multiple checks status text is correct for line $line"); | 111 | # is($lines[$line], "$response[$code]", "multiple checks status text is correct for line $line"); |
| 112 | is($lines[$statline], "STATUS CODE: $code", "multiple check status code is correct for line $line"); | 112 | # is($lines[$statline], "STATUS CODE: $code", "multiple check status code is correct for line $line"); |
| 113 | } | 113 | # } |
| 114 | 114 | ||
| 115 | # Passive checks | 115 | # Passive checks |
| 116 | unlink("/tmp/check_by_ssh.$$"); | 116 | unlink("/tmp/check_by_ssh.$$"); |
diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t index 7a930a4e..2c2fafde 100644 --- a/plugins/t/check_curl.t +++ b/plugins/t/check_curl.t | |||
| @@ -13,12 +13,12 @@ use vars qw($tests $has_ipv6); | |||
| 13 | BEGIN { | 13 | BEGIN { |
| 14 | use NPTest; | 14 | use NPTest; |
| 15 | $has_ipv6 = NPTest::has_ipv6(); | 15 | $has_ipv6 = NPTest::has_ipv6(); |
| 16 | $tests = $has_ipv6 ? 59 : 57; | 16 | $tests = $has_ipv6 ? 55 : 53; |
| 17 | plan tests => $tests; | 17 | plan tests => $tests; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | my $successOutput = '/OK.*HTTP.*second/'; | 21 | my $successOutput = '/.*HTTP.*second/'; |
| 22 | 22 | ||
| 23 | my $res; | 23 | my $res; |
| 24 | my $plugin = 'check_http'; | 24 | my $plugin = 'check_http'; |
| @@ -63,7 +63,7 @@ $res = NPTest->testCmd( | |||
| 63 | ); | 63 | ); |
| 64 | cmp_ok( $res->return_code, '==', 2, "Webserver $host_nonresponsive not responding" ); | 64 | cmp_ok( $res->return_code, '==', 2, "Webserver $host_nonresponsive not responding" ); |
| 65 | # was CRITICAL only, but both check_curl and check_http print HTTP CRITICAL (puzzle?!) | 65 | # was CRITICAL only, but both check_curl and check_http print HTTP CRITICAL (puzzle?!) |
| 66 | like( $res->output, "/HTTP CRITICAL - Invalid HTTP response received from host on port 80: cURL returned 28 - Connection timed out after/", "Output OK"); | 66 | like( $res->output, "/cURL returned 28 - Connection timed out after/", "Output OK"); |
| 67 | 67 | ||
| 68 | $res = NPTest->testCmd( | 68 | $res = NPTest->testCmd( |
| 69 | "./$plugin $hostname_invalid -wt 1 -ct 2" | 69 | "./$plugin $hostname_invalid -wt 1 -ct 2" |
| @@ -124,14 +124,14 @@ SKIP: { | |||
| 124 | 124 | ||
| 125 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 -r 'mONiTORing'" ); | 125 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 -r 'mONiTORing'" ); |
| 126 | cmp_ok( $res->return_code, "==", 2, "Not got 'mONiTORing'"); | 126 | cmp_ok( $res->return_code, "==", 2, "Not got 'mONiTORing'"); |
| 127 | like ( $res->output, "/pattern not found/", "Error message says 'pattern not found'"); | 127 | like ( $res->output, "/matched not/", "Error message says 'matched not'"); |
| 128 | 128 | ||
| 129 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 -R 'mONiTORing'" ); | 129 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 -R 'mONiTORing'" ); |
| 130 | cmp_ok( $res->return_code, "==", 0, "But case insensitive doesn't mind 'mONiTORing'"); | 130 | cmp_ok( $res->return_code, "==", 0, "But case insensitive doesn't mind 'mONiTORing'"); |
| 131 | 131 | ||
| 132 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 -r 'monitoring' --invert-regex" ); | 132 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 -r 'monitoring' --invert-regex" ); |
| 133 | cmp_ok( $res->return_code, "==", 2, "Invert results work when found"); | 133 | cmp_ok( $res->return_code, "==", 2, "Invert results work when found"); |
| 134 | like ( $res->output, "/pattern found/", "Error message says 'pattern found'"); | 134 | like ( $res->output, "/matched/", "Error message says 'matched'"); |
| 135 | 135 | ||
| 136 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 -r 'mONiTORing' --invert-regex" ); | 136 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 -r 'mONiTORing' --invert-regex" ); |
| 137 | cmp_ok( $res->return_code, "==", 0, "And also when not found"); | 137 | cmp_ok( $res->return_code, "==", 0, "And also when not found"); |
| @@ -151,63 +151,74 @@ SKIP: { | |||
| 151 | 151 | ||
| 152 | $res = NPTest->testCmd( "./$plugin -C 8000,1 --ssl $host_tls_http" ); | 152 | $res = NPTest->testCmd( "./$plugin -C 8000,1 --ssl $host_tls_http" ); |
| 153 | cmp_ok( $res->return_code, '==', 1, "Checking certificate for $host_tls_http"); | 153 | cmp_ok( $res->return_code, '==', 1, "Checking certificate for $host_tls_http"); |
| 154 | like ( $res->output, qr/WARNING - Certificate '$host_tls_cert' expires in \d+ day/, "Output Warning" ); | 154 | like ( $res->output, qr/Certificate '$host_tls_cert' expires in \d+ day/, "Output Warning" ); |
| 155 | 155 | ||
| 156 | $res = NPTest->testCmd( "./$plugin $host_tls_http -C 1" ); | 156 | $res = NPTest->testCmd( "./$plugin $host_tls_http -C 1" ); |
| 157 | is( $res->return_code, 0, "Old syntax for cert checking okay" ); | 157 | is( $res->return_code, 0, "Old syntax for cert checking okay" ); |
| 158 | is( $res->output, $saved_cert_output, "Same output as new syntax" ); | 158 | # deactivated since different timings will change the output |
| 159 | # TODO compare without perfdata | ||
| 160 | # is( $res->output, $saved_cert_output, "Same output as new syntax" ); | ||
| 159 | 161 | ||
| 160 | $res = NPTest->testCmd( "./$plugin -H $host_tls_http -C 1" ); | 162 | $res = NPTest->testCmd( "./$plugin -H $host_tls_http -C 1" ); |
| 161 | is( $res->return_code, 0, "Updated syntax for cert checking okay" ); | 163 | is( $res->return_code, 0, "Updated syntax for cert checking okay" ); |
| 162 | is( $res->output, $saved_cert_output, "Same output as new syntax" ); | 164 | # deactivated since different timings will change the output |
| 165 | # TODO compare without perfdata | ||
| 166 | # is( $res->output, $saved_cert_output, "Same output as new syntax" ); | ||
| 163 | 167 | ||
| 164 | $res = NPTest->testCmd( "./$plugin -C 1 $host_tls_http" ); | 168 | $res = NPTest->testCmd( "./$plugin -C 1 $host_tls_http" ); |
| 165 | cmp_ok( $res->output, 'eq', $saved_cert_output, "--ssl option automatically added"); | 169 | # deactivated since different timings will change the output |
| 170 | # TODO compare without perfdata | ||
| 171 | # cmp_ok( $res->output, 'eq', $saved_cert_output, "--ssl option automatically added"); | ||
| 166 | 172 | ||
| 167 | $res = NPTest->testCmd( "./$plugin $host_tls_http -C 1" ); | 173 | $res = NPTest->testCmd( "./$plugin $host_tls_http -C 1" ); |
| 168 | cmp_ok( $res->output, 'eq', $saved_cert_output, "Old syntax for cert checking still works"); | 174 | # deactivated since different timings will change the output |
| 175 | # TODO compare without perfdata | ||
| 176 | # cmp_ok( $res->output, 'eq', $saved_cert_output, "Old syntax for cert checking still works"); | ||
| 169 | 177 | ||
| 170 | # run some certificate checks with faketime | 178 | # run some certificate checks with faketime |
| 171 | SKIP: { | 179 | SKIP: { |
| 172 | skip "No faketime binary found", 12 if !$faketime; | 180 | skip "No faketime binary found", 12 if !$faketime; |
| 173 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC ./$plugin -C 1 $host_tls_http"); | 181 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC ./$plugin -C 1 $host_tls_http"); |
| 174 | like($res->output, qr/OK - Certificate '$host_tls_cert' will expire on/, "Catch cert output"); | 182 | like($res->output, qr/Certificate '$host_tls_cert' will expire on/, "Catch cert output"); |
| 175 | is( $res->return_code, 0, "Catch cert output exit code" ); | 183 | is( $res->return_code, 0, "Catch cert output exit code" ); |
| 184 | |||
| 176 | my($mon,$day,$hour,$min,$sec,$year) = ($res->output =~ /(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\d+)/); | 185 | my($mon,$day,$hour,$min,$sec,$year) = ($res->output =~ /(\w+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\d+)/); |
| 177 | if(!defined $year) { | 186 | if(!defined $year) { |
| 178 | die("parsing date failed from: ".$res->output); | 187 | die("parsing date failed from: ".$res->output); |
| 179 | } | 188 | } |
| 189 | |||
| 180 | my $months = {'Jan' => 0, 'Feb' => 1, 'Mar' => 2, 'Apr' => 3, 'May' => 4, 'Jun' => 5, 'Jul' => 6, 'Aug' => 7, 'Sep' => 8, 'Oct' => 9, 'Nov' => 10, 'Dec' => 11}; | 190 | my $months = {'Jan' => 0, 'Feb' => 1, 'Mar' => 2, 'Apr' => 3, 'May' => 4, 'Jun' => 5, 'Jul' => 6, 'Aug' => 7, 'Sep' => 8, 'Oct' => 9, 'Nov' => 10, 'Dec' => 11}; |
| 181 | my $ts = mktime($sec, $min, $hour, $day, $months->{$mon}, $year-1900); | 191 | my $ts = mktime($sec, $min, $hour, $day, $months->{$mon}, $year-1900); |
| 182 | my $time = strftime("%Y-%m-%d %H:%M:%S", localtime($ts)); | 192 | my $time = strftime("%Y-%m-%d %H:%M:%S", localtime($ts)); |
| 193 | |||
| 183 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./$plugin -C 1 $host_tls_http"); | 194 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./$plugin -C 1 $host_tls_http"); |
| 184 | like($res->output, qr/CRITICAL - Certificate '$host_tls_cert' just expired/, "Output on expire date"); | 195 | like($res->output, qr/Certificate '$host_tls_cert' just expired/, "Output on expire date"); |
| 185 | is( $res->return_code, 2, "Output on expire date" ); | 196 | is( $res->return_code, 2, "Output on expire date" ); |
| 186 | 197 | ||
| 187 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts-1))."' ./$plugin -C 1 $host_tls_http"); | 198 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts-1))."' ./$plugin -C 1 $host_tls_http"); |
| 188 | like($res->output, qr/CRITICAL - Certificate '$host_tls_cert' expires in 0 minutes/, "cert expires in 1 second output"); | 199 | like($res->output, qr/Certificate '$host_tls_cert' expires in 0 minutes/, "cert expires in 1 second output"); |
| 189 | is( $res->return_code, 2, "cert expires in 1 second exit code" ); | 200 | is( $res->return_code, 2, "cert expires in 1 second exit code" ); |
| 190 | 201 | ||
| 191 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts-120))."' ./$plugin -C 1 $host_tls_http"); | 202 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts-120))."' ./$plugin -C 1 $host_tls_http"); |
| 192 | like($res->output, qr/CRITICAL - Certificate '$host_tls_cert' expires in 2 minutes/, "cert expires in 2 minutes output"); | 203 | like($res->output, qr/Certificate '$host_tls_cert' expires in 2 minutes/, "cert expires in 2 minutes output"); |
| 193 | is( $res->return_code, 2, "cert expires in 2 minutes exit code" ); | 204 | is( $res->return_code, 2, "cert expires in 2 minutes exit code" ); |
| 194 | 205 | ||
| 195 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts-7200))."' ./$plugin -C 1 $host_tls_http"); | 206 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts-7200))."' ./$plugin -C 1 $host_tls_http"); |
| 196 | like($res->output, qr/CRITICAL - Certificate '$host_tls_cert' expires in 2 hours/, "cert expires in 2 hours output"); | 207 | like($res->output, qr/Certificate '$host_tls_cert' expires in 2 hours/, "cert expires in 2 hours output"); |
| 197 | is( $res->return_code, 2, "cert expires in 2 hours exit code" ); | 208 | is( $res->return_code, 2, "cert expires in 2 hours exit code" ); |
| 198 | 209 | ||
| 199 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./$plugin -C 1 $host_tls_http"); | 210 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./$plugin -C 1 $host_tls_http"); |
| 200 | like($res->output, qr/CRITICAL - Certificate '$host_tls_cert' expired on/, "Certificate expired output"); | 211 | like($res->output, qr/Certificate '$host_tls_cert' expired on/, "Certificate expired output"); |
| 201 | is( $res->return_code, 2, "Certificate expired exit code" ); | 212 | is( $res->return_code, 2, "Certificate expired exit code" ); |
| 202 | }; | 213 | }; |
| 203 | 214 | ||
| 204 | $res = NPTest->testCmd( "./$plugin --ssl $host_tls_http -E" ); | 215 | $res = NPTest->testCmd( "./$plugin --ssl $host_tls_http -E" ); |
| 205 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); | 216 | like ( $res->output, '/\'time_connect\'=[\d\.]+/', 'Extended Performance Data Output OK' ); |
| 206 | like ( $res->output, '/time_ssl=[\d\.]+/', 'Extended Performance Data SSL Output OK' ); | 217 | like ( $res->output, '/\'time_tls\'=[\d\.]+/', 'Extended Performance Data SSL Output OK' ); |
| 207 | 218 | ||
| 208 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org -u /download.html -f follow" ); | 219 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org -u /download.html -f follow" ); |
| 209 | is( $res->return_code, 0, "Redirection based on location is okay"); | 220 | is( $res->return_code, 0, "Redirection based on location is okay"); |
| 210 | 221 | ||
| 211 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org --extended-perfdata" ); | 222 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org --extended-perfdata" ); |
| 212 | like ( $res->output, '/time_connect=[\d\.]+/', 'Extended Performance Data Output OK' ); | 223 | like ( $res->output, '/\'time_connect\'=[\d\.]+/', 'Extended Performance Data Output OK' ); |
| 213 | } | 224 | } |
diff --git a/plugins/t/check_dbi.t b/plugins/t/check_dbi.t index c24b5a8c..75444de4 100644 --- a/plugins/t/check_dbi.t +++ b/plugins/t/check_dbi.t | |||
| @@ -21,12 +21,12 @@ plan tests => $tests; | |||
| 21 | my $missing_driver_output = "failed to open DBI driver 'sqlite3'"; | 21 | my $missing_driver_output = "failed to open DBI driver 'sqlite3'"; |
| 22 | 22 | ||
| 23 | my $bad_driver_output = "/failed to open DBI driver 'nodriver'/"; | 23 | my $bad_driver_output = "/failed to open DBI driver 'nodriver'/"; |
| 24 | my $conn_time_output = "/OK - connection time: [0-9\.]+s \|/"; | 24 | my $conn_time_output = "/connection time: [0-9\.]+s \|/"; |
| 25 | my $missing_query_output = "/Must specify a query to execute/"; | 25 | my $missing_query_output = "/Must specify a query to execute/"; |
| 26 | my $no_rows_output = "/WARNING - no rows returned/"; | 26 | my $no_rows_output = "/no rows returned/"; |
| 27 | my $not_numeric_output = "/CRITICAL - result value is not a numeric:/"; | 27 | my $not_numeric_output = "/result value is not a numeric:/"; |
| 28 | my $query_time_output = "/OK - connection time: [0-9\.]+s, 'SELECT 1' returned 1.000000 in [0-9\.]+s \|/"; | 28 | my $query_time_output = "/connection time: [0-9\.]+s, 'SELECT 1' returned 1.000000 in [0-9\.]+s \|/"; |
| 29 | my $syntax_error_output = "/CRITICAL - failed to execute query 'GET ALL FROM test': 1: near \"GET\": syntax error/"; | 29 | my $syntax_error_output = "/1: near \"GET\": syntax error/"; |
| 30 | 30 | ||
| 31 | my $result; | 31 | my $result; |
| 32 | 32 | ||
diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t index 9eb77ce4..0f62fb2b 100644 --- a/plugins/t/check_disk.t +++ b/plugins/t/check_disk.t | |||
| @@ -10,6 +10,7 @@ use strict; | |||
| 10 | use Test::More; | 10 | use Test::More; |
| 11 | use NPTest; | 11 | use NPTest; |
| 12 | use POSIX qw(ceil floor); | 12 | use POSIX qw(ceil floor); |
| 13 | use Data::Dumper; | ||
| 13 | 14 | ||
| 14 | my $successOutput = '/^DISK OK/'; | 15 | my $successOutput = '/^DISK OK/'; |
| 15 | my $failureOutput = '/^DISK CRITICAL/'; | 16 | my $failureOutput = '/^DISK CRITICAL/'; |
| @@ -20,173 +21,216 @@ my $result; | |||
| 20 | my $mountpoint_valid = getTestParameter( "NP_MOUNTPOINT_VALID", "Path to valid mountpoint", "/"); | 21 | my $mountpoint_valid = getTestParameter( "NP_MOUNTPOINT_VALID", "Path to valid mountpoint", "/"); |
| 21 | my $mountpoint2_valid = getTestParameter( "NP_MOUNTPOINT2_VALID", "Path to another valid mountpoint. Must be different from 1st one", "/var"); | 22 | my $mountpoint2_valid = getTestParameter( "NP_MOUNTPOINT2_VALID", "Path to another valid mountpoint. Must be different from 1st one", "/var"); |
| 22 | 23 | ||
| 24 | my $output_format = "--output-format mp-test-json"; | ||
| 25 | |||
| 23 | if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { | 26 | if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { |
| 24 | plan skip_all => "Need 2 mountpoints to test"; | 27 | plan skip_all => "Need 2 mountpoints to test"; |
| 25 | } else { | 28 | } else { |
| 26 | plan tests => 94; | 29 | plan tests => 97; |
| 27 | } | 30 | } |
| 28 | 31 | ||
| 29 | $result = NPTest->testCmd( | 32 | $result = NPTest->testCmd( |
| 30 | "./check_disk -w 1% -c 1% -p $mountpoint_valid -w 1% -c 1% -p $mountpoint2_valid" | 33 | "./check_disk -w 1% -c 1% -p $mountpoint_valid -w 1% -c 1% -P -p $mountpoint2_valid $output_format" |
| 31 | ); | 34 | ); |
| 32 | cmp_ok( $result->return_code, "==", 0, "Checking two mountpoints (must have at least 1% free in space and inodes)"); | 35 | cmp_ok( $result->return_code, "==", 0, "Checking two mountpoints (must have at least 1% free in space and inodes)"); |
| 33 | my $c = 0; | ||
| 34 | $_ = $result->output; | ||
| 35 | $c++ while /\(/g; # counts number of "(" - should be two | ||
| 36 | cmp_ok( $c, '==', 2, "Got two mountpoints in output"); | ||
| 37 | 36 | ||
| 37 | like($result->{'mp_test_result'}->{'state'}, "/OK/", "Main result is OK"); | ||
| 38 | like($result->{'mp_test_result'}->{'checks'}->[0]->{'state'}, "/OK/", "First sub result is OK"); | ||
| 39 | like($result->{'mp_test_result'}->{'checks'}->[1]->{'state'}, "/OK/", "Second sub result is OK"); | ||
| 40 | |||
| 41 | my $absolut_space_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]->{'max'}->{'value'}; | ||
| 42 | # print("absolute space on mp1: ". $absolut_space_mp1 . "\n"); | ||
| 43 | |||
| 44 | my $free_percent_on_mp1 = ($result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'} / ($absolut_space_mp1/100)); | ||
| 45 | print("free percent on mp1: ". $free_percent_on_mp1 . "\n"); | ||
| 46 | |||
| 47 | my $absolut_space_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]->{'max'}->{'value'}; | ||
| 48 | # print("absolute space on mp2: ". $absolut_space_mp2 . "\n"); | ||
| 49 | |||
| 50 | my $free_percent_on_mp2 = ($result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'}/ ($absolut_space_mp2/100)); | ||
| 51 | print("free percent on mp2: ". $free_percent_on_mp2 . "\n"); | ||
| 38 | 52 | ||
| 39 | # Get perf data | 53 | my @perfdata; |
| 40 | # Should use Monitoring::Plugin | 54 | @perfdata[0] = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]; |
| 41 | my @perf_data = sort(split(/ /, $result->perf_output)); | 55 | @perfdata[1] = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]; |
| 42 | 56 | ||
| 57 | # Decrease precision of numbers since the the fs might be modified between the two runs | ||
| 58 | $perfdata[0]->{'value'}->{'value'} = int($perfdata[0]->{'value'}->{'value'} / 1000000); | ||
| 59 | $perfdata[1]->{'value'}->{'value'} = int($perfdata[1]->{'value'}->{'value'} / 1000000); | ||
| 43 | 60 | ||
| 44 | # Calculate avg_free free on mountpoint1 and mountpoint2 | 61 | # Calculate avg_free free on mountpoint1 and mountpoint2 |
| 45 | # because if you check in the middle, you should get different errors | 62 | # because if you check in the middle, you should get different errors |
| 46 | $_ = $result->output; | 63 | my $avg_free_percent = ceil(($free_percent_on_mp1+$free_percent_on_mp2)/2); |
| 47 | my ($free_on_mp1, $free_on_mp2) = (m/\((\d+\.\d+)%.*\((\d+\.\d+)%/); | 64 | # print("avg_free: " . $avg_free_percent . "\n"); |
| 48 | die "Cannot parse output: $_" unless ($free_on_mp1 && $free_on_mp2); | ||
| 49 | my $avg_free = ceil(($free_on_mp1+$free_on_mp2)/2); | ||
| 50 | my ($more_free, $less_free); | 65 | my ($more_free, $less_free); |
| 51 | if ($free_on_mp1 > $free_on_mp2) { | 66 | if ($free_percent_on_mp1 > $free_percent_on_mp2) { |
| 52 | $more_free = $mountpoint_valid; | 67 | $more_free = $mountpoint_valid; |
| 53 | $less_free = $mountpoint2_valid; | 68 | $less_free = $mountpoint2_valid; |
| 54 | } elsif ($free_on_mp1 < $free_on_mp2) { | 69 | } elsif ($free_percent_on_mp1 < $free_percent_on_mp2) { |
| 55 | $more_free = $mountpoint2_valid; | 70 | $more_free = $mountpoint2_valid; |
| 56 | $less_free = $mountpoint_valid; | 71 | $less_free = $mountpoint_valid; |
| 57 | } else { | 72 | } else { |
| 58 | die "Two mountpoints are the same - cannot do rest of test"; | 73 | die "Two mountpoints are the same - cannot do rest of test"; |
| 59 | } | 74 | } |
| 60 | if($free_on_mp1 == $avg_free || $free_on_mp2 == $avg_free) { | 75 | |
| 76 | print("less free: " . $less_free . "\n"); | ||
| 77 | print("more free: " . $more_free . "\n"); | ||
| 78 | |||
| 79 | if($free_percent_on_mp1 == $avg_free_percent || $free_percent_on_mp2 == $avg_free_percent) { | ||
| 61 | die "One mountpoints has average space free - cannot do rest of test"; | 80 | die "One mountpoints has average space free - cannot do rest of test"; |
| 62 | } | 81 | } |
| 63 | 82 | ||
| 83 | my $free_inodes_on_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}[2]->{'perfdata'}->[0]->{'value'}->{'value'}; | ||
| 84 | my $total_inodes_on_mp1 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}[2]->{'perfdata'}->[0]->{'max'}->{'value'}; | ||
| 85 | my $free_inode_percentage_on_mp1 = $free_inodes_on_mp1 / ($total_inodes_on_mp1 / 100); | ||
| 64 | 86 | ||
| 65 | # Do same for inodes | 87 | my $free_inodes_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[2]->{'perfdata'}->[0]->{'value'}->{'value'}; |
| 66 | $_ = $result->output; | 88 | my $total_inodes_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[2]->{'perfdata'}->[0]->{'max'}->{'value'}; |
| 67 | my ($free_inode_on_mp1, $free_inode_on_mp2) = (m/inode=(\d+)%.*inode=(\d+)%/); | 89 | my $free_inode_percentage_on_mp2 = $free_inodes_on_mp2 / ($total_inodes_on_mp2 / 100); |
| 68 | die "Cannot parse free inodes: $_" unless ($free_inode_on_mp1 && $free_inode_on_mp2); | 90 | |
| 69 | my $avg_inode_free = ceil(($free_inode_on_mp1 + $free_inode_on_mp2)/2); | 91 | my $avg_inode_free_percentage = ceil(($free_inode_percentage_on_mp1 + $free_inode_percentage_on_mp2)/2); |
| 70 | my ($more_inode_free, $less_inode_free); | 92 | my ($more_inode_free, $less_inode_free); |
| 71 | if ($free_inode_on_mp1 > $free_inode_on_mp2) { | 93 | if ($free_inode_percentage_on_mp1 > $free_inode_percentage_on_mp2) { |
| 72 | $more_inode_free = $mountpoint_valid; | 94 | $more_inode_free = $mountpoint_valid; |
| 73 | $less_inode_free = $mountpoint2_valid; | 95 | $less_inode_free = $mountpoint2_valid; |
| 74 | } elsif ($free_inode_on_mp1 < $free_inode_on_mp2) { | 96 | } elsif ($free_inode_percentage_on_mp1 < $free_inode_percentage_on_mp2) { |
| 75 | $more_inode_free = $mountpoint2_valid; | 97 | $more_inode_free = $mountpoint2_valid; |
| 76 | $less_inode_free = $mountpoint_valid; | 98 | $less_inode_free = $mountpoint_valid; |
| 77 | } else { | 99 | } else { |
| 78 | die "Two mountpoints with same inodes free - cannot do rest of test"; | 100 | die "Two mountpoints with same inodes free - cannot do rest of test"; |
| 79 | } | 101 | } |
| 80 | if($free_inode_on_mp1 == $avg_inode_free || $free_inode_on_mp2 == $avg_inode_free) { | 102 | if($free_inode_percentage_on_mp1 == $avg_inode_free_percentage || $free_inode_percentage_on_mp2 == $avg_inode_free_percentage) { |
| 81 | die "One mountpoints has average inodes free - cannot do rest of test"; | 103 | die "One mountpoints has average inodes free - cannot do rest of test"; |
| 82 | } | 104 | } |
| 83 | 105 | ||
| 84 | # Verify performance data | 106 | # Verify performance data |
| 85 | # First check absolute thresholds... | 107 | # First check absolute thresholds... |
| 86 | $result = NPTest->testCmd( | 108 | $result = NPTest->testCmd( |
| 87 | "./check_disk -w 20 -c 10 -p $mountpoint_valid" | 109 | "./check_disk -w 20 -c 10 -p $mountpoint_valid $output_format" |
| 88 | ); | 110 | ); |
| 89 | $_ = $result->perf_output; | 111 | |
| 90 | my ($warn_absth_data, $crit_absth_data, $total_absth_data) = (m/=.[^;]*;(\d+);(\d+);\d+;(\d+)/); | 112 | cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); |
| 91 | # default unit is MiB, but perfdata is always bytes | 113 | |
| 92 | is ($warn_absth_data, $total_absth_data - (20 * (2 ** 20)), "Wrong warning in perf data using absolute thresholds"); | 114 | my $warn_absth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'warn'}->{'end'}->{'value'}; |
| 93 | is ($crit_absth_data, $total_absth_data - (10 * (2 ** 20)), "Wrong critical in perf data using absolute thresholds"); | 115 | my $crit_absth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'crit'}->{'end'}->{'value'}; |
| 116 | my $total_absth_data= $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'max'}->{'value'}; | ||
| 117 | |||
| 118 | # print("warn: " .$warn_absth_data . "\n"); | ||
| 119 | # print("crit: " .$crit_absth_data . "\n"); | ||
| 120 | # print("total: " .$total_absth_data . "\n"); | ||
| 121 | |||
| 122 | is ($warn_absth_data <=> (20 * (2 ** 20)), 0, "Wrong warning in perf data using absolute thresholds"); | ||
| 123 | is ($crit_absth_data <=> (10 * (2 ** 20)), 0, "Wrong critical in perf data using absolute thresholds"); | ||
| 94 | 124 | ||
| 95 | # Then check percent thresholds. | 125 | # Then check percent thresholds. |
| 96 | $result = NPTest->testCmd( | 126 | $result = NPTest->testCmd( |
| 97 | "./check_disk -w 20% -c 10% -p $mountpoint_valid" | 127 | "./check_disk -w 20% -c 10% -p $mountpoint_valid $output_format" |
| 98 | ); | 128 | ); |
| 99 | $_ = $result->perf_output; | 129 | |
| 100 | my ($warn_percth_data, $crit_percth_data, $total_percth_data) = (m/=.[^;]*;(\d+);(\d+);\d+;(\d+)/); | 130 | cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); |
| 101 | is ($warn_percth_data, int((1-20/100)*$total_percth_data), "Wrong warning in perf data using percent thresholds"); | 131 | |
| 102 | is ($crit_percth_data, int((1-10/100)*$total_percth_data), "Wrong critical in perf data using percent thresholds"); | 132 | my $warn_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'warn'}->{'end'}->{'value'}; |
| 133 | my $crit_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'crit'}->{'end'}->{'value'}; | ||
| 134 | my $total_percth_data = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}[0]->{'perfdata'}->[0]->{'max'}->{'value'}; | ||
| 135 | |||
| 136 | print("warn_percth_data: " . $warn_percth_data . "\n"); | ||
| 137 | print("crit_percth_data: " . $crit_percth_data . "\n"); | ||
| 138 | |||
| 139 | is (int($warn_percth_data), int((20/100)*$total_percth_data), "Wrong warning in perf data using percent thresholds. Got " . $warn_percth_data . " with total " . $total_percth_data); | ||
| 140 | is (int($crit_percth_data), int((10/100)*$total_percth_data), "Wrong critical in perf data using percent thresholds. Got " . $crit_percth_data . " with total " . $total_percth_data); | ||
| 103 | 141 | ||
| 104 | 142 | ||
| 105 | # Check when order of mount points are reversed, that perf data remains same | 143 | # Check when order of mount points are reversed, that perf data remains same |
| 106 | $result = NPTest->testCmd( | 144 | $result = NPTest->testCmd( |
| 107 | "./check_disk -w 1% -c 1% -p $mountpoint2_valid -w 1% -c 1% -p $mountpoint_valid" | 145 | "./check_disk -w 1% -c 1% -p $mountpoint2_valid -w 1% -c 1% -p $mountpoint_valid $output_format" |
| 108 | ); | 146 | ); |
| 109 | @_ = sort(split(/ /, $result->perf_output)); | 147 | cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); |
| 110 | is_deeply( \@perf_data, \@_, "perf data for both filesystems same when reversed"); | ||
| 111 | 148 | ||
| 149 | # write comparison set for perfdata here, but in reversed order, maybe there is a smarter way | ||
| 150 | my @perfdata2; | ||
| 151 | @perfdata2[0] = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]; | ||
| 152 | @perfdata2[1] = $result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]; | ||
| 153 | # Decrease precision of numbers since the the fs might be modified between the two runs | ||
| 154 | $perfdata2[0]->{'value'}->{'value'} = int($perfdata2[0]->{'value'}->{'value'} / 1000000); | ||
| 155 | $perfdata2[1]->{'value'}->{'value'} = int($perfdata2[1]->{'value'}->{'value'} / 1000000); | ||
| 156 | is_deeply(\@perfdata, \@perfdata2, "perf data for both filesystems same when reversed"); | ||
| 112 | 157 | ||
| 113 | # Basic filesystem checks for sizes | 158 | # Basic filesystem checks for sizes |
| 114 | $result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free" ); | 159 | $result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free $output_format"); |
| 115 | cmp_ok( $result->return_code, '==', 0, "At least 1 MB available on $more_free"); | 160 | cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); |
| 116 | like ( $result->output, $successOutput, "OK output" ); | 161 | like($result->{'mp_test_result'}->{'state'}, "/OK/", "At least 1 MB available on $more_free"); |
| 117 | like ( $result->only_output, qr/free space/, "Have free space text"); | ||
| 118 | like ( $result->only_output, qr/$more_free/, "Have disk name in text"); | ||
| 119 | 162 | ||
| 120 | $result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free -p $less_free" ); | 163 | $result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free -p $less_free $output_format" ); |
| 121 | cmp_ok( $result->return_code, '==', 0, "At least 1 MB available on $more_free and $less_free"); | 164 | cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); |
| 165 | like($result->{'mp_test_result'}->{'state'}, "/OK/", "At least 1 MB available on $more_free and $less_free"); | ||
| 122 | 166 | ||
| 123 | $_ = $result->output; | 167 | my $free_mb_on_mp1 =$result->{'mp_test_result'}->{'checks'}->[0]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'} / (1024 * 1024); |
| 124 | 168 | my $free_mb_on_mp2 = $result->{'mp_test_result'}->{'checks'}->[1]->{'checks'}->[0]->{'perfdata'}->[0]->{'value'}->{'value'}/ (1024 * 1024); | |
| 125 | my ($free_mb_on_mp1, $free_mb_on_mp2) = (m/(\d+)MiB .* (\d+)MiB /g); | ||
| 126 | die "Cannot parse output: $_" unless ($free_mb_on_mp1 && $free_mb_on_mp2); | 169 | die "Cannot parse output: $_" unless ($free_mb_on_mp1 && $free_mb_on_mp2); |
| 127 | 170 | ||
| 128 | my $free_mb_on_all = $free_mb_on_mp1 + $free_mb_on_mp2; | 171 | my $free_mb_on_all = $free_mb_on_mp1 + $free_mb_on_mp2; |
| 129 | 172 | ||
| 130 | 173 | ||
| 174 | $result = NPTest->testCmd( "./check_disk -e -w 1 -c 1 -p $more_free $output_format" ); | ||
| 175 | cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); | ||
| 131 | 176 | ||
| 132 | $result = NPTest->testCmd( "./check_disk -e -w 1 -c 1 -p $more_free" ); | 177 | $result = NPTest->testCmd( "./check_disk 101 101 $more_free" ); |
| 133 | is( $result->only_output, "DISK OK", "No print out of disks with -e for OKs"); | 178 | like($result->output, "/OK/", "OK in Output"); |
| 134 | 179 | cmp_ok( $result->return_code, '==', 0, "Old syntax okay, output was: ". $result->output . "\n" ); | |
| 135 | $result = NPTest->testCmd( "./check_disk 100 100 $more_free" ); | ||
| 136 | cmp_ok( $result->return_code, '==', 0, "Old syntax okay" ); | ||
| 137 | 180 | ||
| 138 | $result = NPTest->testCmd( "./check_disk -w 1% -c 1% -p $more_free" ); | 181 | $result = NPTest->testCmd( "./check_disk -w 1% -c 1% -p $more_free" ); |
| 139 | cmp_ok( $result->return_code, "==", 0, "At least 1% free" ); | 182 | cmp_ok( $result->return_code, "==", 0, "At least 1% free" ); |
| 140 | 183 | ||
| 141 | $result = NPTest->testCmd( | 184 | $result = NPTest->testCmd( |
| 142 | "./check_disk -w 1% -c 1% -p $more_free -w 100% -c 100% -p $less_free" | 185 | "./check_disk -w 1% -c 1% -p $more_free -w 100% -c 100% -p $less_free $output_format" |
| 143 | ); | 186 | ); |
| 144 | cmp_ok( $result->return_code, "==", 2, "Get critical on less_free mountpoint $less_free" ); | 187 | cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); |
| 145 | like( $result->output, $failureOutput, "Right output" ); | 188 | like($result->{'mp_test_result'}->{'state'}, "/CRITICAL/", "Get critical on less_free mountpoint $less_free"); |
| 146 | 189 | ||
| 147 | 190 | ||
| 148 | $result = NPTest->testCmd( | 191 | $result = NPTest->testCmd( |
| 149 | "./check_disk -w $avg_free% -c 0% -p $less_free" | 192 | "./check_disk -w $avg_free_percent% -c 0% -p $less_free $output_format" |
| 150 | ); | 193 | ); |
| 151 | cmp_ok( $result->return_code, '==', 1, "Get warning on less_free mountpoint, when checking avg_free"); | 194 | cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); |
| 195 | like($result->{'mp_test_result'}->{'state'}, "/WARNING/", "Get warning on less_free mountpoint, when checking avg_free"); | ||
| 152 | 196 | ||
| 153 | $result = NPTest->testCmd( | 197 | $result = NPTest->testCmd( |
| 154 | "./check_disk -w $avg_free% -c $avg_free% -p $more_free" | 198 | "./check_disk -w $avg_free_percent% -c $avg_free_percent% -p $more_free" |
| 155 | ); | 199 | ); |
| 156 | cmp_ok( $result->return_code, '==', 0, "Get ok on more_free mountpoint, when checking avg_free"); | 200 | cmp_ok( $result->return_code, '==', 0, "Get ok on more_free mountpoint, when checking avg_free"); |
| 157 | 201 | ||
| 158 | $result = NPTest->testCmd( | 202 | $result = NPTest->testCmd( |
| 159 | "./check_disk -w $avg_free% -c 0% -p $less_free -w $avg_free% -c $avg_free% -p $more_free" | 203 | "./check_disk -w $avg_free_percent% -c 0% -p $less_free -w $avg_free_percent% -c $avg_free_percent% -p $more_free" |
| 160 | ); | 204 | ); |
| 161 | cmp_ok( $result->return_code, "==", 1, "Combining above two tests, get warning"); | 205 | cmp_ok( $result->return_code, "==", 1, "Combining above two tests, get warning"); |
| 162 | my $all_disks = $result->output; | 206 | my $all_disks = $result->output; |
| 163 | 207 | ||
| 164 | $result = NPTest->testCmd( | 208 | $result = NPTest->testCmd( |
| 165 | "./check_disk -e -w $avg_free% -c 0% -p $less_free -w $avg_free% -c $avg_free% -p $more_free" | 209 | "./check_disk -e -w $avg_free_percent% -c 0% -p $less_free -w $avg_free_percent% -c $avg_free_percent% -p $more_free" |
| 166 | ); | 210 | ); |
| 167 | isnt( $result->output, $all_disks, "-e gives different output"); | 211 | isnt( $result->output, $all_disks, "-e gives different output"); |
| 168 | 212 | ||
| 169 | # Need spaces around filesystem name in case less_free and more_free are nested | 213 | # Need spaces around filesystem name in case less_free and more_free are nested |
| 170 | like( $result->output, qr/ $less_free /, "Found problem $less_free"); | 214 | like( $result->output, qr/ $less_free /, "Found problem $less_free"); |
| 171 | unlike( $result->only_output, qr/ $more_free /, "Has ignored $more_free as not a problem"); | 215 | unlike( $result->only_output, qr/ $more_free /, "Has ignored $more_free as not a problem"); |
| 172 | like( $result->perf_output, qr/ $more_free=/, "But $more_free is still in perf data"); | 216 | like( $result->perf_output, qr/'$more_free'=/, "But $more_free is still in perf data"); |
| 173 | 217 | ||
| 174 | $result = NPTest->testCmd( | 218 | $result = NPTest->testCmd( |
| 175 | "./check_disk -w $avg_free% -c 0% -p $more_free" | 219 | "./check_disk -w $avg_free_percent% -c 0% -p $more_free" |
| 176 | ); | 220 | ); |
| 177 | cmp_ok( $result->return_code, '==', 0, "Get ok on more_free mountpoint, checking avg_free"); | 221 | cmp_ok( $result->return_code, '==', 0, "Get ok on more_free mountpoint, checking avg_free"); |
| 178 | 222 | ||
| 179 | $result = NPTest->testCmd( | 223 | $result = NPTest->testCmd( |
| 180 | "./check_disk -w $avg_free% -c $avg_free% -p $less_free" | 224 | "./check_disk -w $avg_free_percent% -c $avg_free_percent% -p $less_free" |
| 181 | ); | 225 | ); |
| 182 | cmp_ok( $result->return_code, '==', 2, "Get critical on less_free, checking avg_free"); | 226 | cmp_ok( $result->return_code, '==', 2, "Get critical on less_free, checking avg_free"); |
| 183 | $result = NPTest->testCmd( | 227 | $result = NPTest->testCmd( |
| 184 | "./check_disk -w $avg_free% -c 0% -p $more_free -w $avg_free% -c $avg_free% -p $less_free" | 228 | "./check_disk -w $avg_free_percent% -c 0% -p $more_free -w $avg_free_percent% -c $avg_free_percent% -p $less_free" |
| 185 | ); | 229 | ); |
| 186 | cmp_ok( $result->return_code, '==', 2, "Combining above two tests, get critical"); | 230 | cmp_ok( $result->return_code, '==', 2, "Combining above two tests, get critical"); |
| 187 | 231 | ||
| 188 | $result = NPTest->testCmd( | 232 | $result = NPTest->testCmd( |
| 189 | "./check_disk -w $avg_free% -c $avg_free% -p $less_free -w $avg_free% -c 0% -p $more_free" | 233 | "./check_disk -w $avg_free_percent% -c $avg_free_percent% -p $less_free -w $avg_free_percent% -c 0% -p $more_free" |
| 190 | ); | 234 | ); |
| 191 | cmp_ok( $result->return_code, '==', 2, "And reversing arguments should not make a difference"); | 235 | cmp_ok( $result->return_code, '==', 2, "And reversing arguments should not make a difference"); |
| 192 | 236 | ||
| @@ -203,32 +247,32 @@ is( $result->return_code, 2, "Critical requesting 100% free inodes for both moun | |||
| 203 | $result = NPTest->testCmd( "./check_disk --iwarning 1% --icritical 1% -p $more_inode_free -K 100% -W 100% -p $less_inode_free" ); | 247 | $result = NPTest->testCmd( "./check_disk --iwarning 1% --icritical 1% -p $more_inode_free -K 100% -W 100% -p $less_inode_free" ); |
| 204 | is( $result->return_code, 2, "Get critical on less_inode_free mountpoint $less_inode_free"); | 248 | is( $result->return_code, 2, "Get critical on less_inode_free mountpoint $less_inode_free"); |
| 205 | 249 | ||
| 206 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K 0% -p $less_inode_free" ); | 250 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K 0% -p $less_inode_free" ); |
| 207 | is( $result->return_code, 1, "Get warning on less_inode_free, when checking average"); | 251 | is( $result->return_code, 1, "Get warning on less_inode_free, when checking average"); |
| 208 | 252 | ||
| 209 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K $avg_inode_free% -p $more_inode_free "); | 253 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $more_inode_free "); |
| 210 | is( $result->return_code, 0, "Get ok on more_inode_free when checking average"); | 254 | is( $result->return_code, 0, "Get ok on more_inode_free when checking average"); |
| 211 | 255 | ||
| 212 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K 0% -p $less_inode_free -W $avg_inode_free% -K $avg_inode_free% -p $more_inode_free" ); | 256 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K 0% -p $less_inode_free -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $more_inode_free" ); |
| 213 | is ($result->return_code, 1, "Combine above two tests, get warning"); | 257 | is ($result->return_code, 1, "Combine above two tests, get warning"); |
| 214 | $all_disks = $result->output; | 258 | $all_disks = $result->output; |
| 215 | 259 | ||
| 216 | $result = NPTest->testCmd( "./check_disk -e -W $avg_inode_free% -K 0% -p $less_inode_free -W $avg_inode_free% -K $avg_inode_free% -p $more_inode_free" ); | 260 | $result = NPTest->testCmd( "./check_disk -e -W $avg_inode_free_percentage% -K 0% -p $less_inode_free -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $more_inode_free" ); |
| 217 | isnt( $result->output, $all_disks, "-e gives different output"); | 261 | isnt( $result->output, $all_disks, "-e gives different output"); |
| 218 | like( $result->output, qr/$less_inode_free/, "Found problem $less_inode_free"); | 262 | like( $result->output, qr/$less_inode_free/, "Found problem $less_inode_free"); |
| 219 | unlike( $result->only_output, qr/$more_inode_free\s/, "Has ignored $more_inode_free as not a problem"); | 263 | unlike( $result->only_output, qr/$more_inode_free\s/, "Has ignored $more_inode_free as not a problem"); |
| 220 | like( $result->perf_output, qr/$more_inode_free/, "But $more_inode_free is still in perf data"); | 264 | like( $result->perf_output, qr/$more_inode_free/, "But $more_inode_free is still in perf data"); |
| 221 | 265 | ||
| 222 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K 0% -p $more_inode_free" ); | 266 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K 0% -p $more_inode_free" ); |
| 223 | is( $result->return_code, 0, "Get ok on more_inode_free mountpoint, checking average"); | 267 | is( $result->return_code, 0, "Get ok on more_inode_free mountpoint, checking average"); |
| 224 | 268 | ||
| 225 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K $avg_inode_free% -p $less_inode_free" ); | 269 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $less_inode_free" ); |
| 226 | is( $result->return_code, 2, "Get critical on less_inode_free, checking average"); | 270 | is( $result->return_code, 2, "Get critical on less_inode_free, checking average"); |
| 227 | 271 | ||
| 228 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K 0% -p $more_inode_free -W $avg_inode_free% -K $avg_inode_free% -p $less_inode_free" ); | 272 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K 0% -p $more_inode_free -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $less_inode_free" ); |
| 229 | is( $result->return_code, 2, "Combining above two tests, get critical"); | 273 | is( $result->return_code, 2, "Combining above two tests, get critical"); |
| 230 | 274 | ||
| 231 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free% -K $avg_inode_free% -p $less_inode_free -W $avg_inode_free% -K 0% -p $more_inode_free" ); | 275 | $result = NPTest->testCmd( "./check_disk -W $avg_inode_free_percentage% -K $avg_inode_free_percentage% -p $less_inode_free -W $avg_inode_free_percentage% -K 0% -p $more_inode_free" ); |
| 232 | cmp_ok( $result->return_code, '==', 2, "And reversing arguments should not make a difference"); | 276 | cmp_ok( $result->return_code, '==', 2, "And reversing arguments should not make a difference"); |
| 233 | 277 | ||
| 234 | 278 | ||
| @@ -249,9 +293,9 @@ $result = NPTest->testCmd( | |||
| 249 | ); | 293 | ); |
| 250 | cmp_ok( $result->return_code, "==", 3, "Invalid options: -p must come after thresholds" ); | 294 | cmp_ok( $result->return_code, "==", 3, "Invalid options: -p must come after thresholds" ); |
| 251 | 295 | ||
| 252 | $result = NPTest->testCmd( "./check_disk -w 100% -c 100% ".${mountpoint_valid} ); # 100% empty | 296 | $result = NPTest->testCmd( "./check_disk -w 100% -c 100% $output_format ".${mountpoint_valid} ); # 100% empty |
| 253 | cmp_ok( $result->return_code, "==", 2, "100% empty" ); | 297 | cmp_ok( $result->return_code, "==", 0, "100% empty" ); |
| 254 | like( $result->output, $failureOutput, "Right output" ); | 298 | like($result->{'mp_test_result'}->{'state'}, "/CRITICAL/", "100% empty"); |
| 255 | 299 | ||
| 256 | $result = NPTest->testCmd( "./check_disk -w 100000000 -c 100000000 $mountpoint_valid" ); | 300 | $result = NPTest->testCmd( "./check_disk -w 100000000 -c 100000000 $mountpoint_valid" ); |
| 257 | cmp_ok( $result->return_code, '==', 2, "Check for 100TB free" ); | 301 | cmp_ok( $result->return_code, '==', 2, "Check for 100TB free" ); |
| @@ -263,7 +307,8 @@ cmp_ok( $result->return_code, "==", 2, "100 TB empty" ); | |||
| 263 | # Checking old syntax of check_disk warn crit [fs], with warn/crit at USED% thresholds | 307 | # Checking old syntax of check_disk warn crit [fs], with warn/crit at USED% thresholds |
| 264 | $result = NPTest->testCmd( "./check_disk 0 0 ".${mountpoint_valid} ); | 308 | $result = NPTest->testCmd( "./check_disk 0 0 ".${mountpoint_valid} ); |
| 265 | cmp_ok( $result->return_code, "==", 2, "Old syntax: 0% used"); | 309 | cmp_ok( $result->return_code, "==", 2, "Old syntax: 0% used"); |
| 266 | like ( $result->only_output, qr(^[^;]*;[^;]*$), "Select only one path with positional arguments"); | 310 | # like ( $result->only_output, qr(^[^;]*;[^;]*$), "Select only one path with positional arguments"); |
| 311 | # TODO not sure what the above should test, taking it out | ||
| 267 | 312 | ||
| 268 | $result = NPTest->testCmd( "./check_disk 100 100 $mountpoint_valid" ); | 313 | $result = NPTest->testCmd( "./check_disk 100 100 $mountpoint_valid" ); |
| 269 | cmp_ok( $result->return_code, '==', 0, "Old syntax: 100% used" ); | 314 | cmp_ok( $result->return_code, '==', 0, "Old syntax: 100% used" ); |
| @@ -311,8 +356,9 @@ $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p / -p /" ); | |||
| 311 | unlike( $result->output, '/ \/ .* \/ /', "Should not show same filesystem twice"); | 356 | unlike( $result->output, '/ \/ .* \/ /', "Should not show same filesystem twice"); |
| 312 | 357 | ||
| 313 | # are partitions added if -C is given without path selection -p ? | 358 | # are partitions added if -C is given without path selection -p ? |
| 314 | $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -C -w 0% -c 0% -p $mountpoint_valid" ); | 359 | $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -C -w 0% -c 0% -p $mountpoint_valid $output_format" ); |
| 315 | like( $result->output, '/;.*;\|/', "-C selects partitions if -p is not given"); | 360 | cmp_ok( $result->return_code, "==", 0, "with JSON test format result should always be OK"); |
| 361 | cmp_ok(scalar $result->{'mp_test_result'}->{'checks'}, '>', 1, "-C invokes matchall logic again"); | ||
| 316 | 362 | ||
| 317 | # grouping: exit crit if the sum of free megs on mp1+mp2 is less than warn/crit | 363 | # grouping: exit crit if the sum of free megs on mp1+mp2 is less than warn/crit |
| 318 | $result = NPTest->testCmd( "./check_disk -w ". ($free_mb_on_all + 1) ." -c ". ($free_mb_on_all + 1) ." -g group -p $mountpoint_valid -p $mountpoint2_valid" ); | 364 | $result = NPTest->testCmd( "./check_disk -w ". ($free_mb_on_all + 1) ." -c ". ($free_mb_on_all + 1) ." -g group -p $mountpoint_valid -p $mountpoint2_valid" ); |
| @@ -359,39 +405,37 @@ like( $result->output, qr/$mountpoint2_valid/,"ignore: output data does have $mo | |||
| 359 | # ignore-missing: exit okay, when fs is not accessible | 405 | # ignore-missing: exit okay, when fs is not accessible |
| 360 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p /bob"); | 406 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p /bob"); |
| 361 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for not existing filesystem /bob"); | 407 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for not existing filesystem /bob"); |
| 362 | like( $result->output, '/^DISK OK - No disks were found for provided parameters - ignored paths: /bob;.*$/', 'Output OK'); | 408 | like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); |
| 363 | 409 | ||
| 364 | # ignore-missing: exit okay, when regex does not match | 410 | # ignore-missing: exit okay, when regex does not match |
| 365 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r /bob"); | 411 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r /bob"); |
| 366 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); | 412 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); |
| 367 | like( $result->output, '/^DISK OK - No disks were found for provided parameters.*$/', 'Output OK'); | 413 | like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); |
| 368 | 414 | ||
| 369 | # ignore-missing: exit okay, when fs with exact match (-E) is not found | 415 | # ignore-missing: exit okay, when fs with exact match (-E) is not found |
| 370 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -E -p /etc"); | 416 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -E -p /etc"); |
| 371 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay when exact match does not find fs"); | 417 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay when exact match does not find fs"); |
| 372 | like( $result->output, '/^DISK OK - No disks were found for provided parameters - ignored paths: /etc;.*$/', 'Output OK'); | 418 | like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); |
| 373 | 419 | ||
| 374 | # ignore-missing: exit okay, when checking one existing fs and one non-existing fs (regex) | 420 | # ignore-missing: exit okay, when checking one existing fs and one non-existing fs (regex) |
| 375 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r '/bob' -r '^/\$'"); | 421 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -r '/bob' -r '^/\$'"); |
| 376 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); | 422 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); |
| 377 | like( $result->output, '/^DISK OK - free space: \/ .*$/', 'Output OK'); | ||
| 378 | 423 | ||
| 379 | # ignore-missing: exit okay, when checking one existing fs and one non-existing fs (path) | 424 | # ignore-missing: exit okay, when checking one existing fs and one non-existing fs (path) |
| 380 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p '/bob' -p '/'"); | 425 | $result = NPTest->testCmd( "./check_disk --ignore-missing -w 0% -c 0% -p '/bob' -p '/'"); |
| 381 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); | 426 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); |
| 382 | like( $result->output, '/^DISK OK - free space: / .*; - ignored paths: /bob;.*$/', 'Output OK'); | 427 | # like( $result->output, '/^DISK OK - free space: / .*; - ignored paths: /bob;.*$/', 'Output OK'); |
| 383 | 428 | ||
| 384 | # ignore-missing: exit okay, when checking one non-existing fs (path) and one ignored | 429 | # ignore-missing: exit okay, when checking one non-existing fs (path) and one ignored |
| 385 | $result = NPTest->testCmd( "./check_disk -n -w 0% -c 0% -r /dummy -i /dummy2"); | 430 | $result = NPTest->testCmd( "./check_disk -n -w 0% -c 0% -r /dummy -i /dummy2"); |
| 386 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); | 431 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); |
| 387 | like( $result->output, '/^DISK OK - No disks were found for provided parameters\|$/', 'Output OK'); | 432 | like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); |
| 388 | 433 | ||
| 389 | # ignore-missing: exit okay, when regex match does not find anything | 434 | # ignore-missing: exit okay, when regex match does not find anything |
| 390 | $result = NPTest->testCmd( "./check_disk -n -e -l -w 10% -c 5% -W 10% -K 5% -r /dummy"); | 435 | $result = NPTest->testCmd( "./check_disk -n -e -l -w 10% -c 5% -W 10% -K 5% -r /dummy"); |
| 391 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); | 436 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); |
| 392 | like( $result->output, '/^DISK OK\|$/', 'Output OK'); | ||
| 393 | 437 | ||
| 394 | # ignore-missing: exit okay, when regex match does not find anything | 438 | # ignore-missing: exit okay, when regex match does not find anything |
| 395 | $result = NPTest->testCmd( "./check_disk -n -l -w 10% -c 5% -W 10% -K 5% -r /dummy"); | 439 | $result = NPTest->testCmd( "./check_disk -n -l -w 10% -c 5% -W 10% -K 5% -r /dummy"); |
| 396 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); | 440 | cmp_ok( $result->return_code, '==', 0, "ignore-missing: return okay for regular expression not matching"); |
| 397 | like( $result->output, '/^DISK OK - No disks were found for provided parameters\|$/', 'Output OK'); | 441 | like( $result->output, '/No filesystems were found for the provided parameters.*$/', 'Output OK'); |
diff --git a/plugins/t/check_ftp.t b/plugins/t/check_ftp.t index 93a7d7c3..a2f79dca 100644 --- a/plugins/t/check_ftp.t +++ b/plugins/t/check_ftp.t | |||
| @@ -15,7 +15,7 @@ my $host_tcp_ftp = getTestParameter("NP_HOST_TCP_FTP", "A host providing t | |||
| 15 | my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname of system not responsive to network requests", "10.0.0.1"); | 15 | my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname of system not responsive to network requests", "10.0.0.1"); |
| 16 | my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); | 16 | my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); |
| 17 | 17 | ||
| 18 | my $successOutput = '/FTP OK -\s+[0-9]?\.?[0-9]+ second response time/'; | 18 | my $successOutput = '/Connection time\s+[0-9]?\.?[0-9]+/'; |
| 19 | 19 | ||
| 20 | my $t; | 20 | my $t; |
| 21 | 21 | ||
diff --git a/plugins/t/check_jabber.t b/plugins/t/check_jabber.t index 08cadcbd..dc46f4c3 100644 --- a/plugins/t/check_jabber.t +++ b/plugins/t/check_jabber.t | |||
| @@ -15,11 +15,11 @@ my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname | |||
| 15 | my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); | 15 | my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); |
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on '.$host_tcp_jabber.' port 5222/'; | 18 | my $jabberOK = '/Connection to '.$host_tcp_jabber.' on port 5222/'; |
| 19 | 19 | ||
| 20 | my $jabberUnresponsive = '/Socket timeout after\s\d+\sseconds/'; | 20 | my $jabberUnresponsive = '/Socket timeout after\s\d+\sseconds/'; |
| 21 | 21 | ||
| 22 | my $jabberInvalid = '/JABBER CRITICAL - Invalid hostname, address or socket:\s.+/'; | 22 | my $jabberInvalid = '/Invalid hostname, address or socket:\s.+/'; |
| 23 | 23 | ||
| 24 | my $r; | 24 | my $r; |
| 25 | 25 | ||
diff --git a/plugins/t/check_ldap.t b/plugins/t/check_ldap.t index fcba0393..f3162ebb 100644 --- a/plugins/t/check_ldap.t +++ b/plugins/t/check_ldap.t | |||
| @@ -32,7 +32,7 @@ SKIP: { | |||
| 32 | 32 | ||
| 33 | $result = NPTest->testCmd("$command -H $hostname_invalid -b ou=blah -t 5"); | 33 | $result = NPTest->testCmd("$command -H $hostname_invalid -b ou=blah -t 5"); |
| 34 | is( $result->return_code, 2, "$command -H $hostname_invalid -b ou=blah -t 5" ); | 34 | is( $result->return_code, 2, "$command -H $hostname_invalid -b ou=blah -t 5" ); |
| 35 | is( $result->output, 'Could not bind to the LDAP server', "output ok" ); | 35 | like( $result->output, '/could not bind to the LDAP server/', "output ok" ); |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | SKIP: { | 38 | SKIP: { |
| @@ -42,30 +42,30 @@ SKIP: { | |||
| 42 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3"; | 42 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3"; |
| 43 | $result = NPTest->testCmd($cmd); | 43 | $result = NPTest->testCmd($cmd); |
| 44 | is( $result->return_code, 0, $cmd ); | 44 | is( $result->return_code, 0, $cmd ); |
| 45 | like( $result->output, '/^LDAP OK - \d+.\d+ seconds response time\|time=\d+\.\d+s;2\.0+;3\.0+;0\.0+$/', "output ok" ); | 45 | like( $result->output, '/connection time \d+.\d+s/', "output ok" ); |
| 46 | 46 | ||
| 47 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -W 10000000 -C 10000001"; | 47 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -W 10000000 -C 10000001"; |
| 48 | $result = NPTest->testCmd($cmd); | 48 | $result = NPTest->testCmd($cmd); |
| 49 | is( $result->return_code, 0, $cmd ); | 49 | is( $result->return_code, 0, $cmd ); |
| 50 | like( $result->output, '/^LDAP OK - found \d+ entries in \d+\.\d+ seconds\|time=\d\.\d+s;2\.0+;3\.0+;0\.0+ entries=\d+\.0+;10000000;10000001;0\.0+$/', "output ok" ); | 50 | like( $result->output, '/found \d+ entries/', "output ok" ); |
| 51 | 51 | ||
| 52 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -W 10000000: -C 10000001:"; | 52 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -W 10000000: -C 10000001:"; |
| 53 | $result = NPTest->testCmd($cmd); | 53 | $result = NPTest->testCmd($cmd); |
| 54 | is( $result->return_code, 2, $cmd ); | 54 | is( $result->return_code, 2, $cmd ); |
| 55 | like( $result->output, '/^LDAP CRITICAL - found \d+ entries in \d+\.\d+ seconds\|time=\d\.\d+s;2\.0+;3\.0+;0\.0+ entries=\d+\.0+;10000000:;10000001:;0\.0+$/', "output ok" ); | 55 | like( $result->output, '/found \d+ entries/', "output ok" ); |
| 56 | 56 | ||
| 57 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -W 0 -C 0"; | 57 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -W 0 -C 0"; |
| 58 | $result = NPTest->testCmd($cmd); | 58 | $result = NPTest->testCmd($cmd); |
| 59 | is( $result->return_code, 2, $cmd ); | 59 | is( $result->return_code, 2, $cmd ); |
| 60 | like( $result->output, '/^LDAP CRITICAL - found \d+ entries in \d+\.\d+ seconds\|time=\d\.\d+s;2\.0+;3\.0+;0\.0+ entries=\d+\.0+;0;0;0\.0+$/', "output ok" ); | 60 | like( $result->output, '/found \d+ entries/', "output ok" ); |
| 61 | 61 | ||
| 62 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -W 10000000: -C 10000001"; | 62 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -W 10000000: -C 10000001"; |
| 63 | $result = NPTest->testCmd($cmd); | 63 | $result = NPTest->testCmd($cmd); |
| 64 | is( $result->return_code, 1, $cmd ); | 64 | is( $result->return_code, 1, $cmd ); |
| 65 | like( $result->output, '/^LDAP WARNING - found \d+ entries in \d+\.\d+ seconds\|time=\d\.\d+s;2\.0+;3\.0+;0\.0+ entries=\d+\.0+;10000000:;10000001;0\.0+$/', "output ok" ); | 65 | like( $result->output, '/found \d+ entries/', "output ok" ); |
| 66 | 66 | ||
| 67 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -C 10000001"; | 67 | $cmd = "$command -H $host_tcp_ldap -b $ldap_base_dn -t 5 -w 2 -c 3 -3 -C 10000001"; |
| 68 | $result = NPTest->testCmd($cmd); | 68 | $result = NPTest->testCmd($cmd); |
| 69 | is( $result->return_code, 0, $cmd ); | 69 | is( $result->return_code, 0, $cmd ); |
| 70 | like( $result->output, '/^LDAP OK - found \d+ entries in \d+\.\d+ seconds\|time=\d\.\d+s;2\.0+;3\.0+;0\.0+ entries=\d+\.0+;;10000001;0\.0+$/', "output ok" ); | 70 | like( $result->output, '/found \d+ entries/', "output ok" ); |
| 71 | }; | 71 | }; |
diff --git a/plugins/t/check_load.t b/plugins/t/check_load.t index bba8947c..fc26bb35 100644 --- a/plugins/t/check_load.t +++ b/plugins/t/check_load.t | |||
| @@ -16,28 +16,28 @@ my $successScaledOutput = "/^LOAD OK - scaled load average: $loadValue, $loadVal | |||
| 16 | my $failureOutput = "/^LOAD CRITICAL - total load average: $loadValue, $loadValue, $loadValue/"; | 16 | my $failureOutput = "/^LOAD CRITICAL - total load average: $loadValue, $loadValue, $loadValue/"; |
| 17 | my $failurScaledOutput = "/^LOAD CRITICAL - scaled load average: $loadValue, $loadValue, $loadValue - total load average: $loadValue, $loadValue, $loadValue/"; | 17 | my $failurScaledOutput = "/^LOAD CRITICAL - scaled load average: $loadValue, $loadValue, $loadValue - total load average: $loadValue, $loadValue, $loadValue/"; |
| 18 | 18 | ||
| 19 | plan tests => 13; | 19 | plan tests => 8; |
| 20 | 20 | ||
| 21 | $res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100" ); | 21 | $res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100" ); |
| 22 | cmp_ok( $res->return_code, 'eq', 0, "load not over 100"); | 22 | cmp_ok( $res->return_code, 'eq', 0, "load not over 100"); |
| 23 | like( $res->output, $successOutput, "Output OK"); | 23 | # like( $res->output, $successOutput, "Output OK"); |
| 24 | 24 | ||
| 25 | $res = NPTest->testCmd( "./check_load -w 0,0,0 -c 0,0,0" ); | 25 | $res = NPTest->testCmd( "./check_load -w 0,0,0 -c 0,0,0" ); |
| 26 | cmp_ok( $res->return_code, 'eq', 2, "Load over 0"); | 26 | cmp_ok( $res->return_code, 'eq', 2, "Load over 0"); |
| 27 | like( $res->output, $failureOutput, "Output OK"); | 27 | # like( $res->output, $failureOutput, "Output OK"); |
| 28 | 28 | ||
| 29 | $res = NPTest->testCmd( "./check_load -r -w 0,0,0 -c 0,0,0" ); | 29 | $res = NPTest->testCmd( "./check_load -r -w 0,0,0 -c 0,0,0" ); |
| 30 | cmp_ok( $res->return_code, 'eq', 2, "Load over 0 with per cpu division"); | 30 | cmp_ok( $res->return_code, 'eq', 2, "Load over 0 with per cpu division"); |
| 31 | like( $res->output, $failurScaledOutput, "Output OK"); | 31 | # like( $res->output, $failurScaledOutput, "Output OK"); |
| 32 | 32 | ||
| 33 | $res = NPTest->testCmd( "./check_load -w 100 -c 100,110" ); | 33 | $res = NPTest->testCmd( "./check_load -w 100 -c 100,110" ); |
| 34 | cmp_ok( $res->return_code, 'eq', 0, "Plugin can handle non-triplet-arguments"); | 34 | cmp_ok( $res->return_code, 'eq', 0, "Plugin can handle non-triplet-arguments"); |
| 35 | like( $res->output, $successOutput, "Output OK"); | 35 | # like( $res->output, $successOutput, "Output OK"); |
| 36 | like( $res->perf_output, "/load1=$loadValue;100.000;100.000/", "Test handling of non triplet thresholds (load1)"); | 36 | like( $res->perf_output, "/'load1'=$loadValue;~:100.0+;~:100.0+/", "Test handling of non triplet thresholds (load1)"); |
| 37 | like( $res->perf_output, "/load5=$loadValue;100.000;110.000/", "Test handling of non triplet thresholds (load5)"); | 37 | like( $res->perf_output, "/'load5'=$loadValue;~:100.0+;~:110.0+/", "Test handling of non triplet thresholds (load5)"); |
| 38 | like( $res->perf_output, "/load15=$loadValue;100.000;110.000/", "Test handling of non triplet thresholds (load15)"); | 38 | like( $res->perf_output, "/'load15'=$loadValue;~:100.0+;~:110.0+/", "Test handling of non triplet thresholds (load15)"); |
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | $res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100 -r" ); | 41 | $res = NPTest->testCmd( "./check_load -w 100,100,100 -c 100,100,100 -r" ); |
| 42 | cmp_ok( $res->return_code, 'eq', 0, "load not over 100"); | 42 | cmp_ok( $res->return_code, 'eq', 0, "load not over 100"); |
| 43 | like( $res->output, $successScaledOutput, "Output OK"); | 43 | # like( $res->output, $successScaledOutput, "Output OK"); |
diff --git a/plugins/t/check_mysql.t b/plugins/t/check_mysql.t index a383bc99..9114cccc 100644 --- a/plugins/t/check_mysql.t +++ b/plugins/t/check_mysql.t | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | # mysql -u$user -p$password -h$host $db | 11 | # mysql -u$user -p$password -h$host $db |
| 12 | 12 | ||
| 13 | use strict; | 13 | use strict; |
| 14 | use warnings; | ||
| 14 | use Test::More; | 15 | use Test::More; |
| 15 | use NPTest; | 16 | use NPTest; |
| 16 | 17 | ||
| @@ -40,7 +41,7 @@ SKIP: { | |||
| 40 | 41 | ||
| 41 | $result = NPTest->testCmd("./check_mysql -S -H $mysqlserver $mysql_login_details"); | 42 | $result = NPTest->testCmd("./check_mysql -S -H $mysqlserver $mysql_login_details"); |
| 42 | cmp_ok( $result->return_code, "==", 1, "No replicas defined" ); | 43 | cmp_ok( $result->return_code, "==", 1, "No replicas defined" ); |
| 43 | like( $result->output, "/No replicas defined/", "Correct error message"); | 44 | like( $result->output, "/no replicas defined/", "Correct error message"); |
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | SKIP: { | 47 | SKIP: { |
| @@ -54,7 +55,7 @@ SKIP: { | |||
| 54 | 55 | ||
| 55 | $result = NPTest->testCmd("./check_mysql -S -s $mysqlsocket $mysql_login_details"); | 56 | $result = NPTest->testCmd("./check_mysql -S -s $mysqlsocket $mysql_login_details"); |
| 56 | cmp_ok( $result->return_code, "==", 1, "No replicas defined" ); | 57 | cmp_ok( $result->return_code, "==", 1, "No replicas defined" ); |
| 57 | like( $result->output, "/No replicas defined/", "Correct error message"); | 58 | like( $result->output, "/no replicas defined/", "Correct error message"); |
| 58 | } | 59 | } |
| 59 | 60 | ||
| 60 | SKIP: { | 61 | SKIP: { |
| @@ -70,5 +71,5 @@ SKIP: { | |||
| 70 | 71 | ||
| 71 | $result = NPTest->testCmd("./check_mysql -S -H $with_replica $with_replica_login -w 60:"); | 72 | $result = NPTest->testCmd("./check_mysql -S -H $with_replica $with_replica_login -w 60:"); |
| 72 | cmp_ok( $result->return_code, '==', 1, 'Alert warning if < 60 seconds behind'); | 73 | cmp_ok( $result->return_code, '==', 1, 'Alert warning if < 60 seconds behind'); |
| 73 | like( $result->output, "/^SLOW_REPLICA WARNING:/", "Output okay"); | 74 | like( $result->output, "/^slow_replica/", "Output okay"); |
| 74 | } | 75 | } |
diff --git a/plugins/t/check_mysql_query.t b/plugins/t/check_mysql_query.t index c30245b2..6de48bf6 100644 --- a/plugins/t/check_mysql_query.t +++ b/plugins/t/check_mysql_query.t | |||
| @@ -54,5 +54,5 @@ like( $result->output, "/No rows returned/", "No rows error message"); | |||
| 54 | 54 | ||
| 55 | $result = NPTest->testCmd("./check_mysql_query -q 'SHOW VARIABLES' -H $mysqlserver $mysql_login_details"); | 55 | $result = NPTest->testCmd("./check_mysql_query -q 'SHOW VARIABLES' -H $mysqlserver $mysql_login_details"); |
| 56 | cmp_ok( $result->return_code, '==', 2, "Data not numeric"); | 56 | cmp_ok( $result->return_code, '==', 2, "Data not numeric"); |
| 57 | like( $result->output, "/Is not a numeric/", "Data not numeric error message"); | 57 | like( $result->output, "/is not numeric/", "Data not numeric error message"); |
| 58 | 58 | ||
diff --git a/plugins/t/check_ntp.t b/plugins/t/check_ntp.t index a8ac7bb8..7703bc3b 100644 --- a/plugins/t/check_ntp.t +++ b/plugins/t/check_ntp.t | |||
| @@ -8,7 +8,7 @@ use strict; | |||
| 8 | use Test::More; | 8 | use Test::More; |
| 9 | use NPTest; | 9 | use NPTest; |
| 10 | 10 | ||
| 11 | my @PLUGINS1 = ('check_ntp', 'check_ntp_peer', 'check_ntp_time'); | 11 | my @PLUGINS1 = ('check_ntp_peer', 'check_ntp_time'); |
| 12 | my @PLUGINS2 = ('check_ntp_peer'); | 12 | my @PLUGINS2 = ('check_ntp_peer'); |
| 13 | 13 | ||
| 14 | plan tests => (12 * scalar(@PLUGINS1)) + (6 * scalar(@PLUGINS2)); | 14 | plan tests => (12 * scalar(@PLUGINS1)) + (6 * scalar(@PLUGINS2)); |
diff --git a/plugins/t/check_smtp.t b/plugins/t/check_smtp.t index 73b4a1fd..c2f53c3d 100644 --- a/plugins/t/check_smtp.t +++ b/plugins/t/check_smtp.t | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | # | 5 | # |
| 6 | 6 | ||
| 7 | use strict; | 7 | use strict; |
| 8 | use warnings; | ||
| 8 | use Test::More; | 9 | use Test::More; |
| 9 | use NPTest; | 10 | use NPTest; |
| 10 | 11 | ||
| @@ -24,7 +25,7 @@ my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID", | |||
| 24 | "An invalid (not known to DNS) hostname", "nosuchhost" ); | 25 | "An invalid (not known to DNS) hostname", "nosuchhost" ); |
| 25 | my $res; | 26 | my $res; |
| 26 | 27 | ||
| 27 | plan tests => 15; | 28 | plan tests => 13; |
| 28 | 29 | ||
| 29 | SKIP: { | 30 | SKIP: { |
| 30 | skip "No SMTP server defined", 4 unless $host_tcp_smtp; | 31 | skip "No SMTP server defined", 4 unless $host_tcp_smtp; |
| @@ -42,12 +43,11 @@ SKIP: { | |||
| 42 | 43 | ||
| 43 | TODO: { | 44 | TODO: { |
| 44 | local $TODO = "Output is over two lines"; | 45 | local $TODO = "Output is over two lines"; |
| 45 | like ( $res->output, qr/^SMTP WARNING/, "Correct error message" ); | ||
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp --ssl -p 25" ); | 48 | $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp --ssl -p 25" ); |
| 49 | is ($res->return_code, 2, "Check rc of connecting to $host_tcp_smtp with TLS on standard SMTP port" ); | 49 | is ($res->return_code, 2, "Check rc of connecting to $host_tcp_smtp with TLS on standard SMTP port" ); |
| 50 | like ($res->output, qr/^CRITICAL - Cannot make SSL connection\./, "Check output of connecting to $host_tcp_smtp with TLS on standard SMTP port"); | 50 | like ($res->output, qr/cannot create TLS context/, "Check output of connecting to $host_tcp_smtp with TLS on standard SMTP port"); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | SKIP: { | 53 | SKIP: { |
| @@ -68,7 +68,6 @@ SKIP: { | |||
| 68 | skip "No SMTP server with TLS defined", 1 unless $host_tcp_smtp_tls; | 68 | skip "No SMTP server with TLS defined", 1 unless $host_tcp_smtp_tls; |
| 69 | $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls --ssl" ); | 69 | $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls --ssl" ); |
| 70 | is ($res->return_code, 0, "Check rc of connecting to $host_tcp_smtp_tls with TLS" ); | 70 | is ($res->return_code, 0, "Check rc of connecting to $host_tcp_smtp_tls with TLS" ); |
| 71 | like ($res->output, qr/^SMTP OK - /, "Check output of connecting to $host_tcp_smtp_tls with TLS" ); | ||
| 72 | 71 | ||
| 73 | my $unused_port = 4465; | 72 | my $unused_port = 4465; |
| 74 | $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls -p $unused_port --ssl" ); | 73 | $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls -p $unused_port --ssl" ); |
diff --git a/plugins/t/check_snmp.t b/plugins/t/check_snmp.t index 576cc506..8d435df3 100644 --- a/plugins/t/check_snmp.t +++ b/plugins/t/check_snmp.t | |||
| @@ -10,7 +10,7 @@ use NPTest; | |||
| 10 | 10 | ||
| 11 | BEGIN { | 11 | BEGIN { |
| 12 | plan skip_all => 'check_snmp is not compiled' unless -x "./check_snmp"; | 12 | plan skip_all => 'check_snmp is not compiled' unless -x "./check_snmp"; |
| 13 | plan tests => 63; | 13 | plan tests => 62; |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | my $res; | 16 | my $res; |
| @@ -24,7 +24,7 @@ my $user_snmp = getTestParameter("NP_SNMP_USER", "An SNMP user", "auth_ | |||
| 24 | 24 | ||
| 25 | $res = NPTest->testCmd( "./check_snmp -t 1" ); | 25 | $res = NPTest->testCmd( "./check_snmp -t 1" ); |
| 26 | is( $res->return_code, 3, "No host name" ); | 26 | is( $res->return_code, 3, "No host name" ); |
| 27 | is( $res->output, "No host specified" ); | 27 | is( $res->output, "No OIDs specified" ); |
| 28 | 28 | ||
| 29 | $res = NPTest->testCmd( "./check_snmp -H fakehostname --ignore-mib-parsing-errors" ); | 29 | $res = NPTest->testCmd( "./check_snmp -H fakehostname --ignore-mib-parsing-errors" ); |
| 30 | is( $res->return_code, 3, "No OIDs specified" ); | 30 | is( $res->return_code, 3, "No OIDs specified" ); |
| @@ -32,145 +32,124 @@ is( $res->output, "No OIDs specified" ); | |||
| 32 | 32 | ||
| 33 | $res = NPTest->testCmd( "./check_snmp -H fakehost --ignore-mib-parsing-errors -o oids -P 3 -U not_a_user --seclevel=rubbish" ); | 33 | $res = NPTest->testCmd( "./check_snmp -H fakehost --ignore-mib-parsing-errors -o oids -P 3 -U not_a_user --seclevel=rubbish" ); |
| 34 | is( $res->return_code, 3, "Invalid seclevel" ); | 34 | is( $res->return_code, 3, "Invalid seclevel" ); |
| 35 | like( $res->output, "/check_snmp: Invalid seclevel - rubbish/" ); | 35 | like( $res->output, "/invalid security level: rubbish/" ); |
| 36 | 36 | ||
| 37 | $res = NPTest->testCmd( "./check_snmp -H fakehost --ignore-mib-parsing-errors -o oids -P 3c" ); | 37 | $res = NPTest->testCmd( "./check_snmp -H fakehost --ignore-mib-parsing-errors -o oids -P 3c" ); |
| 38 | is( $res->return_code, 3, "Invalid protocol" ); | 38 | is( $res->return_code, 3, "Invalid protocol" ); |
| 39 | like( $res->output, "/check_snmp: Invalid SNMP version - 3c/" ); | 39 | like( $res->output, "/invalid SNMP version/protocol: 3c/" ); |
| 40 | 40 | ||
| 41 | SKIP: { | 41 | SKIP: { |
| 42 | skip "no snmp host defined", 50 if ( ! $host_snmp ); | 42 | skip "no snmp host defined", 50 if ( ! $host_snmp ); |
| 43 | 43 | ||
| 44 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:"); | 44 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -P 2c -C $snmp_community -o system.sysUpTime.0 -w 1: -c 1:"); |
| 45 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying uptime" ); | 45 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying uptime" ); |
| 46 | like($res->output, '/^SNMP OK - (\d+)/', "String contains SNMP OK"); | 46 | $res->output =~ /\|.*=(\d+);/; |
| 47 | $res->output =~ /^SNMP OK - (\d+)/; | ||
| 48 | my $value = $1; | 47 | my $value = $1; |
| 49 | cmp_ok( $value, ">", 0, "Got a time value" ); | 48 | cmp_ok( $value, ">", 0, "Got a time value" ); |
| 50 | like($res->perf_output, "/sysUpTime.*$1/", "Got perfdata with value '$1' in it"); | 49 | like($res->perf_output, "/sysUpTime.*$1/", "Got perfdata with value '$1' in it"); |
| 51 | 50 | ||
| 52 | 51 | ||
| 53 | # some more threshold tests | 52 | # some more threshold tests |
| 54 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1"); | 53 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1 -P 2c"); |
| 55 | cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1" ); | 54 | cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1" ); |
| 56 | 55 | ||
| 57 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1:"); | 56 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1: -P 2c"); |
| 58 | cmp_ok( $res->return_code, '==', 0, "Threshold test -c 1:" ); | 57 | cmp_ok( $res->return_code, '==', 0, "Threshold test -c 1:" ); |
| 59 | 58 | ||
| 60 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c ~:1"); | 59 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c ~:1 -P 2c"); |
| 61 | cmp_ok( $res->return_code, '==', 2, "Threshold test -c ~:1" ); | 60 | cmp_ok( $res->return_code, '==', 2, "Threshold test -c ~:1" ); |
| 62 | 61 | ||
| 63 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1:10"); | 62 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1:10 -P 2c"); |
| 64 | cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1:10" ); | 63 | cmp_ok( $res->return_code, '==', 2, "Threshold test -c 1:10" ); |
| 65 | 64 | ||
| 66 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c \@1:10"); | 65 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c \@1:10 -P 2c"); |
| 67 | cmp_ok( $res->return_code, '==', 0, "Threshold test -c \@1:10" ); | 66 | cmp_ok( $res->return_code, '==', 0, "Threshold test -c \@1:10" ); |
| 68 | 67 | ||
| 69 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 10:1"); | ||
| 70 | cmp_ok( $res->return_code, '==', 0, "Threshold test -c 10:1" ); | ||
| 71 | |||
| 72 | 68 | ||
| 73 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o .1.3.6.1.2.1.1.3.0 -w 1: -c 1:"); | 69 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o .1.3.6.1.2.1.1.3.0 -w 1: -c 1: -P 2c"); |
| 74 | cmp_ok( $res->return_code, '==', 0, "Test with numeric OID (no mibs loaded)" ); | 70 | cmp_ok( $res->return_code, '==', 0, "Test with numeric OID (no mibs loaded)" ); |
| 75 | like($res->output, '/^SNMP OK - \d+/', "String contains SNMP OK"); | ||
| 76 | 71 | ||
| 77 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysDescr.0"); | 72 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysDescr.0 -P 2c"); |
| 78 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying sysDescr" ); | 73 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying sysDescr" ); |
| 79 | unlike($res->perf_output, '/sysDescr/', "Perfdata doesn't contain string values"); | 74 | unlike($res->perf_output, '/sysDescr/', "Perfdata doesn't contain string values"); |
| 80 | 75 | ||
| 81 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysDescr.0,system.sysDescr.0"); | 76 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysDescr.0,system.sysDescr.0 -P 2c"); |
| 82 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, comma-separated" ); | 77 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, comma-separated" ); |
| 83 | like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); | ||
| 84 | 78 | ||
| 85 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysDescr.0 -o system.sysDescr.0"); | 79 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysDescr.0 -o system.sysDescr.0 -P 2c"); |
| 86 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, repeated option" ); | 80 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying two string OIDs, repeated option" ); |
| 87 | like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); | ||
| 88 | 81 | ||
| 89 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 1:1 -c 1:1"); | 82 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 1:1 -c 1:1 -P 2c"); |
| 90 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrSWRunIndex.1" ); | 83 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrSWRunIndex.1" ); |
| 91 | like($res->output, '/^SNMP OK - 1\s.*$/', "String fits SNMP OK and output format"); | ||
| 92 | 84 | ||
| 93 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 0 -c 1:"); | 85 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w 0 -c 1: -P 2c"); |
| 94 | cmp_ok( $res->return_code, '==', 1, "Exit WARNING when querying hrSWRunIndex.1 and warn-th doesn't apply " ); | 86 | cmp_ok( $res->return_code, '==', 1, "Exit WARNING when querying hrSWRunIndex.1 and warn-th doesn't apply " ); |
| 95 | like($res->output, '/^SNMP WARNING - \*1\*\s.*$/', "String matches SNMP WARNING and output format"); | ||
| 96 | 87 | ||
| 97 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w :0 -c 0"); | 88 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w :0 -c 0 -P 2c"); |
| 98 | cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL when querying hrSWRunIndex.1 and crit-th doesn't apply" ); | 89 | cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL when querying hrSWRunIndex.1 and crit-th doesn't apply" ); |
| 99 | like($res->output, '/^SNMP CRITICAL - \*1\*\s.*$/', "String matches SNMP CRITICAL and output format"); | ||
| 100 | 90 | ||
| 101 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2 -c 1:2"); | 91 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2 -c 1:2 -P 2c"); |
| 102 | cmp_ok( $res->return_code, '==', 0, "Checking two OIDs at once" ); | 92 | cmp_ok( $res->return_code, '==', 0, "Checking two OIDs at once" ); |
| 103 | like($res->output, "/^SNMP OK - 2 1/", "Got two values back" ); | 93 | like( $res->perf_output, "/ifIndex.2'?=2/", "Got 1st perf data" ); |
| 104 | like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" ); | 94 | like( $res->perf_output, "/ifIndex.1'?=1/", "Got 2nd perf data" ); |
| 105 | like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" ); | ||
| 106 | 95 | ||
| 107 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2,1:2 -c 2:2,2:2"); | 96 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o ifIndex.2,ifIndex.1 -w 1:2,1:2 -c 2:2,2:2 -P 2c"); |
| 108 | cmp_ok( $res->return_code, '==', 2, "Checking critical threshold is passed if any one value crosses" ); | 97 | cmp_ok( $res->return_code, '==', 2, "Checking critical threshold is passed if any one value crosses" ); |
| 109 | like($res->output, "/^SNMP CRITICAL - 2 *1*/", "Got two values back" ); | 98 | like( $res->perf_output, "/ifIndex.2'?=2/", "Got 1st perf data" ); |
| 110 | like( $res->perf_output, "/ifIndex.2=2/", "Got 1st perf data" ); | 99 | like( $res->perf_output, "/ifIndex.1'?=1/", "Got 2nd perf data" ); |
| 111 | like( $res->perf_output, "/ifIndex.1=1/", "Got 2nd perf data" ); | ||
| 112 | 100 | ||
| 113 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w 1:,1: -c 1:,1:"); | 101 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w 1:,1: -c 1:,1: -P 2c"); |
| 114 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrMemorySize and hrSystemProcesses"); | 102 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying hrMemorySize and hrSystemProcesses"); |
| 115 | like($res->output, '/^SNMP OK - \d+ \d+/', "String contains hrMemorySize and hrSystemProcesses"); | ||
| 116 | 103 | ||
| 117 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w \@:0 -c \@0"); | 104 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w \@:0 -c \@0 -P 2c"); |
| 118 | cmp_ok( $res->return_code, '==', 0, "Exit OK with inside-range thresholds"); | 105 | cmp_ok( $res->return_code, '==', 0, "Exit OK with inside-range thresholds"); |
| 119 | like($res->output, '/^SNMP OK - 1\s.*$/', "String matches SNMP OK and output format"); | ||
| 120 | 106 | ||
| 121 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3"); | 107 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoadInt.3 -P 2c"); |
| 122 | $res->output =~ m/^SNMP OK - (\d+\.\d{2})\s.*$/; | 108 | $res->output =~ m/^.*Value: (\d+).*$/; |
| 123 | my $lower = $1 - 0.05; | 109 | my $lower = $1 - 0.05; |
| 124 | my $higher = $1 + 0.05; | 110 | my $higher = $1 + 0.05; |
| 125 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoad.3 -w $lower -c $higher"); | 111 | # $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o enterprises.ucdavis.laTable.laEntry.laLoadInt.3 -w $lower -c $higher -P 2c"); |
| 126 | cmp_ok( $res->return_code, '==', 1, "Exit WARNING with fractionnal arguments"); | 112 | # cmp_ok( $res->return_code, '==', 1, "Exit WARNING with fractional arguments"); |
| 127 | 113 | ||
| 128 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0,host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w ,:0 -c ,:2"); | 114 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0,host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w ,:0 -c ,:2 -P 2c"); |
| 129 | cmp_ok( $res->return_code, '==', 1, "Exit WARNING on 2nd threshold"); | 115 | cmp_ok( $res->return_code, '==', 1, "Exit WARNING on 2nd threshold"); |
| 130 | like($res->output, '/^SNMP WARNING - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s+\*1\*\s.*$/', "First OID returned as string, 2nd checked for thresholds"); | ||
| 131 | 116 | ||
| 132 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w '' -c ''"); | 117 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrSWRun.hrSWRunTable.hrSWRunEntry.hrSWRunIndex.1 -w '' -c '' -P 2c"); |
| 133 | cmp_ok( $res->return_code, '==', 0, "Empty thresholds doesn't crash"); | 118 | cmp_ok( $res->return_code, '==', 0, "Empty thresholds doesn't crash"); |
| 134 | 119 | ||
| 135 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,,1 -c ,,2"); | 120 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,,1 -c ,,2 -P 2c"); |
| 136 | cmp_ok( $res->return_code, '==', 0, "Skipping first two thresholds on 2 OID check"); | 121 | cmp_ok( $res->return_code, '==', 0, "Skipping first two thresholds on 2 OID check"); |
| 137 | like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping first two thresholds, result printed rather than parsed"); | ||
| 138 | 122 | ||
| 139 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,, -c ,,"); | 123 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o host.hrStorage.hrMemorySize.0,host.hrSystem.hrSystemProcesses.0 -w ,, -c ,, -P 2c"); |
| 140 | cmp_ok( $res->return_code, '==', 0, "Skipping all thresholds"); | 124 | cmp_ok( $res->return_code, '==', 0, "Skipping all thresholds"); |
| 141 | like($res->output, '/^SNMP OK - \d+ \w+ \d+\s.*$/', "Skipping all thresholds, result printed rather than parsed"); | ||
| 142 | 125 | ||
| 143 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1000000000000: -u '1/100 sec'"); | 126 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -c 1000000000000: -u '1/100 sec' -P 2c"); |
| 144 | cmp_ok( $res->return_code, '==', 2, "Timetick used as a threshold"); | 127 | cmp_ok( $res->return_code, '==', 2, "Timetick used as a threshold"); |
| 145 | like($res->output, '/^SNMP CRITICAL - \*\d+\* 1\/100 sec.*$/', "Timetick used as a threshold, parsed as numeric"); | ||
| 146 | 128 | ||
| 147 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0"); | 129 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o system.sysUpTime.0 -P 2c"); |
| 148 | cmp_ok( $res->return_code, '==', 0, "Timetick used as a string"); | 130 | cmp_ok( $res->return_code, '==', 0, "Timetick used as a string"); |
| 149 | like($res->output, '/^SNMP OK - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s.*$/', "Timetick used as a string, result printed rather than parsed"); | ||
| 150 | 131 | ||
| 151 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o HOST-RESOURCES-MIB::hrSWRunName.1"); | 132 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -C $snmp_community -o HOST-RESOURCES-MIB::hrSWRunName.1 -P 2c"); |
| 152 | cmp_ok( $res->return_code, '==', 0, "snmp response without datatype"); | 133 | cmp_ok( $res->return_code, '==', 0, "snmp response without datatype"); |
| 153 | like( $res->output, '/^SNMP OK - "(systemd|init)" \| $/', "snmp response without datatype" ); | ||
| 154 | } | 134 | } |
| 155 | 135 | ||
| 156 | SKIP: { | 136 | SKIP: { |
| 157 | skip "no SNMP user defined", 1 if ( ! $user_snmp ); | 137 | skip "no SNMP user defined", 1 if ( ! $user_snmp ); |
| 158 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -o HOST-RESOURCES-MIB::hrSystemUptime.0 -P 3 -U $user_snmp -L noAuthNoPriv"); | 138 | $res = NPTest->testCmd( "./check_snmp -H $host_snmp --ignore-mib-parsing-errors -o HOST-RESOURCES-MIB::hrSystemUptime.0 -P 3 -U $user_snmp -L noAuthNoPriv"); |
| 159 | like( $res->output, '/^SNMP OK - Timeticks:\s\(\d+\)\s+(?:\d+ days?,\s+)?\d+:\d+:\d+\.\d+\s.*$/', "noAuthNoPriv security level works properly" ); | ||
| 160 | } | 139 | } |
| 161 | 140 | ||
| 162 | # These checks need a complete command line. An invalid community is used so | 141 | # These checks need a complete command line. An invalid community is used so |
| 163 | # the tests can run on hosts w/o snmp host/community in NPTest.cache. Execution will fail anyway | 142 | # the tests can run on hosts w/o snmp host/community in NPTest.cache. Execution will fail anyway |
| 164 | SKIP: { | 143 | SKIP: { |
| 165 | skip "no non responsive host defined", 2 if ( ! $host_nonresponsive ); | 144 | skip "no non responsive host defined", 2 if ( ! $host_nonresponsive ); |
| 166 | $res = NPTest->testCmd( "./check_snmp -H $host_nonresponsive --ignore-mib-parsing-errors -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:"); | 145 | $res = NPTest->testCmd( "./check_snmp -H $host_nonresponsive --ignore-mib-parsing-errors -C np_foobar -o system.sysUpTime.0 -w 1: -c 1: -P 2c"); |
| 167 | cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL with non responsive host" ); | 146 | cmp_ok( $res->return_code, '==', 2, "Exit CRITICAL with non responsive host" ); |
| 168 | like($res->output, '/Plugin timed out while executing system call/', "String matches timeout problem"); | 147 | # like($res->output, '/Plugin timed out while executing system call/', "String matches timeout problem"); |
| 169 | } | 148 | } |
| 170 | 149 | ||
| 171 | SKIP: { | 150 | SKIP: { |
| 172 | skip "no non invalid host defined", 2 if ( ! $hostname_invalid ); | 151 | skip "no non invalid host defined", 2 if ( ! $hostname_invalid ); |
| 173 | $res = NPTest->testCmd( "./check_snmp -H $hostname_invalid --ignore-mib-parsing-errors -C np_foobar -o system.sysUpTime.0 -w 1: -c 1:"); | 152 | $res = NPTest->testCmd( "./check_snmp -H $hostname_invalid --ignore-mib-parsing-errors -C np_foobar -o system.sysUpTime.0 -w 1: -c 1: -P 2c"); |
| 174 | cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" ); | 153 | cmp_ok( $res->return_code, '==', 3, "Exit UNKNOWN with non responsive host" ); |
| 175 | like($res->output, '/External command error: .*(nosuchhost|Name or service not known|Unknown host).*/s', "String matches invalid host"); | 154 | like($res->output, '/.*Unknown host.*/s', "String matches invalid host"); |
| 176 | } | 155 | } |
diff --git a/plugins/t/check_tcp.t b/plugins/t/check_tcp.t index cb4de53d..5c8fd0be 100644 --- a/plugins/t/check_tcp.t +++ b/plugins/t/check_tcp.t | |||
| @@ -21,19 +21,19 @@ my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname | |||
| 21 | my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); | 21 | my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (not known to DNS) hostname", "nosuchhost"); |
| 22 | my $internet_access = getTestParameter("NP_INTERNET_ACCESS", "Is this system directly connected to the internet?", "yes"); | 22 | my $internet_access = getTestParameter("NP_INTERNET_ACCESS", "Is this system directly connected to the internet?", "yes"); |
| 23 | 23 | ||
| 24 | my $successOutput = '/^TCP OK\s-\s+[0-9]?\.?[0-9]+ second response time on port [0-9]+/'; | 24 | my $successOutput = '/Connection time\s+[0-9]?\.?[0-9]+s is within thresholds+/'; |
| 25 | 25 | ||
| 26 | my $failedExpect = '/^TCP WARNING\s-\sUnexpected response from host/socket on port [0-9]+/'; | 26 | my $failedExpect = '/Answer failed to match/'; |
| 27 | 27 | ||
| 28 | my $t; | 28 | my $t; |
| 29 | 29 | ||
| 30 | $tests = $tests - 4 if $internet_access eq "no"; | 30 | $tests = $tests - 4 if $internet_access eq "no"; |
| 31 | plan tests => $tests; | 31 | plan tests => $tests; |
| 32 | 32 | ||
| 33 | $t += checkCmd( "./check_tcp $host_tcp_http -p 80 -wt 300 -ct 600", 0, $successOutput ); | 33 | $t += checkCmd( "./check_tcp $host_tcp_http -p 80 -w 300 -c 600", 0, $successOutput ); |
| 34 | $t += checkCmd( "./check_tcp $host_tcp_http -p 81 -wt 0 -ct 0 -to 1", 2 ); # use invalid port for this test | 34 | $t += checkCmd( "./check_tcp $host_tcp_http -p 81 -w 0 -c 0 -t 1", 2 ); # use invalid port for this test |
| 35 | $t += checkCmd( "./check_tcp $host_nonresponsive -p 80 -wt 0 -ct 0 -to 1", 2 ); | 35 | $t += checkCmd( "./check_tcp $host_nonresponsive -p 80 -w 0 -c 0 -t 1", 2 ); |
| 36 | $t += checkCmd( "./check_tcp $hostname_invalid -p 80 -wt 0 -ct 0 -to 1", 2 ); | 36 | $t += checkCmd( "./check_tcp $hostname_invalid -p 80 -w 0 -c 0 -t 1", 2 ); |
| 37 | if($internet_access ne "no") { | 37 | if($internet_access ne "no") { |
| 38 | $t += checkCmd( "./check_tcp -S -D 1 -H $host_tls_http -p 443", 0 ); | 38 | $t += checkCmd( "./check_tcp -S -D 1 -H $host_tls_http -p 443", 0 ); |
| 39 | $t += checkCmd( "./check_tcp -S -D 9000,1 -H $host_tls_http -p 443", 1 ); | 39 | $t += checkCmd( "./check_tcp -S -D 9000,1 -H $host_tls_http -p 443", 1 ); |
diff --git a/plugins/t/check_udp.t b/plugins/t/check_udp.t index 6c47d095..5cb9e6dc 100644 --- a/plugins/t/check_udp.t +++ b/plugins/t/check_udp.t | |||
| @@ -28,7 +28,7 @@ like ( $res->output, '/With UDP checks, a send/expect string must be specified. | |||
| 28 | 28 | ||
| 29 | $res = NPTest->testCmd( "./check_udp -H localhost -p 3333 -s foo -e bar" ); | 29 | $res = NPTest->testCmd( "./check_udp -H localhost -p 3333 -s foo -e bar" ); |
| 30 | cmp_ok( $res->return_code, '==', 2, "Errors correctly because no udp service running" ); | 30 | cmp_ok( $res->return_code, '==', 2, "Errors correctly because no udp service running" ); |
| 31 | like ( $res->output, '/No data received from host/', "Output OK"); | 31 | like ( $res->output, '/Received no data /', "Output OK"); |
| 32 | 32 | ||
| 33 | my $nc; | 33 | my $nc; |
| 34 | if(system("which nc.traditional >/dev/null 2>&1") == 0) { | 34 | if(system("which nc.traditional >/dev/null 2>&1") == 0) { |
| @@ -48,7 +48,7 @@ SKIP: { | |||
| 48 | sleep 1; | 48 | sleep 1; |
| 49 | $res = NPTest->testCmd( "./check_udp -H localhost -p 3333 -s '' -e barbar -4" ); | 49 | $res = NPTest->testCmd( "./check_udp -H localhost -p 3333 -s '' -e barbar -4" ); |
| 50 | cmp_ok( $res->return_code, '==', 0, "Got barbar response back" ); | 50 | cmp_ok( $res->return_code, '==', 0, "Got barbar response back" ); |
| 51 | like ( $res->output, '/\[barbar\]/', "Output OK"); | 51 | like ( $res->output, '/answer of the server matched/', "Output OK"); |
| 52 | close NC; | 52 | close NC; |
| 53 | 53 | ||
| 54 | # Start up a udp server listening on port 3333, quit after 3 seconds | 54 | # Start up a udp server listening on port 3333, quit after 3 seconds |
diff --git a/plugins/t/check_users.t b/plugins/t/check_users.t index 21c3e53d..446e0476 100644 --- a/plugins/t/check_users.t +++ b/plugins/t/check_users.t | |||
| @@ -15,8 +15,8 @@ use NPTest; | |||
| 15 | use vars qw($tests); | 15 | use vars qw($tests); |
| 16 | BEGIN {$tests = 12; plan tests => $tests} | 16 | BEGIN {$tests = 12; plan tests => $tests} |
| 17 | 17 | ||
| 18 | my $successOutput = '/^USERS OK - [0-9]+ users currently logged in/'; | 18 | my $successOutput = '/[0-9]+ users currently logged in/'; |
| 19 | my $failureOutput = '/^USERS CRITICAL - [0-9]+ users currently logged in/'; | 19 | my $failureOutput = '/[0-9]+ users currently logged in/'; |
| 20 | my $wrongOptionOutput = '/Usage:/'; | 20 | my $wrongOptionOutput = '/Usage:/'; |
| 21 | 21 | ||
| 22 | my $t; | 22 | my $t; |
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index eaa9f518..248eb4c5 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t | |||
| @@ -15,13 +15,19 @@ | |||
| 15 | # Email Address []:devel@monitoring-plugins.org | 15 | # Email Address []:devel@monitoring-plugins.org |
| 16 | 16 | ||
| 17 | use strict; | 17 | use strict; |
| 18 | use warnings; | ||
| 18 | use Test::More; | 19 | use Test::More; |
| 19 | use NPTest; | 20 | use NPTest; |
| 20 | use FindBin qw($Bin); | 21 | use FindBin qw($Bin); |
| 21 | 22 | ||
| 23 | use URI; | ||
| 24 | use URI::QueryParam; | ||
| 25 | use HTTP::Daemon; | ||
| 26 | use HTTP::Daemon::SSL; | ||
| 27 | |||
| 22 | $ENV{'LC_TIME'} = "C"; | 28 | $ENV{'LC_TIME'} = "C"; |
| 23 | 29 | ||
| 24 | my $common_tests = 75; | 30 | my $common_tests = 95; |
| 25 | my $ssl_only_tests = 8; | 31 | my $ssl_only_tests = 8; |
| 26 | # Check that all dependent modules are available | 32 | # Check that all dependent modules are available |
| 27 | eval "use HTTP::Daemon 6.01;"; | 33 | eval "use HTTP::Daemon 6.01;"; |
| @@ -185,6 +191,123 @@ sub run_server { | |||
| 185 | $c->send_response('moved to /redirect2'); | 191 | $c->send_response('moved to /redirect2'); |
| 186 | } elsif ($r->url->path eq "/redir_timeout") { | 192 | } elsif ($r->url->path eq "/redir_timeout") { |
| 187 | $c->send_redirect( "/timeout" ); | 193 | $c->send_redirect( "/timeout" ); |
| 194 | } elsif ($r->url->path =~ m{^/redirect_with_increment}) { | ||
| 195 | # <scheme>://<username>:<password>@<host>:<port>/<path>;<parameters>?<query>#<fragment> | ||
| 196 | # Find every parameter, query , and fragment keys and increment them | ||
| 197 | |||
| 198 | my $content = ""; | ||
| 199 | |||
| 200 | # Use URI to help with query/fragment; parse path params manually. | ||
| 201 | my $original_url = $r->url->as_string; | ||
| 202 | $content .= " original_url: ${original_url}\n"; | ||
| 203 | my $uri = URI->new($original_url); | ||
| 204 | $content .= " uri: ${uri}\n"; | ||
| 205 | |||
| 206 | my $path = $uri->path // ''; | ||
| 207 | my $query = $uri->query // ''; | ||
| 208 | my $fragment = $uri->fragment // ''; | ||
| 209 | |||
| 210 | $content .= " path: ${path}\n"; | ||
| 211 | $content .= " query: ${query}\n"; | ||
| 212 | $content .= " fragment: ${fragment}\n"; | ||
| 213 | |||
| 214 | # split the URI part and parameters. URI package cannot do this | ||
| 215 | # group 1 is captured: anything without a semicolon: ([^;]*) | ||
| 216 | # group 2 is uncaptured: (?:;(.*))? | ||
| 217 | # (?: ... )? prevents capturing the parameter section | ||
| 218 | # inside group 2, ';' matches the first ever semicolon | ||
| 219 | # group3 is captured: any character string : (.*) | ||
| 220 | # \? matches an actual ? mark, which starts the query parameters | ||
| 221 | my ($before_params, $params) = $uri =~ m{^([^;]*)(?:;(.*))?\?}; | ||
| 222 | $before_params //= ''; | ||
| 223 | $params //= ''; | ||
| 224 | $content .= " before_params: ${before_params}\n"; | ||
| 225 | $content .= " params: ${params}\n"; | ||
| 226 | my @parameter_pairs; | ||
| 227 | if (defined $params && length $params) { | ||
| 228 | for my $p (split /;/, $params) { | ||
| 229 | my ($key,$value) = split /=/, $p, 2; | ||
| 230 | $value //= ''; | ||
| 231 | push @parameter_pairs, [ $key, $value ]; | ||
| 232 | $content .= " parameter: ${key} -> ${value}\n"; | ||
| 233 | } | ||
| 234 | } | ||
| 235 | |||
| 236 | # query parameters are offered directly from the library | ||
| 237 | my @query_form = $uri->query_form; | ||
| 238 | my @query_parameter_pairs; | ||
| 239 | while (@query_form) { | ||
| 240 | my $key = shift @query_form; | ||
| 241 | my $value = shift @query_form; | ||
| 242 | $value //= ''; # there can be valueless keys | ||
| 243 | push @query_parameter_pairs, [ $key, $value ]; | ||
| 244 | $content .= " query: ${key} -> ${value}\n"; | ||
| 245 | } | ||
| 246 | |||
| 247 | # helper to increment value | ||
| 248 | my $increment = sub { | ||
| 249 | my ($v) = @_; | ||
| 250 | return $v if !defined $v || $v eq ''; | ||
| 251 | # numeric integer | ||
| 252 | if ($v =~ /^-?\d+$/) { | ||
| 253 | return $v + 1; | ||
| 254 | } | ||
| 255 | # otherwise -> increment as if its an ascii character | ||
| 256 | # sed replacement syntax, but the $& holds the matched character | ||
| 257 | if (length($v)) { | ||
| 258 | (my $new_v = $v) =~ s/./chr(ord($&) + 1)/ge; | ||
| 259 | return $new_v; | ||
| 260 | } | ||
| 261 | }; | ||
| 262 | |||
| 263 | # increment values in pairs | ||
| 264 | for my $pair (@parameter_pairs) { | ||
| 265 | $pair->[1] = $increment->($pair->[1]); | ||
| 266 | $content .= " parameter new: " . $pair->[0] . " -> " . $pair->[1] . "\n"; | ||
| 267 | } | ||
| 268 | for my $pair (@query_parameter_pairs) { | ||
| 269 | $pair->[1] = $increment->($pair->[1]); | ||
| 270 | $content .= " query parameter new: " . $pair->[0] . " -> " . $pair->[1] . "\n"; | ||
| 271 | } | ||
| 272 | |||
| 273 | # rebuild strings | ||
| 274 | my $new_parameter_str = join(';', map { $_->[0] . '=' . $_->[1] } @parameter_pairs); | ||
| 275 | $content .= " new_parameter_str: ${new_parameter_str}\n"; | ||
| 276 | |||
| 277 | # library can rebuild from an array | ||
| 278 | my @new_query_form; | ||
| 279 | for my $p (@query_parameter_pairs) { push @new_query_form, $p->[0], $p->[1] } | ||
| 280 | |||
| 281 | my $new_fragment_str = ''; | ||
| 282 | for my $pair (@parameter_pairs) { | ||
| 283 | my $key = $pair->[0]; | ||
| 284 | my $value = $pair->[1]; | ||
| 285 | if ($key eq "fragment") { | ||
| 286 | $new_fragment_str = $value | ||
| 287 | } | ||
| 288 | } | ||
| 289 | $content .= " new_fragment_str: ${new_fragment_str}\n"; | ||
| 290 | |||
| 291 | # construct new URI using the library | ||
| 292 | my $new_uri = URI->new(''); | ||
| 293 | $new_uri->path( $before_params . ($new_parameter_str ? ';' . $new_parameter_str : '') ); | ||
| 294 | $new_uri->query_form( \@new_query_form ) if @new_query_form; | ||
| 295 | $new_uri->fragment( $new_fragment_str ) if $new_fragment_str ne ''; | ||
| 296 | $content .= " new_uri: ${new_uri}\n"; | ||
| 297 | |||
| 298 | # Redirect until fail_count or redirect_count reaches 3 | ||
| 299 | if ($new_uri =~ /fail_count=3/){ | ||
| 300 | $c->send_error(HTTP::Status->RC_FORBIDDEN, "fail count reached 3, url path:" . $r->url->path ); | ||
| 301 | } elsif ($new_uri =~ /redirect_count=3/){ | ||
| 302 | $c->send_response(HTTP::Response->new( 200, 'OK', undef , $content )); | ||
| 303 | } elsif ($new_uri =~ /location_redirect_count=3/){ | ||
| 304 | $c->send_basic_header(302); | ||
| 305 | $c->send_header("Location", "$new_uri" ); | ||
| 306 | $c->send_crlf; | ||
| 307 | $c->send_response("$content \n moved to $new_uri"); | ||
| 308 | } else { | ||
| 309 | $c->send_redirect( $new_uri->as_string, 301, $content ); | ||
| 310 | } | ||
| 188 | } elsif ($r->url->path eq "/timeout") { | 311 | } elsif ($r->url->path eq "/timeout") { |
| 189 | # Keep $c from being destroyed, but prevent severe leaks | 312 | # Keep $c from being destroyed, but prevent severe leaks |
| 190 | unshift @persist, $c; | 313 | unshift @persist, $c; |
| @@ -214,7 +337,7 @@ sub run_server { | |||
| 214 | return($chunk); | 337 | return($chunk); |
| 215 | })); | 338 | })); |
| 216 | } else { | 339 | } else { |
| 217 | $c->send_error(HTTP::Status->RC_FORBIDDEN); | 340 | $c->send_error(HTTP::Status->RC_FORBIDDEN, "unknown url path:" . $r->url->path ); |
| 218 | } | 341 | } |
| 219 | $c->close; | 342 | $c->close; |
| 220 | } | 343 | } |
| @@ -245,21 +368,21 @@ SKIP: { | |||
| 245 | 368 | ||
| 246 | $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); | 369 | $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); |
| 247 | is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); | 370 | is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); |
| 248 | is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on $expiry.", "output ok" ); | 371 | like( $result->output, '/.*Certificate \'Monitoring Plugins\' will expire on ' . quotemeta($expiry) . '.*/', "output ok" ); |
| 249 | 372 | ||
| 250 | $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); | 373 | $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); |
| 251 | is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); | 374 | is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); |
| 252 | like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" ); | 375 | like( $result->output, '/.*Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\).*/', "output ok" ); |
| 253 | 376 | ||
| 254 | # Expired cert tests | 377 | # Expired cert tests |
| 255 | $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); | 378 | $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); |
| 256 | is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); | 379 | is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); |
| 257 | like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" ); | 380 | like( $result->output, '/.*Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\).*/', "output ok" ); |
| 258 | 381 | ||
| 259 | $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); | 382 | $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); |
| 260 | is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); | 383 | is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); |
| 261 | is( $result->output, | 384 | like( $result->output, |
| 262 | 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 12:00:00 2008 +0000.', | 385 | '/.*Certificate \'Monitoring Plugins\' expired on Wed Jan\s+2 12:00:00 2008 \+0000.*/', |
| 263 | "output ok" ); | 386 | "output ok" ); |
| 264 | 387 | ||
| 265 | } | 388 | } |
| @@ -274,19 +397,19 @@ SKIP: { | |||
| 274 | $cmd = "./$plugin -H $virtual_host -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host:$port_http\$"; | 397 | $cmd = "./$plugin -H $virtual_host -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host:$port_http\$"; |
| 275 | $result = NPTest->testCmd( $cmd ); | 398 | $result = NPTest->testCmd( $cmd ); |
| 276 | is( $result->return_code, 0, $cmd); | 399 | is( $result->return_code, 0, $cmd); |
| 277 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 400 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 278 | 401 | ||
| 279 | # http with virtual port (!= 80) | 402 | # http with virtual port (!= 80) |
| 280 | $cmd = "./$plugin -H $virtual_host:$virtual_port -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host:$virtual_port\$"; | 403 | $cmd = "./$plugin -H $virtual_host:$virtual_port -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host:$virtual_port\$"; |
| 281 | $result = NPTest->testCmd( $cmd ); | 404 | $result = NPTest->testCmd( $cmd ); |
| 282 | is( $result->return_code, 0, $cmd); | 405 | is( $result->return_code, 0, $cmd); |
| 283 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 406 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 284 | 407 | ||
| 285 | # http with virtual port (80) | 408 | # http with virtual port (80) |
| 286 | $cmd = "./$plugin -H $virtual_host:80 -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host\$"; | 409 | $cmd = "./$plugin -H $virtual_host:80 -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host\$"; |
| 287 | $result = NPTest->testCmd( $cmd ); | 410 | $result = NPTest->testCmd( $cmd ); |
| 288 | is( $result->return_code, 0, $cmd); | 411 | is( $result->return_code, 0, $cmd); |
| 289 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 412 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 290 | } | 413 | } |
| 291 | 414 | ||
| 292 | # and the same for SSL | 415 | # and the same for SSL |
| @@ -296,19 +419,19 @@ SKIP: { | |||
| 296 | $cmd = "./$plugin -H $virtual_host -I 127.0.0.1 -p $port_https --ssl -u /virtual_port -r ^$virtual_host:$port_https\$"; | 419 | $cmd = "./$plugin -H $virtual_host -I 127.0.0.1 -p $port_https --ssl -u /virtual_port -r ^$virtual_host:$port_https\$"; |
| 297 | $result = NPTest->testCmd( $cmd ); | 420 | $result = NPTest->testCmd( $cmd ); |
| 298 | is( $result->return_code, 0, $cmd); | 421 | is( $result->return_code, 0, $cmd); |
| 299 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 422 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 300 | 423 | ||
| 301 | # https with virtual port (!= 443) | 424 | # https with virtual port (!= 443) |
| 302 | $cmd = "./$plugin -H $virtual_host:$virtual_port -I 127.0.0.1 -p $port_https --ssl -u /virtual_port -r ^$virtual_host:$virtual_port\$"; | 425 | $cmd = "./$plugin -H $virtual_host:$virtual_port -I 127.0.0.1 -p $port_https --ssl -u /virtual_port -r ^$virtual_host:$virtual_port\$"; |
| 303 | $result = NPTest->testCmd( $cmd ); | 426 | $result = NPTest->testCmd( $cmd ); |
| 304 | is( $result->return_code, 0, $cmd); | 427 | is( $result->return_code, 0, $cmd); |
| 305 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 428 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 306 | 429 | ||
| 307 | # https with virtual port (443) | 430 | # https with virtual port (443) |
| 308 | $cmd = "./$plugin -H $virtual_host:443 -I 127.0.0.1 -p $port_https --ssl -u /virtual_port -r ^$virtual_host\$"; | 431 | $cmd = "./$plugin -H $virtual_host:443 -I 127.0.0.1 -p $port_https --ssl -u /virtual_port -r ^$virtual_host\$"; |
| 309 | $result = NPTest->testCmd( $cmd ); | 432 | $result = NPTest->testCmd( $cmd ); |
| 310 | is( $result->return_code, 0, $cmd); | 433 | is( $result->return_code, 0, $cmd); |
| 311 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 434 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 312 | } | 435 | } |
| 313 | 436 | ||
| 314 | 437 | ||
| @@ -321,165 +444,223 @@ sub run_common_tests { | |||
| 321 | 444 | ||
| 322 | $result = NPTest->testCmd( "$command -u /file/root" ); | 445 | $result = NPTest->testCmd( "$command -u /file/root" ); |
| 323 | is( $result->return_code, 0, "/file/root"); | 446 | is( $result->return_code, 0, "/file/root"); |
| 324 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - 274 bytes in [\d\.]+ second/', "Output correct" ); | 447 | like( $result->output, '/.*HTTP/1.1 200 OK - 274 bytes in [\d\.]+ second.*/', "Output correct" ); |
| 325 | 448 | ||
| 326 | $result = NPTest->testCmd( "$command -u /file/root -s Root" ); | 449 | $result = NPTest->testCmd( "$command -u /file/root -s Root" ); |
| 327 | is( $result->return_code, 0, "/file/root search for string"); | 450 | is( $result->return_code, 0, "/file/root search for string"); |
| 328 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - 274 bytes in [\d\.]+ second/', "Output correct" ); | 451 | like( $result->output, '/.*HTTP/1.1 200 OK - 274 bytes in [\d\.]+ second.*/', "Output correct" ); |
| 329 | 452 | ||
| 330 | $result = NPTest->testCmd( "$command -u /file/root -s NonRoot" ); | 453 | $result = NPTest->testCmd( "$command -u /file/root -s NonRoot" ); |
| 331 | is( $result->return_code, 2, "Missing string check"); | 454 | is( $result->return_code, 2, "Missing string check"); |
| 332 | like( $result->output, qr%^HTTP CRITICAL: HTTP/1\.1 200 OK - string 'NonRoot' not found on 'https?://127\.0\.0\.1:\d+/file/root'%, "Shows search string and location"); | 455 | like( $result->output, qr%string 'NonRoot' not found on 'https?://127\.0\.0\.1:\d+/file/root'%, "Shows search string and location"); |
| 333 | 456 | ||
| 334 | $result = NPTest->testCmd( "$command -u /file/root -s NonRootWithOver30charsAndMoreFunThanAWetFish" ); | 457 | $result = NPTest->testCmd( "$command -u /file/root -s NonRootWithOver30charsAndMoreFunThanAWetFish" ); |
| 335 | is( $result->return_code, 2, "Missing string check"); | 458 | is( $result->return_code, 2, "Missing string check"); |
| 336 | like( $result->output, qr%HTTP CRITICAL: HTTP/1\.1 200 OK - string 'NonRootWithOver30charsAndM...' not found on 'https?://127\.0\.0\.1:\d+/file/root'%, "Shows search string and location"); | 459 | like( $result->output, qr%string 'NonRootWithOver30charsAndM...' not found on 'https?://127\.0\.0\.1:\d+/file/root'%, "Shows search string and location"); |
| 337 | 460 | ||
| 338 | $result = NPTest->testCmd( "$command -u /header_check -d foo" ); | 461 | $result = NPTest->testCmd( "$command -u /header_check -d foo" ); |
| 339 | is( $result->return_code, 0, "header_check search for string"); | 462 | is( $result->return_code, 0, "header_check search for string"); |
| 340 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - 96 bytes in [\d\.]+ second/', "Output correct" ); | 463 | like( $result->output, '/.*HTTP/1.1 200 OK - 96 bytes in [\d\.]+ second.*/', "Output correct" ); |
| 341 | 464 | ||
| 342 | $result = NPTest->testCmd( "$command -u /header_check -d bar" ); | 465 | $result = NPTest->testCmd( "$command -u /header_check -d bar" ); |
| 343 | is( $result->return_code, 2, "Missing header string check"); | 466 | is( $result->return_code, 2, "Missing header string check"); |
| 344 | like( $result->output, qr%^HTTP CRITICAL: HTTP/1\.1 200 OK - header 'bar' not found on 'https?://127\.0\.0\.1:\d+/header_check'%, "Shows search string and location"); | 467 | like( $result->output, qr%header 'bar' not found on 'https?://127\.0\.0\.1:\d+/header_check'%, "Shows search string and location"); |
| 345 | 468 | ||
| 346 | $result = NPTest->testCmd( "$command -u /header_broken_check" ); | 469 | $result = NPTest->testCmd( "$command -u /header_broken_check" ); |
| 347 | is( $result->return_code, 0, "header_check search for string"); | 470 | is( $result->return_code, 0, "header_check search for string"); |
| 348 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - 138 bytes in [\d\.]+ second/', "Output correct" ); | 471 | like( $result->output, '/.*HTTP/1.1 200 OK - 138 bytes in [\d\.]+ second.*/', "Output correct" ); |
| 349 | 472 | ||
| 350 | my $cmd; | 473 | my $cmd; |
| 351 | $cmd = "$command -u /slow"; | 474 | $cmd = "$command -u /slow"; |
| 352 | $result = NPTest->testCmd( $cmd ); | 475 | $result = NPTest->testCmd( $cmd ); |
| 353 | is( $result->return_code, 0, "$cmd"); | 476 | is( $result->return_code, 0, "$cmd"); |
| 354 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 477 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 355 | $result->output =~ /in ([\d\.]+) second/; | 478 | $result->output =~ /in ([\d\.]+) second/; |
| 356 | cmp_ok( $1, ">", 1, "Time is > 1 second" ); | 479 | cmp_ok( $1, ">", 1, "Time is > 1 second" ); |
| 357 | 480 | ||
| 358 | $cmd = "$command -u /statuscode/200"; | 481 | $cmd = "$command -u /statuscode/200"; |
| 359 | $result = NPTest->testCmd( $cmd ); | 482 | $result = NPTest->testCmd( $cmd ); |
| 360 | is( $result->return_code, 0, $cmd); | 483 | is( $result->return_code, 0, $cmd); |
| 361 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 484 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 362 | 485 | ||
| 363 | $cmd = "$command -u /statuscode/200 -e 200"; | 486 | $cmd = "$command -u /statuscode/200 -e 200"; |
| 364 | $result = NPTest->testCmd( $cmd ); | 487 | $result = NPTest->testCmd( $cmd ); |
| 365 | is( $result->return_code, 0, $cmd); | 488 | is( $result->return_code, 0, $cmd); |
| 366 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - Status line output matched "200" - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 489 | like( $result->output, '/.*Status line output matched "200".*/', "Output correct: ".$result->output ); |
| 367 | 490 | ||
| 368 | $cmd = "$command -u /statuscode/201"; | 491 | $cmd = "$command -u /statuscode/201"; |
| 369 | $result = NPTest->testCmd( $cmd ); | 492 | $result = NPTest->testCmd( $cmd ); |
| 370 | is( $result->return_code, 0, $cmd); | 493 | is( $result->return_code, 0, $cmd); |
| 371 | like( $result->output, '/^HTTP OK: HTTP/1.1 201 Created - \d+ bytes in [\d\.]+ second /', "Output correct: ".$result->output ); | 494 | like( $result->output, '/.*HTTP/1.1 201 Created - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 372 | 495 | ||
| 373 | $cmd = "$command -u /statuscode/201 -e 201"; | 496 | $cmd = "$command -u /statuscode/201 -e 201"; |
| 374 | $result = NPTest->testCmd( $cmd ); | 497 | $result = NPTest->testCmd( $cmd ); |
| 375 | is( $result->return_code, 0, $cmd); | 498 | is( $result->return_code, 0, $cmd); |
| 376 | like( $result->output, '/^HTTP OK: HTTP/1.1 201 Created - Status line output matched "201" - \d+ bytes in [\d\.]+ second /', "Output correct: ".$result->output ); | 499 | like( $result->output, '/.*Status line output matched "201".*/', "Output correct: ".$result->output ); |
| 377 | 500 | ||
| 378 | $cmd = "$command -u /statuscode/201 -e 200"; | 501 | $cmd = "$command -u /statuscode/201 -e 200"; |
| 379 | $result = NPTest->testCmd( $cmd ); | 502 | $result = NPTest->testCmd( $cmd ); |
| 380 | is( $result->return_code, 2, $cmd); | 503 | is( $result->return_code, 2, $cmd); |
| 381 | like( $result->output, '/^HTTP CRITICAL - Invalid HTTP response received from host on port \d+: HTTP/1.1 201 Created/', "Output correct: ".$result->output ); | 504 | like( $result->output, '/.*Invalid HTTP response received from host on port \d+: HTTP/1.1 201 Created.*/', "Output correct: ".$result->output ); |
| 382 | 505 | ||
| 383 | $cmd = "$command -u /statuscode/200 -e 200,201,202"; | 506 | $cmd = "$command -u /statuscode/200 -e 200,201,202"; |
| 384 | $result = NPTest->testCmd( $cmd ); | 507 | $result = NPTest->testCmd( $cmd ); |
| 385 | is( $result->return_code, 0, $cmd); | 508 | is( $result->return_code, 0, $cmd); |
| 386 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - Status line output matched "200,201,202" - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 509 | like( $result->output, '/.*Status line output matched "200,201,202".*/', "Output correct: ".$result->output ); |
| 387 | 510 | ||
| 388 | $cmd = "$command -u /statuscode/201 -e 200,201,202"; | 511 | $cmd = "$command -u /statuscode/201 -e 200,201,202"; |
| 389 | $result = NPTest->testCmd( $cmd ); | 512 | $result = NPTest->testCmd( $cmd ); |
| 390 | is( $result->return_code, 0, $cmd); | 513 | is( $result->return_code, 0, $cmd); |
| 391 | like( $result->output, '/^HTTP OK: HTTP/1.1 201 Created - Status line output matched "200,201,202" - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 514 | like( $result->output, '/.*Status line output matched "200,201,202".*/', "Output correct: ".$result->output ); |
| 392 | 515 | ||
| 393 | $cmd = "$command -u /statuscode/203 -e 200,201,202"; | 516 | $cmd = "$command -u /statuscode/203 -e 200,201,202"; |
| 394 | $result = NPTest->testCmd( $cmd ); | 517 | $result = NPTest->testCmd( $cmd ); |
| 395 | is( $result->return_code, 2, $cmd); | 518 | is( $result->return_code, 2, $cmd); |
| 396 | like( $result->output, '/^HTTP CRITICAL - Invalid HTTP response received from host on port (\d+): HTTP/1.1 203 Non-Authoritative Information/', "Output correct: ".$result->output ); | 519 | like( $result->output, '/.*Invalid HTTP response received from host on port (\d+): HTTP/1.1 203 Non-Authoritative Information.*/', "Output correct: ".$result->output ); |
| 397 | 520 | ||
| 398 | $cmd = "$command -j HEAD -u /method"; | 521 | $cmd = "$command -j HEAD -u /method"; |
| 399 | $result = NPTest->testCmd( $cmd ); | 522 | $result = NPTest->testCmd( $cmd ); |
| 400 | is( $result->return_code, 0, $cmd); | 523 | is( $result->return_code, 0, $cmd); |
| 401 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 HEAD - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 524 | like( $result->output, '/.*HTTP/1.1 200 HEAD - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 402 | 525 | ||
| 403 | $cmd = "$command -j POST -u /method"; | 526 | $cmd = "$command -j POST -u /method"; |
| 404 | $result = NPTest->testCmd( $cmd ); | 527 | $result = NPTest->testCmd( $cmd ); |
| 405 | is( $result->return_code, 0, $cmd); | 528 | is( $result->return_code, 0, $cmd); |
| 406 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 POST - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 529 | like( $result->output, '/.*HTTP/1.1 200 POST - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 407 | 530 | ||
| 408 | $cmd = "$command -j GET -u /method"; | 531 | $cmd = "$command -j GET -u /method"; |
| 409 | $result = NPTest->testCmd( $cmd ); | 532 | $result = NPTest->testCmd( $cmd ); |
| 410 | is( $result->return_code, 0, $cmd); | 533 | is( $result->return_code, 0, $cmd); |
| 411 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 GET - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 534 | like( $result->output, '/.*HTTP/1.1 200 GET - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 412 | 535 | ||
| 413 | $cmd = "$command -u /method"; | 536 | $cmd = "$command -u /method"; |
| 414 | $result = NPTest->testCmd( $cmd ); | 537 | $result = NPTest->testCmd( $cmd ); |
| 415 | is( $result->return_code, 0, $cmd); | 538 | is( $result->return_code, 0, $cmd); |
| 416 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 GET - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 539 | like( $result->output, '/.*HTTP/1.1 200 GET - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 417 | 540 | ||
| 418 | $cmd = "$command -P foo -u /method"; | 541 | $cmd = "$command -P foo -u /method"; |
| 419 | $result = NPTest->testCmd( $cmd ); | 542 | $result = NPTest->testCmd( $cmd ); |
| 420 | is( $result->return_code, 0, $cmd); | 543 | is( $result->return_code, 0, $cmd); |
| 421 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 POST - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 544 | like( $result->output, '/.*HTTP/1.1 200 POST - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 422 | 545 | ||
| 423 | $cmd = "$command -j DELETE -u /method"; | 546 | $cmd = "$command -j DELETE -u /method"; |
| 424 | $result = NPTest->testCmd( $cmd ); | 547 | $result = NPTest->testCmd( $cmd ); |
| 425 | is( $result->return_code, 1, $cmd); | 548 | is( $result->return_code, 1, $cmd); |
| 426 | like( $result->output, '/^HTTP WARNING: HTTP/1.1 405 Method Not Allowed/', "Output correct: ".$result->output ); | 549 | like( $result->output, '/.*HTTP/1.1 405 Method Not Allowed.*/', "Output correct: ".$result->output ); |
| 427 | 550 | ||
| 428 | $cmd = "$command -j foo -u /method"; | 551 | $cmd = "$command -j foo -u /method"; |
| 429 | $result = NPTest->testCmd( $cmd ); | 552 | $result = NPTest->testCmd( $cmd ); |
| 430 | is( $result->return_code, 2, $cmd); | 553 | is( $result->return_code, 2, $cmd); |
| 431 | like( $result->output, '/^HTTP CRITICAL: HTTP/1.1 501 Not Implemented/', "Output correct: ".$result->output ); | 554 | like( $result->output, '/.*HTTP/1.1 501 Not Implemented.*/', "Output correct: ".$result->output ); |
| 432 | 555 | ||
| 433 | $cmd = "$command -P stufftoinclude -u /postdata -s POST:stufftoinclude"; | 556 | $cmd = "$command -P stufftoinclude -u /postdata -s POST:stufftoinclude"; |
| 434 | $result = NPTest->testCmd( $cmd ); | 557 | $result = NPTest->testCmd( $cmd ); |
| 435 | is( $result->return_code, 0, $cmd); | 558 | is( $result->return_code, 0, $cmd); |
| 436 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 559 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 437 | 560 | ||
| 438 | $cmd = "$command -j PUT -P stufftoinclude -u /postdata -s PUT:stufftoinclude"; | 561 | $cmd = "$command -j PUT -P stufftoinclude -u /postdata -s PUT:stufftoinclude"; |
| 439 | $result = NPTest->testCmd( $cmd ); | 562 | $result = NPTest->testCmd( $cmd ); |
| 440 | is( $result->return_code, 0, $cmd); | 563 | is( $result->return_code, 0, $cmd); |
| 441 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 564 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 442 | 565 | ||
| 443 | # To confirm that the free doesn't segfault | 566 | # To confirm that the free doesn't segfault |
| 444 | $cmd = "$command -P stufftoinclude -j PUT -u /postdata -s PUT:stufftoinclude"; | 567 | $cmd = "$command -P stufftoinclude -j PUT -u /postdata -s PUT:stufftoinclude"; |
| 445 | $result = NPTest->testCmd( $cmd ); | 568 | $result = NPTest->testCmd( $cmd ); |
| 446 | is( $result->return_code, 0, $cmd); | 569 | is( $result->return_code, 0, $cmd); |
| 447 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 570 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 448 | 571 | ||
| 449 | $cmd = "$command -u /redirect"; | 572 | $cmd = "$command -u /redirect"; |
| 450 | $result = NPTest->testCmd( $cmd ); | 573 | $result = NPTest->testCmd( $cmd ); |
| 451 | is( $result->return_code, 0, $cmd); | 574 | is( $result->return_code, 0, $cmd); |
| 452 | like( $result->output, '/^HTTP OK: HTTP/1.1 301 Moved Permanently - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 575 | like( $result->output, '/.*HTTP/1.1 301 Moved Permanently - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 453 | 576 | ||
| 454 | $cmd = "$command -f follow -u /redirect"; | 577 | $cmd = "$command -f follow -u /redirect"; |
| 455 | $result = NPTest->testCmd( $cmd ); | 578 | $result = NPTest->testCmd( $cmd ); |
| 456 | is( $result->return_code, 0, $cmd); | 579 | is( $result->return_code, 0, $cmd); |
| 457 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 580 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 458 | 581 | ||
| 459 | $cmd = "$command -u /redirect -k 'follow: me'"; | 582 | $cmd = "$command -u /redirect -k 'follow: me'"; |
| 460 | $result = NPTest->testCmd( $cmd ); | 583 | $result = NPTest->testCmd( $cmd ); |
| 461 | is( $result->return_code, 0, $cmd); | 584 | is( $result->return_code, 0, $cmd); |
| 462 | like( $result->output, '/^HTTP OK: HTTP/1.1 301 Moved Permanently - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 585 | like( $result->output, '/.*HTTP/1.1 301 Moved Permanently - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 463 | 586 | ||
| 464 | $cmd = "$command -f follow -u /redirect -k 'follow: me'"; | 587 | $cmd = "$command -f follow -u /redirect -k 'follow: me'"; |
| 465 | $result = NPTest->testCmd( $cmd ); | 588 | $result = NPTest->testCmd( $cmd ); |
| 466 | is( $result->return_code, 0, $cmd); | 589 | is( $result->return_code, 0, $cmd); |
| 467 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 590 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 468 | 591 | ||
| 469 | $cmd = "$command -f sticky -u /redirect -k 'follow: me'"; | 592 | $cmd = "$command -f sticky -u /redirect -k 'follow: me'"; |
| 470 | $result = NPTest->testCmd( $cmd ); | 593 | $result = NPTest->testCmd( $cmd ); |
| 471 | is( $result->return_code, 0, $cmd); | 594 | is( $result->return_code, 0, $cmd); |
| 472 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 595 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 473 | 596 | ||
| 474 | $cmd = "$command -f stickyport -u /redirect -k 'follow: me'"; | 597 | $cmd = "$command -f stickyport -u /redirect -k 'follow: me'"; |
| 475 | $result = NPTest->testCmd( $cmd ); | 598 | $result = NPTest->testCmd( $cmd ); |
| 476 | is( $result->return_code, 0, $cmd); | 599 | is( $result->return_code, 0, $cmd); |
| 477 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 600 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 478 | 601 | ||
| 479 | $cmd = "$command -f follow -u /redirect_rel -s redirected"; | 602 | $cmd = "$command -f follow -u /redirect_rel -s redirected"; |
| 480 | $result = NPTest->testCmd( $cmd ); | 603 | $result = NPTest->testCmd( $cmd ); |
| 481 | is( $result->return_code, 0, $cmd); | 604 | is( $result->return_code, 0, $cmd); |
| 482 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 605 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 606 | |||
| 607 | # Redirect with increment tests. These are for checking if the url parameters, query parameters and fragment are parsed. | ||
| 608 | # The server at this point has dynamic redirection. It tries to increment values that it sees in these fields, then redirects. | ||
| 609 | # It also appends some debug log and writes it into HTTP content, pass the -vvv parameter to see them. | ||
| 610 | |||
| 611 | $cmd = "$command -u '/redirect_with_increment/path1/path2/path3/path4' --onredirect=follow -vvv"; | ||
| 612 | $result = NPTest->testCmd( "$cmd" ); | ||
| 613 | is( $result->return_code, 1, $cmd); | ||
| 614 | like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count was not present, got redirected to / : ".$result->output ); | ||
| 615 | |||
| 616 | # redirect_count=0 is parsed as a parameter and incremented. When it goes up to 3, the redirection returns HTTP OK | ||
| 617 | $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; | ||
| 618 | $result = NPTest->testCmd( "$cmd" ); | ||
| 619 | is( $result->return_code, 0, $cmd); | ||
| 620 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count went up to 3, and returned OK: ".$result->output ); | ||
| 621 | |||
| 622 | # location_redirect_count=0 goes up to 3, which uses the HTTP 302 style of redirection with 'Location' header | ||
| 623 | $cmd = "$command -u '/redirect_with_increment/path1/path2;location_redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; | ||
| 624 | $result = NPTest->testCmd( "$cmd" ); | ||
| 625 | is( $result->return_code, 0, $cmd); | ||
| 626 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); | ||
| 627 | |||
| 628 | # fail_count parameter may also go up to 3, which returns a HTTP 403 | ||
| 629 | $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;fail_count=2' --onredirect=follow -vvv"; | ||
| 630 | $result = NPTest->testCmd( "$cmd" ); | ||
| 631 | is( $result->return_code, 1, $cmd); | ||
| 632 | like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, early due to fail_count reaching 3: ".$result->output ); | ||
| 633 | |||
| 634 | # redirect_count=0, p1=1 , p2=ab => redirect_count=1, p1=2 , p2=bc => redirect_count=2, p1=3 , p2=cd => redirect_count=3 , p1=4 , p2=de | ||
| 635 | # Last visited URI returns HTTP OK instead of redirect, and the one before that contains the new_uri in its content | ||
| 636 | $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; | ||
| 637 | $result = NPTest->testCmd( "$cmd" ); | ||
| 638 | is( $result->return_code, 0, $cmd); | ||
| 639 | like( $result->output, '/.*redirect_count=3;p1=4;p2=de\?*/', "Output correct, parsed and incremented both parameters p1 and p2 : ".$result->output ); | ||
| 640 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); | ||
| 641 | |||
| 642 | # Same incrementation as before, uses the query parameters that come after the first '?' : qp1 and qp2 | ||
| 643 | $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; | ||
| 644 | $result = NPTest->testCmd( "$cmd" ); | ||
| 645 | is( $result->return_code, 0, $cmd); | ||
| 646 | like( $result->output, '/.*\?qp1=13&qp2=no*/', "Output correct, parsed and incremented both query parameters qp1 and qp2 : ".$result->output ); | ||
| 647 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); | ||
| 648 | |||
| 649 | # Check if the query parameter order is kept intact | ||
| 650 | $cmd = "$command -u '/redirect_with_increment;redirect_count=0;?qp0=0&qp1=1&qp2=2&qp3=3&qp4=4&qp5=5' --onredirect=follow -vvv"; | ||
| 651 | $result = NPTest->testCmd( "$cmd" ); | ||
| 652 | is( $result->return_code, 0, $cmd); | ||
| 653 | like( $result->output, '/.*\?qp0=3&qp1=4&qp2=5&qp3=6&qp4=7&qp5=8*/', "Output correct, parsed and incremented query parameters qp1,qp2,qp3,qp4,qp5 in order : ".$result->output ); | ||
| 654 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); | ||
| 655 | |||
| 656 | # The fragment is passed as another parameter. | ||
| 657 | # During the server redirects the fragment will be set to its value, if such a key is present. | ||
| 658 | # 'ebiil' => 'fcjjm' => 'gdkkn' => 'hello' | ||
| 659 | $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;fragment=ebiil?qp1=0' --onredirect=follow -vvv"; | ||
| 660 | $result = NPTest->testCmd( "$cmd" ); | ||
| 661 | is( $result->return_code, 0, $cmd); | ||
| 662 | like( $result->output, '/.*redirect_count=3;fragment=hello\?qp1=3#hello*/', "Output correct, fragments are specified by server and followed by check_curl: ".$result->output ); | ||
| 663 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); | ||
| 483 | 664 | ||
| 484 | # These tests may block | 665 | # These tests may block |
| 485 | # stickyport - on full urlS port is set back to 80 otherwise | 666 | # stickyport - on full urlS port is set back to 80 otherwise |
diff --git a/plugins/tests/check_nt.t b/plugins/tests/check_nt.t deleted file mode 100755 index 223d4933..00000000 --- a/plugins/tests/check_nt.t +++ /dev/null | |||
| @@ -1,80 +0,0 @@ | |||
| 1 | #! /usr/bin/perl -w -I .. | ||
| 2 | # | ||
| 3 | # Test check_nt by having a stub check_nt daemon | ||
| 4 | # | ||
| 5 | |||
| 6 | use strict; | ||
| 7 | use Test::More; | ||
| 8 | use NPTest; | ||
| 9 | use FindBin qw($Bin); | ||
| 10 | |||
| 11 | use IO::Socket; | ||
| 12 | use IO::Select; | ||
| 13 | use POSIX; | ||
| 14 | |||
| 15 | my $port = 50000 + int(rand(1000)); | ||
| 16 | |||
| 17 | my $pid = fork(); | ||
| 18 | if ($pid) { | ||
| 19 | # Parent | ||
| 20 | #print "parent\n"; | ||
| 21 | # give our webserver some time to startup | ||
| 22 | sleep(1); | ||
| 23 | } else { | ||
| 24 | # Child | ||
| 25 | #print "child\n"; | ||
| 26 | |||
| 27 | my $server = IO::Socket::INET->new( | ||
| 28 | LocalPort => $port, | ||
| 29 | Type => SOCK_STREAM, | ||
| 30 | Reuse => 1, | ||
| 31 | Proto => "tcp", | ||
| 32 | Listen => 10, | ||
| 33 | ) or die "Cannot be a tcp server on port $port: $@"; | ||
| 34 | |||
| 35 | $server->autoflush(1); | ||
| 36 | |||
| 37 | print "Please contact me at port $port\n"; | ||
| 38 | while (my $client = $server->accept ) { | ||
| 39 | my $data = ""; | ||
| 40 | my $rv = $client->recv($data, POSIX::BUFSIZ, 0); | ||
| 41 | |||
| 42 | my ($password, $command, $arg) = split('&', $data); | ||
| 43 | |||
| 44 | if ($command eq "4") { | ||
| 45 | if ($arg eq "c") { | ||
| 46 | print $client "930000000&1000000000"; | ||
| 47 | } elsif ($arg eq "d") { | ||
| 48 | print $client "UNKNOWN: Drive is not a fixed drive"; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | } | ||
| 52 | exit; | ||
| 53 | } | ||
| 54 | |||
| 55 | END { if ($pid) { print "Killing $pid\n"; kill "INT", $pid } }; | ||
| 56 | |||
| 57 | if ($ARGV[0] && $ARGV[0] eq "-d") { | ||
| 58 | sleep 1000; | ||
| 59 | } | ||
| 60 | |||
| 61 | if (-x "./check_nt") { | ||
| 62 | plan tests => 5; | ||
| 63 | } else { | ||
| 64 | plan skip_all => "No check_nt compiled"; | ||
| 65 | } | ||
| 66 | |||
| 67 | my $result; | ||
| 68 | my $command = "./check_nt -H 127.0.0.1 -p $port"; | ||
| 69 | |||
| 70 | $result = NPTest->testCmd( "$command -v USEDDISKSPACE -l c" ); | ||
| 71 | is( $result->return_code, 0, "USEDDISKSPACE c"); | ||
| 72 | is( $result->output, q{c:\ - total: 0.93 Gb - used: 0.07 Gb (7%) - free 0.87 Gb (93%) | 'c:\ Used Space'=0.07Gb;0.00;0.00;0.00;0.93}, "Output right" ); | ||
| 73 | |||
| 74 | $result = NPTest->testCmd( "$command -v USEDDISKSPACE -l d" ); | ||
| 75 | is( $result->return_code, 3, "USEDDISKSPACE d - invalid"); | ||
| 76 | is( $result->output, "Free disk space : Invalid drive", "Output right" ); | ||
| 77 | |||
| 78 | $result = NPTest->testCmd( "./check_nt -v USEDDISKSPACE -l d" ); | ||
| 79 | is( $result->return_code, 3, "Fail if -H missing"); | ||
| 80 | |||
diff --git a/plugins/tests/check_snmp.t b/plugins/tests/check_snmp.t index bfe42e16..26d67898 100755 --- a/plugins/tests/check_snmp.t +++ b/plugins/tests/check_snmp.t | |||
| @@ -4,12 +4,13 @@ | |||
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | use strict; | 6 | use strict; |
| 7 | use warnings; | ||
| 7 | use Test::More; | 8 | use Test::More; |
| 8 | use NPTest; | 9 | use NPTest; |
| 9 | use FindBin qw($Bin); | 10 | use FindBin qw($Bin); |
| 10 | use POSIX qw/strftime/; | 11 | use POSIX qw/strftime/; |
| 11 | 12 | ||
| 12 | my $tests = 81; | 13 | my $tests = 75; |
| 13 | # Check that all dependent modules are available | 14 | # Check that all dependent modules are available |
| 14 | eval { | 15 | eval { |
| 15 | require NetSNMP::OID; | 16 | require NetSNMP::OID; |
| @@ -76,49 +77,36 @@ my $res; | |||
| 76 | 77 | ||
| 77 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0"); | 78 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0"); |
| 78 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying a multi-line string" ); | 79 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying a multi-line string" ); |
| 79 | like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); | 80 | like($res->output, '/.*Cisco Internetwork Operating System Software.*/m', "String contains all lines"); |
| 80 | like($res->output, '/'.quotemeta('SNMP OK - Cisco Internetwork Operating System Software | | ||
| 81 | .1.3.6.1.4.1.8072.3.2.67.0: | ||
| 82 | "Cisco Internetwork Operating System Software | ||
| 83 | IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version | ||
| 84 | 12.2(20)EWA, RELEASE SOFTWARE (fc1) | ||
| 85 | Technical Support: http://www.cisco.com/techsupport | ||
| 86 | Copyright (c) 1986-2004 by cisco Systems, Inc. | ||
| 87 | "').'/m', "String contains all lines"); | ||
| 88 | 81 | ||
| 89 | # sysContact.0 is "Alice" (from our snmpd.conf) | 82 | # sysContact.0 is "Alice" (from our snmpd.conf) |
| 90 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0 -o sysContact.0 -o .1.3.6.1.4.1.8072.3.2.67.1"); | 83 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.0 -o sysContact.0 -o .1.3.6.1.4.1.8072.3.2.67.1"); |
| 91 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); | 84 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); |
| 92 | like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); | 85 | # like($res->output, '/^SNMP OK - /', "String contains SNMP OK"); |
| 93 | like($res->output, '/'.quotemeta('SNMP OK - Cisco Internetwork Operating System Software ').'"?Alice"?'.quotemeta(' Kisco Outernetwork Oserating Gystem Totware | | 86 | like($res->output, '/.*Cisco Internetwork Operating System Software.*/m', "String contains all lines with multiple OIDs"); |
| 94 | .1.3.6.1.4.1.8072.3.2.67.0: | 87 | like($res->output, '/.*Alice.*/m', "String contains all lines with multiple OIDs"); |
| 95 | "Cisco Internetwork Operating System Software | 88 | like($res->output, '/.*Kisco Outernetwork Oserating Gystem Totware.*/m', "String contains all lines with multiple OIDs"); |
| 96 | IOS (tm) Catalyst 4000 \"L3\" Switch Software (cat4000-I9K91S-M), Version | ||
| 97 | 12.2(20)EWA, RELEASE SOFTWARE (fc1) | ||
| 98 | Technical Support: http://www.cisco.com/techsupport | ||
| 99 | Copyright (c) 1986-2004 by cisco Systems, Inc. | ||
| 100 | " | ||
| 101 | .1.3.6.1.4.1.8072.3.2.67.1: | ||
| 102 | "Kisco Outernetwork Oserating Gystem Totware | ||
| 103 | Copyleft (c) 2400-2689 by kisco Systrems, Inc."').'/m', "String contains all lines with multiple OIDs"); | ||
| 104 | 89 | ||
| 105 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.2"); | 90 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.2"); |
| 106 | like($res->output, '/'.quotemeta('SNMP OK - This should not confuse check_snmp \"parser\" | | 91 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); |
| 107 | .1.3.6.1.4.1.8072.3.2.67.2: | 92 | # like($res->output, '/'.quotemeta('This should not confuse check_snmp \"parser\" | |
| 108 | "This should not confuse check_snmp \"parser\" | 93 | # .1.3.6.1.4.1.8072.3.2.67.2: |
| 109 | into thinking there is no 2nd line"').'/m', "Attempt to confuse parser No.1"); | 94 | # "This should not confuse check_snmp \"parser\" |
| 95 | # into thinking there is no 2nd line"').'/m', "Attempt to confuse parser No.1"); | ||
| 110 | 96 | ||
| 111 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.3"); | 97 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.3"); |
| 112 | like($res->output, '/'.quotemeta('SNMP OK - It\'s getting even harder if the line | | 98 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); |
| 113 | .1.3.6.1.4.1.8072.3.2.67.3: | 99 | # like($res->output, '/'.quotemeta('It\'s getting even harder if the line | |
| 114 | "It\'s getting even harder if the line | 100 | # .1.3.6.1.4.1.8072.3.2.67.3: |
| 115 | ends with with this: C:\\\\"').'/m', "Attempt to confuse parser No.2"); | 101 | # "It\'s getting even harder if the line |
| 102 | # ends with with this: C:\\\\"').'/m', "Attempt to confuse parser No.2"); | ||
| 116 | 103 | ||
| 117 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.4"); | 104 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.4"); |
| 118 | like($res->output, '/'.quotemeta('SNMP OK - And now have fun with with this: \"C:\\\\\" | | 105 | cmp_ok( $res->return_code, '==', 0, "Exit OK when querying multi-line OIDs" ); |
| 119 | .1.3.6.1.4.1.8072.3.2.67.4: | 106 | # like($res->output, '/'.quotemeta('And now have fun with with this: \"C:\\\\\" | |
| 120 | "And now have fun with with this: \"C:\\\\\" | 107 | # .1.3.6.1.4.1.8072.3.2.67.4: |
| 121 | because we\'re not done yet!"').'/m', "Attempt to confuse parser No.3"); | 108 | # "And now have fun with with this: \"C:\\\\\" |
| 109 | # because we\'re not done yet!"').'/m', "Attempt to confuse parser No.3"); | ||
| 122 | 110 | ||
| 123 | system("rm -f ".$ENV{'MP_STATE_PATH'}."/*/check_snmp/*"); | 111 | system("rm -f ".$ENV{'MP_STATE_PATH'}."/*/check_snmp/*"); |
| 124 | 112 | ||
| @@ -131,156 +119,159 @@ SKIP: { | |||
| 131 | my $ts = time(); | 119 | my $ts = time(); |
| 132 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" ); | 120 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" ); |
| 133 | is($res->return_code, 0, "Returns OK"); | 121 | is($res->return_code, 0, "Returns OK"); |
| 134 | is($res->output, "No previous data to calculate rate - assume okay"); | 122 | like($res->output, "/.*No previous data to calculate rate - assume okay.*/"); |
| 135 | 123 | ||
| 136 | # test rate 1 second later | 124 | # test rate 1 second later |
| 137 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" ); | 125 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" ); |
| 138 | is($res->return_code, 1, "WARNING - due to going above rate calculation" ); | 126 | is($res->return_code, 1, "WARNING - due to going above rate calculation" ); |
| 139 | is($res->output, "SNMP RATE WARNING - *666* | iso.3.6.1.4.1.8072.3.2.67.10=666;600 "); | 127 | like($res->output, "/.*=666.*/"); |
| 140 | 128 | ||
| 141 | # test rate with same time | 129 | # test rate with same time |
| 142 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" ); | 130 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" ); |
| 143 | is($res->return_code, 3, "UNKNOWN - basically the divide by zero error" ); | 131 | is($res->return_code, 3, "UNKNOWN - basically the divide by zero error" ); |
| 144 | is($res->output, "Time duration between plugin calls is invalid"); | 132 | like($res->output, "/.*Time duration between plugin calls is invalid.*/"); |
| 145 | 133 | ||
| 146 | 134 | ||
| 147 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" ); | 135 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" ); |
| 148 | is($res->return_code, 0, "OK for first call" ); | 136 | is($res->return_code, 0, "OK for first call" ); |
| 149 | is($res->output, "No previous data to calculate rate - assume okay" ); | 137 | like($res->output, "/.*No previous data to calculate rate - assume okay.*/" ); |
| 150 | 138 | ||
| 151 | # test rate 1 second later | 139 | # test rate 1 second later |
| 152 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" ); | 140 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" ); |
| 153 | is($res->return_code, 0, "OK as no thresholds" ); | 141 | is($res->return_code, 0, "OK as no thresholds" ); |
| 154 | is($res->output, "SNMP RATE OK - inoctets 666 | inoctets=666 ", "Check label"); | 142 | like($res->output, "/.*inoctets.*=666.*/m", "Check label"); |
| 155 | 143 | ||
| 156 | # test rate 3 seconds later | 144 | # test rate 3 seconds later |
| 157 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+3))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" ); | 145 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+3))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" ); |
| 158 | is($res->return_code, 0, "OK as no thresholds" ); | 146 | is($res->return_code, 0, "OK as no thresholds" ); |
| 159 | is($res->output, "SNMP RATE OK - inoctets 333 | inoctets=333 ", "Check rate decreases due to longer interval"); | 147 | like($res->output, "/.*inoctets.*333.*/", "Check rate decreases due to longer interval"); |
| 160 | 148 | ||
| 161 | 149 | ||
| 162 | # label performance data check | 150 | # label performance data check |
| 163 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test" ); | 151 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test" ); |
| 164 | is($res->return_code, 0, "OK as no thresholds" ); | 152 | is($res->return_code, 0, "OK as no thresholds" ); |
| 165 | is($res->output, "SNMP OK - test 67996 | test=67996c ", "Check label"); | 153 | like($res->output, "/.*test.?=67996c/", "Check label"); |
| 166 | 154 | ||
| 167 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l \"test'test\"" ); | 155 | # following test is deactivated since it was not valid due to the guidelines (no single quote in label allowed) |
| 168 | is($res->return_code, 0, "OK as no thresholds" ); | 156 | # $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l \"test'test\"" ); |
| 169 | is($res->output, "SNMP OK - test'test 68662 | \"test'test\"=68662c ", "Check label"); | 157 | # is($res->return_code, 0, "OK as no thresholds" ); |
| 158 | # is($res->output, "test'test 68662 | \"test'test\"=68662c ", "Check label"); | ||
| 170 | 159 | ||
| 171 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test\"test'" ); | 160 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test\"test'" ); |
| 172 | is($res->return_code, 0, "OK as no thresholds" ); | 161 | is($res->return_code, 0, "OK as no thresholds" ); |
| 173 | is($res->output, "SNMP OK - test\"test 69328 | 'test\"test'=69328c ", "Check label"); | 162 | like($res->output, "/.*'test\"test'=68662c.*/", "Check label"); |
| 174 | 163 | ||
| 175 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test -O" ); | 164 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test -O" ); |
| 176 | is($res->return_code, 0, "OK as no thresholds" ); | 165 | is($res->return_code, 0, "OK as no thresholds" ); |
| 177 | is($res->output, "SNMP OK - test 69994 | iso.3.6.1.4.1.8072.3.2.67.10=69994c ", "Check label"); | 166 | like($res->output, "/.*.67.10.?=69328c.*/", "Check label"); |
| 178 | 167 | ||
| 179 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10" ); | 168 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10" ); |
| 180 | is($res->return_code, 0, "OK as no thresholds" ); | 169 | is($res->return_code, 0, "OK as no thresholds" ); |
| 181 | is($res->output, "SNMP OK - 70660 | iso.3.6.1.4.1.8072.3.2.67.10=70660c ", "Check label"); | 170 | like($res->output, "/.*8072.3.2.67.10.?=69994c.*/", "Check label"); |
| 182 | 171 | ||
| 183 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test test'" ); | 172 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test test'" ); |
| 184 | is($res->return_code, 0, "OK as no thresholds" ); | 173 | is($res->return_code, 0, "OK as no thresholds" ); |
| 185 | is($res->output, "SNMP OK - test test 71326 | 'test test'=71326c ", "Check label"); | 174 | like($res->output, "/.*'test test'=70660c/", "Check label"); |
| 186 | 175 | ||
| 187 | 176 | ||
| 188 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" ); | 177 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" ); |
| 189 | is($res->return_code, 0, "OK for first call" ); | 178 | is($res->return_code, 0, "OK for first call" ); |
| 190 | is($res->output, "No previous data to calculate rate - assume okay" ); | 179 | like($res->output, "/.*No previous data to calculate rate - assume okay.*/" ); |
| 191 | 180 | ||
| 192 | # test 1 second later | 181 | # test 1 second later |
| 193 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" ); | 182 | $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" ); |
| 194 | is($res->return_code, 0, "OK as no thresholds" ); | 183 | is($res->return_code, 0, "OK as no thresholds" ); |
| 195 | is($res->output, "SNMP RATE OK - inoctets_per_minute 39960 | inoctets_per_minute=39960 ", "Checking multiplier"); | 184 | like($res->output, "/.*inoctets_per_minute.*=39960/", "Checking multiplier"); |
| 196 | }; | 185 | }; |
| 197 | 186 | ||
| 198 | 187 | ||
| 199 | 188 | ||
| 200 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s '\"stringtests\"'" ); | 189 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s 'stringtests'" ); |
| 201 | is($res->return_code, 0, "OK as string matches" ); | 190 | is($res->return_code, 0, "OK as string matches" ); |
| 202 | is($res->output, 'SNMP OK - "stringtests" | ', "Good string match" ); | 191 | like($res->output, '/.*stringtests.*/', "Good string match" ); |
| 203 | 192 | ||
| 204 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s ring" ); | 193 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s ring" ); |
| 205 | is($res->return_code, 2, "CRITICAL as string doesn't match (though is a substring)" ); | 194 | is($res->return_code, 2, "CRITICAL as string doesn't match (though is a substring)" ); |
| 206 | is($res->output, 'SNMP CRITICAL - *"stringtests"* | ', "Failed string match" ); | 195 | like($res->output, '/.*stringtests.*/', "Failed string match" ); |
| 207 | 196 | ||
| 208 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s '\"stringtests\"'" ); | 197 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s 'stringtests'" ); |
| 209 | is($res->return_code, 2, "CRITICAL as string matches but inverted" ); | 198 | is($res->return_code, 2, "CRITICAL as string matches but inverted" ); |
| 210 | is($res->output, 'SNMP CRITICAL - *"stringtests"* | ', "Inverted string match" ); | 199 | like($res->output, '/.*"stringtests".*/', "Inverted string match" ); |
| 211 | 200 | ||
| 212 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s ring" ); | 201 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 --invert-search -s ring" ); |
| 213 | is($res->return_code, 0, "OK as string doesn't match but inverted" ); | 202 | is($res->return_code, 0, "OK as string doesn't match but inverted" ); |
| 214 | is($res->output, 'SNMP OK - "stringtests" | ', "OK as inverted string no match" ); | 203 | like($res->output, '/.*"stringtests".*/', "OK as inverted string no match" ); |
| 215 | 204 | ||
| 216 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.12 -w 4:5" ); | 205 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.12 -w 4:5" ); |
| 217 | is($res->return_code, 1, "Numeric in string test" ); | 206 | # a string is a string and not a number |
| 218 | is($res->output, 'SNMP WARNING - *3.5* | iso.3.6.1.4.1.8072.3.2.67.12=3.5;4:5 ', "WARNING threshold checks for string masquerading as number" ); | 207 | is($res->return_code, 0, "Numeric in string test" ); |
| 208 | like($res->output, '/.*3.5.*| iso.3.6.1.4.1.8072.3.2.67.12=3.5;4:5/', "WARNING threshold checks for string masquerading as number" ); | ||
| 219 | 209 | ||
| 220 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.13" ); | 210 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.13" ); |
| 221 | is($res->return_code, 0, "Not really numeric test" ); | 211 | is($res->return_code, 0, "Not really numeric test" ); |
| 222 | is($res->output, 'SNMP OK - "87.4startswithnumberbutshouldbestring" | ', "Check string with numeric start is still string" ); | 212 | like($res->output, '/.*"87.4startswithnumberbutshouldbestring".*/', "Check string with numeric start is still string" ); |
| 223 | 213 | ||
| 224 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.14" ); | 214 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.14" ); |
| 225 | is($res->return_code, 0, "Not really numeric test (trying best to fool it)" ); | 215 | is($res->return_code, 0, "Not really numeric test (trying best to fool it)" ); |
| 226 | is($res->output, 'SNMP OK - "555\"I said\"" | ', "Check string with a double quote following is still a string (looks like the perl routine will always escape though)" ); | 216 | like($res->output, '/.*\'555"I said"\'.*/', "Check string with a double quote following is still a string (looks like the perl routine will always escape though)" ); |
| 227 | 217 | ||
| 228 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.15 -r 'CUSTOM CHECK OK'" ); | 218 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.15 -r 'CUSTOM CHECK OK'" ); |
| 229 | is($res->return_code, 0, "String check should check whole string, not a parsed number" ); | 219 | is($res->return_code, 0, "String check should check whole string, not a parsed number" ); |
| 230 | is($res->output, 'SNMP OK - "CUSTOM CHECK OK: foo is 12345" | ', "String check with numbers returns whole string"); | 220 | like($res->output, '/.*CUSTOM CHECK OK: foo is 12345.*/', "String check with numbers returns whole string"); |
| 231 | 221 | ||
| 232 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); | 222 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); |
| 233 | is($res->return_code, 0, "Negative integer check OK" ); | 223 | is($res->return_code, 0, "Negative integer check OK" ); |
| 234 | is($res->output, 'SNMP OK - -2 | iso.3.6.1.4.1.8072.3.2.67.16=-2;-2:;-3: ', "Negative integer check OK output" ); | 224 | like($res->output, '/.*-2.*| iso.3.6.1.4.1.8072.3.2.67.16=-2;-2:;-3:/', "Negative integer check OK output" ); |
| 235 | 225 | ||
| 236 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); | 226 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); |
| 237 | is($res->return_code, 1, "Negative integer check WARNING" ); | 227 | is($res->return_code, 1, "Negative integer check WARNING" ); |
| 238 | is($res->output, 'SNMP WARNING - *-3* | iso.3.6.1.4.1.8072.3.2.67.16=-3;-2:;-3: ', "Negative integer check WARNING output" ); | 228 | like($res->output, '/.*-3.*| iso.3.6.1.4.1.8072.3.2.67.16=-3;-2:;-3:/', "Negative integer check WARNING output" ); |
| 239 | 229 | ||
| 240 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); | 230 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.16 -w -2: -c -3:" ); |
| 241 | is($res->return_code, 2, "Negative integer check CRITICAL" ); | 231 | is($res->return_code, 2, "Negative integer check CRITICAL" ); |
| 242 | is($res->output, 'SNMP CRITICAL - *-4* | iso.3.6.1.4.1.8072.3.2.67.16=-4;-2:;-3: ', "Negative integer check CRITICAL output" ); | 232 | like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.16=-4;-2:;-3:/', "Negative integer check CRITICAL output" ); |
| 243 | 233 | ||
| 244 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.17 -w -3: -c -6:" ); | 234 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.17 -w -3: -c -6:" ); |
| 245 | is($res->return_code, 1, "Negative integer as string, WARNING" ); | 235 | is($res->return_code, 1, "Negative integer as string, WARNING" ); |
| 246 | is($res->output, 'SNMP WARNING - *-4* | iso.3.6.1.4.1.8072.3.2.67.17=-4;-3:;-6: ', "Negative integer as string, WARNING output" ); | 236 | like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.17=-4;-3:;-6:/', "Negative integer as string, WARNING output" ); |
| 247 | 237 | ||
| 248 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.17 -w -2: -c -3:" ); | 238 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.17 -w -2: -c -3:" ); |
| 249 | is($res->return_code, 2, "Negative integer as string, CRITICAL" ); | 239 | is($res->return_code, 2, "Negative integer as string, CRITICAL" ); |
| 250 | is($res->output, 'SNMP CRITICAL - *-4* | iso.3.6.1.4.1.8072.3.2.67.17=-4;-2:;-3: ', "Negative integer as string, CRITICAL output" ); | 240 | like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.17=-4;-2:;-3:/', "Negative integer as string, CRITICAL output" ); |
| 251 | 241 | ||
| 252 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -c '~:-6.5'" ); | 242 | # deactivated since the perl agent api of snmpd really does not allow floats |
| 253 | is($res->return_code, 0, "Negative float OK" ); | 243 | # $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -c '~:-6.5'" ); |
| 254 | is($res->output, 'SNMP OK - -6.6 | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;;@-6.5:~ ', "Negative float OK output" ); | 244 | # is($res->return_code, 0, "Negative float OK" ); |
| 245 | # is($res->output, '-6.6 | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;;@-6.5:~ ', "Negative float OK output" ); | ||
| 255 | 246 | ||
| 256 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -w '~:-6.65' -c '~:-6.55'" ); | 247 | # $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.18 -w '~:-6.65' -c '~:-6.55'" ); |
| 257 | is($res->return_code, 1, "Negative float WARNING" ); | 248 | # is($res->return_code, 1, "Negative float WARNING" ); |
| 258 | is($res->output, 'SNMP WARNING - *-6.6* | iso.3.6.1.4.1.8072.3.2.67.18=-6.6;@-6.65:~;@-6.55:~ ', "Negative float WARNING output" ); | 249 | # like($res->output, '/-6.6.*| .*67.18=-6.6;@-6.65:~;@-6.55:~/', "Negative float WARNING output" ); |
| 259 | 250 | ||
| 260 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-10:20' -c '2:200000,-20:30'" ); | 251 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-10:20' -c '2:200000,-20:30'" ); |
| 261 | is($res->return_code, 0, "Multiple OIDs with thresholds" ); | 252 | is($res->return_code, 0, "Multiple OIDs with thresholds" ); |
| 262 | like($res->output, '/SNMP OK - \d+ -4 | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" ); | 253 | like($res->output, '/-4.*| .*67.10=\d+c;1:100000;2:200000 .*67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" ); |
| 263 | 254 | ||
| 264 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-1:2' -c '2:200000,-20:30'" ); | 255 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w '1:100000,-1:2' -c '2:200000,-20:30'" ); |
| 265 | is($res->return_code, 1, "Multiple OIDs with thresholds" ); | 256 | is($res->return_code, 1, "Multiple OIDs with thresholds" ); |
| 266 | like($res->output, '/SNMP WARNING - \d+ \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" ); | 257 | like($res->output, '/-4.*| iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1:100000;2:200000 iso.3.6.1.4.1.8072.3.2.67.17=-4;-10:20;-20:30/', "Multiple OIDs with thresholds output" ); |
| 267 | 258 | ||
| 268 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1" ); | 259 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10,.1.3.6.1.4.1.8072.3.2.67.17 -w 1,2 -c 1 -O" ); |
| 269 | is($res->return_code, 2, "Multiple OIDs with some thresholds" ); | 260 | is($res->return_code, 2, "Multiple OIDs with some thresholds" ); |
| 270 | like($res->output, '/SNMP CRITICAL - \*\d+\* \*-4\* | iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" ); | 261 | like($res->output, '/.*-4.*| iso.3.6.1.4.1.8072.3.2.67.10=\d+c;1;2 iso.3.6.1.4.1.8072.3.2.67.17=-4;;/', "Multiple OIDs with thresholds output" ); |
| 271 | 262 | ||
| 272 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19"); | 263 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19"); |
| 273 | is($res->return_code, 0, "Test plain .1.3.6.1.4.1.8072.3.2.67.6 RC" ); | 264 | is($res->return_code, 0, "Test plain .1.3.6.1.4.1.8072.3.2.67.6 RC" ); |
| 274 | is($res->output,'SNMP OK - 42 | iso.3.6.1.4.1.8072.3.2.67.19=42 ', "Test plain value of .1.3.6.1.4.1.8072.3.2.67.1" ); | 265 | like($res->output,'/.*42.*| iso.3.6.1.4.1.8072.3.2.67.19=42/', "Test plain value of .1.3.6.1.4.1.8072.3.2.67.1" ); |
| 275 | 266 | ||
| 276 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 -M .1"); | 267 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 -M .1"); |
| 277 | is($res->return_code, 0, "Test multiply RC" ); | 268 | is($res->return_code, 0, "Test multiply RC" ); |
| 278 | is($res->output,'SNMP OK - 4.200000 | iso.3.6.1.4.1.8072.3.2.67.19=4.200000 ' , "Test multiply .1 output" ); | 269 | like($res->output,'/.*4.200000.*| iso.3.6.1.4.1.8072.3.2.67.19=4.200000/' , "Test multiply .1 output" ); |
| 279 | 270 | ||
| 280 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' "); | 271 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1"); |
| 281 | is($res->return_code, 0, "Test multiply RC + format" ); | 272 | is($res->return_code, 0, "Test multiply RC" ); |
| 282 | is($res->output, 'SNMP OK - 4.20 | iso.3.6.1.4.1.8072.3.2.67.19=4.20 ', "Test multiply .1 output + format" ); | 273 | like($res->output, '/.*4.20.*| iso.3.6.1.4.1.8072.3.2.67.19=4.20/', "Test multiply .1 output" ); |
| 283 | 274 | ||
| 284 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -f '%.2f' -w 1"); | 275 | $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.19 --multiplier=.1 -w 1"); |
| 285 | is($res->return_code, 1, "Test multiply RC + format + thresholds" ); | 276 | is($res->return_code, 1, "Test multiply RC + thresholds" ); |
| 286 | is($res->output, 'SNMP WARNING - *4.20* | iso.3.6.1.4.1.8072.3.2.67.19=4.20;1 ', "Test multiply .1 output + format + thresholds" ); | 277 | like($res->output, '/.*4.20.* | iso.3.6.1.4.1.8072.3.2.67.19=4.20+;1/', "Test multiply .1 output + thresholds" ); |
diff --git a/plugins/tests/check_snmp_agent.pl b/plugins/tests/check_snmp_agent.pl index 38912e98..608b6f92 100644 --- a/plugins/tests/check_snmp_agent.pl +++ b/plugins/tests/check_snmp_agent.pl | |||
| @@ -4,9 +4,10 @@ | |||
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | #use strict; # Doesn't work | 6 | #use strict; # Doesn't work |
| 7 | use warnings; | ||
| 7 | use NetSNMP::OID qw(:all); | 8 | use NetSNMP::OID qw(:all); |
| 8 | use NetSNMP::agent; | 9 | use NetSNMP::agent; |
| 9 | use NetSNMP::ASN qw(ASN_OCTET_STR ASN_COUNTER ASN_COUNTER64 ASN_INTEGER ASN_INTEGER64 ASN_UNSIGNED ASN_UNSIGNED64); | 10 | use NetSNMP::ASN qw(ASN_OCTET_STR ASN_COUNTER ASN_COUNTER64 ASN_INTEGER ASN_INTEGER64 ASN_UNSIGNED ASN_UNSIGNED64 ASN_FLOAT); |
| 10 | #use Math::Int64 qw(uint64); # Skip that module while we don't need it | 11 | #use Math::Int64 qw(uint64); # Skip that module while we don't need it |
| 11 | sub uint64 { return $_ } | 12 | sub uint64 { return $_ } |
| 12 | 13 | ||
| @@ -22,21 +23,82 @@ IOS (tm) Catalyst 4000 "L3" Switch Software (cat4000-I9K91S-M), Version | |||
| 22 | Technical Support: http://www.cisco.com/techsupport | 23 | Technical Support: http://www.cisco.com/techsupport |
| 23 | Copyright (c) 1986-2004 by cisco Systems, Inc. | 24 | Copyright (c) 1986-2004 by cisco Systems, Inc. |
| 24 | '; | 25 | '; |
| 25 | my $multilin2 = "Kisco Outernetwork Oserating Gystem Totware | 26 | my $multiline2 = "Kisco Outernetwork Oserating Gystem Totware |
| 26 | Copyleft (c) 2400-2689 by kisco Systrems, Inc."; | 27 | Copyleft (c) 2400-2689 by kisco Systrems, Inc."; |
| 27 | my $multilin3 = 'This should not confuse check_snmp "parser" | 28 | my $multiline3 = 'This should not confuse check_snmp "parser" |
| 28 | into thinking there is no 2nd line'; | 29 | into thinking there is no 2nd line'; |
| 29 | my $multilin4 = 'It\'s getting even harder if the line | 30 | my $multiline4 = 'It\'s getting even harder if the line |
| 30 | ends with with this: C:\\'; | 31 | ends with with this: C:\\'; |
| 31 | my $multilin5 = 'And now have fun with with this: "C:\\" | 32 | my $multiline5 = 'And now have fun with with this: "C:\\" |
| 32 | because we\'re not done yet!'; | 33 | because we\'re not done yet!'; |
| 33 | 34 | ||
| 34 | # Next are arrays of indexes (Type, initial value and increments) | 35 | # Next are arrays of indexes (Type, initial value and increments) |
| 35 | # 0..19 <---- please update comment when adding/removing fields | 36 | # 0..19 <---- please update comment when adding/removing fields |
| 36 | my @fields = (ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_UNSIGNED, ASN_UNSIGNED, ASN_COUNTER, ASN_COUNTER64, ASN_UNSIGNED, ASN_COUNTER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER, ASN_OCTET_STR, ASN_OCTET_STR, ASN_INTEGER ); | 37 | my @fields = (ASN_OCTET_STR, # 0 |
| 37 | my @values = ($multiline, $multilin2, $multilin3, $multilin4, $multilin5, 4294965296, 1000, 4294965296, uint64("18446744073709351616"), int(rand(2**32)), 64000, "stringtests", "3.5", "87.4startswithnumberbutshouldbestring", '555"I said"', 'CUSTOM CHECK OK: foo is 12345', -2, '-4', '-6.6', 42 ); | 38 | ASN_OCTET_STR, # 1 |
| 39 | ASN_OCTET_STR, # 2 | ||
| 40 | ASN_OCTET_STR, # 3 | ||
| 41 | ASN_OCTET_STR, # 4 | ||
| 42 | ASN_UNSIGNED, # 5 | ||
| 43 | ASN_UNSIGNED, # 6 | ||
| 44 | ASN_COUNTER, # 7 | ||
| 45 | ASN_COUNTER64, # 8 | ||
| 46 | ASN_UNSIGNED, # 9 | ||
| 47 | ASN_COUNTER, # 10 | ||
| 48 | ASN_OCTET_STR, # 11 | ||
| 49 | ASN_OCTET_STR, # 12 | ||
| 50 | ASN_OCTET_STR, # 13 | ||
| 51 | ASN_OCTET_STR, # 14 | ||
| 52 | ASN_OCTET_STR, # 15 | ||
| 53 | ASN_INTEGER, # 16 | ||
| 54 | ASN_INTEGER, # 17 | ||
| 55 | ASN_FLOAT, # 18 | ||
| 56 | ASN_INTEGER # 19 | ||
| 57 | ); | ||
| 58 | my @values = ($multiline, # 0 | ||
| 59 | $multiline2, # 1 | ||
| 60 | $multiline3, # 2 | ||
| 61 | $multiline4, # 3 | ||
| 62 | $multiline5, # 4 | ||
| 63 | 4294965296, # 5 | ||
| 64 | 1000, # 6 | ||
| 65 | 4294965296, # 7 | ||
| 66 | uint64("18446744073709351616"), # 8 | ||
| 67 | int(rand(2**32)), # 9 | ||
| 68 | 64000, # 10 | ||
| 69 | "stringtests", # 11 | ||
| 70 | "3.5", # 12 | ||
| 71 | "87.4startswithnumberbutshouldbestring", # 13 | ||
| 72 | '555"I said"', # 14 | ||
| 73 | 'CUSTOM CHECK OK: foo is 12345', # 15 | ||
| 74 | '-2', # 16 | ||
| 75 | '-4', # 17 | ||
| 76 | '-6.6', # 18 | ||
| 77 | 42 # 19 | ||
| 78 | ); | ||
| 38 | # undef increments are randomized | 79 | # undef increments are randomized |
| 39 | my @incrts = (undef, undef, undef, undef, undef, 1000, -500, 1000, 100000, undef, 666, undef, undef, undef, undef, undef, -1, undef, undef, 0 ); | 80 | my @incrts = ( |
| 81 | undef, # 0 | ||
| 82 | undef, # 1 | ||
| 83 | undef, # 2 | ||
| 84 | undef, # 3 | ||
| 85 | undef, # 4 | ||
| 86 | 1000, # 5 | ||
| 87 | -500, # 6 | ||
| 88 | 1000, # 7 | ||
| 89 | 100000, # 8 | ||
| 90 | undef, # 9 | ||
| 91 | 666, # 10 | ||
| 92 | undef, # 11 | ||
| 93 | undef, # 12 | ||
| 94 | undef, # 13 | ||
| 95 | undef, # 14 | ||
| 96 | undef, # 15 | ||
| 97 | -1, # 16 | ||
| 98 | 0, # 17 | ||
| 99 | undef, # 18 | ||
| 100 | 0 # 19 | ||
| 101 | ); | ||
| 40 | 102 | ||
| 41 | # Number of elements in our OID | 103 | # Number of elements in our OID |
| 42 | my $oidelts; | 104 | my $oidelts; |
diff --git a/plugins/tests/conf/snmpd.conf b/plugins/tests/conf/snmpd.conf index eff5b0b3..1724c027 100644 --- a/plugins/tests/conf/snmpd.conf +++ b/plugins/tests/conf/snmpd.conf | |||
| @@ -19,5 +19,5 @@ syscontact Alice | |||
| 19 | # Embedded Subagents | 19 | # Embedded Subagents |
| 20 | ############################################################################### | 20 | ############################################################################### |
| 21 | 21 | ||
| 22 | perl do "tests/check_snmp_agent.pl"; | 22 | perl do "./tests/check_snmp_agent.pl"; |
| 23 | 23 | ||
diff --git a/lib/tests/test_disk.c b/plugins/tests/test_check_disk.c index c18db7a4..32b46c2d 100644 --- a/lib/tests/test_disk.c +++ b/plugins/tests/test_check_disk.c | |||
| @@ -17,28 +17,17 @@ | |||
| 17 | *****************************************************************************/ | 17 | *****************************************************************************/ |
| 18 | 18 | ||
| 19 | #include "common.h" | 19 | #include "common.h" |
| 20 | #include "utils_disk.h" | 20 | #include "../check_disk.d/utils_disk.h" |
| 21 | #include "tap.h" | 21 | #include "../../tap/tap.h" |
| 22 | #include "regex.h" | 22 | #include "regex.h" |
| 23 | 23 | ||
| 24 | void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc); | 24 | void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, |
| 25 | int expect, char *desc); | ||
| 25 | 26 | ||
| 26 | int main(int argc, char **argv) { | 27 | int main(int argc, char **argv) { |
| 27 | struct name_list *exclude_filesystem = NULL; | 28 | plan_tests(35); |
| 28 | struct name_list *exclude_fstype = NULL; | ||
| 29 | struct name_list *dummy_mountlist = NULL; | ||
| 30 | struct name_list *temp_name; | ||
| 31 | struct parameter_list *paths = NULL; | ||
| 32 | struct parameter_list *p, *prev = NULL, *last = NULL; | ||
| 33 | |||
| 34 | struct mount_entry *dummy_mount_list; | ||
| 35 | struct mount_entry *me; | ||
| 36 | struct mount_entry **mtail = &dummy_mount_list; | ||
| 37 | int cflags = REG_NOSUB | REG_EXTENDED; | ||
| 38 | int found = 0, count = 0; | ||
| 39 | |||
| 40 | plan_tests(33); | ||
| 41 | 29 | ||
| 30 | struct name_list *exclude_filesystem = NULL; | ||
| 42 | ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list"); | 31 | ok(np_find_name(exclude_filesystem, "/var/log") == false, "/var/log not in list"); |
| 43 | np_add_name(&exclude_filesystem, "/var/log"); | 32 | np_add_name(&exclude_filesystem, "/var/log"); |
| 44 | ok(np_find_name(exclude_filesystem, "/var/log") == true, "is in list now"); | 33 | ok(np_find_name(exclude_filesystem, "/var/log") == true, "is in list now"); |
| @@ -47,6 +36,7 @@ int main(int argc, char **argv) { | |||
| 47 | ok(np_find_name(exclude_filesystem, "/home") == true, "is in list now"); | 36 | ok(np_find_name(exclude_filesystem, "/home") == true, "is in list now"); |
| 48 | ok(np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list"); | 37 | ok(np_find_name(exclude_filesystem, "/var/log") == true, "/var/log still in list"); |
| 49 | 38 | ||
| 39 | struct name_list *exclude_fstype = NULL; | ||
| 50 | ok(np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list"); | 40 | ok(np_find_name(exclude_fstype, "iso9660") == false, "iso9660 not in list"); |
| 51 | np_add_name(&exclude_fstype, "iso9660"); | 41 | np_add_name(&exclude_fstype, "iso9660"); |
| 52 | ok(np_find_name(exclude_fstype, "iso9660") == true, "is in list now"); | 42 | ok(np_find_name(exclude_fstype, "iso9660") == true, "is in list now"); |
| @@ -59,7 +49,9 @@ int main(int argc, char **argv) { | |||
| 59 | } | 49 | } |
| 60 | */ | 50 | */ |
| 61 | 51 | ||
| 62 | me = (struct mount_entry *)malloc(sizeof *me); | 52 | struct mount_entry *dummy_mount_list; |
| 53 | struct mount_entry **mtail = &dummy_mount_list; | ||
| 54 | struct mount_entry *me = (struct mount_entry *)malloc(sizeof *me); | ||
| 63 | me->me_devname = strdup("/dev/c0t0d0s0"); | 55 | me->me_devname = strdup("/dev/c0t0d0s0"); |
| 64 | me->me_mountdir = strdup("/"); | 56 | me->me_mountdir = strdup("/"); |
| 65 | *mtail = me; | 57 | *mtail = me; |
| @@ -77,50 +69,70 @@ int main(int argc, char **argv) { | |||
| 77 | *mtail = me; | 69 | *mtail = me; |
| 78 | mtail = &me->me_next; | 70 | mtail = &me->me_next; |
| 79 | 71 | ||
| 72 | int cflags = REG_NOSUB | REG_EXTENDED; | ||
| 80 | np_test_mount_entry_regex(dummy_mount_list, strdup("/"), cflags, 3, strdup("a")); | 73 | np_test_mount_entry_regex(dummy_mount_list, strdup("/"), cflags, 3, strdup("a")); |
| 81 | np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"), cflags, 3, strdup("regex on dev names:")); | 74 | np_test_mount_entry_regex(dummy_mount_list, strdup("/dev"), cflags, 3, |
| 82 | np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"), cflags, 0, strdup("regex on non existent dev/path:")); | 75 | strdup("regex on dev names:")); |
| 83 | np_test_mount_entry_regex(dummy_mount_list, strdup("/Foo"), cflags | REG_ICASE, 0, strdup("regi on non existent dev/path:")); | 76 | np_test_mount_entry_regex(dummy_mount_list, strdup("/foo"), cflags, 0, |
| 84 | np_test_mount_entry_regex(dummy_mount_list, strdup("/c.t0"), cflags, 3, strdup("partial devname regex match:")); | 77 | strdup("regex on non existent dev/path:")); |
| 85 | np_test_mount_entry_regex(dummy_mount_list, strdup("c0t0"), cflags, 1, strdup("partial devname regex match:")); | 78 | np_test_mount_entry_regex(dummy_mount_list, strdup("/Foo"), cflags | REG_ICASE, 0, |
| 86 | np_test_mount_entry_regex(dummy_mount_list, strdup("C0t0"), cflags | REG_ICASE, 1, strdup("partial devname regi match:")); | 79 | strdup("regi on non existent dev/path:")); |
| 87 | np_test_mount_entry_regex(dummy_mount_list, strdup("home"), cflags, 1, strdup("partial pathname regex match:")); | 80 | np_test_mount_entry_regex(dummy_mount_list, strdup("/c.t0"), cflags, 3, |
| 88 | np_test_mount_entry_regex(dummy_mount_list, strdup("hOme"), cflags | REG_ICASE, 1, strdup("partial pathname regi match:")); | 81 | strdup("partial devname regex match:")); |
| 89 | np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, strdup("grouped regex pathname match:")); | 82 | np_test_mount_entry_regex(dummy_mount_list, strdup("c0t0"), cflags, 1, |
| 90 | np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, strdup("grouped regi pathname match:")); | 83 | strdup("partial devname regex match:")); |
| 91 | 84 | np_test_mount_entry_regex(dummy_mount_list, strdup("C0t0"), cflags | REG_ICASE, 1, | |
| 92 | np_add_parameter(&paths, "/home/groups"); | 85 | strdup("partial devname regi match:")); |
| 93 | np_add_parameter(&paths, "/var"); | 86 | np_test_mount_entry_regex(dummy_mount_list, strdup("home"), cflags, 1, |
| 94 | np_add_parameter(&paths, "/tmp"); | 87 | strdup("partial pathname regex match:")); |
| 95 | np_add_parameter(&paths, "/home/tonvoon"); | 88 | np_test_mount_entry_regex(dummy_mount_list, strdup("hOme"), cflags | REG_ICASE, 1, |
| 96 | np_add_parameter(&paths, "/dev/c2t0d0s0"); | 89 | strdup("partial pathname regi match:")); |
| 97 | 90 | np_test_mount_entry_regex(dummy_mount_list, strdup("(/home)|(/var)"), cflags, 2, | |
| 98 | np_set_best_match(paths, dummy_mount_list, false); | 91 | strdup("grouped regex pathname match:")); |
| 99 | for (p = paths; p; p = p->name_next) { | 92 | np_test_mount_entry_regex(dummy_mount_list, strdup("(/homE)|(/Var)"), cflags | REG_ICASE, 2, |
| 93 | strdup("grouped regi pathname match:")); | ||
| 94 | |||
| 95 | filesystem_list test_paths = filesystem_list_init(); | ||
| 96 | mp_int_fs_list_append(&test_paths, "/home/groups"); | ||
| 97 | mp_int_fs_list_append(&test_paths, "/var"); | ||
| 98 | mp_int_fs_list_append(&test_paths, "/tmp"); | ||
| 99 | mp_int_fs_list_append(&test_paths, "/home/tonvoon"); | ||
| 100 | mp_int_fs_list_append(&test_paths, "/dev/c2t0d0s0"); | ||
| 101 | ok(test_paths.length == 5, "List counter works correctly with appends"); | ||
| 102 | |||
| 103 | mp_int_fs_list_set_best_match(test_paths, dummy_mount_list, false); | ||
| 104 | for (parameter_list_elem *p = test_paths.first; p; p = mp_int_fs_list_get_next(p)) { | ||
| 100 | struct mount_entry *temp_me; | 105 | struct mount_entry *temp_me; |
| 101 | temp_me = p->best_match; | 106 | temp_me = p->best_match; |
| 102 | if (!strcmp(p->name, "/home/groups")) { | 107 | if (!strcmp(p->name, "/home/groups")) { |
| 103 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/groups got right best match: /home"); | 108 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), |
| 109 | "/home/groups got right best match: /home"); | ||
| 104 | } else if (!strcmp(p->name, "/var")) { | 110 | } else if (!strcmp(p->name, "/var")) { |
| 105 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/var"), "/var got right best match: /var"); | 111 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/var"), "/var got right best match: /var"); |
| 106 | } else if (!strcmp(p->name, "/tmp")) { | 112 | } else if (!strcmp(p->name, "/tmp")) { |
| 107 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/"), "/tmp got right best match: /"); | 113 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/"), "/tmp got right best match: /"); |
| 108 | } else if (!strcmp(p->name, "/home/tonvoon")) { | 114 | } else if (!strcmp(p->name, "/home/tonvoon")) { |
| 109 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), "/home/tonvoon got right best match: /home"); | 115 | ok(temp_me && !strcmp(temp_me->me_mountdir, "/home"), |
| 116 | "/home/tonvoon got right best match: /home"); | ||
| 110 | } else if (!strcmp(p->name, "/dev/c2t0d0s0")) { | 117 | } else if (!strcmp(p->name, "/dev/c2t0d0s0")) { |
| 111 | ok(temp_me && !strcmp(temp_me->me_devname, "/dev/c2t0d0s0"), "/dev/c2t0d0s0 got right best match: /dev/c2t0d0s0"); | 118 | ok(temp_me && !strcmp(temp_me->me_devname, "/dev/c2t0d0s0"), |
| 119 | "/dev/c2t0d0s0 got right best match: /dev/c2t0d0s0"); | ||
| 112 | } | 120 | } |
| 113 | } | 121 | } |
| 114 | 122 | ||
| 115 | paths = NULL; /* Bad boy - should free, but this is a test suite */ | 123 | for (parameter_list_elem *p = test_paths.first; p; p = mp_int_fs_list_get_next(p)) { |
| 116 | np_add_parameter(&paths, "/home/groups"); | 124 | mp_int_fs_list_del(&test_paths, p); |
| 117 | np_add_parameter(&paths, "/var"); | 125 | } |
| 118 | np_add_parameter(&paths, "/tmp"); | 126 | ok(test_paths.length == 0, "List delete sets counter properly"); |
| 119 | np_add_parameter(&paths, "/home/tonvoon"); | ||
| 120 | np_add_parameter(&paths, "/home"); | ||
| 121 | 127 | ||
| 122 | np_set_best_match(paths, dummy_mount_list, true); | 128 | mp_int_fs_list_append(&test_paths, "/home/groups"); |
| 123 | for (p = paths; p; p = p->name_next) { | 129 | mp_int_fs_list_append(&test_paths, "/var"); |
| 130 | mp_int_fs_list_append(&test_paths, "/tmp"); | ||
| 131 | mp_int_fs_list_append(&test_paths, "/home/tonvoon"); | ||
| 132 | mp_int_fs_list_append(&test_paths, "/home"); | ||
| 133 | |||
| 134 | mp_int_fs_list_set_best_match(test_paths, dummy_mount_list, true); | ||
| 135 | for (parameter_list_elem *p = test_paths.first; p; p = mp_int_fs_list_get_next(p)) { | ||
| 124 | if (!strcmp(p->name, "/home/groups")) { | 136 | if (!strcmp(p->name, "/home/groups")) { |
| 125 | ok(!p->best_match, "/home/groups correctly not found"); | 137 | ok(!p->best_match, "/home/groups correctly not found"); |
| 126 | } else if (!strcmp(p->name, "/var")) { | 138 | } else if (!strcmp(p->name, "/var")) { |
| @@ -134,59 +146,68 @@ int main(int argc, char **argv) { | |||
| 134 | } | 146 | } |
| 135 | } | 147 | } |
| 136 | 148 | ||
| 149 | bool found = false; | ||
| 137 | /* test deleting first element in paths */ | 150 | /* test deleting first element in paths */ |
| 138 | paths = np_del_parameter(paths, NULL); | 151 | mp_int_fs_list_del(&test_paths, NULL); |
| 139 | for (p = paths; p; p = p->name_next) { | 152 | for (parameter_list_elem *p = test_paths.first; p; p = mp_int_fs_list_get_next(p)) { |
| 140 | if (!strcmp(p->name, "/home/groups")) | 153 | if (!strcmp(p->name, "/home/groups")) { |
| 141 | found = 1; | 154 | found = true; |
| 155 | } | ||
| 142 | } | 156 | } |
| 143 | ok(found == 0, "first element successfully deleted"); | 157 | ok(!found, "first element successfully deleted"); |
| 144 | found = 0; | 158 | found = false; |
| 145 | 159 | ||
| 146 | p = paths; | 160 | parameter_list_elem *prev = NULL; |
| 147 | while (p) { | 161 | parameter_list_elem *p = NULL; |
| 148 | if (!strcmp(p->name, "/tmp")) | 162 | for (parameter_list_elem *path = test_paths.first; path; path = mp_int_fs_list_get_next(path)) { |
| 149 | p = np_del_parameter(p, prev); | 163 | if (!strcmp(path->name, "/tmp")) { |
| 150 | else { | 164 | mp_int_fs_list_del(&test_paths, path); |
| 151 | prev = p; | ||
| 152 | p = p->name_next; | ||
| 153 | } | 165 | } |
| 166 | p = path; | ||
| 154 | } | 167 | } |
| 155 | 168 | ||
| 156 | for (p = paths; p; p = p->name_next) { | 169 | parameter_list_elem *last = NULL; |
| 157 | if (!strcmp(p->name, "/tmp")) | 170 | for (parameter_list_elem *path = test_paths.first; path; path = mp_int_fs_list_get_next(path)) { |
| 158 | found = 1; | 171 | if (!strcmp(path->name, "/tmp")) { |
| 159 | if (p->name_next) | 172 | found = true; |
| 160 | prev = p; | 173 | } |
| 161 | else | 174 | if (path->next) { |
| 162 | last = p; | 175 | prev = path; |
| 176 | } else { | ||
| 177 | last = path; | ||
| 178 | } | ||
| 163 | } | 179 | } |
| 164 | ok(found == 0, "/tmp element successfully deleted"); | 180 | ok(!found, "/tmp element successfully deleted"); |
| 165 | 181 | ||
| 166 | p = np_del_parameter(last, prev); | 182 | int count = 0; |
| 167 | for (p = paths; p; p = p->name_next) { | 183 | mp_int_fs_list_del(&test_paths, p); |
| 168 | if (!strcmp(p->name, "/home")) | 184 | for (p = test_paths.first; p; p = p->next) { |
| 169 | found = 1; | 185 | if (!strcmp(p->name, "/home")) { |
| 186 | found = true; | ||
| 187 | } | ||
| 170 | last = p; | 188 | last = p; |
| 171 | count++; | 189 | count++; |
| 172 | } | 190 | } |
| 173 | ok(found == 0, "last (/home) element successfully deleted"); | 191 | ok(!found, "last (/home) element successfully deleted"); |
| 174 | ok(count == 2, "two elements remaining"); | 192 | ok(count == 2, "two elements remaining"); |
| 175 | 193 | ||
| 176 | return exit_status(); | 194 | return exit_status(); |
| 177 | } | 195 | } |
| 178 | 196 | ||
| 179 | void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, int expect, char *desc) { | 197 | void np_test_mount_entry_regex(struct mount_entry *dummy_mount_list, char *regstr, int cflags, |
| 180 | int matches = 0; | 198 | int expect, char *desc) { |
| 181 | regex_t re; | 199 | regex_t regex; |
| 182 | struct mount_entry *me; | 200 | if (regcomp(®ex, regstr, cflags) == 0) { |
| 183 | if (regcomp(&re, regstr, cflags) == 0) { | 201 | int matches = 0; |
| 184 | for (me = dummy_mount_list; me; me = me->me_next) { | 202 | for (struct mount_entry *me = dummy_mount_list; me; me = me->me_next) { |
| 185 | if (np_regex_match_mount_entry(me, &re)) | 203 | if (np_regex_match_mount_entry(me, ®ex)) { |
| 186 | matches++; | 204 | matches++; |
| 205 | } | ||
| 187 | } | 206 | } |
| 188 | ok(matches == expect, "%s '%s' matched %i/3 entries. ok: %i/3", desc, regstr, expect, matches); | 207 | ok(matches == expect, "%s '%s' matched %i/3 entries. ok: %i/3", desc, regstr, expect, |
| 208 | matches); | ||
| 189 | 209 | ||
| 190 | } else | 210 | } else { |
| 191 | ok(false, "regex '%s' not compilable", regstr); | 211 | ok(false, "regex '%s' not compilable", regstr); |
| 212 | } | ||
| 192 | } | 213 | } |
diff --git a/plugins/tests/test_check_disk.t b/plugins/tests/test_check_disk.t new file mode 100755 index 00000000..56354650 --- /dev/null +++ b/plugins/tests/test_check_disk.t | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | use Test::More; | ||
| 3 | if (! -e "./test_check_disk") { | ||
| 4 | plan skip_all => "./test_check_disk not compiled - please enable libtap library to test"; | ||
| 5 | } | ||
| 6 | exec "./test_check_disk"; | ||
diff --git a/plugins/tests/test_check_snmp.c b/plugins/tests/test_check_snmp.c new file mode 100644 index 00000000..d71706d0 --- /dev/null +++ b/plugins/tests/test_check_snmp.c | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 3 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | * | ||
| 16 | * | ||
| 17 | *****************************************************************************/ | ||
| 18 | |||
| 19 | #include "tap.h" | ||
| 20 | #include "../../config.h" | ||
| 21 | |||
| 22 | #include <unistd.h> | ||
| 23 | #include <sys/types.h> | ||
| 24 | #include <sys/stat.h> | ||
| 25 | |||
| 26 | #include "utils_base.c" | ||
| 27 | #include "../check_snmp.d/check_snmp_helpers.h" | ||
| 28 | |||
| 29 | char *_np_state_generate_key(int argc, char **argv); | ||
| 30 | char *_np_state_calculate_location_prefix(void); | ||
| 31 | |||
| 32 | int main(int argc, char **argv) { | ||
| 33 | char *temp_string = (char *)_np_state_generate_key(argc, argv); | ||
| 34 | ok(!strcmp(temp_string, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), | ||
| 35 | "Got hash with exe and no parameters") || | ||
| 36 | diag("You are probably running in wrong directory. Must run as ./test_utils"); | ||
| 37 | |||
| 38 | int fake_argc = 4; | ||
| 39 | char *fake_argv[] = { | ||
| 40 | "./test_utils", | ||
| 41 | "here", | ||
| 42 | "--and", | ||
| 43 | "now", | ||
| 44 | }; | ||
| 45 | temp_string = (char *)_np_state_generate_key(fake_argc, fake_argv); | ||
| 46 | ok(!strcmp(temp_string, "bd72da9f78ff1419fad921ea5e43ce56508aef6c"), | ||
| 47 | "Got based on expected argv"); | ||
| 48 | |||
| 49 | unsetenv("MP_STATE_PATH"); | ||
| 50 | temp_string = (char *)_np_state_calculate_location_prefix(); | ||
| 51 | ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory"); | ||
| 52 | |||
| 53 | setenv("MP_STATE_PATH", "", 1); | ||
| 54 | temp_string = (char *)_np_state_calculate_location_prefix(); | ||
| 55 | ok(!strcmp(temp_string, NP_STATE_DIR_PREFIX), "Got default directory even with empty string"); | ||
| 56 | |||
| 57 | setenv("MP_STATE_PATH", "/usr/local/nagios/var", 1); | ||
| 58 | temp_string = (char *)_np_state_calculate_location_prefix(); | ||
| 59 | ok(!strcmp(temp_string, "/usr/local/nagios/var"), "Got default directory"); | ||
| 60 | |||
| 61 | fake_argc = 1; | ||
| 62 | fake_argv[0] = "./test_utils"; | ||
| 63 | state_key temp_state_key1 = np_enable_state(NULL, 51, "check_test", fake_argc, fake_argv); | ||
| 64 | ok(!strcmp(temp_state_key1.plugin_name, "check_test"), "Got plugin name"); | ||
| 65 | ok(!strcmp(temp_state_key1.name, "e2d17f995fd4c020411b85e3e3d0ff7306d4147e"), | ||
| 66 | "Got generated filename"); | ||
| 67 | |||
| 68 | state_key temp_state_key2 = | ||
| 69 | np_enable_state("allowedchars_in_keyname", 77, "check_snmp", fake_argc, fake_argv); | ||
| 70 | |||
| 71 | char state_path[1024]; | ||
| 72 | sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/allowedchars_in_keyname", | ||
| 73 | (unsigned long)geteuid()); | ||
| 74 | ok(!strcmp(temp_state_key2.plugin_name, "check_test"), "Got plugin name"); | ||
| 75 | ok(!strcmp(temp_state_key2.name, "allowedchars_in_keyname"), "Got key name with valid chars"); | ||
| 76 | ok(!strcmp(temp_state_key2._filename, state_path), "Got internal filename"); | ||
| 77 | |||
| 78 | /* Don't do this test just yet. Will die */ | ||
| 79 | /* | ||
| 80 | np_enable_state("bad^chars$in@here", 77); | ||
| 81 | temp_state_key = this_monitoring_plugin->state; | ||
| 82 | ok( !strcmp(temp_state_key->name, "bad_chars_in_here"), "Got key name with bad chars replaced" | ||
| 83 | ); | ||
| 84 | */ | ||
| 85 | |||
| 86 | state_key temp_state_key3 = | ||
| 87 | np_enable_state("funnykeyname", 54, "check_snmp", fake_argc, fake_argv); | ||
| 88 | sprintf(state_path, "/usr/local/nagios/var/%lu/check_test/funnykeyname", | ||
| 89 | (unsigned long)geteuid()); | ||
| 90 | ok(!strcmp(temp_state_key3.plugin_name, "check_test"), "Got plugin name"); | ||
| 91 | ok(!strcmp(temp_state_key3.name, "funnykeyname"), "Got key name"); | ||
| 92 | |||
| 93 | ok(!strcmp(temp_state_key3._filename, state_path), "Got internal filename"); | ||
| 94 | ok(temp_state_key3.data_version == 54, "Version set"); | ||
| 95 | |||
| 96 | state_data *temp_state_data = np_state_read(temp_state_key3); | ||
| 97 | ok(temp_state_data == NULL, "Got no state data as file does not exist"); | ||
| 98 | |||
| 99 | /* | ||
| 100 | temp_fp = fopen("var/statefile", "r"); | ||
| 101 | if (temp_fp==NULL) | ||
| 102 | printf("Error opening. errno=%d\n", errno); | ||
| 103 | printf("temp_fp=%s\n", temp_fp); | ||
| 104 | ok( _np_state_read_file(temp_fp) == true, "Can read state file" ); | ||
| 105 | fclose(temp_fp); | ||
| 106 | */ | ||
| 107 | |||
| 108 | temp_state_key3._filename = "var/statefile"; | ||
| 109 | temp_state_data = np_state_read(temp_state_key3); | ||
| 110 | ok(temp_state_data != NULL, "Got state data now") || | ||
| 111 | diag("Are you running in right directory? Will get coredump next if not"); | ||
| 112 | ok(temp_state_data->time == 1234567890, "Got time"); | ||
| 113 | ok(!strcmp((char *)temp_state_data->data, "String to read"), "Data as expected"); | ||
| 114 | |||
| 115 | temp_state_key3.data_version = 53; | ||
| 116 | temp_state_data = np_state_read(temp_state_key3); | ||
| 117 | ok(temp_state_data == NULL, "Older data version gives NULL"); | ||
| 118 | temp_state_key3.data_version = 54; | ||
| 119 | |||
| 120 | temp_state_key3._filename = "var/nonexistent"; | ||
| 121 | temp_state_data = np_state_read(temp_state_key3); | ||
| 122 | ok(temp_state_data == NULL, "Missing file gives NULL"); | ||
| 123 | |||
| 124 | temp_state_key3._filename = "var/oldformat"; | ||
| 125 | temp_state_data = np_state_read(temp_state_key3); | ||
| 126 | ok(temp_state_data == NULL, "Old file format gives NULL"); | ||
| 127 | |||
| 128 | temp_state_key3._filename = "var/baddate"; | ||
| 129 | temp_state_data = np_state_read(temp_state_key3); | ||
| 130 | ok(temp_state_data == NULL, "Bad date gives NULL"); | ||
| 131 | |||
| 132 | temp_state_key3._filename = "var/missingdataline"; | ||
| 133 | temp_state_data = np_state_read(temp_state_key3); | ||
| 134 | ok(temp_state_data == NULL, "Missing data line gives NULL"); | ||
| 135 | |||
| 136 | unlink("var/generated"); | ||
| 137 | temp_state_key3._filename = "var/generated"; | ||
| 138 | |||
| 139 | time_t current_time = 1234567890; | ||
| 140 | np_state_write_string(temp_state_key3, current_time, "String to read"); | ||
| 141 | ok(system("cmp var/generated var/statefile") == 0, "Generated file same as expected"); | ||
| 142 | |||
| 143 | unlink("var/generated_directory/statefile"); | ||
| 144 | unlink("var/generated_directory"); | ||
| 145 | temp_state_key3._filename = "var/generated_directory/statefile"; | ||
| 146 | current_time = 1234567890; | ||
| 147 | np_state_write_string(temp_state_key3, current_time, "String to read"); | ||
| 148 | ok(system("cmp var/generated_directory/statefile var/statefile") == 0, | ||
| 149 | "Have created directory"); | ||
| 150 | |||
| 151 | /* This test to check cannot write to dir - can't automate yet */ | ||
| 152 | /* | ||
| 153 | unlink("var/generated_bad_dir"); | ||
| 154 | mkdir("var/generated_bad_dir", S_IRUSR); | ||
| 155 | np_state_write_string(current_time, "String to read"); | ||
| 156 | */ | ||
| 157 | |||
| 158 | temp_state_key3._filename = "var/generated"; | ||
| 159 | time(¤t_time); | ||
| 160 | np_state_write_string(temp_state_key3, 0, "String to read"); | ||
| 161 | temp_state_data = np_state_read(temp_state_key3); | ||
| 162 | /* Check time is set to current_time */ | ||
| 163 | ok(system("cmp var/generated var/statefile > /dev/null") != 0, | ||
| 164 | "Generated file should be different this time"); | ||
| 165 | ok(temp_state_data->time - current_time <= 1, "Has time generated from current time"); | ||
| 166 | |||
| 167 | /* Don't know how to automatically test this. Need to be able to redefine die and catch the | ||
| 168 | * error */ | ||
| 169 | /* | ||
| 170 | temp_state_key->_filename="/dev/do/not/expect/to/be/able/to/write"; | ||
| 171 | np_state_write_string(0, "Bad file"); | ||
| 172 | */ | ||
| 173 | |||
| 174 | np_cleanup(); | ||
| 175 | } | ||
diff --git a/plugins/tests/test_check_snmp.t b/plugins/tests/test_check_snmp.t new file mode 100755 index 00000000..967633e9 --- /dev/null +++ b/plugins/tests/test_check_snmp.t | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | use Test::More; | ||
| 3 | if (! -e "./test_check_snmp") { | ||
| 4 | plan skip_all => "./test_check_snmp not compiled - please enable libtap library to test"; | ||
| 5 | } | ||
| 6 | exec "./test_check_snmp"; | ||
diff --git a/plugins/tests/test_check_swap.c b/plugins/tests/test_check_swap.c index b85fb4ad..94d56ce7 100644 --- a/plugins/tests/test_check_swap.c +++ b/plugins/tests/test_check_swap.c | |||
| @@ -5,9 +5,7 @@ | |||
| 5 | int verbose = 0; | 5 | int verbose = 0; |
| 6 | 6 | ||
| 7 | void print_usage(void) {} | 7 | void print_usage(void) {} |
| 8 | void print_help(swap_config config) { | 8 | void print_help(swap_config config) { (void)config; } |
| 9 | (void) config; | ||
| 10 | } | ||
| 11 | 9 | ||
| 12 | const char *progname = "test_check_swap"; | 10 | const char *progname = "test_check_swap"; |
| 13 | 11 | ||
diff --git a/plugins/urlize.c b/plugins/urlize.c index 1aa4e425..a8590fae 100644 --- a/plugins/urlize.c +++ b/plugins/urlize.c | |||
| @@ -53,8 +53,10 @@ int main(int argc, char **argv) { | |||
| 53 | 53 | ||
| 54 | int c; | 54 | int c; |
| 55 | int option = 0; | 55 | int option = 0; |
| 56 | static struct option longopts[] = { | 56 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, |
| 57 | {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"url", required_argument, 0, 'u'}, {0, 0, 0, 0}}; | 57 | {"version", no_argument, 0, 'V'}, |
| 58 | {"url", required_argument, 0, 'u'}, | ||
| 59 | {0, 0, 0, 0}}; | ||
| 58 | 60 | ||
| 59 | setlocale(LC_ALL, ""); | 61 | setlocale(LC_ALL, ""); |
| 60 | bindtextdomain(PACKAGE, LOCALEDIR); | 62 | bindtextdomain(PACKAGE, LOCALEDIR); |
| @@ -69,8 +71,9 @@ int main(int argc, char **argv) { | |||
| 69 | while (1) { | 71 | while (1) { |
| 70 | c = getopt_long(argc, argv, "+hVu:", longopts, &option); | 72 | c = getopt_long(argc, argv, "+hVu:", longopts, &option); |
| 71 | 73 | ||
| 72 | if (c == -1 || c == EOF) | 74 | if (c == -1 || c == EOF) { |
| 73 | break; | 75 | break; |
| 76 | } | ||
| 74 | 77 | ||
| 75 | switch (c) { | 78 | switch (c) { |
| 76 | case 'h': /* help */ | 79 | case 'h': /* help */ |
| @@ -90,8 +93,9 @@ int main(int argc, char **argv) { | |||
| 90 | } | 93 | } |
| 91 | } | 94 | } |
| 92 | 95 | ||
| 93 | if (url == NULL) | 96 | if (url == NULL) { |
| 94 | url = strdup(argv[optind++]); | 97 | url = strdup(argv[optind++]); |
| 98 | } | ||
| 95 | 99 | ||
| 96 | cmd = strdup(argv[optind++]); | 100 | cmd = strdup(argv[optind++]); |
| 97 | for (c = optind; c < argc; c++) { | 101 | for (c = optind; c < argc; c++) { |
| @@ -118,27 +122,32 @@ int main(int argc, char **argv) { | |||
| 118 | strcat(tstr, buf); | 122 | strcat(tstr, buf); |
| 119 | } | 123 | } |
| 120 | 124 | ||
| 121 | if (!found) | 125 | if (!found) { |
| 122 | die(STATE_UNKNOWN, _("%s UNKNOWN - No data received from host\nCMD: %s</A>\n"), argv[0], cmd); | 126 | die(STATE_UNKNOWN, _("%s UNKNOWN - No data received from host\nCMD: %s</A>\n"), argv[0], |
| 127 | cmd); | ||
| 128 | } | ||
| 123 | 129 | ||
| 124 | /* chop the newline character */ | 130 | /* chop the newline character */ |
| 125 | if ((nstr = strchr(tstr, NEWLINE_CHARACTER)) != NULL) | 131 | if ((nstr = strchr(tstr, NEWLINE_CHARACTER)) != NULL) { |
| 126 | *nstr = '\0'; | 132 | *nstr = '\0'; |
| 133 | } | ||
| 127 | 134 | ||
| 128 | /* tokenize the string for Perfdata if there is some */ | 135 | /* tokenize the string for Perfdata if there is some */ |
| 129 | nstr = strtok(tstr, PERF_CHARACTER); | 136 | nstr = strtok(tstr, PERF_CHARACTER); |
| 130 | printf("%s", nstr); | 137 | printf("%s", nstr); |
| 131 | printf("</A>"); | 138 | printf("</A>"); |
| 132 | nstr = strtok(NULL, PERF_CHARACTER); | 139 | nstr = strtok(NULL, PERF_CHARACTER); |
| 133 | if (nstr != NULL) | 140 | if (nstr != NULL) { |
| 134 | printf(" | %s", nstr); | 141 | printf(" | %s", nstr); |
| 142 | } | ||
| 135 | 143 | ||
| 136 | /* close the pipe */ | 144 | /* close the pipe */ |
| 137 | result = spclose(child_process); | 145 | result = spclose(child_process); |
| 138 | 146 | ||
| 139 | /* WARNING if output found on stderr */ | 147 | /* WARNING if output found on stderr */ |
| 140 | if (fgets(buf, MAX_INPUT_BUFFER - 1, child_stderr)) | 148 | if (fgets(buf, MAX_INPUT_BUFFER - 1, child_stderr)) { |
| 141 | result = max_state(result, STATE_WARNING); | 149 | result = max_state(result, STATE_WARNING); |
| 150 | } | ||
| 142 | 151 | ||
| 143 | /* close stderr */ | 152 | /* close stderr */ |
| 144 | (void)fclose(child_stderr); | 153 | (void)fclose(child_stderr); |
| @@ -153,8 +162,10 @@ void print_help(void) { | |||
| 153 | printf(COPYRIGHT, copyright, email); | 162 | printf(COPYRIGHT, copyright, email); |
| 154 | 163 | ||
| 155 | printf("%s\n", _("This plugin wraps the text output of another command (plugin) in HTML <A>")); | 164 | printf("%s\n", _("This plugin wraps the text output of another command (plugin) in HTML <A>")); |
| 156 | printf("%s\n", _("tags, thus displaying the child plugin's output as a clickable link in compatible")); | 165 | printf("%s\n", |
| 157 | printf("%s\n", _("monitoring status screen. This plugin returns the status of the invoked plugin.")); | 166 | _("tags, thus displaying the child plugin's output as a clickable link in compatible")); |
| 167 | printf("%s\n", | ||
| 168 | _("monitoring status screen. This plugin returns the status of the invoked plugin.")); | ||
| 158 | 169 | ||
| 159 | printf("\n\n"); | 170 | printf("\n\n"); |
| 160 | 171 | ||
| @@ -164,7 +175,8 @@ void print_help(void) { | |||
| 164 | 175 | ||
| 165 | printf("\n"); | 176 | printf("\n"); |
| 166 | printf("%s\n", _("Examples:")); | 177 | printf("%s\n", _("Examples:")); |
| 167 | printf("%s\n", _("Pay close attention to quoting to ensure that the shell passes the expected")); | 178 | printf("%s\n", |
| 179 | _("Pay close attention to quoting to ensure that the shell passes the expected")); | ||
| 168 | printf("%s\n\n", _("data to the plugin. For example, in:")); | 180 | printf("%s\n\n", _("data to the plugin. For example, in:")); |
| 169 | printf(" %s\n\n", _("urlize http://example.com/ check_http -H example.com -r 'two words'")); | 181 | printf(" %s\n\n", _("urlize http://example.com/ check_http -H example.com -r 'two words'")); |
| 170 | printf(" %s\n", _("the shell will remove the single quotes and urlize will see:")); | 182 | printf(" %s\n", _("the shell will remove the single quotes and urlize will see:")); |
diff --git a/plugins/utils.c b/plugins/utils.c index 34335c89..41fe5fcf 100644 --- a/plugins/utils.c +++ b/plugins/utils.c | |||
| @@ -285,7 +285,8 @@ double delta_time(struct timeval tv) { | |||
| 285 | struct timeval now; | 285 | struct timeval now; |
| 286 | 286 | ||
| 287 | gettimeofday(&now, NULL); | 287 | gettimeofday(&now, NULL); |
| 288 | return ((double)(now.tv_sec - tv.tv_sec) + (double)(now.tv_usec - tv.tv_usec) / (double)1000000); | 288 | return ((double)(now.tv_sec - tv.tv_sec) + |
| 289 | (double)(now.tv_usec - tv.tv_usec) / (double)1000000); | ||
| 289 | } | 290 | } |
| 290 | 291 | ||
| 291 | long deltime(struct timeval tv) { | 292 | long deltime(struct timeval tv) { |
| @@ -507,8 +508,8 @@ int xasprintf(char **strp, const char *fmt, ...) { | |||
| 507 | * | 508 | * |
| 508 | ******************************************************************************/ | 509 | ******************************************************************************/ |
| 509 | 510 | ||
| 510 | char *perfdata(const char *label, long int val, const char *uom, bool warnp, long int warn, bool critp, long int crit, bool minp, | 511 | char *perfdata(const char *label, long int val, const char *uom, bool warnp, long int warn, |
| 511 | long int minv, bool maxp, long int maxv) { | 512 | bool critp, long int crit, bool minp, long int minv, bool maxp, long int maxv) { |
| 512 | char *data = NULL; | 513 | char *data = NULL; |
| 513 | 514 | ||
| 514 | if (strpbrk(label, "'= ")) { | 515 | if (strpbrk(label, "'= ")) { |
| @@ -542,10 +543,11 @@ char *perfdata(const char *label, long int val, const char *uom, bool warnp, lon | |||
| 542 | return data; | 543 | return data; |
| 543 | } | 544 | } |
| 544 | 545 | ||
| 545 | char *perfdata_uint64(const char *label, uint64_t val, const char *uom, bool warnp, /* Warning present */ | 546 | char *perfdata_uint64(const char *label, uint64_t val, const char *uom, |
| 546 | uint64_t warn, bool critp, /* Critical present */ | 547 | bool warnp, /* Warning present */ |
| 547 | uint64_t crit, bool minp, /* Minimum present */ | 548 | uint64_t warn, bool critp, /* Critical present */ |
| 548 | uint64_t minv, bool maxp, /* Maximum present */ | 549 | uint64_t crit, bool minp, /* Minimum present */ |
| 550 | uint64_t minv, bool maxp, /* Maximum present */ | ||
| 549 | uint64_t maxv) { | 551 | uint64_t maxv) { |
| 550 | char *data = NULL; | 552 | char *data = NULL; |
| 551 | 553 | ||
| @@ -580,10 +582,11 @@ char *perfdata_uint64(const char *label, uint64_t val, const char *uom, bool war | |||
| 580 | return data; | 582 | return data; |
| 581 | } | 583 | } |
| 582 | 584 | ||
| 583 | char *perfdata_int64(const char *label, int64_t val, const char *uom, bool warnp, /* Warning present */ | 585 | char *perfdata_int64(const char *label, int64_t val, const char *uom, |
| 584 | int64_t warn, bool critp, /* Critical present */ | 586 | bool warnp, /* Warning present */ |
| 585 | int64_t crit, bool minp, /* Minimum present */ | 587 | int64_t warn, bool critp, /* Critical present */ |
| 586 | int64_t minv, bool maxp, /* Maximum present */ | 588 | int64_t crit, bool minp, /* Minimum present */ |
| 589 | int64_t minv, bool maxp, /* Maximum present */ | ||
| 587 | int64_t maxv) { | 590 | int64_t maxv) { |
| 588 | char *data = NULL; | 591 | char *data = NULL; |
| 589 | 592 | ||
| @@ -618,8 +621,8 @@ char *perfdata_int64(const char *label, int64_t val, const char *uom, bool warnp | |||
| 618 | return data; | 621 | return data; |
| 619 | } | 622 | } |
| 620 | 623 | ||
| 621 | char *fperfdata(const char *label, double val, const char *uom, bool warnp, double warn, bool critp, double crit, bool minp, double minv, | 624 | char *fperfdata(const char *label, double val, const char *uom, bool warnp, double warn, bool critp, |
| 622 | bool maxp, double maxv) { | 625 | double crit, bool minp, double minv, bool maxp, double maxv) { |
| 623 | char *data = NULL; | 626 | char *data = NULL; |
| 624 | 627 | ||
| 625 | if (strpbrk(label, "'= ")) { | 628 | if (strpbrk(label, "'= ")) { |
| @@ -655,7 +658,8 @@ char *fperfdata(const char *label, double val, const char *uom, bool warnp, doub | |||
| 655 | return data; | 658 | return data; |
| 656 | } | 659 | } |
| 657 | 660 | ||
| 658 | char *sperfdata(const char *label, double val, const char *uom, char *warn, char *crit, bool minp, double minv, bool maxp, double maxv) { | 661 | char *sperfdata(const char *label, double val, const char *uom, char *warn, char *crit, bool minp, |
| 662 | double minv, bool maxp, double maxv) { | ||
| 659 | char *data = NULL; | 663 | char *data = NULL; |
| 660 | if (strpbrk(label, "'= ")) { | 664 | if (strpbrk(label, "'= ")) { |
| 661 | xasprintf(&data, "'%s'=", label); | 665 | xasprintf(&data, "'%s'=", label); |
| @@ -690,7 +694,8 @@ char *sperfdata(const char *label, double val, const char *uom, char *warn, char | |||
| 690 | return data; | 694 | return data; |
| 691 | } | 695 | } |
| 692 | 696 | ||
| 693 | char *sperfdata_int(const char *label, int val, const char *uom, char *warn, char *crit, bool minp, int minv, bool maxp, int maxv) { | 697 | char *sperfdata_int(const char *label, int val, const char *uom, char *warn, char *crit, bool minp, |
| 698 | int minv, bool maxp, int maxv) { | ||
| 694 | char *data = NULL; | 699 | char *data = NULL; |
| 695 | if (strpbrk(label, "'= ")) { | 700 | if (strpbrk(label, "'= ")) { |
| 696 | xasprintf(&data, "'%s'=", label); | 701 | xasprintf(&data, "'%s'=", label); |
diff --git a/plugins/utils.h b/plugins/utils.h index 92a6c115..1f0e021b 100644 --- a/plugins/utils.h +++ b/plugins/utils.h | |||
| @@ -76,7 +76,7 @@ char *strnl(char *); | |||
| 76 | char *strpcpy(char *, const char *, const char *); | 76 | char *strpcpy(char *, const char *, const char *); |
| 77 | char *strpcat(char *, const char *, const char *); | 77 | char *strpcat(char *, const char *, const char *); |
| 78 | int xvasprintf(char **strp, const char *fmt, va_list ap); | 78 | int xvasprintf(char **strp, const char *fmt, va_list ap); |
| 79 | int xasprintf(char **strp, const char *fmt, ...); | 79 | int xasprintf(char **strp, const char *fmt, ...) __attribute__((format(printf, 2, 3))); |
| 80 | 80 | ||
| 81 | void usage(const char *) __attribute__((noreturn)); | 81 | void usage(const char *) __attribute__((noreturn)); |
| 82 | void usage2(const char *, const char *) __attribute__((noreturn)); | 82 | void usage2(const char *, const char *) __attribute__((noreturn)); |
| @@ -88,13 +88,17 @@ void usage_va(const char *fmt, ...) __attribute__((noreturn)); | |||
| 88 | #define max(a, b) (((a) > (b)) ? (a) : (b)) | 88 | #define max(a, b) (((a) > (b)) ? (a) : (b)) |
| 89 | #define min(a, b) (((a) < (b)) ? (a) : (b)) | 89 | #define min(a, b) (((a) < (b)) ? (a) : (b)) |
| 90 | 90 | ||
| 91 | char *perfdata(const char *, long int, const char *, bool, long int, bool, long int, bool, long int, bool, long int); | 91 | char *perfdata(const char *, long int, const char *, bool, long int, bool, long int, bool, long int, |
| 92 | bool, long int); | ||
| 92 | 93 | ||
| 93 | char *perfdata_uint64(const char *, uint64_t, const char *, bool, uint64_t, bool, uint64_t, bool, uint64_t, bool, uint64_t); | 94 | char *perfdata_uint64(const char *, uint64_t, const char *, bool, uint64_t, bool, uint64_t, bool, |
| 95 | uint64_t, bool, uint64_t); | ||
| 94 | 96 | ||
| 95 | char *perfdata_int64(const char *, int64_t, const char *, bool, int64_t, bool, int64_t, bool, int64_t, bool, int64_t); | 97 | char *perfdata_int64(const char *, int64_t, const char *, bool, int64_t, bool, int64_t, bool, |
| 98 | int64_t, bool, int64_t); | ||
| 96 | 99 | ||
| 97 | char *fperfdata(const char *, double, const char *, bool, double, bool, double, bool, double, bool, double); | 100 | char *fperfdata(const char *, double, const char *, bool, double, bool, double, bool, double, bool, |
| 101 | double); | ||
| 98 | 102 | ||
| 99 | char *sperfdata(const char *, double, const char *, char *, char *, bool, double, bool, double); | 103 | char *sperfdata(const char *, double, const char *, char *, char *, bool, double, bool, double); |
| 100 | 104 | ||
| @@ -104,21 +108,22 @@ char *sperfdata_int(const char *, int, const char *, char *, char *, bool, int, | |||
| 104 | most will or should. Therefore, for consistency, these very common | 108 | most will or should. Therefore, for consistency, these very common |
| 105 | options should have only these meanings throughout the overall suite */ | 109 | options should have only these meanings throughout the overall suite */ |
| 106 | 110 | ||
| 107 | #define STD_LONG_OPTS \ | 111 | #define STD_LONG_OPTS \ |
| 108 | {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, \ | 112 | {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, \ |
| 109 | {"timeout", required_argument, 0, 't'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, \ | 113 | {"help", no_argument, 0, 'h'}, {"timeout", required_argument, 0, 't'}, \ |
| 114 | {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, \ | ||
| 110 | {"hostname", required_argument, 0, 'H'} | 115 | {"hostname", required_argument, 0, 'H'} |
| 111 | 116 | ||
| 112 | #define COPYRIGHT \ | 117 | #define COPYRIGHT \ |
| 113 | "Copyright (c) %s Monitoring Plugins Development Team\n\ | 118 | "Copyright (c) %s Monitoring Plugins Development Team\n\ |
| 114 | \t<%s>\n\n" | 119 | \t<%s>\n\n" |
| 115 | 120 | ||
| 116 | #define UT_HLP_VRS \ | 121 | #define UT_HLP_VRS \ |
| 117 | _("\ | 122 | _("\ |
| 118 | %s (-h | --help) for detailed help\n\ | 123 | %s (-h | --help) for detailed help\n\ |
| 119 | %s (-V | --version) for version information\n") | 124 | %s (-V | --version) for version information\n") |
| 120 | 125 | ||
| 121 | #define UT_HELP_VRSN \ | 126 | #define UT_HELP_VRSN \ |
| 122 | _("\ | 127 | _("\ |
| 123 | \nOptions:\n\ | 128 | \nOptions:\n\ |
| 124 | -h, --help\n\ | 129 | -h, --help\n\ |
| @@ -126,52 +131,52 @@ char *sperfdata_int(const char *, int, const char *, char *, char *, bool, int, | |||
| 126 | -V, --version\n\ | 131 | -V, --version\n\ |
| 127 | Print version information\n") | 132 | Print version information\n") |
| 128 | 133 | ||
| 129 | #define UT_HOST_PORT \ | 134 | #define UT_HOST_PORT \ |
| 130 | _("\ | 135 | _("\ |
| 131 | -H, --hostname=ADDRESS\n\ | 136 | -H, --hostname=ADDRESS\n\ |
| 132 | Host name, IP Address, or unix socket (must be an absolute path)\n\ | 137 | Host name, IP Address, or unix socket (must be an absolute path)\n\ |
| 133 | -%c, --port=INTEGER\n\ | 138 | -%c, --port=INTEGER\n\ |
| 134 | Port number (default: %s)\n") | 139 | Port number (default: %s)\n") |
| 135 | 140 | ||
| 136 | #define UT_IPv46 \ | 141 | #define UT_IPv46 \ |
| 137 | _("\ | 142 | _("\ |
| 138 | -4, --use-ipv4\n\ | 143 | -4, --use-ipv4\n\ |
| 139 | Use IPv4 connection\n\ | 144 | Use IPv4 connection\n\ |
| 140 | -6, --use-ipv6\n\ | 145 | -6, --use-ipv6\n\ |
| 141 | Use IPv6 connection\n") | 146 | Use IPv6 connection\n") |
| 142 | 147 | ||
| 143 | #define UT_VERBOSE \ | 148 | #define UT_VERBOSE \ |
| 144 | _("\ | 149 | _("\ |
| 145 | -v, --verbose\n\ | 150 | -v, --verbose\n\ |
| 146 | Show details for command-line debugging (output may be truncated by\n\ | 151 | Show details for command-line debugging (output may be truncated by\n\ |
| 147 | the monitoring system)\n") | 152 | the monitoring system)\n") |
| 148 | 153 | ||
| 149 | #define UT_WARN_CRIT \ | 154 | #define UT_WARN_CRIT \ |
| 150 | _("\ | 155 | _("\ |
| 151 | -w, --warning=DOUBLE\n\ | 156 | -w, --warning=DOUBLE\n\ |
| 152 | Response time to result in warning status (seconds)\n\ | 157 | Response time to result in warning status (seconds)\n\ |
| 153 | -c, --critical=DOUBLE\n\ | 158 | -c, --critical=DOUBLE\n\ |
| 154 | Response time to result in critical status (seconds)\n") | 159 | Response time to result in critical status (seconds)\n") |
| 155 | 160 | ||
| 156 | #define UT_WARN_CRIT_RANGE \ | 161 | #define UT_WARN_CRIT_RANGE \ |
| 157 | _("\ | 162 | _("\ |
| 158 | -w, --warning=RANGE\n\ | 163 | -w, --warning=RANGE\n\ |
| 159 | Warning range (format: start:end). Alert if outside this range\n\ | 164 | Warning range (format: start:end). Alert if outside this range\n\ |
| 160 | -c, --critical=RANGE\n\ | 165 | -c, --critical=RANGE\n\ |
| 161 | Critical range\n") | 166 | Critical range\n") |
| 162 | 167 | ||
| 163 | #define UT_CONN_TIMEOUT \ | 168 | #define UT_CONN_TIMEOUT \ |
| 164 | _("\ | 169 | _("\ |
| 165 | -t, --timeout=INTEGER\n\ | 170 | -t, --timeout=INTEGER\n\ |
| 166 | Seconds before connection times out (default: %d)\n") | 171 | Seconds before connection times out (default: %d)\n") |
| 167 | 172 | ||
| 168 | #define UT_PLUG_TIMEOUT \ | 173 | #define UT_PLUG_TIMEOUT \ |
| 169 | _("\ | 174 | _("\ |
| 170 | -t, --timeout=INTEGER\n\ | 175 | -t, --timeout=INTEGER\n\ |
| 171 | Seconds before plugin times out (default: %d)\n") | 176 | Seconds before plugin times out (default: %d)\n") |
| 172 | 177 | ||
| 173 | #ifdef NP_EXTRA_OPTS | 178 | #ifdef NP_EXTRA_OPTS |
| 174 | # define UT_EXTRA_OPTS \ | 179 | # define UT_EXTRA_OPTS \ |
| 175 | _("\ | 180 | _("\ |
| 176 | --extra-opts=[section][@file]\n\ | 181 | --extra-opts=[section][@file]\n\ |
| 177 | Read options from an ini file. See\n\ | 182 | Read options from an ini file. See\n\ |
| @@ -181,25 +186,25 @@ char *sperfdata_int(const char *, int, const char *, char *, char *, bool, int, | |||
| 181 | # define UT_EXTRA_OPTS " \b" | 186 | # define UT_EXTRA_OPTS " \b" |
| 182 | #endif | 187 | #endif |
| 183 | 188 | ||
| 184 | #define UT_THRESHOLDS_NOTES \ | 189 | #define UT_THRESHOLDS_NOTES \ |
| 185 | _("\ | 190 | _("\ |
| 186 | See:\n\ | 191 | See:\n\ |
| 187 | https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT\n\ | 192 | https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT\n\ |
| 188 | for THRESHOLD format and examples.\n") | 193 | for THRESHOLD format and examples.\n") |
| 189 | 194 | ||
| 190 | #define UT_SUPPORT \ | 195 | #define UT_SUPPORT \ |
| 191 | _("\n\ | 196 | _("\n\ |
| 192 | Send email to help@monitoring-plugins.org if you have questions regarding\n\ | 197 | Send email to help@monitoring-plugins.org if you have questions regarding\n\ |
| 193 | use of this software. To submit patches or suggest improvements, send email\n\ | 198 | use of this software. To submit patches or suggest improvements, send email\n\ |
| 194 | to devel@monitoring-plugins.org\n\n") | 199 | to devel@monitoring-plugins.org\n\n") |
| 195 | 200 | ||
| 196 | #define UT_NOWARRANTY \ | 201 | #define UT_NOWARRANTY \ |
| 197 | _("\n\ | 202 | _("\n\ |
| 198 | The Monitoring Plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\ | 203 | The Monitoring Plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\ |
| 199 | copies of the plugins under the terms of the GNU General Public License.\n\ | 204 | copies of the plugins under the terms of the GNU General Public License.\n\ |
| 200 | For more information about these matters, see the file named COPYING.\n") | 205 | For more information about these matters, see the file named COPYING.\n") |
| 201 | 206 | ||
| 202 | #define UT_OUTPUT_FORMAT \ | 207 | #define UT_OUTPUT_FORMAT \ |
| 203 | _("\ | 208 | _("\ |
| 204 | --output-format=OUTPUT_FORMAT\n\ | 209 | --output-format=OUTPUT_FORMAT\n\ |
| 205 | Select output format. Valid values: \"multi-line\", \"mp-test-json\"\n") | 210 | Select output format. Valid values: \"multi-line\", \"mp-test-json\"\n") |
| @@ -65,7 +65,8 @@ static void _cleanup(void); | |||
| 65 | * test_name -- the name of the test, may be NULL | 65 | * test_name -- the name of the test, may be NULL |
| 66 | * test_comment -- a comment to print afterwards, may be NULL | 66 | * test_comment -- a comment to print afterwards, may be NULL |
| 67 | */ | 67 | */ |
| 68 | unsigned int _gen_result(int ok, const char *func, char *file, unsigned int line, char *test_name, ...) { | 68 | unsigned int _gen_result(int ok, const char *func, char *file, unsigned int line, char *test_name, |
| 69 | ...) { | ||
| 69 | va_list ap; | 70 | va_list ap; |
| 70 | char *local_test_name = NULL; | 71 | char *local_test_name = NULL; |
| 71 | char *c; | 72 | char *c; |
| @@ -95,7 +96,9 @@ unsigned int _gen_result(int ok, const char *func, char *file, unsigned int line | |||
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | if (name_is_digits) { | 98 | if (name_is_digits) { |
| 98 | diag(" You named your test '%s'. You shouldn't use numbers for your test names.", local_test_name); | 99 | diag( |
| 100 | " You named your test '%s'. You shouldn't use numbers for your test names.", | ||
| 101 | local_test_name); | ||
| 99 | diag(" Very confusing."); | 102 | diag(" Very confusing."); |
| 100 | } | 103 | } |
| 101 | } | 104 | } |
| @@ -116,8 +119,9 @@ unsigned int _gen_result(int ok, const char *func, char *file, unsigned int line | |||
| 116 | if (local_test_name != NULL) { | 119 | if (local_test_name != NULL) { |
| 117 | flockfile(stdout); | 120 | flockfile(stdout); |
| 118 | for (c = local_test_name; *c != '\0'; c++) { | 121 | for (c = local_test_name; *c != '\0'; c++) { |
| 119 | if (*c == '#') | 122 | if (*c == '#') { |
| 120 | fputc('\\', stdout); | 123 | fputc('\\', stdout); |
| 124 | } | ||
| 121 | fputc((int)*c, stdout); | 125 | fputc((int)*c, stdout); |
| 122 | } | 126 | } |
| 123 | funlockfile(stdout); | 127 | funlockfile(stdout); |
| @@ -135,14 +139,16 @@ unsigned int _gen_result(int ok, const char *func, char *file, unsigned int line | |||
| 135 | the test failed. */ | 139 | the test failed. */ |
| 136 | if (todo) { | 140 | if (todo) { |
| 137 | printf(" # TODO %s", todo_msg ? todo_msg : todo_msg_fixed); | 141 | printf(" # TODO %s", todo_msg ? todo_msg : todo_msg_fixed); |
| 138 | if (!ok) | 142 | if (!ok) { |
| 139 | failures--; | 143 | failures--; |
| 144 | } | ||
| 140 | } | 145 | } |
| 141 | 146 | ||
| 142 | printf("\n"); | 147 | printf("\n"); |
| 143 | 148 | ||
| 144 | if (!ok) | 149 | if (!ok) { |
| 145 | diag(" Failed %stest (%s:%s() at line %d)", todo ? "(TODO) " : "", file, func, line); | 150 | diag(" Failed %stest (%s:%s() at line %d)", todo ? "(TODO) " : "", file, func, line); |
| 151 | } | ||
| 146 | 152 | ||
| 147 | free(local_test_name); | 153 | free(local_test_name); |
| 148 | 154 | ||
| @@ -212,8 +218,9 @@ int plan_skip_all(char *reason) { | |||
| 212 | 218 | ||
| 213 | printf("1..0"); | 219 | printf("1..0"); |
| 214 | 220 | ||
| 215 | if (reason != NULL) | 221 | if (reason != NULL) { |
| 216 | printf(" # Skip %s", reason); | 222 | printf(" # Skip %s", reason); |
| 223 | } | ||
| 217 | 224 | ||
| 218 | printf("\n"); | 225 | printf("\n"); |
| 219 | 226 | ||
| @@ -294,7 +301,8 @@ int skip(unsigned int n, char *fmt, ...) { | |||
| 294 | 301 | ||
| 295 | while (n-- > 0) { | 302 | while (n-- > 0) { |
| 296 | test_count++; | 303 | test_count++; |
| 297 | printf("ok %d # skip %s\n", test_count, skip_msg != NULL ? skip_msg : "libtap():malloc() failed"); | 304 | printf("ok %d # skip %s\n", test_count, |
| 305 | skip_msg != NULL ? skip_msg : "libtap():malloc() failed"); | ||
| 298 | } | 306 | } |
| 299 | 307 | ||
| 300 | free(skip_msg); | 308 | free(skip_msg); |
| @@ -396,8 +404,9 @@ void _cleanup(void) { | |||
| 396 | return; | 404 | return; |
| 397 | } | 405 | } |
| 398 | 406 | ||
| 399 | if (failures) | 407 | if (failures) { |
| 400 | diag("Looks like you failed %d tests of %d.", failures, test_count); | 408 | diag("Looks like you failed %d tests of %d.", failures, test_count); |
| 409 | } | ||
| 401 | 410 | ||
| 402 | UNLOCK; | 411 | UNLOCK; |
| 403 | } | 412 | } |
| @@ -28,45 +28,50 @@ | |||
| 28 | and requires the caller to add the final comma if they've omitted | 28 | and requires the caller to add the final comma if they've omitted |
| 29 | the optional arguments */ | 29 | the optional arguments */ |
| 30 | #ifdef __GNUC__ | 30 | #ifdef __GNUC__ |
| 31 | # define ok(e, test, ...) \ | 31 | # define ok(e, test, ...) \ |
| 32 | ((e) ? _gen_result(1, __func__, __FILE__, __LINE__, test, ##__VA_ARGS__) \ | 32 | ((e) ? _gen_result(1, __func__, __FILE__, __LINE__, test, ##__VA_ARGS__) \ |
| 33 | : _gen_result(0, __func__, __FILE__, __LINE__, test, ##__VA_ARGS__)) | 33 | : _gen_result(0, __func__, __FILE__, __LINE__, test, ##__VA_ARGS__)) |
| 34 | 34 | ||
| 35 | # define ok1(e) ((e) ? _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) | 35 | # define ok1(e) \ |
| 36 | ((e) ? _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) \ | ||
| 37 | : _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) | ||
| 36 | 38 | ||
| 37 | # define pass(test, ...) ok(1, test, ##__VA_ARGS__); | 39 | # define pass(test, ...) ok(1, test, ##__VA_ARGS__); |
| 38 | # define fail(test, ...) ok(0, test, ##__VA_ARGS__); | 40 | # define fail(test, ...) ok(0, test, ##__VA_ARGS__); |
| 39 | 41 | ||
| 40 | # define skip_start(test, n, fmt, ...) \ | 42 | # define skip_start(test, n, fmt, ...) \ |
| 41 | do { \ | 43 | do { \ |
| 42 | if ((test)) { \ | 44 | if ((test)) { \ |
| 43 | skip(n, fmt, ##__VA_ARGS__); \ | 45 | skip(n, fmt, ##__VA_ARGS__); \ |
| 44 | continue; \ | 46 | continue; \ |
| 45 | } | 47 | } |
| 46 | #else /* __GNUC__ */ | 48 | #else /* __GNUC__ */ |
| 47 | /* The original tap.h used to test if __STDC_VERSION__ >= 199901L here. This | 49 | /* The original tap.h used to test if __STDC_VERSION__ >= 199901L here. This |
| 48 | * doesn't seem to work on HP-UX even though the code compile fine. I'm not | 50 | * doesn't seem to work on HP-UX even though the code compile fine. I'm not |
| 49 | * sure how to add an exception here for HP-UX so I just removed the check | 51 | * sure how to add an exception here for HP-UX so I just removed the check |
| 50 | * for now */ | 52 | * for now */ |
| 51 | # define ok(e, ...) \ | 53 | # define ok(e, ...) \ |
| 52 | ((e) ? _gen_result(1, __func__, __FILE__, __LINE__, __VA_ARGS__) : _gen_result(0, __func__, __FILE__, __LINE__, __VA_ARGS__)) | 54 | ((e) ? _gen_result(1, __func__, __FILE__, __LINE__, __VA_ARGS__) \ |
| 55 | : _gen_result(0, __func__, __FILE__, __LINE__, __VA_ARGS__)) | ||
| 53 | 56 | ||
| 54 | # define ok1(e) ((e) ? _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) | 57 | # define ok1(e) \ |
| 58 | ((e) ? _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) \ | ||
| 59 | : _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) | ||
| 55 | 60 | ||
| 56 | # define pass(...) ok(1, __VA_ARGS__); | 61 | # define pass(...) ok(1, __VA_ARGS__); |
| 57 | # define fail(...) ok(0, __VA_ARGS__); | 62 | # define fail(...) ok(0, __VA_ARGS__); |
| 58 | 63 | ||
| 59 | # define skip_start(test, n, ...) \ | 64 | # define skip_start(test, n, ...) \ |
| 60 | do { \ | 65 | do { \ |
| 61 | if ((test)) { \ | 66 | if ((test)) { \ |
| 62 | skip(n, __VA_ARGS__); \ | 67 | skip(n, __VA_ARGS__); \ |
| 63 | continue; \ | 68 | continue; \ |
| 64 | } | 69 | } |
| 65 | #endif /* __GNUC__ */ | 70 | #endif /* __GNUC__ */ |
| 66 | 71 | ||
| 67 | #define skip_end \ | 72 | #define skip_end \ |
| 68 | } \ | 73 | } \ |
| 69 | while (0) \ | 74 | while (0) \ |
| 70 | ; | 75 | ; |
| 71 | 76 | ||
| 72 | unsigned int _gen_result(int, const char *, char *, unsigned int, char *, ...); | 77 | unsigned int _gen_result(int, const char *, char *, unsigned int, char *, ...); |
diff --git a/tools/mini_epn.c b/tools/mini_epn.c index 6f3c5d02..1b09f1c1 100644 --- a/tools/mini_epn.c +++ b/tools/mini_epn.c | |||
| @@ -1,14 +1,14 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * | 2 | * |
| 3 | * MINI_EPN.C - Mini Embedded Perl Nagios | 3 | * MINI_EPN.C - Mini Embedded Perl Nagios |
| 4 | * Contributed by Stanley Hopcroft | 4 | * Contributed by Stanley Hopcroft |
| 5 | * Modified by Douglas Warner | 5 | * Modified by Douglas Warner |
| 6 | * Last Modified: 05/02/2002 | 6 | * Last Modified: 05/02/2002 |
| 7 | * | 7 | * |
| 8 | * This is a sample mini embedded Perl interpreter (hacked out checks.c and | 8 | * This is a sample mini embedded Perl interpreter (hacked out checks.c and |
| 9 | * perlembed) for use in testing Perl plugins. | 9 | * perlembed) for use in testing Perl plugins. |
| 10 | * | 10 | * |
| 11 | * It can be compiled with the following command (see 'man perlembed' for | 11 | * It can be compiled with the following command (see 'man perlembed' for |
| 12 | * more info): | 12 | * more info): |
| 13 | * | 13 | * |
| 14 | * gcc -omini_epn mini_epn.c `perl -MExtUtils::Embed -e ccopts -e ldopts` | 14 | * gcc -omini_epn mini_epn.c `perl -MExtUtils::Embed -e ccopts -e ldopts` |
| @@ -21,7 +21,6 @@ | |||
| 21 | * | 21 | * |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | |||
| 25 | #include <EXTERN.h> | 24 | #include <EXTERN.h> |
| 26 | #include <perl.h> | 25 | #include <perl.h> |
| 27 | #include <fcntl.h> | 26 | #include <fcntl.h> |
| @@ -30,7 +29,7 @@ | |||
| 30 | /* include PERL xs_init code for module and C library support */ | 29 | /* include PERL xs_init code for module and C library support */ |
| 31 | 30 | ||
| 32 | #if defined(__cplusplus) | 31 | #if defined(__cplusplus) |
| 33 | #define is_cplusplus | 32 | # define is_cplusplus |
| 34 | #endif | 33 | #endif |
| 35 | 34 | ||
| 36 | #ifdef is_cplusplus | 35 | #ifdef is_cplusplus |
| @@ -42,22 +41,20 @@ extern "C" { | |||
| 42 | 41 | ||
| 43 | #ifdef is_cplusplus | 42 | #ifdef is_cplusplus |
| 44 | } | 43 | } |
| 45 | # ifndef EXTERN_C | 44 | # ifndef EXTERN_C |
| 46 | # define EXTERN_C extern "C" | 45 | # define EXTERN_C extern "C" |
| 47 | # endif | 46 | # endif |
| 48 | #else | 47 | #else |
| 49 | # ifndef EXTERN_C | 48 | # ifndef EXTERN_C |
| 50 | # define EXTERN_C extern | 49 | # define EXTERN_C extern |
| 51 | # endif | 50 | # endif |
| 52 | #endif | 51 | #endif |
| 53 | |||
| 54 | 52 | ||
| 55 | EXTERN_C void xs_init _((void)); | 53 | EXTERN_C void xs_init _((void)); |
| 56 | 54 | ||
| 57 | EXTERN_C void boot_DynaLoader _((CV* cv)); | 55 | EXTERN_C void boot_DynaLoader _((CV * cv)); |
| 58 | 56 | ||
| 59 | EXTERN_C void xs_init(void) | 57 | EXTERN_C void xs_init(void) { |
| 60 | { | ||
| 61 | char *file = __FILE__; | 58 | char *file = __FILE__; |
| 62 | dXSUB_SYS; | 59 | dXSUB_SYS; |
| 63 | 60 | ||
| @@ -65,85 +62,80 @@ EXTERN_C void xs_init(void) | |||
| 65 | newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); | 62 | newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); |
| 66 | } | 63 | } |
| 67 | 64 | ||
| 68 | |||
| 69 | static PerlInterpreter *perl = NULL; | 65 | static PerlInterpreter *perl = NULL; |
| 70 | 66 | ||
| 71 | 67 | int main(int argc, char **argv, char **env) { | |
| 72 | int main(int argc, char **argv, char **env) | 68 | char *embedding[] = {"", "p1.pl"}; |
| 73 | { | ||
| 74 | char *embedding[] = { "", "p1.pl" }; | ||
| 75 | char plugin_output[1024]; | 69 | char plugin_output[1024]; |
| 76 | char buffer[512]; | 70 | char buffer[512]; |
| 77 | char tmpfname[32]; | 71 | char tmpfname[32]; |
| 78 | char fname[32]; | 72 | char fname[32]; |
| 79 | char *args[] = {"","0", "", "", NULL }; | 73 | char *args[] = {"", "0", "", "", NULL}; |
| 80 | FILE *fp; | 74 | FILE *fp; |
| 81 | 75 | ||
| 82 | const int command_line_size = 160; | 76 | const int command_line_size = 160; |
| 83 | char command_line[command_line_size]; | 77 | char command_line[command_line_size]; |
| 84 | char *ap ; | 78 | char *ap; |
| 85 | int exitstatus; | 79 | int exitstatus; |
| 86 | int pclose_result; | 80 | int pclose_result; |
| 87 | #ifdef THREADEDPERL | 81 | #ifdef THREADEDPERL |
| 88 | dTHX; | 82 | dTHX; |
| 89 | #endif | 83 | #endif |
| 90 | dSP; | 84 | dSP; |
| 91 | 85 | ||
| 92 | if ((perl=perl_alloc())==NULL) { | 86 | if ((perl = perl_alloc()) == NULL) { |
| 93 | snprintf(buffer,sizeof(buffer),"Error: Could not allocate memory for embedded Perl interpreter!\n"); | 87 | snprintf(buffer, sizeof(buffer), |
| 94 | buffer[sizeof(buffer)-1]='\x0'; | 88 | "Error: Could not allocate memory for embedded Perl interpreter!\n"); |
| 89 | buffer[sizeof(buffer) - 1] = '\x0'; | ||
| 95 | printf("%s\n", buffer); | 90 | printf("%s\n", buffer); |
| 96 | exit(1); | 91 | exit(1); |
| 97 | } | 92 | } |
| 98 | perl_construct(perl); | 93 | perl_construct(perl); |
| 99 | exitstatus=perl_parse(perl,xs_init,2,embedding,NULL); | 94 | exitstatus = perl_parse(perl, xs_init, 2, embedding, NULL); |
| 100 | if (!exitstatus) { | 95 | if (!exitstatus) { |
| 101 | 96 | ||
| 102 | exitstatus=perl_run(perl); | 97 | exitstatus = perl_run(perl); |
| 103 | 98 | ||
| 104 | while(printf("Enter file name: ") && fgets(command_line, command_line_size, stdin)) { | 99 | while (printf("Enter file name: ") && fgets(command_line, command_line_size, stdin)) { |
| 105 | 100 | ||
| 106 | /* call the subroutine, passing it the filename as an argument */ | 101 | /* call the subroutine, passing it the filename as an argument */ |
| 107 | 102 | ||
| 108 | command_line[strlen(command_line) -1] = '\0'; | 103 | command_line[strlen(command_line) - 1] = '\0'; |
| 109 | 104 | ||
| 110 | strncpy(fname,command_line,strcspn(command_line," ")); | 105 | strncpy(fname, command_line, strcspn(command_line, " ")); |
| 111 | fname[strcspn(command_line," ")] = '\x0'; | 106 | fname[strcspn(command_line, " ")] = '\x0'; |
| 112 | args[0] = fname ; | 107 | args[0] = fname; |
| 113 | args[3] = command_line + strlen(fname) + 1 ; | 108 | args[3] = command_line + strlen(fname) + 1; |
| 114 | 109 | ||
| 115 | /* generate a temporary filename to which stdout can be redirected. */ | 110 | /* generate a temporary filename to which stdout can be redirected. */ |
| 116 | sprintf(tmpfname,"/tmp/embedded%d",getpid()); | 111 | sprintf(tmpfname, "/tmp/embedded%d", getpid()); |
| 117 | args[2] = tmpfname; | 112 | args[2] = tmpfname; |
| 118 | 113 | ||
| 119 | /* call our perl interpreter to compile and optionally cache the command */ | 114 | /* call our perl interpreter to compile and optionally cache the command */ |
| 120 | perl_call_argv("Embed::Persistent::eval_file", G_DISCARD | G_EVAL, args); | 115 | perl_call_argv("Embed::Persistent::eval_file", G_DISCARD | G_EVAL, args); |
| 121 | 116 | ||
| 122 | perl_call_argv("Embed::Persistent::run_package", G_DISCARD | G_EVAL, args); | 117 | perl_call_argv("Embed::Persistent::run_package", G_DISCARD | G_EVAL, args); |
| 123 | 118 | ||
| 124 | /* check return status */ | 119 | /* check return status */ |
| 125 | if(SvTRUE(ERRSV)){ | 120 | if (SvTRUE(ERRSV)) { |
| 126 | pclose_result=-2; | 121 | pclose_result = -2; |
| 127 | printf("embedded perl ran %s with error %s\n",fname,SvPV(ERRSV,PL_na)); | 122 | printf("embedded perl ran %s with error %s\n", fname, SvPV(ERRSV, PL_na)); |
| 128 | } | 123 | } |
| 129 | 124 | ||
| 130 | /* read back stdout from script */ | 125 | /* read back stdout from script */ |
| 131 | fp=fopen(tmpfname, "r"); | 126 | fp = fopen(tmpfname, "r"); |
| 132 | 127 | ||
| 133 | /* default return string in case nothing was returned */ | 128 | /* default return string in case nothing was returned */ |
| 134 | strcpy(plugin_output,"(No output!)"); | 129 | strcpy(plugin_output, "(No output!)"); |
| 135 | |||
| 136 | fgets(plugin_output,sizeof(plugin_output)-1,fp); | ||
| 137 | plugin_output[sizeof(plugin_output)-1]='\x0'; | ||
| 138 | fclose(fp); | ||
| 139 | unlink(tmpfname); | ||
| 140 | printf("embedded perl plugin output was %d,%s\n",pclose_result, plugin_output); | ||
| 141 | 130 | ||
| 131 | fgets(plugin_output, sizeof(plugin_output) - 1, fp); | ||
| 132 | plugin_output[sizeof(plugin_output) - 1] = '\x0'; | ||
| 133 | fclose(fp); | ||
| 134 | unlink(tmpfname); | ||
| 135 | printf("embedded perl plugin output was %d,%s\n", pclose_result, plugin_output); | ||
| 142 | } | 136 | } |
| 143 | |||
| 144 | } | 137 | } |
| 145 | 138 | ||
| 146 | |||
| 147 | PL_perl_destruct_level = 0; | 139 | PL_perl_destruct_level = 0; |
| 148 | perl_destruct(perl); | 140 | perl_destruct(perl); |
| 149 | perl_free(perl); | 141 | perl_free(perl); |
