Mercurial > pidgin.yaz
diff libpurple/protocols/gg/lib/pubdir50.c @ 29995:2292d8896b0b
merged with im.pidgin.pidgin
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Tue, 16 Mar 2010 12:07:06 +0900 |
parents | 4491a662d527 6359fde67f4c |
children | fa88dc1dcabb |
line wrap: on
line diff
--- a/libpurple/protocols/gg/lib/pubdir50.c Thu Mar 04 15:19:39 2010 +0900 +++ b/libpurple/protocols/gg/lib/pubdir50.c Tue Mar 16 12:07:06 2010 +0900 @@ -1,4 +1,4 @@ -/* $Id: pubdir50.c 16856 2006-08-19 01:13:25Z evands $ */ +/* $Id: pubdir50.c 854 2009-10-12 21:06:28Z wojtekka $ */ /* * (C) Copyright 2003 Wojtek Kaniewski <wojtekka@irc.pl> @@ -14,11 +14,15 @@ * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301, + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, * USA. */ -#include "libgadu.h" +/** + * \file pubdir50.c + * + * \brief ObsĹ‚uga katalogu publicznego od wersji Gadu-Gadu 5.x + */ #include <errno.h> #include <stdlib.h> @@ -26,12 +30,17 @@ #include <time.h> #include <glib.h> -/* - * gg_pubdir50_new() +#include "libgadu.h" +#include "libgadu-internal.h" + +/** + * Tworzy nowe zapytanie katalogu publicznego. * - * tworzy now± zmienn± typu gg_pubdir50_t. + * \param type Rodzaj zapytania * - * zaalokowana zmienna lub NULL w przypadku braku pamięci. + * \return Zmienna \c gg_pubdir50_t lub \c NULL w przypadku bĹ‚Ä™du. + * + * \ingroup pubdir50 */ gg_pubdir50_t gg_pubdir50_new(int type) { @@ -51,17 +60,16 @@ return res; } -/* - * gg_pubdir50_add_n() // funkcja wewnętrzna - * - * funkcja dodaje lub zastępuje istniej±ce pole do zapytania lub odpowiedzi. +/** + * \internal Dodaje lub zastÄ™puje pole zapytania lub odpowiedzi katalogu + * publicznego. * - * - req - wskaĽnik opisu zapytania, - * - num - numer wyniku (0 dla zapytania), - * - field - nazwa pola, - * - value - warto¶ć pola, + * \param req Zapytanie lub odpowiedĹş + * \param num Numer wyniku odpowiedzi (0 dla zapytania) + * \param field Nazwa pola + * \param value Wartość pola * - * 0/-1 + * \return 0 jeĹ›li siÄ™ powiodĹ‚o, -1 w przypadku bĹ‚Ä™du */ static int gg_pubdir50_add_n(gg_pubdir50_t req, int num, const char *field, const char *value) { @@ -111,31 +119,31 @@ return 0; } -/* - * gg_pubdir50_add() - * - * funkcja dodaje pole do zapytania. +/** + * Dodaje pole zapytania. * - * - req - wskaĽnik opisu zapytania, - * - field - nazwa pola, - * - value - warto¶ć pola, + * \param req Zapytanie + * \param field Nazwa pola + * \param value Wartość pola * - * 0/-1 + * \return 0 jeĹ›li siÄ™ powiodĹ‚o, -1 w przypadku bĹ‚Ä™du + * + * \ingroup pubdir50 */ int gg_pubdir50_add(gg_pubdir50_t req, const char *field, const char *value) { return gg_pubdir50_add_n(req, 0, field, value); } -/* - * gg_pubdir50_seq_set() - * - * ustawia numer sekwencyjny zapytania. +/** + * Ustawia numer sekwencyjny zapytania. * - * - req - zapytanie, - * - seq - nowy numer sekwencyjny. + * \param req Zapytanie + * \param seq Numer sekwencyjny * - * 0/-1. + * \return 0 jeĹ›li siÄ™ powiodĹ‚o, -1 w przypadku bĹ‚Ä™du + * + * \ingroup pubdir50 */ int gg_pubdir50_seq_set(gg_pubdir50_t req, uint32_t seq) { @@ -152,12 +160,12 @@ return 0; } -/* - * gg_pubdir50_free() +/** + * Zwalnia zasoby po zapytaniu lub odpowiedzi katalogu publicznego. * - * zwalnia pamięć po zapytaniu lub rezultacie szukania użytkownika. + * \param s Zapytanie lub odpowiedĹş * - * - s - zwalniana zmienna, + * \ingroup pubdir50 */ void gg_pubdir50_free(gg_pubdir50_t s) { @@ -175,15 +183,15 @@ free(s); } -/* - * gg_pubdir50() - * - * wysyła zapytanie katalogu publicznego do serwera. +/** + * WysyĹ‚a zapytanie katalogu publicznego do serwera. * - * - sess - sesja, - * - req - zapytanie. + * \param sess Struktura sesji + * \param req Zapytanie * - * numer sekwencyjny wyszukiwania lub 0 w przypadku błędu. + * \return Numer sekwencyjny zapytania lub 0 w przypadku bĹ‚Ä™du + * + * \ingroup pubdir50 */ uint32_t gg_pubdir50(struct gg_session *sess, gg_pubdir50_t req) { @@ -192,16 +200,16 @@ char *buf, *p; struct gg_pubdir50_request *r; - gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50(%p, %p);\n", sess, req); + gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_pubdir50(%p, %p);\n", sess, req); if (!sess || !req) { - gg_debug(GG_DEBUG_MISC, "// gg_pubdir50() invalid arguments\n"); + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_pubdir50() invalid arguments\n"); errno = EFAULT; return 0; } if (sess->state != GG_STATE_CONNECTED) { - gg_debug(GG_DEBUG_MISC, "// gg_pubdir50() not connected\n"); + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_pubdir50() not connected\n"); errno = ENOTCONN; return 0; } @@ -211,30 +219,81 @@ if (req->entries[i].num) continue; - size += strlen(req->entries[i].field) + 1; - size += strlen(req->entries[i].value) + 1; + if (sess->encoding == GG_ENCODING_CP1250) { + size += strlen(req->entries[i].field) + 1; + size += strlen(req->entries[i].value) + 1; + } else { + char *tmp; + + tmp = gg_utf8_to_cp(req->entries[i].field); + + if (tmp == NULL) + return -1; + + size += strlen(tmp) + 1; + + free(tmp); + + tmp = gg_utf8_to_cp(req->entries[i].value); + + if (tmp == NULL) + return -1; + + size += strlen(tmp) + 1; + + free(tmp); + } } if (!(buf = malloc(size))) { - gg_debug(GG_DEBUG_MISC, "// gg_pubdir50() out of memory (%d bytes)\n", size); + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_pubdir50() out of memory (%d bytes)\n", size); return 0; } + if (!req->seq) + req->seq = time(NULL); + + res = req->seq; + r = (struct gg_pubdir50_request*) buf; - res = time(NULL); r->type = req->type; - r->seq = (req->seq) ? gg_fix32(req->seq) : gg_fix32(time(NULL)); - req->seq = gg_fix32(r->seq); + r->seq = gg_fix32(req->seq); for (i = 0, p = buf + 5; i < req->entries_count; i++) { if (req->entries[i].num) continue; - strcpy(p, req->entries[i].field); - p += strlen(p) + 1; + if (sess->encoding == GG_ENCODING_CP1250) { + strcpy(p, req->entries[i].field); + p += strlen(p) + 1; + + strcpy(p, req->entries[i].value); + p += strlen(p) + 1; + } else { + char *tmp; + + tmp = gg_utf8_to_cp(req->entries[i].field); + + if (tmp == NULL) { + free(buf); + return -1; + } - strcpy(p, req->entries[i].value); - p += strlen(p) + 1; + strcpy(p, tmp); + p += strlen(tmp) + 1; + free(tmp); + + tmp = gg_utf8_to_cp(req->entries[i].value); + + if (tmp == NULL) { + free(buf); + return -1; + } + + strcpy(p, tmp); + p += strlen(tmp) + 1; + free(tmp); + } } if (gg_send_packet(sess, GG_PUBDIR50_REQUEST, buf, size, NULL, 0) == -1) @@ -246,26 +305,26 @@ } /* - * gg_pubdir50_handle_reply() // funkcja wewnętrzna - * - * analizuje przychodz±cy pakiet odpowiedzi i zapisuje wynik w struct gg_event. + * \internal Analizuje przychodzÄ…cy pakiet odpowiedzi i zapisuje wynik + * w strukturze \c gg_event. * - * - e - opis zdarzenia - * - packet - zawarto¶ć pakietu odpowiedzi - * - length - długo¶ć pakietu odpowiedzi + * \param sess Struktura sesji + * \param e Struktura zdarzenia + * \param packet Pakiet odpowiedzi + * \param length DĹ‚ugość pakietu odpowiedzi * - * 0/-1 + * \return 0 jeĹ›li siÄ™ powiodĹ‚o, -1 w przypadku bĹ‚Ä™du */ -int gg_pubdir50_handle_reply(struct gg_event *e, const char *packet, int length) +int gg_pubdir50_handle_reply_sess(struct gg_session *sess, struct gg_event *e, const char *packet, int length) { const char *end = packet + length, *p; struct gg_pubdir50_reply *r = (struct gg_pubdir50_reply*) packet; gg_pubdir50_t res; int num = 0; - gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_handle_reply(%p, %p, %d);\n", e, packet, length); + gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_handle_reply_sess(%p, %p, %p, %d);\n", sess, e, packet, length); - if (!e || !packet) { + if (!sess || !e || !packet) { gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() invalid arguments\n"); errno = EFAULT; return -1; @@ -300,11 +359,11 @@ break; } - /* brak wyników? */ + /* brak wynikĂłw? */ if (length == 5) return 0; - /* pomiń pocz±tek odpowiedzi */ + /* pomiĹ„ poczÄ…tek odpowiedzi */ p = packet + 5; while (p < end) { @@ -312,7 +371,7 @@ field = p; - /* sprawdĽ, czy nie mamy podziału na kolejne pole */ + /* sprawdĹş, czy nie mamy podziaĹ‚u na kolejne pole */ if (!*field) { num++; field++; @@ -321,22 +380,22 @@ value = NULL; for (p = field; p < end; p++) { - /* je¶li mamy koniec tekstu... */ + /* jeĹ›li mamy koniec tekstu... */ if (!*p) { - /* ...i jeszcze nie mieli¶my warto¶ci pola to - * wiemy, że po tym zerze jest warto¶ć... */ + /* ...i jeszcze nie mieliĹ›my wartoĹ›ci pola to + * wiemy, ĹĽe po tym zerze jest wartość... */ if (!value) value = p + 1; else /* ...w przeciwym wypadku koniec - * warto¶ci i możemy wychodzić - * grzecznie z pętli */ + * wartoĹ›ci i moĹĽemy wychodzić + * grzecznie z pÄ™tli */ break; } } - /* sprawdĽmy, czy pole nie wychodzi poza pakiet, żeby nie - * mieć segfaultów, je¶li serwer przestanie zakańczać pakietów + /* sprawdĹşmy, czy pole nie wychodzi poza pakiet, ĹĽeby nie + * mieć segfaultĂłw, jeĹ›li serwer przestanie zakaĹ„czać pakietĂłw * przez \0 */ if (p == end) { @@ -346,14 +405,30 @@ p++; - /* je¶li dostali¶my namier na następne wyniki, to znaczy że - * mamy koniec wyników i nie jest to kolejna osoba. */ + /* jeĹ›li dostaliĹ›my namier na nastÄ™pne wyniki, to znaczy ĹĽe + * mamy koniec wynikĂłw i nie jest to kolejna osoba. */ if (!strcasecmp(field, "nextstart")) { res->next = atoi(value); num--; } else { - if (gg_pubdir50_add_n(res, num, field, value) == -1) - goto failure; + if (sess->encoding == GG_ENCODING_CP1250) { + if (gg_pubdir50_add_n(res, num, field, value) == -1) + goto failure; + } else { + char *tmp; + + tmp = gg_cp_to_utf8(value); + + if (tmp == NULL) + goto failure; + + if (gg_pubdir50_add_n(res, num, field, tmp) == -1) { + free(tmp); + goto failure; + } + + free(tmp); + } } } @@ -366,16 +441,16 @@ return -1; } -/* - * gg_pubdir50_get() - * - * pobiera informację z rezultatu wyszukiwania. +/** + * Pobiera pole z odpowiedzi katalogu publicznego. * - * - res - rezultat wyszukiwania, - * - num - numer odpowiedzi, - * - field - nazwa pola (wielko¶ć liter nie ma znaczenia). + * \param res OdpowiedĹş + * \param num Numer wyniku odpowiedzi + * \param field Nazwa pola (wielkość liter nie ma znaczenia) * - * warto¶ć pola lub NULL, je¶li nie znaleziono. + * \return Wartość pola lub \c NULL jeĹ›li nie znaleziono + * + * \ingroup pubdir50 */ const char *gg_pubdir50_get(gg_pubdir50_t res, int num, const char *field) { @@ -400,57 +475,61 @@ return value; } -/* - * gg_pubdir50_count() +/** + * Zwraca liczbÄ™ wynikĂłw odpowiedzi. * - * zwraca ilo¶ć wyników danego zapytania. + * \param res OdpowiedĹş * - * - res - odpowiedĽ + * \return Liczba wynikĂłw lub -1 w przypadku bĹ‚Ä™du * - * ilo¶ć lub -1 w przypadku błędu. + * \ingroup pubdir50 */ int gg_pubdir50_count(gg_pubdir50_t res) { return (!res) ? -1 : res->count; } -/* - * gg_pubdir50_type() +/** + * Zwraca rodzaj zapytania lub odpowiedzi. * - * zwraca rodzaj zapytania lub odpowiedzi. + * \param res Zapytanie lub odpowiedĹş * - * - res - zapytanie lub odpowiedĽ + * \return Rodzaj lub -1 w przypadku bĹ‚Ä™du * - * ilo¶ć lub -1 w przypadku błędu. + * \ingroup pubdir50 */ int gg_pubdir50_type(gg_pubdir50_t res) { return (!res) ? -1 : res->type; } -/* - * gg_pubdir50_next() +/** + * Zwraca numer, od ktĂłrego naleĹĽy rozpoczÄ…c kolejne wyszukiwanie. * - * zwraca numer, od którego należy rozpocz±ć kolejne wyszukiwanie, je¶li - * zależy nam na kolejnych wynikach. + * DĹ‚uĹĽsze odpowiedzi katalogu publicznego sÄ… wysyĹ‚ane przez serwer + * w mniejszych paczkach. Po otrzymaniu odpowiedzi, jeĹ›li numer kolejnego + * wyszukiwania jest wiÄ™kszy od zera, dalsze wyniki moĹĽna otrzymać przez + * wywoĹ‚anie kolejnego zapytania z okreĹ›lonym numerem poczÄ…tkowym. * - * - res - odpowiedĽ + * \param res OdpowiedĹş * - * numer lub -1 w przypadku błędu. + * \return Numer lub -1 w przypadku bĹ‚Ä™du + * + * \ingroup pubdir50 */ uin_t gg_pubdir50_next(gg_pubdir50_t res) { return (!res) ? (unsigned) -1 : res->next; } -/* - * gg_pubdir50_seq() +/** + * Zwraca numer sekwencyjny zapytania lub odpowiedzi. * - * zwraca numer sekwencyjny zapytania lub odpowiedzi. + * \param res Zapytanie lub odpowiedĹş * - * - res - zapytanie lub odpowiedĽ + * \return Numer sekwencyjny lub -1 w przypadku bĹ‚Ä™du * - * numer lub -1 w przypadku błędu. + * \ingroup pubdir50 */ uint32_t gg_pubdir50_seq(gg_pubdir50_t res) {