ducaale/xh

Latest release fails to build on NetBSD

Closed this issue ยท 12 comments

Hi,

Trying to update our package from 0.18.0 to 0.19.2 fails with:

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
  --> /usr/pkgsrc/wip/xh/work/vendor/network-interface-1.0.0/src/target/getifaddrs.rs:25:18
   |
25 |         unsafe { libc::freeifaddrs(self.base) }
   |                  ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
  --> /usr/pkgsrc/wip/xh/work/vendor/network-interface-1.0.0/src/target/getifaddrs.rs:31:20
   |
31 |     match unsafe { libc::getifaddrs(addr.as_mut_ptr()) } {
   |                    ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
 --> /usr/pkgsrc/wip/xh/work/vendor/network-interface-1.0.0/src/target/getifaddrs.rs:5:16
  |
5 |     base: *mut libc::ifaddrs,
  |                ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
 --> /usr/pkgsrc/wip/xh/work/vendor/network-interface-1.0.0/src/target/getifaddrs.rs:6:16
  |
6 |     next: *mut libc::ifaddrs,
  |                ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
  --> /usr/pkgsrc/wip/xh/work/vendor/network-interface-1.0.0/src/target/getifaddrs.rs:10:17
   |
10 |     type Item = libc::ifaddrs;
   |                 ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
  --> /usr/pkgsrc/wip/xh/work/vendor/network-interface-1.0.0/src/target/getifaddrs.rs:30:44
   |
30 |     let mut addr = mem::MaybeUninit::<*mut libc::ifaddrs>::uninit();
   |                                            ^^^^ use of undeclared crate or module `libc`

For more information about this error, try `rustc --explain E0433`.
error: could not compile `network-interface` (lib) due to 6 previous errors
warning: build failed, waiting for other jobs to finish...
*** Error code 101

Stop.
make[1]: stopped in /usr/pkgsrc/wip/xh
*** Error code 1

Stop.

Could you please look into it?
TIA

Hi,

It seems that network-interface doesn't support NetBSD. But we only use it for one CLI option.

As a quick fix you could patch out the --interface option. This diff should be enough to make it build (unless there are other problems):

diff
diff --git a/Cargo.lock b/Cargo.lock
index 29fde7b..68101e3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1027,18 +1027,6 @@ dependencies = [
  "tempfile",
 ]
 
-[[package]]
-name = "network-interface"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10c4dbf727f42893b058d7619d5b4da3743dfe9cdb6e440880f7717a68b57e0e"
-dependencies = [
- "cc",
- "libc",
- "thiserror",
- "winapi",
-]
-
 [[package]]
 name = "normalize-line-endings"
 version = "0.3.0"
@@ -2323,7 +2311,6 @@ dependencies = [
  "mime",
  "mime2ext",
  "mime_guess",
- "network-interface",
  "once_cell",
  "os_display",
  "pem",
diff --git a/Cargo.toml b/Cargo.toml
index 80509ed..b4d475d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,7 +33,6 @@ memchr = "2.4.1"
 mime = "0.3.16"
 mime2ext = "0.1.0"
 mime_guess = "2.0"
-network-interface = "1.0.0"
 once_cell = "1.8.0"
 os_display = "0.1.3"
 pem = "0.8.2"
diff --git a/completions/_xh b/completions/_xh
index 4b57bcd..751cb8c 100644
--- a/completions/_xh
+++ b/completions/_xh
@@ -47,7 +47,6 @@ none\:"Disable both coloring and formatting"))' \
 '--ssl=[Force a particular TLS version]:VERSION:(auto tls1 tls1.1 tls1.2 tls1.3)' \
 '--default-scheme=[The default scheme to use if not specified in the URL]:SCHEME: ' \
 '--http-version=[HTTP version to use]:VERSION:(1.0 1.1 2)' \
-'--interface=[Bind to a network interface or local IP address]:NAME: ' \
 '-j[(default) Serialize data items from the command line as a JSON object]' \
 '--json[(default) Serialize data items from the command line as a JSON object]' \
 '-f[Serialize data items from the command line as form fields]' \
@@ -127,7 +126,6 @@ none\:"Disable both coloring and formatting"))' \
 '--no-default-scheme[]' \
 '--no-https[]' \
 '--no-http-version[]' \
-'--no-interface[]' \
 '--no-ipv4[]' \
 '--no-ipv6[]' \
 '--no-ignore-stdin[]' \
diff --git a/completions/_xh.ps1 b/completions/_xh.ps1
index 2154bf8..8c4f8fc 100644
--- a/completions/_xh.ps1
+++ b/completions/_xh.ps1
@@ -50,7 +50,6 @@ Register-ArgumentCompleter -Native -CommandName 'xh' -ScriptBlock {
             [CompletionResult]::new('--ssl', 'ssl', [CompletionResultType]::ParameterName, 'Force a particular TLS version')
             [CompletionResult]::new('--default-scheme', 'default-scheme', [CompletionResultType]::ParameterName, 'The default scheme to use if not specified in the URL')
             [CompletionResult]::new('--http-version', 'http-version', [CompletionResultType]::ParameterName, 'HTTP version to use')
-            [CompletionResult]::new('--interface', 'interface', [CompletionResultType]::ParameterName, 'Bind to a network interface or local IP address')
             [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, '(default) Serialize data items from the command line as a JSON object')
             [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, '(default) Serialize data items from the command line as a JSON object')
             [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Serialize data items from the command line as form fields')
@@ -130,7 +129,6 @@ Register-ArgumentCompleter -Native -CommandName 'xh' -ScriptBlock {
             [CompletionResult]::new('--no-default-scheme', 'no-default-scheme', [CompletionResultType]::ParameterName, 'no-default-scheme')
             [CompletionResult]::new('--no-https', 'no-https', [CompletionResultType]::ParameterName, 'no-https')
             [CompletionResult]::new('--no-http-version', 'no-http-version', [CompletionResultType]::ParameterName, 'no-http-version')
-            [CompletionResult]::new('--no-interface', 'no-interface', [CompletionResultType]::ParameterName, 'no-interface')
             [CompletionResult]::new('--no-ipv4', 'no-ipv4', [CompletionResultType]::ParameterName, 'no-ipv4')
             [CompletionResult]::new('--no-ipv6', 'no-ipv6', [CompletionResultType]::ParameterName, 'no-ipv6')
             [CompletionResult]::new('--no-ignore-stdin', 'no-ignore-stdin', [CompletionResultType]::ParameterName, 'no-ignore-stdin')
diff --git a/completions/xh.bash b/completions/xh.bash
index ac255a2..843d866 100644
--- a/completions/xh.bash
+++ b/completions/xh.bash
@@ -19,7 +19,7 @@ _xh() {
 
     case "${cmd}" in
         xh)
-            opts="-j -f -s -p -h -b -m -v -P -q -S -o -d -c -A -a -F -4 -6 -I -V --json --form --multipart --raw --pretty --format-options --style --response-charset --response-mime --print --headers --body --meta --verbose --all --history-print --quiet --stream --output --download --continue --session --session-read-only --auth-type --auth --bearer --ignore-netrc --offline --check-status --follow --max-redirects --timeout --proxy --verify --cert --cert-key --ssl --native-tls --default-scheme --https --http-version --interface --ipv4 --ipv6 --ignore-stdin --curl --curl-long --help --no-json --no-form --no-multipart --no-raw --no-pretty --no-format-options --no-style --no-response-charset --no-response-mime --no-print --no-headers --no-body --no-meta --no-verbose --no-all --no-history-print --no-quiet --no-stream --no-output --no-download --no-continue --no-session --no-session-read-only --no-auth-type --no-auth --no-bearer --no-ignore-netrc --no-offline --no-check-status --no-follow --no-max-redirects --no-timeout --no-proxy --no-verify --no-cert --no-cert-key --no-ssl --no-native-tls --no-default-scheme --no-https --no-http-version --no-interface --no-ipv4 --no-ipv6 --no-ignore-stdin --no-curl --no-curl-long --no-help --version <[METHOD] URL> [REQUEST_ITEM]..."
+            opts="-j -f -s -p -h -b -m -v -P -q -S -o -d -c -A -a -F -4 -6 -I -V --json --form --multipart --raw --pretty --format-options --style --response-charset --response-mime --print --headers --body --meta --verbose --all --history-print --quiet --stream --output --download --continue --session --session-read-only --auth-type --auth --bearer --ignore-netrc --offline --check-status --follow --max-redirects --timeout --proxy --verify --cert --cert-key --ssl --native-tls --default-scheme --https --http-version --ipv4 --ipv6 --ignore-stdin --curl --curl-long --help --no-json --no-form --no-multipart --no-raw --no-pretty --no-format-options --no-style --no-response-charset --no-response-mime --no-print --no-headers --no-body --no-meta --no-verbose --no-all --no-history-print --no-quiet --no-stream --no-output --no-download --no-continue --no-session --no-session-read-only --no-auth-type --no-auth --no-bearer --no-ignore-netrc --no-offline --no-check-status --no-follow --no-max-redirects --no-timeout --no-proxy --no-verify --no-cert --no-cert-key --no-ssl --no-native-tls --no-default-scheme --no-https --no-http-version --no-ipv4 --no-ipv6 --no-ignore-stdin --no-curl --no-curl-long --no-help --version <[METHOD] URL> [REQUEST_ITEM]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -141,10 +141,6 @@ _xh() {
                     COMPREPLY=($(compgen -W "1.0 1.1 2" -- "${cur}"))
                     return 0
                     ;;
-                --interface)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
                 *)
                     COMPREPLY=()
                     ;;
diff --git a/completions/xh.fish b/completions/xh.fish
index 57758f8..79f7152 100644
--- a/completions/xh.fish
+++ b/completions/xh.fish
@@ -21,7 +21,6 @@ complete -c xh -l cert-key -d 'A private key file to use with --cert' -r -F
 complete -c xh -l ssl -d 'Force a particular TLS version' -r -f -a "{auto	,tls1	,tls1.1	,tls1.2	,tls1.3	}"
 complete -c xh -l default-scheme -d 'The default scheme to use if not specified in the URL' -r
 complete -c xh -l http-version -d 'HTTP version to use' -r -f -a "{1.0	,1.1	,2	}"
-complete -c xh -l interface -d 'Bind to a network interface or local IP address' -r
 complete -c xh -s j -l json -d '(default) Serialize data items from the command line as a JSON object'
 complete -c xh -s f -l form -d 'Serialize data items from the command line as form fields'
 complete -c xh -l multipart -d 'Like --form, but force a multipart/form-data request even without files'
@@ -87,7 +86,6 @@ complete -c xh -l no-native-tls
 complete -c xh -l no-default-scheme
 complete -c xh -l no-https
 complete -c xh -l no-http-version
-complete -c xh -l no-interface
 complete -c xh -l no-ipv4
 complete -c xh -l no-ipv6
 complete -c xh -l no-ignore-stdin
diff --git a/doc/xh.1 b/doc/xh.1
index 02b19e7..968e9cc 100644
--- a/doc/xh.1
+++ b/doc/xh.1
@@ -280,11 +280,6 @@ HTTP version to use.
 
 [possible values: 1.0, 1.1, 2]
 .TP 4
-\fB\-\-interface\fR=\fINAME\fR
-Bind to a network interface or local IP address.
-
-Example: \-\-interface=eth0 \-\-interface=192.168.0.2.
-.TP 4
 \fB\-4\fR, \fB\-\-ipv4\fR
 Resolve hostname to ipv4 addresses only.
 .TP 4
diff --git a/src/cli.rs b/src/cli.rs
index 6bf2f12..a46dc71 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -310,12 +310,6 @@ Example: --print=Hb"
     #[clap(long, value_name = "VERSION", value_parser)]
     pub http_version: Option<HttpVersion>,
 
-    /// Bind to a network interface or local IP address.
-    ///
-    /// Example: --interface=eth0 --interface=192.168.0.2
-    #[clap(long, value_name = "NAME")]
-    pub interface: Option<String>,
-
     /// Resolve hostname to ipv4 addresses only.
     #[clap(short = '4', long)]
     pub ipv4: bool,
diff --git a/src/main.rs b/src/main.rs
index c54639a..76933a0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -28,7 +28,6 @@ use std::sync::Arc;
 use anyhow::{anyhow, Context, Result};
 use atty::Stream;
 use cookie_store::{CookieStore, RawCookie};
-use network_interface::{NetworkInterface, NetworkInterfaceConfig};
 use redirect::RedirectFollower;
 use reqwest::blocking::Client;
 use reqwest::header::{
@@ -285,30 +284,6 @@ fn run(args: Cli) -> Result<i32> {
         _ => client,
     };
 
-    if let Some(name_or_ip) = &args.interface {
-        let ip_addr = if let Ok(ip_addr) = IpAddr::from_str(name_or_ip) {
-            Some(ip_addr)
-        } else {
-            // TODO: Directly bind to interface name once hyper/reqwest adds support for it.
-            // See https://github.com/seanmonstar/reqwest/issues/1336 and https://github.com/hyperium/hyper/pull/3076
-            let network_interfaces = NetworkInterface::show()?;
-            network_interfaces.iter().find_map(|interface| {
-                if &interface.name == name_or_ip {
-                    if let Some(addr) = interface.addr.first() {
-                        return Some(addr.ip());
-                    }
-                }
-                None
-            })
-        };
-
-        if let Some(ip_addr) = ip_addr {
-            client = client.local_address(ip_addr);
-        } else {
-            return Err(anyhow!("Couldn't bind to {:?}", name_or_ip));
-        }
-    }
-
     let client = client.build()?;
 
     let mut session = match &args.session {
diff --git a/src/to_curl.rs b/src/to_curl.rs
index 8360ba5..21e7cfa 100644
--- a/src/to_curl.rs
+++ b/src/to_curl.rs
@@ -284,11 +284,6 @@ pub fn translate(args: Cli) -> Result<Command> {
         _ => (),
     };
 
-    if let Some(interface) = args.interface {
-        cmd.arg("--interface");
-        cmd.arg(interface);
-    };
-
     // Payload
     for (header, value) in headers.iter() {
         cmd.opt("-H", "--header");

But in the meantime we should work on a proper fix. Maybe we can guard network-interface and --interface behind a feature and only enable that feature by default on supported platforms.

Are you interested in opening an issue on the network-interface repo as well?

@blyxxyz thanks for your reply. Usually, I'd try to fix this myself but, I still have a bunch of other packages to update.

I'll have a look at it in the next few days and let you know if we need a feature gate.

Yes, I'll either, open an issue with network-interface or, a PR with a fix. We'll see ๐Ÿ‘

@blyxxyz I got the same error on Ubuntu.

@DerGoogler do you mind sharing with us the build error you're seeing? thanks

@ducaale

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
  --> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/network-interface-1.0.0/src/target/getifaddrs.rs:25:18
   |
25 |         unsafe { libc::freeifaddrs(self.base) }
   |                  ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
  --> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/network-interface-1.0.0/src/target/getifaddrs.rs:31:20
   |
31 |     match unsafe { libc::getifaddrs(addr.as_mut_ptr()) } {
   |                    ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
 --> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/network-interface-1.0.0/src/target/getifaddrs.rs:5:16
  |
5 |     base: *mut libc::ifaddrs,
  |                ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
 --> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/network-interface-1.0.0/src/target/getifaddrs.rs:6:16
  |
6 |     next: *mut libc::ifaddrs,
  |                ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
  --> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/network-interface-1.0.0/src/target/getifaddrs.rs:10:17
   |
10 |     type Item = libc::ifaddrs;
   |                 ^^^^ use of undeclared crate or module `libc`

error[E0433]: failed to resolve: use of undeclared crate or module `libc`
  --> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/network-interface-1.0.0/src/target/getifaddrs.rs:30:44
   |
30 |     let mut addr = mem::MaybeUninit::<*mut libc::ifaddrs>::uninit();
   |                                            ^^^^ use of undeclared crate or module `libc`

For more information about this error, try `rustc --explain E0433`.
error: could not compile `network-interface` (lib) due to 6 previous errors

Trying to build for Android

@DerGoogler Are you by any chance cross-compiling for Android? It got support in network-interface v1.0.2, but we still use v1.0.0 in our lockfile.

A native GNU/Linux build should work OK, it succeeds on my Debian system.

@blyxxyz v18 is already cross compiled (see Magisk/KernelSU module). I want update it to v19

It somehow compiled...
image

Thanks for making this an optional feature.
I had a look at the network-interface crate but, I don't think it makes much sense opening an issue right now, rust-libc itself is missing those functions.

Question is, @ducaale are you planning a new release? If not, that's fine, I can pull the sources from #332. Just would like to know. Thanks @blyxxyz

@0323pin Yes, I'm planning to cut a release soon in a moment.

The network-interface crate is now behind a feature gate in xh v0.19.3

Looks like support needs to be added to rust-libc as the C-components do exist on my system.

2023-10-22-074831_1132x453_scrot