.\" -*- coding: UTF-8 -*-
'\" t
.\" Copyright (c) 2007, 2008 Michael Kerrisk <mtk.manpages@gmail.com>
.\" and Copyright (c) 2006 Ulrich Drepper <drepper@redhat.com>
.\" A few pieces of an earlier version remain:
.\" Copyright 2000, Sam Varshavchik <mrsam@courier-mta.com>
.\"
.\" SPDX-License-Identifier: Linux-man-pages-copyleft
.\"
.\" References: RFC 2553
.\"
.\" 2005-08-09, mtk, added AI_ALL, AI_ADDRCONFIG, AI_V4MAPPED,
.\"			and AI_NUMERICSERV.
.\" 2006-11-25, Ulrich Drepper <drepper@redhat.com>
.\"     Add text describing Internationalized Domain Name extensions.
.\" 2007-06-08, mtk: added example programs
.\" 2008-02-26, mtk; clarify discussion of NULL 'hints' argument; other
.\"     minor rewrites.
.\" 2008-06-18, mtk: many parts rewritten
.\" 2008-12-04, Petr Baudis <pasky@suse.cz>
.\"	Describe results ordering and reference /etc/gai.conf.
.\"
.\" FIXME . glibc's 2.9 NEWS file documents DCCP and UDP-lite support
.\"           and is SCTP support now also there?
.\"
.\"*******************************************************************
.\"
.\" This file was generated with po4a. Translate the source file.
.\"
.\"*******************************************************************
.TH getaddrinfo 3 "5 lutego 2023 r." "Linux man\-pages 6.03" 
.SH NAZWA
getaddrinfo, freeaddrinfo, gai_strerror \- tłumaczy adresy i usługi sieciowe
.SH BIBLIOTEKA
Standardowa biblioteka C (\fIlibc\fP, \fI\-lc\fP)
.SH SKŁADNIA
.nf
\fB#include <sys/types.h>\fP
\fB#include <sys/socket.h>\fP
\fB#include <netdb.h>\fP
.PP
\fBint getaddrinfo(const char *restrict \fP\fInode\fP\fB,\fP
\fB                const char *restrict \fP\fIservice\fP\fB,\fP
\fB                const struct addrinfo *restrict \fP\fIhints\fP\fB,\fP
\fB                struct addrinfo **restrict \fP\fIres\fP\fB);\fP
.PP
\fBvoid freeaddrinfo(struct addrinfo *\fP\fIres\fP\fB);\fP
.PP
\fBconst char *gai_strerror(int \fP\fIerrcode\fP\fB);\fP
.fi
.PP
.RS -4
Wymagane ustawienia makr biblioteki glibc (patrz \fBfeature_test_macros\fP(7)):
.RE
.PP
\fBgetaddrinfo\fP(), \fBfreeaddrinfo\fP(), \fBgai_strerror\fP():
.nf
    Od glibc 2.22:
        _POSIX_C_SOURCE >= 200112L
    glibc 2.21 i wcześniejsze:
        _POSIX_C_SOURCE
.fi
.SH OPIS
.\" .BR getipnodebyname (3),
.\" .BR getipnodebyaddr (3),
Dla danego węzła \fInode\fP i usługi \fIservice\fP, które identyfikują stację i
usługę internetową, \fBgetaddrinfo\fP() zwraca jedną lub więcej struktur
\fIaddrinfo\fP, każda z których zawiera adres internetowy, który można podać w
wywołaniu do \fBbind\fP(2) lub \fBconnect\fP(2). Funkcja \fBgetaddrinfo\fP() łączy
funkcjonalność udostępnianą przez funkcje \fBgethostbyname\fP(3) i
\fBgetservbyname\fP(3) w jeden interfejs, lecz w przeciwieństwie do nich,
\fBgetaddrinfo\fP() jest wielobieżna i umożliwia programom wyeliminowanie
zależności od IPv4 lub IPv6.
.PP
Struktura \fIaddrinfo\fP używana przez \fBgetaddrinfo\fP() zawiera następujące
pola:
.PP
.in +4n
.EX
struct addrinfo {
    int              ai_flags;
    int              ai_family;
    int              ai_socktype;
    int              ai_protocol;
    socklen_t        ai_addrlen;
    struct sockaddr *ai_addr;
    char            *ai_canonname;
    struct addrinfo *ai_next;
};
.EE
.in
.PP
Argument \fIhints\fP wskazuje na strukturę \fIaddrinfo\fP, która określa kryteria
wyboru struktur adresów gniazd zwracanych w liście wskazywanej przez
\fIres\fP. Jeśli \fIhints\fP nie wynosi NULL, wskazuje na strukturę \fIaddrinfo\fP,
której pola \fIai_family\fP, \fIai_socktype\fP i \fIai_protocol\fP określają kryteria
ograniczające zbiory adresów gniazd zwracane przez \fBgetaddrinfo\fP(), zgodnie
z poniższym opisem:
.TP 
\fIai_family\fP
Pole określa żądaną rodzinę adresów wobec zwracanych adresów. Prawidłowe
wartości tego pola obejmują \fBAF_INET\fP i \fBAF_INET6\fP. Wartość \fBAF_UNSPEC\fP
wskazuje, że \fBgetaddrinfo\fP() powinno zwrócić adresy gniazd dla dowolnej
rodziny adresów (np. IPv4 lub IPv6), których można użyć z \fInode\fP i
\fIservice\fP.
.TP 
\fIai_socktype\fP
Pole określa preferowany typ gniazda np. \fBSOCK_STREAM\fP lub
\fBSOCK_DGRAM\fP. Podanie w tym polu wartości 0 wskazuje, że \fBgetaddrinfo\fP()
może zwrócić adresy gniazd dowolnego typu.
.TP 
\fIai_protocol\fP
Pole określa protokół zwracanych adresów gniazd. Podanie w tym polu wartości
0 wskazuje, że \fBgetaddrinfo\fP() może zwrócić adresy gniazd dowolnego
protokołu.
.TP 
\fIai_flags\fP
Pole określa dodatkowe opcje, opisane poniżej. Można podać wiele flag,
sumując je bitowo (OR).
.PP
Wszystkie pozostałe pola w strukturze na którą wskazuje \fIhints\fP, muszą
zawierać albo 0, albo pusty wskaźnik (w zależności od pola).
.PP
Podanie \fIhints\fP jako NULL jest równoważne ustawieniu \fIai_socktype\fP i
\fIai_protocol\fP na 0; \fIai_family\fP na \fBAF_UNSPEC\fP; a \fIai_flags\fP na
\fB(AI_V4MAPPED\ |\ AI_ADDRCONFIG)\fP (POSIX określa inną wartość domyślną dla
\fIai_flags\fP; zob. UWAGI). \fInode\fP zawiera albo adres sieciowy w postaci
numerycznej (dla IPv4: w formacie liczb i kropek takim, jak obsługiwany
przez \fBinet_aton\fP(3); dla IPv6: w formacie szesnastkowego łańcucha takim,
jak obsługiwany przez \fBinit_pton\fP(3)), albo nazwę stacji, dla której adresy
sieciowe będą poszukiwane i rozwiązane. Jeśli \fIhints.ai_flags\fP zawiera
znacznik \fBAI_NUMERICHOST\fP, to \fInode\fP musi być adresem sieciowym w postaci
numerycznej. Znacznik \fBAI_NUMERICHOST\fP eliminuje jakiekolwiek, potencjalnie
długotrwałe, poszukiwania adresu sieciowego stacji.
.PP
Jeśli w \fIhints.ai_flags\fP podano znacznik \fBAI_PASSIVE\fP, a \fInode\fP wynosi
NULL, to zwracane adresy gniazd będą odpowiednie do przypisywania
(\fBbind\fP(2)) gniazd, które będą akceptowały (\fBaccept\fP(2))
połączenia. Zwracany adres gniazda będzie zawierał \[Bq]adres
wieloznaczny\[rq] (\[Bq]wildcard address\[rq]; \fBINADDR_ANY\fP w przypadku
adresów IPv4, \fBIN6ADDR_ANY_INIT\fP w przypadku adresów IPv6). Adres
wieloznaczny jest używany przez aplikacje (zwykle serwery), które mają
zamiar akceptować połączenia na dowolnym z adresów sieciowych stacji. Jeśli
\fInode\fP nie wynosi NULL, to znacznik \fBAI_PASSIVE\fP jest ignorowany.
.PP
Jeśli w \fIhints.ai_flags\fP nie podano znacznika \fBAI_PASSIVE\fP, to zwracane
adresy gniazd będą odpowiednie do korzystania z \fBconnect\fP(2), \fBsendto\fP(2)
lub \fBsendmsg\fP(2). Jeśli \fInode\fP wynosi NULL, to adres sieciowy będzie
ustawiony na adres interfejsu pętli zwrotnej (\fBINADDR_LOOPBACK\fP w przypadku
adresów IPv4, \fBIN6ADDR_LOOPBACK_INIT\fP w przypadku adresów IPv6); jest to
używane przez aplikacje, które mają zamiar komunikować się z innymi
aplikacjami działającymi na tej samej stacji.
.PP
\fIservice\fP ustawia port w każdej zwracanej strukturze adresu. Jeśli argument
ten jest nazwą usługi (zob. \fBservices\fP(5)), to jest tłumaczona na
odpowiedni numer portu. Argument ten może być też liczbą dziesiętną, wówczas
jest jedynie przekształcana na liczbę binarną. Jeśli \fIservice\fP wynosi NULL,
to numer portu zwracanych adresów gniazd będzie pozostawiony
niezainicjowany. Jeśli w \fIhints.ai_flags\fP podano \fBAI_NUMERICSERV\fP, a
\fIservice\fP nie wynosi NULL, to \fIservice\fP musi wskazywać na łańcuch
zawierający numeryczny numer portu. Znacznik ten jest używany do
powstrzymania rozwiązywania nazw w przypadkach, w których wiadomo, że nie
będzie to konieczne.
.PP
Parametry \fInode\fP i \fIservice\fP mogą być równe NULL, ale nie oba naraz.
.PP
Funkcja \fBgetaddrinfo\fP() alokuje i inicjuje podlinkowaną listę struktur
\fIaddrinfo\fP, po jednej dla każdego adresu sieciowego, który pasuje do
\fInode\fP i \fIservice\fP, jest przedmiotem wszelkich ograniczeń nałożonych przez
\fIhints\fP, a zwraca wskaźnik do początku listy w \fIres\fP. Pozycje na
podlinkownej liście są linkowane za pomocą pola \fIai_next\fP.
.PP
Istnieje wiele powodów, dla których podlinkowana lista może mieć więcej niż
jedną strukturę \fIaddrinfo\fP m.in.: stacja sieciowa może być wieloadresowa,
dostępna za pomocą różnych protokołów (np. \fBAF_INET\fP oraz \fBAF_INET6\fP);
albo ta sama usługa jest dostępna za pomocą różnych typów gniazd (np. jeden
adres \fBSOCK_STREAM\fP i inny adres \fBSOCK_DGRAM\fP). Aplikacja zwykle spróbuje
użyć adresy w zwracanej kolejności. Funkcja sortowania używana w
\fBgetaddrinfo\fP() jest zdefiniowana w RFC\ 3484; kolejność można dostosować
dla danego systemu, edytując plik \fI/etc/gai.conf\fP (dostępny od glibc 2.5).
.PP
.\" Prior to glibc 2.3.4, the ai_canonname of each addrinfo
.\" structure was set pointing to the canonical name; that was
.\" more than POSIX.1-2001 specified, or other implementations provided.
.\" MTK, Aug 05
Jeśli \fIhints.ai_flags\fP zawiera znacznik \fBAI_CANONNAME\fP, to pole
\fIai_canonname\fP w pierwszej ze struktur \fIaddrinfo\fP w zwracanej liście, jest
ustawiane na oficjalną nazwę stacji.
.PP
Pozostałe pola w każdej ze zwracanych struktur \fIaddrinfo\fP są inicjowane w
następujący sposób:
.IP \[bu] 3
Pola \fIai_family\fP, \fIai_socktype\fP i \fIai_protocol\fP zwracają parametry
tworzenia gniazd (tzn. pola te mają takie samo znaczenie, jak odpowiadające
im argumenty \fBsocket\fP(2)). Przykładowo \fIai_family\fP może zwrócić \fBAF_INET\fP
lub \fBAF_INET6\fP; \fIai_socktype\fP może zwrócić \fBSOCK_DGRAM\fP lub
\fBSOCK_STREAM\fP; a \fIai_protocol\fP zwróci protokół gniazda.
.IP \[bu]
Wskaźnik do adresu gniazda jest umieszczany w polu \fIai_addr\fP, a długość
adresu gniazda w bajtach, jest umieszczana w polu \fIai_addrlen\fP.
.PP
Jeśli \fIhints.ai_flags\fP zawiera znacznik \fBAI_ADDRCONFIG\fP, to adresy IPv4 są
zwracane w liście, na którą wskazuje \fIres\fP tylko, gdy lokalny system ma
skonfigurowany przynajmniej jeden adres IPv4, a adresy IPv6 są zwracane
tylko, gdy lokalny system ma skonfigurowany przynajmniej jeden adres
IPv6. Adres pętli zwrotnej nie jest w tym przypadku uważany za prawidłowy
skonfigurowany adres. Znacznik ten jest przydatny np. w systemach
korzystających wyłącznie z IPv4 aby zapewnić, że \fBgetaddrinfo\fP() nie zwróci
adresów gniazd IPv6, które zawsze zawiodłyby w \fBconnect\fP(2) lub \fBbind\fP(2).
.PP
Jeśli \fIhints.ai_flags\fP określa znacznik \fBAI_V4MAPPED\fP, a
\fIhints.ai_family\fP podano jako \fBAF_INET6\fP oraz nie da się znaleźć
pasującego adresu IPv6, to w liście, na którą wskazuje \fIres\fP, zwracane są
adresy IPv4 zmapowane jako IPv6. Jeśli w \fIhints.ai_flags\fP podano
\fBAI_V4MAPPED\fP oraz \fBAI_ALL\fP, to zwracane są adresy IPv6 oraz adresy IPv4
zmapowane jako IPv6. \fBAI_ALL\fP jest ignorowane, jeśli nie podano również
\fBAI_V4MAPPED\fP.
.PP
Funkcja \fBfreeaddrinfo\fP() zwalnia pamięć przydzieloną dla dynamicznie
zaalokowanej listy \fIres\fP.
.SS "Rozszerzenia getaddrinfo() dla domen ze znakami spoza ASCII (IDN)"
Od glibc 2.3.4, \fBgetaddrinfo\fP() rozszerzono w celu umożliwiania wybiórczego
i przezroczystego konwertowania przychodzących i wychodzących nazw stacji z
i na format Internationalized Domain Name (IDN; zob. RFC\ 3490,
\fIInternationalizing Domain Names in Applications (IDNA)\fP). Zdefiniowano
cztery nowe znaczniki:
.TP 
\fBAI_IDN\fP
Jeśli znacznik jest podany, nazwa węzła podana w \fInode\fP jest konwertowana
na format IDN, jeśli to konieczne. Kodowanie źródłowe jest takie, jak w
bieżących ustawieniach regionalnych (locale).
.IP
.\" Implementation Detail:
.\" To minimize effects on system performance the implementation might
.\" want to check whether the input string contains any non-ASCII
.\" characters.  If there are none the IDN step can be skipped completely.
.\" On systems which allow not-ASCII safe encodings for a locale this
.\" might be a problem.
Jeśli nazwa wejściowa zawiera znaki spoza ASCII, to używane jest kodowanie
IDN. Te fragmenty nazwy węzła (oddzielone kropką), które zawierają znaki
spoza ASCII są kodowane za pomocą ASCII Compatible Encoding, przed ich
przekazaniem do funkcji rozwiązywania nazw.
.TP 
\fBAI_CANONIDN\fP
Po pomyślnym wyszukaniu nazwy, jeśli podano \fBAI_CANONNAME\fP,
\fBgetaddrinfo\fP() zwróci kanoniczną nazwę węzła odnoszącą się do wartości
struktury \fIaddrinfo\fP przekazywanej zwrotnie. Zwracana wartość jest dokładną
kopią wartości zwracanej przez funkcję rozwiązywania nazw.
.IP
.\"
.\"Implementation Detail:
.\"If no component of the returned name starts with xn\-\- the IDN
.\"step can be skipped, therefore avoiding unnecessary slowdowns.
Jeśli nazwa jest zakodowana za pomocą ACE, to będzie zawierać przedrostek
\fIxn\-\-\fP w jednej lub więcej składowych nazw. Aby przekształcić te składowe w
czytelną postać, oprócz znacznika \fBAI_CANONNAME\fP można podać też
\fBAI_CANONIDN\fP. Wynikowy łańcuch będzie kodowany przy użyciu kodowania z
bieżących ustawieniach regionalnych (locale).
.TP 
\fBAI_IDN_ALLOW_UNASSIGNED\fP, \fBAI_IDN_USE_STD3_ASCII_RULES\fP
Ustawienie tych znaczników włączy znaczniki, odpowiednio,
IDNA_ALLOW_UNASSIGNED (zezwala na nieprzypisane kody Unikodu) i
IDNA_USE_STD3_ASCII_RULES (sprawdza wyjście, aby upewnić się że jest to
nazwa stacji zgodna z STD3) do użycia w obsłudze IDNA.
.SH "WARTOŚĆ ZWRACANA"
.\" FIXME glibc defines the following additional errors, some which
.\" can probably be returned by getaddrinfo(); they need to
.\" be documented.
.\"    #ifdef __USE_GNU
.\"    #define EAI_INPROGRESS  -100  /* Processing request in progress.  */
.\"    #define EAI_CANCELED    -101  /* Request canceled.  */
.\"    #define EAI_NOTCANCELED -102  /* Request not canceled.  */
.\"    #define EAI_ALLDONE     -103  /* All requests done.  */
.\"    #define EAI_INTR        -104  /* Interrupted by a signal.  */
.\"    #define EAI_IDN_ENCODE  -105  /* IDN encoding failed.  */
.\"    #endif
\fBgetaddrinfo\fP() zwraca 0, gdy zakończy się pomyślnie, a w przeciwnym razie
jeden z następujących niezerowych kodów błędów:
.TP 
\fBEAI_ADDRFAMILY\fP
.\" Not in SUSv3
Podana stacja nie posiada żadnego adresu sieciowego dla zadanej rodziny
adresów.
.TP 
\fBEAI_AGAIN\fP
Serwer nazw zwrócił błąd tymczasowy. Należy spróbować później.
.TP 
\fBEAI_BADFLAGS\fP
\fIhints.ai_flags\fP zawiera nieprawidłowe znaczniki; albo \fIhints.ai_flags\fP
zawierało \fBAI_CANONNAME\fP, a \fIname\fP wynosiło NULL.
.TP 
\fBEAI_FAIL\fP
Serwer nazw zwrócił błąd trwały.
.TP 
\fBEAI_FAMILY\fP
Żądana rodzina adresów nie jest obsługiwana.
.TP 
\fBEAI_MEMORY\fP
Brak pamięci.
.TP 
\fBEAI_NODATA\fP
.\" Not in SUSv3
Podana stacja sieciowa istnieje, ale nie zdefiniowano dla niej żadnego
adresu sieciowego.
.TP 
\fBEAI_NONAME\fP
\fInode\fP lub \fIservice\fP nie jest znane; albo zarówno \fInode\fP jak i \fIservice\fP
wynoszą NULL; albo w \fIhints.ai_flags\fP podano \fBAI_NUMERICSERV\fP, a
\fIservice\fP nie było numerycznym łańcuchem numeru portu.
.TP 
\fBEAI_SERVICE\fP
Żądana usługa nie jest dostępna dla żądanego typu portu. Może być dostępna
za pomocą innego typu portu. Ten błąd może wystąpić na przykład, gdy jako
\fIservice\fP podano \[Bq]shell\[rq] (usługa dostępna tylko na gniazdach
strumieniowych), a \fIhints.ai_protocol\fP wynosiło \fBIPPROTO_UDP\fP albo
\fIhints.ai_socktype\fP wynosiło \fBSOCK_DGRAM\fP; albo błąd może wystąpić gdy
\fIservice\fP nie wynosiło NULL, a \fIhints.ai_socktype\fP wynosiło \fBSOCK_RAW\fP
(typ gniazda, w ogóle nie obsługujący koncepcji usług).
.TP 
\fBEAI_SOCKTYPE\fP
Żądany typ gniazda nie jest obsługiwany. Może się to zdarzyć na przykład,
gdy \fIhints.ai_socktype\fP i \fIhints.ai_protocol\fP są niespójne (np. wynoszą,
odpowiednio, \fBSOCK_DGRAM\fP i \fBIPPROTO_TCP\fP).
.TP 
\fBEAI_SYSTEM\fP
Inny błąd systemowy; ustawiane jest \fIerrno\fP aby wskazać błąd.
.PP
Funkcja \fBgai_strerror\fP() tłumaczy te kody błędów na czytelny dla człowieka
łańcuch, odpowiedni do zgłaszania błędów.
.SH PLIKI
\fI/etc/gai.conf\fP
.SH ATRYBUTY
Informacje o pojęciach używanych w tym rozdziale można znaleźć w podręczniku
\fBattributes\fP(7).
.ad l
.nh
.TS
allbox;
lbx lb lb
l l l.
Interfejs	Atrybut	Wartość
T{
\fBgetaddrinfo\fP()
T}	Bezpieczeństwo wątkowe	MT\-bezpieczne env locale
T{
\fBfreeaddrinfo\fP(),
\fBgai_strerror\fP()
T}	Bezpieczeństwo wątkowe	MT\-bezpieczne
.TE
.hy
.ad
.sp 1
.SH STANDARDY
POSIX.1\-2001, POSIX.1\-2008. Funkcja \fBgetaddrinfo\fP() jest udokumentowana w
RFC\ 2553.
.SH UWAGI
\fBgetaddrinfo\fP() obsługuje notację \fIadres\fP\fB%\fP\fIidentyfikator\-zasięgu\fP do
określenia identyfikatora zasięgu IPv6.
.PP
\fBAI_ADDRCONFIG\fP, \fBAI_ALL\fP i \fBAI_V4MAPPED\fP są dostępne od glibc
2.3.3. \fBAI_NUMERICSERV\fP jest dostępne od glibc 2.3.4.
.PP
.\" POSIX.1-2001, POSIX.1-2008
According to POSIX.1, specifying \fIhints\fP as NULL should cause \fIai_flags\fP
to be assumed as 0.  The GNU C library instead assumes a value of
\fB(AI_V4MAPPED\~|\~AI_ADDRCONFIG)\fP for this case, since this value is
considered an improvement on the specification.
.SH PRZYKŁADY
.\" getnameinfo.3 refers to this example
.\" socket.2 refers to this example
.\" bind.2 refers to this example
.\" connect.2 refers to this example
.\" recvfrom.2 refers to this example
.\" sendto.2 refers to this example
Poniższe programy demonstrują użycie \fBgetaddrinfo\fP(), \fBgai_strerror\fP(),
\fBfreeaddrinfo\fP() i \fBgetnameinfo\fP(3). Programy są serwerem i klientem typu
echo dla datagramów UDP.
.SS "Program serwera"
.\" SRC BEGIN (server.c)
\&
.EX
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define BUF_SIZE 500

int
main(int argc, char *argv[])
{
    int                      sfd, s;
    char                     buf[BUF_SIZE];
    ssize_t                  nread;
    socklen_t                peer_addrlen;
    struct addrinfo          hints;
    struct addrinfo          *result, *rp;
    struct sockaddr_storage  peer_addr;
};

    if (argc != 2) {
        fprintf(stderr, "Użycie: %s port\en", argv[0]);
        exit(EXIT_FAILURE);
    }

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;    /* Zezwala na IPv4 lub IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Gniazdo datagramowe */
    hints.ai_flags = AI_PASSIVE;    /* Dla wieloznacznego adresu IP */
    hints.ai_protocol = 0;          /* Dowolny protokół */
    hints.ai_canonname = NULL;
    hints.ai_addr = NULL;
    hints.ai_next = NULL;

    s = getaddrinfo(NULL, argv[1], &hints, &result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\en", gai_strerror(s));
        exit(EXIT_FAILURE);
    }

    /* getaddrinfo() zwraca listę struktur adresów. Próbowany
       jest każdy adres do momentu pomyślnego bind(2).
       Jeśli socket(2) (lub bind(2)) zawiedzie, (gniazdo jest
       jest zamykane i) próbowany jest następny adres. */

    for (rp = result; rp != NULL; rp = rp\->ai_next) {
        sfd = socket(rp\->ai_family, rp\->ai_socktype,
                     rp\->ai_protocol);
        if (sfd == \-1)
            continue;

        if (bind(sfd, rp\->ai_addr, rp\->ai_addrlen) == 0)
            break;                  /* Powodzenie */

        close(sfd);
    }

    freeaddrinfo(result);           /* Nie jest już potrzebne */

    if (rp == NULL) {               /* Wszystkie adresy zawiodły */
        fprintf(stderr, "Przypisanie nie powiodło się\en");
        exit(EXIT_FAILURE);
    }

    /* Odczytuje datagramy i odsyła je wysyłającemu. */

    for (;;) {
        char host[NI_MAXHOST], service[NI_MAXSERV];

        peer_addrlen = sizeof(peer_addr);
        nread = recvfrom(sfd, buf, BUF_SIZE, 0,
                         (struct sockaddr *) &peer_addr, &peer_addrlen);
        if (nread == \-1)
            continue;               /* Ignoruje niepomyślne żądanie */

        s = getnameinfo((struct sockaddr *) &peer_addr,
                        peer_addrlen, host, NI_MAXHOST,
                        service, NI_MAXSERV, NI_NUMERICSERV);
        if (s == 0)
            printf("Otrzymano %zd bajtów z %s:%s\en",
                   nread, host, service);
        else
            fprintf(stderr, "getnameinfo: %s\en", gai_strerror(s));

        if (sendto(sfd, buf, nread, 0, (struct sockaddr *) &peer_addr,
                   peer_addrlen) != nread)
        {
            fprintf(stderr, "Błąd przy wysyłaniu odpowiedzi\en");
        }
    }
}
.EE
.\" SRC END
.SS "Program klienta"
.\" SRC BEGIN (client.c)
\&
.EX
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define BUF_SIZE 500

int
main(int argc, char *argv[])
{
    int              sfd, s;
    char             buf[BUF_SIZE];
    size_t           len;
    ssize_t          nread;
    struct addrinfo  hints;
    struct addrinfo  *result, *rp;

    if (argc < 3) {
        fprintf(stderr, "Użycie: %s stacja port komunik...\en", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* Pozyskuje adres(y) pasującej stacji/portu. */

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;    /* Zezwala na IPv4 lub IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Gniazdo datagramowe */
    hints.ai_flags = 0;
    hints.ai_protocol = 0;          /* Dowolny protokół */

    s = getaddrinfo(argv[1], argv[2], &hints, &result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\en", gai_strerror(s));
        exit(EXIT_FAILURE);
    }

    /* getaddrinfo() zwraca listę struktur adresów. Próbuje
       każdego adresu, do pomyślnego połączenia (connect(2)).
       Jeśli socket(2) (lub connect(2)) zawiedzie, (zamykamy
       gniazdo i) próbujemy następny adres. */

    for (rp = result; rp != NULL; rp = rp\->ai_next) {
        sfd = socket(rp\->ai_family, rp\->ai_socktype,
                     rp\->ai_protocol);
        if (sfd == \-1)
            continue;

        if (connect(sfd, rp\->ai_addr, rp\->ai_addrlen) != \-1)
            break;                  /* Powodzenie */

        close(sfd);
    }

    freeaddrinfo(result);           /* Nie jest już potrzebne */

    if (rp == NULL) {               /* Wszystkie adresy zawiodły */
        fprintf(stderr, "Nie udało się połączyć\en");
        exit(EXIT_FAILURE);
    }

    /* Wysyła pozostałe argumenty wiersza poleceń jako oddzielne
       datagramy i odczytuje odpowiedzi z serwera. */

    for (size_t j = 3; j < argc; j++) {
        len = strlen(argv[j]) + 1;
                /* +1 dla końcowego bajtu null */

        if (len > BUF_SIZE) {
            fprintf(stderr,
                "Ignorowanie długiego komunikatu w argumencie %zu\en", j);
            continue;
        }

        if (write(sfd, argv[j], len) != len) {
            fprintf(stderr, "częściowy/nieudany zapis\en");
            exit(EXIT_FAILURE);
        }

        nread = read(sfd, buf, BUF_SIZE);
        if (nread == \-1) {
            perror("read");
            exit(EXIT_FAILURE);
        }

        printf("Otrzymano %zd bajtów: %s\en", nread, buf);
    }

    exit(EXIT_SUCCESS);
}
.EE
.\" SRC END
.SH "ZOBACZ TAKŻE"
.\" .BR getipnodebyaddr (3),
.\" .BR getipnodebyname (3),
\fBgetaddrinfo_a\fP(3), \fBgethostbyname\fP(3), \fBgetnameinfo\fP(3), \fBinet\fP(3),
\fBgai.conf\fP(5), \fBhostname\fP(7), \fBip\fP(7)
.PP
.SH TŁUMACZENIE
Autorami polskiego tłumaczenia niniejszej strony podręcznika są:
Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl>
i
Michał Kułach <michal.kulach@gmail.com>
.
.PP
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach
licencji można uzyskać zapoznając się z
.UR https://www.gnu.org/licenses/gpl-3.0.html
GNU General Public License w wersji 3
.UE
lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
.PP
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy
dyskusyjnej
.MT manpages-pl-list@lists.sourceforge.net
.ME .
