/** * Pobiera token do autoryzacji operacji na katalogu publicznym. * * Token jest niezbędny do tworzenia nowego i usuwania użytkownika, * zmiany hasła itd. * * \param async Flaga połączenia asynchronicznego * * \return Struktura \c gg_http lub \c NULL w przypadku błędu * * \ingroup token */ struct gg_http *gg_token(int async) { struct gg_http *h; const char *query; query = "Host: " GG_REGISTER_HOST "\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "User-Agent: " GG_HTTP_USERAGENT "\r\n" "Content-Length: 0\r\n" "Pragma: no-cache\r\n" "\r\n"; if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/regtoken.asp", query))) { gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n"); return NULL; } h->type = GG_SESSION_TOKEN; h->callback = gg_token_watch_fd; h->destroy = gg_token_free; if (!async) gg_token_watch_fd(h); return h; }
/** * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia. * * Operacja będzie zakończona, gdy pole \c state będzie równe \c GG_STATE_DONE. * Jeśli wystąpi błąd, \c state będzie równe \c GG_STATE_ERROR, a kod błędu * znajdzie się w polu \c error. * * \param h Struktura połączenia * * \return 0 jeśli się powiodło, -1 w przypadku błędu * * \ingroup token */ int gg_token_watch_fd(struct gg_http *h) { if (!h) { errno = EFAULT; return -1; } if (h->state == GG_STATE_ERROR) { gg_debug(GG_DEBUG_MISC, "=> token, watch_fd issued on failed session\n"); errno = EINVAL; return -1; } if (h->state != GG_STATE_PARSING) { if (gg_http_watch_fd(h) == -1) { gg_debug(GG_DEBUG_MISC, "=> token, http failure\n"); errno = EINVAL; return -1; } } if (h->state != GG_STATE_PARSING) return 0; /* jeśli h->data jest puste, to ściągaliśmy tokenid i url do niego, * ale jeśli coś tam jest, to znaczy, że mamy drugi etap polegający * na pobieraniu tokenu. */ if (!h->data) { int width, height, length; char *url = NULL, *tokenid = NULL, *path, *headers; const char *host; struct gg_http *h2; struct gg_token *t; gg_debug(GG_DEBUG_MISC, "=> token body \"%s\"\n", h->body); if (h->body && (!(url = (char*)malloc(strlen(h->body) + 1)) || !(tokenid = (char*)malloc(strlen(h->body) + 1)))) { gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for results\n"); free(url); return -1; } if (!h->body || sscanf(h->body, "%d %d %d\r\n%s\r\n%s", &width, &height, &length, tokenid, url) != 5) { gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n"); free(url); free(tokenid); errno = EINVAL; return -1; } /* dostaliśmy tokenid i wszystkie niezbędne informacje, * więc pobierzmy obrazek z tokenem */ if (strncmp(url, "http://", 7)) { path = gg_saprintf("%s?tokenid=%s", url, tokenid); host = GG_REGISTER_HOST; } else { char *slash = strchr(url + 7, '/'); if (slash) { path = gg_saprintf("%s?tokenid=%s", slash, tokenid); *slash = 0; host = url + 7; } else { gg_debug(GG_DEBUG_MISC, "=> token, url parsing failed\n"); free(url); free(tokenid); errno = EINVAL; return -1; } } if (!path) { gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n"); free(url); free(tokenid); return -1; } if (!(headers = gg_saprintf("Host: %s\r\nUser-Agent: " GG_HTTP_USERAGENT "\r\n\r\n", host))) { gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n"); free(path); free(url); free(tokenid); return -1; } if (!(h2 = gg_http_connect(host, GG_REGISTER_PORT, h->async, "GET", path, headers))) { gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n"); free(headers); free(url); free(path); free(tokenid); return -1; } free(headers); free(path); free(url); gg_http_free_fields(h); memcpy(h, h2, sizeof(struct gg_http)); free(h2); h->type = GG_SESSION_TOKEN; h->callback = gg_token_watch_fd; h->destroy = gg_token_free; if (!h->async) gg_token_watch_fd(h); if (!(h->data = t = (struct gg_token*)malloc(sizeof(struct gg_token)))) { gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token data\n"); free(tokenid); return -1; } t->width = width; t->height = height; t->length = length; t->tokenid = tokenid; } else { /* obrazek mamy w h->body */ h->state = GG_STATE_DONE; } return 0; }
/** * Rejestruje nowego użytkownika. * * Wymaga wcześniejszego pobrania tokenu za pomocą \c gg_token(). * * \param email Adres e-mail * \param password Hasło * \param tokenid Identyfikator tokenu * \param tokenval Zawartość tokenu * \param async Flaga połączenia asynchronicznego * * \return Struktura \c gg_http lub \c NULL w przypadku błędu * * \ingroup register */ struct gg_http *gg_register3(const char *email, const char *password, const char *tokenid, const char *tokenval, int async) { struct gg_http *h; char *__pwd, *__email, *__tokenid, *__tokenval, *form, *query; if (!email || !password || !tokenid || !tokenval) { gg_debug(GG_DEBUG_MISC, "=> register, NULL parameter\n"); errno = EFAULT; return NULL; } __pwd = gg_urlencode(password); __email = gg_urlencode(email); __tokenid = gg_urlencode(tokenid); __tokenval = gg_urlencode(tokenval); if (!__pwd || !__email || !__tokenid || !__tokenval) { gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form fields\n"); free(__pwd); free(__email); free(__tokenid); free(__tokenval); return NULL; } form = gg_saprintf("pwd=%s&email=%s&tokenid=%s&tokenval=%s&code=%u", __pwd, __email, __tokenid, __tokenval, gg_http_hash("ss", email, password)); free(__pwd); free(__email); free(__tokenid); free(__tokenval); if (!form) { gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form query\n"); return NULL; } gg_debug(GG_DEBUG_MISC, "=> register, %s\n", form); query = gg_saprintf( "Host: " GG_REGISTER_HOST "\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "User-Agent: " GG_HTTP_USERAGENT "\r\n" "Content-Length: %d\r\n" "Pragma: no-cache\r\n" "\r\n" "%s", (int) strlen(form), form); free(form); if (!query) { gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for query\n"); return NULL; } if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) { gg_debug(GG_DEBUG_MISC, "=> register, gg_http_connect() failed mysteriously\n"); free(query); return NULL; } h->type = GG_SESSION_REGISTER; free(query); h->callback = gg_pubdir_watch_fd; h->destroy = gg_pubdir_free; if (!async) gg_pubdir_watch_fd(h); return h; }
/** * Wysyła hasło użytkownika na e-mail. * * Wymaga wcześniejszego pobrania tokenu za pomocą \c gg_token(). * * \param uin Numer Gadu-Gadu * \param email Adres e-mail (podany przy rejestracji) * \param tokenid Identyfikator tokenu * \param tokenval Zawartość tokenu * \param async Flaga połączenia asynchronicznego * * \return Struktura \c gg_http lub \c NULL w przypadku błędu * * \ingroup remind */ struct gg_http *gg_remind_passwd3(uin_t uin, const char *email, const char *tokenid, const char *tokenval, int async) { struct gg_http *h; char *form, *query, *__tokenid, *__tokenval, *__email; if (!tokenid || !tokenval || !email) { gg_debug(GG_DEBUG_MISC, "=> remind, NULL parameter\n"); errno = EFAULT; return NULL; } __tokenid = gg_urlencode(tokenid); __tokenval = gg_urlencode(tokenval); __email = gg_urlencode(email); if (!__tokenid || !__tokenval || !__email) { gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n"); free(__tokenid); free(__tokenval); free(__email); return NULL; } if (!(form = gg_saprintf("userid=%d&code=%u&tokenid=%s&tokenval=%s&email=%s", uin, gg_http_hash("u", uin), __tokenid, __tokenval, __email))) { gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n"); free(__tokenid); free(__tokenval); free(__email); return NULL; } free(__tokenid); free(__tokenval); free(__email); gg_debug(GG_DEBUG_MISC, "=> remind, %s\n", form); query = gg_saprintf( "Host: " GG_REMIND_HOST "\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "User-Agent: " GG_HTTP_USERAGENT "\r\n" "Content-Length: %d\r\n" "Pragma: no-cache\r\n" "\r\n" "%s", (int) strlen(form), form); free(form); if (!query) { gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for query\n"); return NULL; } if (!(h = gg_http_connect(GG_REMIND_HOST, GG_REMIND_PORT, async, "POST", "/appsvc/fmsendpwd3.asp", query))) { gg_debug(GG_DEBUG_MISC, "=> remind, gg_http_connect() failed mysteriously\n"); free(query); return NULL; } h->type = GG_SESSION_REMIND; free(query); h->callback = gg_pubdir_watch_fd; h->destroy = gg_pubdir_free; if (!async) gg_pubdir_watch_fd(h); return h; }
static int test_set_get(void) { struct gg_session *gs; struct gg_http *gh; struct gg_login_params glp; memset(&glp, 0, sizeof(glp)); glp.uin = 1; glp.password = ""; glp.resolver = 0; glp.async = 1; /* Test globalnych ustawień */ if (gg_global_get_resolver() != GG_RESOLVER_DEFAULT) { printf("Expected global default resolver #1\n"); return 0; } #ifdef GG_CONFIG_HAVE_FORK printf("Setting global fork resolver\n"); gg_global_set_resolver(GG_RESOLVER_FORK); if (gg_global_get_resolver() != GG_RESOLVER_FORK) { printf("Expected global fork resolver\n"); return 0; } #endif #ifdef GG_CONFIG_HAVE_PTHREAD printf("Setting global pthread resolver\n"); gg_global_set_resolver(GG_RESOLVER_PTHREAD); if (gg_global_get_resolver() != GG_RESOLVER_PTHREAD) { printf("Expected global thread resolver\n"); return 0; } #endif #ifdef _WIN32 printf("Setting global win32 resolver\n"); gg_global_set_resolver(GG_RESOLVER_WIN32); if (gg_global_get_resolver() != GG_RESOLVER_WIN32) { printf("Expected global win32 resolver\n"); return 0; } #endif printf("Setting global custom resolver\n"); gg_global_set_custom_resolver(dummy_start, dummy_cleanup); if (gg_global_get_resolver() != GG_RESOLVER_CUSTOM) { printf("Expected global custom resolver\n"); return 0; } printf("Setting global default resolver\n"); gg_global_set_resolver(GG_RESOLVER_DEFAULT); if (gg_global_get_resolver() != GG_RESOLVER_DEFAULT) { printf("Expected global default resolver #2\n"); return 0; } /* Test lokalnych ustawień -- domyślny */ printf("Testing local default resolver\n"); gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_FORK && gg_session_get_resolver(gs) != GG_RESOLVER_PTHREAD && gg_session_get_resolver(gs) != GG_RESOLVER_WIN32) { printf("Expected local fork, pthread or win32 resolver\n"); return 0; } gg_free_session(gs); /* Testy globalnego default + lokalne */ printf("Testing global default fork\n"); gg_global_set_resolver(GG_RESOLVER_DEFAULT); #ifdef GG_CONFIG_HAVE_FORK /* Test lokalnych ustawień -- fork */ printf("Testing local fork resolver\n"); glp.resolver = GG_RESOLVER_FORK; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_FORK) { printf("Expected local fork resolver\n"); return 0; } gg_free_session(gs); #endif #ifdef GG_CONFIG_HAVE_PTHREAD /* Test lokalnych ustawień -- pthread */ printf("Testing local pthread resolver\n"); glp.resolver = GG_RESOLVER_PTHREAD; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_PTHREAD) { printf("Expected local pthread resolver\n"); return 0; } gg_free_session(gs); #endif #ifdef _WIN32 /* Test lokalnych ustawień -- win32 */ printf("Testing local win32 resolver\n"); glp.resolver = GG_RESOLVER_WIN32; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_WIN32) { printf("Expected local win32 resolver\n"); return 0; } gg_free_session(gs); #endif #ifdef GG_CONFIG_HAVE_FORK /* Testy globalnego fork + lokalne */ printf("Setting global fork resolver\n"); gg_global_set_resolver(GG_RESOLVER_FORK); /* Test globalnych ustawień + lokalne */ printf("Testing local default resolver\n"); glp.resolver = GG_RESOLVER_DEFAULT; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_FORK) { printf("Expected local fork resolver\n"); return 0; } gg_free_session(gs); /* Test globalnych ustawień + lokalne */ printf("Testing local fork resolver\n"); glp.resolver = GG_RESOLVER_FORK; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_FORK) { printf("Expected local fork resolver\n"); return 0; } gg_free_session(gs); #ifdef GG_CONFIG_HAVE_PTHREAD /* Test globalnych ustawień + lokalne */ printf("Testing local pthread resolver\n"); glp.resolver = GG_RESOLVER_PTHREAD; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_PTHREAD) { printf("Expected local fork resolver\n"); return 0; } gg_free_session(gs); #endif /* GG_CONFIG_HAVE_PTHREAD */ #endif /* GG_CONFIG_HAVE_FORK */ #ifdef GG_CONFIG_HAVE_PTHREAD /* Testy globalnego pthread + lokalne */ printf("Setting global pthread resolver\n"); gg_global_set_resolver(GG_RESOLVER_PTHREAD); /* Test globalnych ustawień + lokalne */ printf("Testing local default resolver\n"); glp.resolver = GG_RESOLVER_DEFAULT; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_PTHREAD) { printf("Expected local pthread resolver\n"); return 0; } gg_free_session(gs); #ifdef GG_CONFIG_HAVE_FORK /* Test globalnych ustawień + lokalne */ printf("Testing local fork resolver\n"); glp.resolver = GG_RESOLVER_FORK; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_FORK) { printf("Expected local fork resolver\n"); return 0; } gg_free_session(gs); #endif /* Test globalnych ustawień + lokalne */ printf("Testing local pthread resolver\n"); glp.resolver = GG_RESOLVER_PTHREAD; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_PTHREAD) { printf("Expected local fork resolver\n"); return 0; } gg_free_session(gs); #ifdef _WIN32 /* Test globalnych ustawień + lokalne */ printf("Testing local win32 resolver\n"); glp.resolver = GG_RESOLVER_WIN32; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_WIN32) { printf("Expected local win32 resolver\n"); return 0; } gg_free_session(gs); #endif #endif /* GG_CONFIG_HAVE_PTHREAD */ /* Testy globalnego custom + lokalne */ printf("Setting global custom resolver\n"); gg_global_set_custom_resolver(dummy_start, dummy_cleanup); /* Test globalnych ustawień + lokalne */ printf("Testing local default resolver\n"); glp.resolver = GG_RESOLVER_DEFAULT; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_CUSTOM) { printf("Expected local custom resolver\n"); return 0; } gg_free_session(gs); #ifdef GG_CONFIG_HAVE_FORK /* Test globalnych ustawień + lokalne */ printf("Testing local fork resolver\n"); glp.resolver = GG_RESOLVER_FORK; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_FORK) { printf("Expected local fork resolver\n"); return 0; } gg_free_session(gs); #endif #ifdef GG_CONFIG_HAVE_PTHREAD /* Test globalnych ustawień + lokalne */ printf("Testing local pthread resolver\n"); glp.resolver = GG_RESOLVER_PTHREAD; gs = gg_login(&glp); if (gs == NULL) return 0; if (gg_session_get_resolver(gs) != GG_RESOLVER_PTHREAD) { printf("Expected local fork resolver\n"); return 0; } gg_free_session(gs); #endif /* Test HTTP */ printf("Testing global default resolver in HTTP\n"); gg_global_set_resolver(GG_RESOLVER_DEFAULT); gh = gg_http_connect("test", 80, 1, "GET", "/test", ""); if (gh == NULL) return 0; if (gg_http_get_resolver(gh) != GG_RESOLVER_FORK && gg_http_get_resolver(gh) != GG_RESOLVER_PTHREAD && gg_http_get_resolver(gh) != GG_RESOLVER_WIN32) { printf("Expected local fork, pthread or win32 resolver\n"); return 0; } gg_http_free(gh); #ifdef GG_CONFIG_HAVE_FORK /* Test HTTP */ printf("Testing global fork resolver in HTTP\n"); gg_global_set_resolver(GG_RESOLVER_FORK); gh = gg_http_connect("test", 80, 1, "GET", "/test", ""); if (gh == NULL) return 0; if (gg_http_get_resolver(gh) != GG_RESOLVER_FORK) { printf("Expected local fork resolver\n"); return 0; } gg_http_free(gh); #endif #ifdef GG_CONFIG_HAVE_PTHREAD /* Test HTTP */ printf("Testing global pthread resolver in HTTP\n"); gg_global_set_resolver(GG_RESOLVER_PTHREAD); gh = gg_http_connect("test", 80, 1, "GET", "/test", ""); if (gh == NULL) return 0; if (gg_http_get_resolver(gh) != GG_RESOLVER_PTHREAD) { printf("Expected local pthread resolver\n"); return 0; } gg_http_free(gh); #endif /* Test HTTP */ printf("Testing global custom resolver in HTTP\n"); gg_global_set_custom_resolver(dummy_start, dummy_cleanup); gh = gg_http_connect("test", 80, 1, "GET", "/test", ""); if (gh == NULL) return 0; if (gg_http_get_resolver(gh) != GG_RESOLVER_CUSTOM) { printf("Expected local custom resolver\n"); return 0; } gg_http_free(gh); /* Czyścimy po sobie */ printf("Cleaning up after resolver tests...\n"); gg_global_set_resolver(GG_RESOLVER_DEFAULT); return 1; }
/* * gg_token_watch_fd() * * przy asynchronicznych operacjach zwi±zanych z tokenem nale¿y wywo³ywaæ * tê funkcjê przy zmianach na obserwowanym deskryptorze. * * - h - struktura opisuj±ca po³±czenie * * je¶li wszystko posz³o dobrze to 0, inaczej -1. operacja bêdzie * zakoñczona, je¶li h->state == GG_STATE_DONE. je¶li wyst±pi jaki¶ * b³±d, to bêdzie tam GG_STATE_ERROR i odpowiedni kod b³êdu w h->error. */ int gg_token_watch_fd(struct gg_http *h) { if (!h) { errno = EINVAL; return -1; } if (h->state == GG_STATE_ERROR) { gg_debug(GG_DEBUG_MISC, "=> token, watch_fd issued on failed session\n"); errno = EINVAL; return -1; } if (h->state != GG_STATE_PARSING) { if (gg_http_watch_fd(h) == -1) { gg_debug(GG_DEBUG_MISC, "=> token, http failure\n"); errno = EINVAL; return -1; } } if (h->state != GG_STATE_PARSING) return 0; /* je¶li h->data jest puste, to ¶ci±gali¶my tokenid i url do niego, * ale je¶li co¶ tam jest, to znaczy, ¿e mamy drugi etap polegaj±cy * na pobieraniu tokenu. */ if (!h->data) { int width, height, length; char *url = NULL, *tokenid = NULL, *path; struct gg_http *h2; struct gg_token *t; gg_debug(GG_DEBUG_MISC, "=> token body \"%s\"\n", h->body); if (h->body && (!(url = malloc(strlen(h->body))) || !(tokenid = malloc(strlen(h->body))))) { gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for results\n"); free(url); return -1; } if (!h->body || sscanf(h->body, "%d %d %d\r\n%s\r\n%s", &width, &height, &length, tokenid, url) != 5) { gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n"); free(url); free(tokenid); return -1; } /* dostali¶my tokenid i wszystkie niezbêdne informacje, * wiêc pobierzmy obrazek z tokenem */ if (!(path = gg_saprintf("%s?tokenid=%s", url, tokenid))) { gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n"); free(url); free(tokenid); return -1; } free(url); if (!(h2 = gg_http_connect(GG_APPMSG_HOST, GG_APPMSG_PORT, h->async, "GET", path, "Host: " GG_APPMSG_HOST "\r\nUser-Agent: " GG_HTTP_USERAGENT "\r\n\r\n"))) { gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n"); free(path); free(tokenid); return -1; } free(path); memcpy(h, h2, sizeof(struct gg_http)); free(h2); h->type = GG_SESSION_TOKEN; h->callback = gg_token_watch_fd; h->destroy = gg_token_free; if (!h->async) gg_token_watch_fd(h); if (!(h->data = t = malloc(sizeof(struct gg_token)))) { gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token data\n"); free(tokenid); return -1; } t->width = width; t->height = height; t->length = length; t->tokenid = tokenid; } else { /* obrazek mamy w h->body */ h->state = GG_STATE_DONE; } return 0; }
/* * gg_change_passwd4() * * wysy³a ¿±danie zmiany has³a zgodnie z protoko³em GG 6.0. wymaga * wcze¶niejszego pobrania tokenu za pomoc± funkcji gg_token(). * * - uin - numer * - email - adres e-mail * - passwd - stare has³o * - newpasswd - nowe has³o * - tokenid - identyfikator tokenu * - tokenval - warto¶æ tokenu * - async - po³±czenie asynchroniczne * * zaalokowana struct gg_http, któr± po¼niej nale¿y zwolniæ * funkcj± gg_change_passwd_free(), albo NULL je¶li wyst±pi³ b³±d. */ struct gg_http *gg_change_passwd4(uin_t uin, const char *email, const char *passwd, const char *newpasswd, const char *tokenid, const char *tokenval, int async) { struct gg_http *h; char *form, *query, *__email, *__fmpwd, *__pwd, *__tokenid, *__tokenval; if (!uin || !email || !passwd || !newpasswd || !tokenid || !tokenval) { gg_debug(GG_DEBUG_MISC, "=> change, NULL parameter\n"); errno = EINVAL; return NULL; } __fmpwd = gg_urlencode(passwd); __pwd = gg_urlencode(newpasswd); __email = gg_urlencode(email); __tokenid = gg_urlencode(tokenid); __tokenval = gg_urlencode(tokenval); if (!__fmpwd || !__pwd || !__email || !__tokenid || !__tokenval) { gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n"); free(__fmpwd); free(__pwd); free(__email); free(__tokenid); free(__tokenval); errno = ENOMEM; return NULL; } if (!(form = gg_saprintf("fmnumber=%d&fmpwd=%s&pwd=%s&email=%s&tokenid=%s&tokenval=%s&code=%u", uin, __fmpwd, __pwd, __email, __tokenid, __tokenval, gg_http_hash("ss", email, newpasswd)))) { gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n"); free(__fmpwd); free(__pwd); free(__email); free(__tokenid); free(__tokenval); errno = ENOMEM; return NULL; } free(__fmpwd); free(__pwd); free(__email); free(__tokenid); free(__tokenval); gg_debug(GG_DEBUG_MISC, "=> change, %s\n", form); query = gg_saprintf( "Host: " GG_REGISTER_HOST "\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "User-Agent: " GG_HTTP_USERAGENT "\r\n" "Content-Length: %d\r\n" "Pragma: no-cache\r\n" "\r\n" "%s", (int) strlen(form), form); free(form); if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) { gg_debug(GG_DEBUG_MISC, "=> change, gg_http_connect() failed mysteriously\n"); free(query); return NULL; } h->type = GG_SESSION_PASSWD; free(query); h->callback = gg_pubdir_watch_fd; h->destroy = gg_pubdir_free; if (!async) gg_pubdir_watch_fd(h); return h; }
/* * gg_unregister3() * * usuwa konto u¿ytkownika z serwera protoko³em GG 6.0 * * - uin - numerek GG * - password - has³o klienta * - tokenid - identyfikator tokenu * - tokenval - warto¶æ tokenu * - async - po³±czenie asynchroniczne * * zaalokowana struct gg_http, któr± po¼niej nale¿y zwolniæ * funkcj± gg_unregister_free(), albo NULL je¶li wyst±pi³ b³±d. */ struct gg_http *gg_unregister3(uin_t uin, const char *password, const char *tokenid, const char *tokenval, int async) { struct gg_http *h; char *__fmpwd, *__pwd, *__tokenid, *__tokenval, *form, *query; if (!password || !tokenid || !tokenval) { gg_debug(GG_DEBUG_MISC, "=> unregister, NULL parameter\n"); errno = EINVAL; return NULL; } __pwd = gg_saprintf("%ld", random()); __fmpwd = gg_urlencode(password); __tokenid = gg_urlencode(tokenid); __tokenval = gg_urlencode(tokenval); if (!__fmpwd || !__pwd || !__tokenid || !__tokenval) { gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form fields\n"); free(__pwd); free(__fmpwd); free(__tokenid); free(__tokenval); errno = ENOMEM; return NULL; } form = gg_saprintf("fmnumber=%d&fmpwd=%s&delete=1&pwd=%s&[email protected]&tokenid=%s&tokenval=%s&code=%u", uin, __fmpwd, __pwd, __tokenid, __tokenval, gg_http_hash("ss", "*****@*****.**", __pwd)); free(__fmpwd); free(__pwd); free(__tokenid); free(__tokenval); if (!form) { gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form query\n"); errno = ENOMEM; return NULL; } gg_debug(GG_DEBUG_MISC, "=> unregister, %s\n", form); query = gg_saprintf( "Host: " GG_REGISTER_HOST "\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "User-Agent: " GG_HTTP_USERAGENT "\r\n" "Content-Length: %d\r\n" "Pragma: no-cache\r\n" "\r\n" "%s", (int) strlen(form), form); free(form); if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) { gg_debug(GG_DEBUG_MISC, "=> unregister, gg_http_connect() failed mysteriously\n"); free(query); return NULL; } h->type = GG_SESSION_UNREGISTER; free(query); h->callback = gg_pubdir_watch_fd; h->destroy = gg_pubdir_free; if (!async) gg_pubdir_watch_fd(h); return h; }