Packages

Socket handling library for Elixir, updated for OTP20+

Current section

Files

Jump to
sockets lib socket host.ex
Raw

lib/socket/host.ex

# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# Version 2, December 2004
#
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
# 0. You just DO WHAT THE FUCK YOU WANT TO.
defmodule Socket.Host do
@moduledoc """
Looks up information about a host by name or IP address.
Given a hostname like `"google.com"` or an IP address, it returns a struct
with the canonical name, any known aliases, and the list of IP addresses
associated with that host. Also exposes helpers for getting the local
machine's hostname and network interfaces.
"""
defstruct [:name, :aliases, :type, :length, :list]
use Socket.Helpers
@type t :: %Socket.Host{
name: String.t(),
aliases: [String.t()],
type: :inet | :inet6,
length: integer,
list: [tuple]
}
@doc """
Get the hostent by address.
"""
@spec by_address(Socket.Address.t()) :: {:ok, t} | {:error, :inet.posix()}
def by_address(address) do
case :inet.gethostbyaddr(Socket.Address.parse(address)) do
{:ok, host} ->
{:ok, convert(host)}
{:error, reason} ->
{:error, reason}
end
end
@doc """
Get the hostent by address, raising if an error occurs.
"""
@spec by_address!(Socket.Address.t()) :: t
defbang(by_address(address))
@doc """
Get the hostent by name and family.
"""
@spec by_name(binary, :inet.address_family()) :: {:ok, t} | {:error, :inet.posix()}
def by_name(name, family) when name |> is_binary do
case :inet.gethostbyname(String.to_charlist(name), family) do
{:ok, host} ->
{:ok, convert(host)}
{:error, reason} ->
{:error, reason}
end
end
@doc """
Get the hostent by name.
"""
@spec by_name(binary) :: {:ok, t} | {:error, :inet.posix()}
def by_name(name) when name |> is_binary,
do: by_name(name, :inet)
@doc """
Get the hostent by name and family, raising if an error occurs.
"""
@spec by_name!(binary, :inet.address_family()) :: t
defbang(by_name(name, family))
@doc """
Get the hostent by name, raising if an error occurs.
"""
@spec by_name!(binary) :: t
defbang(by_name(name))
@doc """
Get the hostname of the machine.
"""
@spec name :: String.t()
def name do
{:ok, name} = :inet.gethostname()
to_string(name)
end
@doc """
Get the interfaces of the machine.
"""
@spec interfaces :: {:ok, [tuple]} | {:error, :inet.posix()}
def interfaces,
do: :inet.getifaddrs()
@doc """
Get the interfaces of the machine, raising if an error occurs.
"""
@spec interfaces! :: [tuple]
defbang(interfaces)
defp convert({_, name, aliases, type, length, list}) do
%Socket.Host{
name: List.to_string(name),
aliases: aliases |> Enum.map(&List.to_string/1),
type: type,
length: length,
list: list
}
end
end