summaryrefslogtreecommitdiff
path: root/protocols/Gadu-Gadu/src/libgadu/resolver.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Gadu-Gadu/src/libgadu/resolver.c')
-rw-r--r--protocols/Gadu-Gadu/src/libgadu/resolver.c766
1 files changed, 0 insertions, 766 deletions
diff --git a/protocols/Gadu-Gadu/src/libgadu/resolver.c b/protocols/Gadu-Gadu/src/libgadu/resolver.c
deleted file mode 100644
index 1adef3ef9d..0000000000
--- a/protocols/Gadu-Gadu/src/libgadu/resolver.c
+++ /dev/null
@@ -1,766 +0,0 @@
-/* coding: UTF-8 */
-/* $Id$ */
-
-/*
- * (C) Copyright 2001-2009 Wojtek Kaniewski <wojtekka@irc.pl>
- * Robert J. Woźny <speedy@ziew.org>
- * Arkadiusz Miśkiewicz <arekm@pld-linux.org>
- * Tomasz Chiliński <chilek@chilan.com>
- * Adam Wysocki <gophi@ekg.chmurka.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
- * USA.
- */
-
-/**
- * \file resolver.c
- *
- * \brief Funkcje rozwiązywania nazw
- */
-
-#ifdef _WIN32
-#include "win32.h"
-#else
-#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif /* _WIN32 */
-
-#ifndef _WIN32
-#include <netdb.h>
-#endif
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-#include <signal.h>
-
-#include "libgadu.h"
-#include "resolver.h"
-#include "compat.h"
-
-/** Sposób rozwiązywania nazw serwerów */
-static gg_resolver_t gg_global_resolver_type = GG_RESOLVER_DEFAULT;
-
-/** Funkcja rozpoczynająca rozwiązywanie nazwy */
-static int (*gg_global_resolver_start)(SOCKET *fd, void **private_data, const char *hostname);
-
-/** Funkcja zwalniająca zasoby po rozwiązaniu nazwy */
-static void (*gg_global_resolver_cleanup)(void **private_data, int force);
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-
-#include <pthread.h>
-
-#ifdef GG_CONFIG_HAVE_GETHOSTBYNAME_R
-/**
- * \internal Funkcja pomocnicza zwalniająca zasoby po rozwiązywaniu nazwy
- * w wątku.
- *
- * \param data Wskaźnik na wskaźnik bufora zaalokowanego w wątku
- */
-static void gg_gethostbyname_cleaner(void *data)
-{
- char **buf_ptr = (char**) data;
-
- if (buf_ptr != NULL) {
- free(*buf_ptr);
- *buf_ptr = NULL;
- }
-}
-#endif
-#endif /* GG_CONFIG_HAVE_PTHREAD */
-
-/**
- * \internal Odpowiednik \c gethostbyname zapewniający współbieżność.
- *
- * Jeśli dany system dostarcza \c gethostbyname_r, używa się tej wersji, jeśli
- * nie, to zwykłej \c gethostbyname.
- *
- * \param hostname Nazwa serwera
- * \param addr Wskaźnik na rezultat rozwiązywania nazwy
- * \param pthread Flaga blokowania unicestwiania wątku podczas alokacji pamięci
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_gethostbyname_real(const char *hostname, struct in_addr *addr, int pthread)
-{
-#ifdef GG_CONFIG_HAVE_GETHOSTBYNAME_R
- char *buf = NULL;
- char *new_buf = NULL;
- struct hostent he;
- struct hostent *he_ptr = NULL;
- size_t buf_len = 1024;
- int result = -1;
- int h_errnop;
- int ret = 0;
-#ifdef GG_CONFIG_HAVE_PTHREAD
- int old_state;
-#endif
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- pthread_cleanup_push(gg_gethostbyname_cleaner, &buf);
-
- if (pthread)
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
- buf = malloc(buf_len);
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- if (pthread)
- pthread_setcancelstate(old_state, NULL);
-#endif
-
- if (buf != NULL) {
-#ifndef sun
- while ((ret = gethostbyname_r(hostname, &he, buf, buf_len, &he_ptr, &h_errnop)) == ERANGE) {
-#else
- while (((he_ptr = gethostbyname_r(hostname, &he, buf, buf_len, &h_errnop)) == NULL) && (errno == ERANGE)) {
-#endif
- buf_len *= 2;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- if (pthread)
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
- new_buf = realloc(buf, buf_len);
-
- if (new_buf != NULL)
- buf = new_buf;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- if (pthread)
- pthread_setcancelstate(old_state, NULL);
-#endif
-
- if (new_buf == NULL) {
- ret = ENOMEM;
- break;
- }
- }
-
- if (ret == 0 && he_ptr != NULL) {
- memcpy(addr, he_ptr->h_addr, sizeof(struct in_addr));
- result = 0;
- }
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- if (pthread)
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
-#endif
-
- free(buf);
- buf = NULL;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- if (pthread)
- pthread_setcancelstate(old_state, NULL);
-#endif
- }
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- pthread_cleanup_pop(1);
-#endif
-
- return result;
-#else
- struct hostent *he;
-
- he = gethostbyname(hostname);
-
- if (he == NULL)
- return -1;
-
- memcpy(addr, he->h_addr, sizeof(struct in_addr));
-
- return 0;
-#endif /* GG_CONFIG_HAVE_GETHOSTBYNAME_R */
-}
-
-/**
- * \internal Odpowiednik \c gethostbyname zapewniający współbieżność.
- *
- * Jeśli dany system dostarcza \c gethostbyname_r, używa się tej wersji, jeśli
- * nie, to zwykłej \c gethostbyname.
- *
- * \param hostname Nazwa serwera
- *
- * \return Zaalokowana struktura \c in_addr lub NULL w przypadku błędu.
- */
-struct in_addr *gg_gethostbyname(const char *hostname)
-{
- struct in_addr *addr;
-
- if (!(addr = malloc(sizeof(struct in_addr))))
- return NULL;
-
- if (gg_gethostbyname_real(hostname, addr, 0)) {
- free(addr);
- return NULL;
- }
- return addr;
-}
-
-/**
- * \internal Struktura przekazywana do wątku rozwiązującego nazwę.
- */
-struct gg_resolver_fork_data {
- int pid; /*< Identyfikator procesu */
-};
-
-/**
- * \internal Rozwiązuje nazwę serwera w osobnym procesie.
- *
- * Połączenia asynchroniczne nie mogą blokować procesu w trakcie rozwiązywania
- * nazwy serwera. W tym celu tworzony jest potok, nowy proces i dopiero w nim
- * przeprowadzane jest rozwiązywanie nazwy. Deskryptor strony do odczytu
- * zapisuje się w strukturze sieci i czeka na dane w postaci struktury
- * \c in_addr. Jeśli nie znaleziono nazwy, zwracana jest \c INADDR_NONE.
- *
- * \param fd Wskaźnik na zmienną, gdzie zostanie umieszczony deskryptor
- * potoku
- * \param priv_data Wskaźnik na zmienną, gdzie zostanie umieszczony wskaźnik
- * do numeru procesu potomnego rozwiązującego nazwę
- * \param hostname Nazwa serwera do rozwiązania
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_resolver_fork_start(SOCKET *fd, void **priv_data, const char *hostname)
-{
- struct gg_resolver_fork_data *data = NULL;
- struct in_addr addr;
- int new_errno;
- SOCKET pipes[2];
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_resolver_fork_start(%p, %p, \"%s\");\n", fd, priv_data, hostname);
-
- if (fd == NULL || priv_data == NULL || hostname == NULL) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_fork_start() invalid arguments\n");
- errno = EFAULT;
- return -1;
- }
-
- data = malloc(sizeof(struct gg_resolver_fork_data));
-
- if (data == NULL) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_fork_start() out of memory for resolver data\n");
- return -1;
- }
-
- if (pipe(pipes) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_fork_start() unable to create pipes (errno=%d, %s)\n", errno, strerror(errno));
- free(data);
- return -1;
- }
-
- data->pid = fork();
-
- if (data->pid == -1) {
- new_errno = errno;
- goto cleanup;
- }
-
- if (data->pid == 0) {
- gg_sock_close(pipes[0]);
-
- if ((addr.s_addr = inet_addr(hostname)) == INADDR_NONE) {
- /* W przypadku błędu gg_gethostbyname_real() zwróci -1
- * i nie zmieni &addr. Tam jest już INADDR_NONE,
- * więc nie musimy robić nic więcej. */
- gg_gethostbyname_real(hostname, &addr, 0);
- }
-
- if (gg_sock_write(pipes[1], &addr, sizeof(addr)) != sizeof(addr))
- exit(1);
-
- exit(0);
- }
-
- gg_sock_close(pipes[1]);
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_fork_start() %p\n", data);
-
- *fd = pipes[0];
- *priv_data = data;
-
- return 0;
-
-cleanup:
- free(data);
- gg_sock_close(pipes[0]);
- gg_sock_close(pipes[1]);
-
- errno = new_errno;
-
- return -1;
-}
-
-/**
- * \internal Usuwanie zasobów po procesie rozwiązywaniu nazwy.
- *
- * Funkcja wywoływana po zakończeniu rozwiązanywania nazwy lub przy zwalnianiu
- * zasobów sesji podczas rozwiązywania nazwy.
- *
- * \param priv_data Wskaźnik na zmienną przechowującą wskaźnik do prywatnych
- * danych
- * \param force Flaga usuwania zasobów przed zakończeniem działania
- */
-static void gg_resolver_fork_cleanup(void **priv_data, int force)
-{
- struct gg_resolver_fork_data *data;
-
- if (priv_data == NULL || *priv_data == NULL)
- return;
-
- data = (struct gg_resolver_fork_data*) *priv_data;
- *priv_data = NULL;
-
- if (force)
- kill(data->pid, SIGKILL);
-
- waitpid(data->pid, NULL, WNOHANG);
-
- free(data);
-}
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
-
-/**
- * \internal Struktura przekazywana do wątku rozwiązującego nazwę.
- */
-struct gg_resolver_pthread_data {
- pthread_t thread; /*< Identyfikator wątku */
- char *hostname; /*< Nazwa serwera */
- SOCKET rfd; /*< Deskryptor do odczytu */
- SOCKET wfd; /*< Deskryptor do zapisu */
-};
-
-/**
- * \internal Usuwanie zasobów po wątku rozwiązywaniu nazwy.
- *
- * Funkcja wywoływana po zakończeniu rozwiązanywania nazwy lub przy zwalnianiu
- * zasobów sesji podczas rozwiązywania nazwy.
- *
- * \param priv_data Wskaźnik na zmienną przechowującą wskaźnik do prywatnych
- * danych
- * \param force Flaga usuwania zasobów przed zakończeniem działania
- */
-static void gg_resolver_pthread_cleanup(void **priv_data, int force)
-{
- struct gg_resolver_pthread_data *data;
-
- if (priv_data == NULL || *priv_data == NULL)
- return;
-
- data = (struct gg_resolver_pthread_data *) *priv_data;
- *priv_data = NULL;
-
- if (force) {
- pthread_cancel(&data->thread);
- pthread_join(&data->thread, NULL);
- }
-
- free(data->hostname);
- data->hostname = NULL;
-
- if (data->wfd != -1) {
- gg_sock_close(data->wfd);
- data->wfd = -1;
- }
-
- free(data);
-}
-
-/**
- * \internal Wątek rozwiązujący nazwę.
- *
- * \param arg Wskaźnik na strukturę \c gg_resolver_pthread_data
- */
-static void *__stdcall gg_resolver_pthread_thread(void *arg)
-{
- struct gg_resolver_pthread_data *data = arg;
- struct in_addr addr;
-
- pthread_detach(pthread_self());
-
- if ((addr.s_addr = inet_addr(data->hostname)) == INADDR_NONE) {
- /* W przypadku błędu gg_gethostbyname_real() zwróci -1
- * i nie zmieni &addr. Tam jest już INADDR_NONE,
- * więc nie musimy robić nic więcej. */
- gg_gethostbyname_real(data->hostname, &addr, 1);
- }
-
- if (gg_sock_write(data->wfd, &addr, sizeof(addr)) == sizeof(addr))
- pthread_exit(NULL);
- else
- pthread_exit((void*) -1);
-
- return NULL; /* żeby kompilator nie marudził */
-}
-
-/**
- * \internal Rozwiązuje nazwę serwera w osobnym wątku.
- *
- * Funkcja działa analogicznie do \c gg_resolver_fork_start(), z tą różnicą,
- * że działa na wątkach, nie procesach. Jest dostępna wyłącznie gdy podczas
- * kompilacji włączono odpowiednią opcję.
- *
- * \param fd Wskaźnik na zmienną, gdzie zostanie umieszczony deskryptor
- * potoku
- * \param priv_data Wskaźnik na zmienną, gdzie zostanie umieszczony wskaźnik
- * do prywatnych danych wątku rozwiązującego nazwę
- * \param hostname Nazwa serwera do rozwiązania
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-static int gg_resolver_pthread_start(SOCKET *fd, void **priv_data, const char *hostname)
-{
- struct gg_resolver_pthread_data *data = NULL;
- int new_errno;
- SOCKET pipes[2];
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_resolver_pthread_start(%p, %p, \"%s\");\n", fd, priv_data, hostname);
-
- if (fd == NULL || priv_data == NULL || hostname == NULL) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() invalid arguments\n");
- errno = EFAULT;
- return -1;
- }
-
- data = malloc(sizeof(struct gg_resolver_pthread_data));
-
- if (data == NULL) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() out of memory for resolver data\n");
- return -1;
- }
-
- if (pipe(pipes) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() unable to create pipes (errno=%d, %s)\n", errno, strerror(errno));
- free(data);
- return -1;
- }
-
- data->hostname = strdup(hostname);
-
- if (data->hostname == NULL) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() out of memory\n");
- new_errno = errno;
- goto cleanup;
- }
-
- data->rfd = pipes[0];
- data->wfd = pipes[1];
-
- if (pthread_create(&data->thread, NULL, gg_resolver_pthread_thread, data)) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() unable to create thread\n");
- new_errno = errno;
- goto cleanup;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolver_pthread_start() %p\n", data);
-
- *fd = pipes[0];
- *priv_data = data;
-
- return 0;
-
-cleanup:
- if (data) {
- free(data->hostname);
- free(data);
- }
-
- gg_sock_close(pipes[0]);
- gg_sock_close(pipes[1]);
-
- errno = new_errno;
-
- return -1;
-}
-
-#endif /* GG_CONFIG_HAVE_PTHREAD */
-
-/**
- * Ustawia sposób rozwiązywania nazw w sesji.
- *
- * \param gs Struktura sesji
- * \param type Sposób rozwiązywania nazw (patrz \ref build-resolver)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_session_set_resolver(struct gg_session *gs, gg_resolver_t type)
-{
- if (gs == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- if (type == GG_RESOLVER_DEFAULT) {
- if (gg_global_resolver_type != GG_RESOLVER_DEFAULT) {
- gs->resolver_type = gg_global_resolver_type;
- gs->resolver_start = gg_global_resolver_start;
- gs->resolver_cleanup = gg_global_resolver_cleanup;
- return 0;
- }
-
-#if !defined(GG_CONFIG_HAVE_PTHREAD) || !defined(GG_CONFIG_PTHREAD_DEFAULT)
- type = GG_RESOLVER_FORK;
-#else
- type = GG_RESOLVER_PTHREAD;
-#endif
- }
-
- switch (type) {
- case GG_RESOLVER_FORK:
- gs->resolver_type = type;
- gs->resolver_start = gg_resolver_fork_start;
- gs->resolver_cleanup = gg_resolver_fork_cleanup;
- return 0;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- case GG_RESOLVER_PTHREAD:
- gs->resolver_type = type;
- gs->resolver_start = gg_resolver_pthread_start;
- gs->resolver_cleanup = gg_resolver_pthread_cleanup;
- return 0;
-#endif
-
- default:
- errno = EINVAL;
- return -1;
- }
-}
-
-/**
- * Zwraca sposób rozwiązywania nazw w sesji.
- *
- * \param gs Struktura sesji
- *
- * \return Sposób rozwiązywania nazw
- */
-gg_resolver_t gg_session_get_resolver(struct gg_session *gs)
-{
- if (gs == NULL) {
- errno = EINVAL;
- return GG_RESOLVER_INVALID;
- }
-
- return gs->resolver_type;
-}
-
-/**
- * Ustawia własny sposób rozwiązywania nazw w sesji.
- *
- * \param gs Struktura sesji
- * \param resolver_start Funkcja rozpoczynająca rozwiązywanie nazwy
- * \param resolver_cleanup Funkcja zwalniająca zasoby
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_session_set_custom_resolver(struct gg_session *gs, int (*resolver_start)(SOCKET*, void**, const char*), void (*resolver_cleanup)(void**, int))
-{
- if (gs == NULL || resolver_start == NULL || resolver_cleanup == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- gs->resolver_type = GG_RESOLVER_CUSTOM;
- gs->resolver_start = resolver_start;
- gs->resolver_cleanup = resolver_cleanup;
-
- return 0;
-}
-
-/**
- * Ustawia sposób rozwiązywania nazw połączenia HTTP.
- *
- * \param gh Struktura połączenia
- * \param type Sposób rozwiązywania nazw (patrz \ref build-resolver)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_http_set_resolver(struct gg_http *gh, gg_resolver_t type)
-{
- if (gh == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- if (type == GG_RESOLVER_DEFAULT) {
- if (gg_global_resolver_type != GG_RESOLVER_DEFAULT) {
- gh->resolver_type = gg_global_resolver_type;
- gh->resolver_start = gg_global_resolver_start;
- gh->resolver_cleanup = gg_global_resolver_cleanup;
- return 0;
- }
-
-#if !defined(GG_CONFIG_HAVE_PTHREAD) || !defined(GG_CONFIG_PTHREAD_DEFAULT)
- type = GG_RESOLVER_FORK;
-#else
- type = GG_RESOLVER_PTHREAD;
-#endif
- }
-
- switch (type) {
- case GG_RESOLVER_FORK:
- gh->resolver_type = type;
- gh->resolver_start = gg_resolver_fork_start;
- gh->resolver_cleanup = gg_resolver_fork_cleanup;
- return 0;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- case GG_RESOLVER_PTHREAD:
- gh->resolver_type = type;
- gh->resolver_start = gg_resolver_pthread_start;
- gh->resolver_cleanup = gg_resolver_pthread_cleanup;
- return 0;
-#endif
-
- default:
- errno = EINVAL;
- return -1;
- }
-}
-
-/**
- * Zwraca sposób rozwiązywania nazw połączenia HTTP.
- *
- * \param gh Struktura połączenia
- *
- * \return Sposób rozwiązywania nazw
- */
-gg_resolver_t gg_http_get_resolver(struct gg_http *gh)
-{
- if (gh == NULL) {
- errno = EINVAL;
- return GG_RESOLVER_INVALID;
- }
-
- return gh->resolver_type;
-}
-
-/**
- * Ustawia własny sposób rozwiązywania nazw połączenia HTTP.
- *
- * \param gh Struktura sesji
- * \param resolver_start Funkcja rozpoczynająca rozwiązywanie nazwy
- * \param resolver_cleanup Funkcja zwalniająca zasoby
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_http_set_custom_resolver(struct gg_http *gh, int (*resolver_start)(SOCKET*, void**, const char*), void (*resolver_cleanup)(void**, int))
-{
- if (gh == NULL || resolver_start == NULL || resolver_cleanup == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- gh->resolver_type = GG_RESOLVER_CUSTOM;
- gh->resolver_start = resolver_start;
- gh->resolver_cleanup = resolver_cleanup;
-
- return 0;
-}
-
-/**
- * Ustawia sposób rozwiązywania nazw globalnie dla biblioteki.
- *
- * \param type Sposób rozwiązywania nazw (patrz \ref build-resolver)
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_global_set_resolver(gg_resolver_t type)
-{
- switch (type) {
- case GG_RESOLVER_DEFAULT:
- gg_global_resolver_type = type;
- gg_global_resolver_start = NULL;
- gg_global_resolver_cleanup = NULL;
- return 0;
-
- case GG_RESOLVER_FORK:
- gg_global_resolver_type = type;
- gg_global_resolver_start = gg_resolver_fork_start;
- gg_global_resolver_cleanup = gg_resolver_fork_cleanup;
- return 0;
-
-#ifdef GG_CONFIG_HAVE_PTHREAD
- case GG_RESOLVER_PTHREAD:
- gg_global_resolver_type = type;
- gg_global_resolver_start = gg_resolver_pthread_start;
- gg_global_resolver_cleanup = gg_resolver_pthread_cleanup;
- return 0;
-#endif
-
- default:
- errno = EINVAL;
- return -1;
- }
-}
-
-/**
- * Zwraca sposób rozwiązywania nazw globalnie dla biblioteki.
- *
- * \return Sposób rozwiązywania nazw
- */
-gg_resolver_t gg_global_get_resolver(void)
-{
- return gg_global_resolver_type;
-}
-
-/**
- * Ustawia własny sposób rozwiązywania nazw globalnie dla biblioteki.
- *
- * \param resolver_start Funkcja rozpoczynająca rozwiązywanie nazwy
- * \param resolver_cleanup Funkcja zwalniająca zasoby
- *
- * Parametry funkcji rozpoczynającej rozwiązywanie nazwy wyglądają następująco:
- * - \c "SOCKET *fd" &mdash; wskaźnik na zmienną, gdzie zostanie umieszczony deskryptor potoku
- * - \c "void **priv_data" &mdash; wskaźnik na zmienną, gdzie można umieścić wskaźnik do prywatnych danych na potrzeby rozwiązywania nazwy
- * - \c "const char *name" &mdash; nazwa serwera do rozwiązania
- *
- * Parametry funkcji zwalniającej zasoby wyglądają następująco:
- * - \c "void **priv_data" &mdash; wskaźnik na zmienną przechowującą wskaźnik do prywatnych danych, należy go ustawić na \c NULL po zakończeniu
- * - \c "int force" &mdash; flaga mówiąca o tym, że zasoby są zwalniane przed zakończeniem rozwiązywania nazwy, np. z powodu zamknięcia sesji.
- *
- * Własny kod rozwiązywania nazwy powinien stworzyć potok, parę gniazd lub
- * inny deskryptor pozwalający na co najmniej jednostronną komunikację i
- * przekazać go w parametrze \c fd. Po zakończeniu rozwiązywania nazwy,
- * powinien wysłać otrzymany adres IP w postaci sieciowej (big-endian) do
- * deskryptora. Jeśli rozwiązywanie nazwy się nie powiedzie, należy wysłać
- * \c INADDR_NONE. Następnie zostanie wywołana funkcja zwalniająca zasoby
- * z parametrem \c force równym \c 0. Gdyby sesja została zakończona przed
- * rozwiązaniem nazwy, np. za pomocą funkcji \c gg_logoff(), funkcja
- * zwalniająca zasoby zostanie wywołana z parametrem \c force równym \c 1.
- *
- * \return 0 jeśli się powiodło, -1 w przypadku błędu
- */
-int gg_global_set_custom_resolver(int (*resolver_start)(SOCKET*, void**, const char*), void (*resolver_cleanup)(void**, int))
-{
- if (resolver_start == NULL || resolver_cleanup == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- gg_global_resolver_type = GG_RESOLVER_CUSTOM;
- gg_global_resolver_start = resolver_start;
- gg_global_resolver_cleanup = resolver_cleanup;
-
- return 0;
-}
-