From: Eric W. <war...@us...> - 2001-11-27 22:54:35
|
Update of /cvsroot/gaim/gaim/src/protocols/gg In directory usw-pr-cvs1:/tmp/cvs-serv5003/src/protocols/gg Modified Files: gg.c protocol.txt Log Message: thanks Arkadiusz Miskiewicz: Here is patch that adds ,,delete userlist from server'', updates protocol.txt and makes small cleanup with freeing webdata + with function names (all agg_ names are reserved for struct prpl functions ;) Index: gg.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/gg/gg.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- gg.c 2001/11/26 21:22:56 1.12 +++ gg.c 2001/11/27 22:54:32 1.13 @@ -79,6 +79,7 @@ #define AGG_HTTP_SEARCH 1 #define AGG_HTTP_USERLIST_IMPORT 2 #define AGG_HTTP_USERLIST_EXPORT 3 +#define AGG_HTTP_USERLIST_DELETE 4 #define UC_NORMAL 2 @@ -578,7 +579,6 @@ gd->sess->state = GG_STATE_CONNECTING_HTTP; gd->sess->check = GG_CHECK_WRITE; gd->sess->async = 1; - gd->sess->recv_left = 0; gd->sess->fd = proxy_connect(GG_APPMSG_HOST, GG_APPMSG_PORT, login_callback, gc); if (gd->sess->fd < 0) { @@ -667,7 +667,6 @@ if ((ptr = strstr(webdata, "query_results:")) == NULL || (ptr = strchr(ptr, '\n')) == NULL) { debug_printf("search_callback: pubdir result [%s]\n", webdata); - g_free(webdata); do_error_dialog(_("Couldn't get search results"), _("Gadu-Gadu Error")); return; } @@ -677,8 +676,6 @@ webdata_tbl = g_strsplit(ptr, "\n", AGG_PUBDIR_MAX_ENTRIES); - g_free(webdata); - j = 0; /* Parse array */ @@ -768,28 +765,25 @@ g_free(buf); } -static void agg_import_buddies_results(struct gaim_connection *gc, gchar *webdata) +static void import_buddies_server_results(struct gaim_connection *gc, gchar *webdata) { gchar *ptr; gchar **users_tbl; int i; if (strstr(webdata, "no_data:")) { - g_free(webdata); do_error_dialog(_("There is no Buddy List stored on server. Sorry!"), _("Gadu-Gadu Error")); return; } if ((ptr = strstr(webdata, "get_results:")) == NULL || (ptr = strchr(ptr, ':')) == NULL) { - debug_printf("agg_import_buddies_list: import buddies result [%s]\n", webdata); - g_free(webdata); + debug_printf("import_buddies_server_results: import buddies result [%s]\n", webdata); do_error_dialog(_("Couldn't Import Buddies List from Server"), _("Gadu-Gadu Error")); return; } ptr++; users_tbl = g_strsplit(ptr, "\n", AGG_PUBDIR_MAX_ENTRIES); - g_free(webdata); /* Parse array of Buddies List */ for (i = 0; users_tbl[i] != NULL; i++) { @@ -806,7 +800,7 @@ continue; } - debug_printf("uin: %s\n", name); + debug_printf("import_buddies_server_results: uin: %s\n", name); if (!find_buddy(gc, name)) { /* Default group if none specified on server */ gchar *group = g_strdup("Gadu-Gadu"); @@ -828,20 +822,30 @@ g_strfreev(users_tbl); } -static void agg_export_buddies_results(struct gaim_connection *gc, gchar *webdata) +static void export_buddies_server_results(struct gaim_connection *gc, gchar *webdata) { if (strstr(webdata, "put_success:")) { - g_free(webdata); do_error_dialog(_("Buddies List sucessfully transfered into Server"), _("Gadu-Gadu Information")); return; } - debug_printf("agg_export_buddies_results: webdata [%s]\n", webdata); - g_free(webdata); + debug_printf("export_buddies_server_results: webdata [%s]\n", webdata); do_error_dialog(_("Couldn't transfer Buddies List into Server"), _("Gadu-Gadu Error")); } +static void delete_buddies_server_results(struct gaim_connection *gc, gchar *webdata) +{ + if (strstr(webdata, "put_success:")) { + do_error_dialog(_("Buddies List sucessfully deleted from Server"), + _("Gadu-Gadu Information")); + return; + } + + debug_printf("delete_buddies_server_results: webdata [%s]\n", webdata); + do_error_dialog(_("Couldn't delete Buddies List from Server"), _("Gadu-Gadu Error")); +} + static void http_results(gpointer data, gint source, GaimInputCondition cond) { struct agg_http *hdata = data; @@ -890,17 +894,21 @@ search_results(gc, webdata); break; case AGG_HTTP_USERLIST_IMPORT: - agg_import_buddies_results(gc, webdata); + import_buddies_server_results(gc, webdata); break; case AGG_HTTP_USERLIST_EXPORT: - agg_export_buddies_results(gc, webdata); + export_buddies_server_results(gc, webdata); break; + case AGG_HTTP_USERLIST_DELETE: + delete_buddies_server_results(gc, webdata); + break; case AGG_HTTP_NONE: default: debug_printf("http_results: unsupported type %d\n", hdata->type); break; } + g_free(webdata); g_free(hdata); } @@ -956,7 +964,7 @@ hdata->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_results, hdata); } -static void agg_import_buddies(struct gaim_connection *gc) +static void import_buddies_server(struct gaim_connection *gc) { struct agg_http *hi = g_new0(struct agg_http, 1); static char msg[AGG_BUF_LEN]; @@ -977,7 +985,7 @@ } } -static void agg_export_buddies(struct gaim_connection *gc) +static void export_buddies_server(struct gaim_connection *gc) { struct agg_http *he = g_new0(struct agg_http, 1); static char msg[AGG_BUF_LEN]; @@ -1023,6 +1031,27 @@ } } +static void delete_buddies_server(struct gaim_connection *gc) +{ + struct agg_http *he = g_new0(struct agg_http, 1); + static char msg[AGG_BUF_LEN]; + + he->gc = gc; + he->type = AGG_HTTP_USERLIST_DELETE; + he->form = AGG_PUBDIR_USERLIST_EXPORT_FORM; + he->host = GG_PUBDIR_HOST; + he->request = g_strdup_printf("FmNum=%s&Pass=%s&Delete=1", gc->username, gc->password); + + if (proxy_connect(GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, he) < 0) { + g_snprintf(msg, sizeof(msg), _("Deletion of Buddies List from Server failed (%s)"), + GG_PUBDIR_HOST); + do_error_dialog(msg, _("Gadu-Gadu Error")); + g_free(he->request); + g_free(he); + return; + } +} + static void agg_dir_search(struct gaim_connection *gc, char *first, char *middle, char *last, char *maiden, char *city, char *state, char *country, char *email) { @@ -1066,9 +1095,11 @@ if (!strcmp(action, _("Directory Search"))) { show_find_info(gc); } else if (!strcmp(action, _("Import Buddies List from Server"))) { - agg_import_buddies(gc); + import_buddies_server(gc); } else if (!strcmp(action, _("Export Buddies List to Server"))) { - agg_export_buddies(gc); + export_buddies_server(gc); + } else if (!strcmp(action, _("Delete Buddies List from Server"))) { + delete_buddies_server(gc); } } @@ -1079,6 +1110,7 @@ m = g_list_append(m, _("Directory Search")); m = g_list_append(m, _("Import Buddies List from Server")); m = g_list_append(m, _("Export Buddies List to Server")); + m = g_list_append(m, _("Delete Buddies List from Server")); return m; } Index: protocol.txt =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/gg/protocol.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- protocol.txt 2001/09/29 23:06:30 1.1 +++ protocol.txt 2001/11/27 22:54:32 1.2 @@ -1,12 +1,20 @@ --------------------------------------------------------------------------- - protokó³ g*du-g*du 4.x - (c) copyright 2001 by wojtek kaniewski <woj...@ir...> + Protokó³ G*du-G*du 4.x + + (C) Copyright 2001 by Wojtek Kaniewski <woj...@ir...>, + Robert J. Wo¼ny <sp...@at...>, + Tomasz Jarzynka <to...@cp...>, + Adam Ludwikowski <ada...@wp...>, + Marek Kozina <kl...@hy...>, + Rafa³ Florek <ra...@re...>, + Igor Popik <ig...@ws...> --- 0) disclaimer --------------------------------------------------------- -wszystkie informacje bazuj± na do¶wiadczeniach przeprowadzonych na moim -domowym komputerze. ¿aden klient g*du-g*du nie zosta³ skrzywdzony podczas +opis protoko³u bazuj± na do¶wiadczeniach przeprowadzonych na moim +domowym komputerze oraz informacjach przys³anych do mnie przez ró¿nych +ludzi. ¿aden klient g*du-g*du nie zosta³ skrzywdzony podczas przeprowadzania badañ, blabla. --- 1) transmisja, format wszystkich pakietów ----------------------------- @@ -37,8 +45,20 @@ User-Agent: Mozilla/4.7 [en] (Win98; I) Pragma: no-cache -na co powinni¶my dostaæ odpowied¼ w stylu: +oryginalny klient mo¿e wys³aæ jeden z podanych identyfikatorów przegl±darki: + Mozilla/4.04 [en] (Win95; I ;Nav) + Mozilla/4.7 [en] (Win98; I) + Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt) + Mozilla/4.0 (compatible; MSIE 5.0; Windows NT) + Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt) + Mozilla/4.0 (compatible; MSIE 5.0; Windows 98) + +nowsze wersje klienta do zapytania dodaj± równie¿ `version=...' opisuj±ce, +z jakim klientem serwer ma do czynienia. jednak ze wzglêdu na mo¿liwe +ró¿nice w protokole, lepiej pomijaæ ten parametr i uwagaæ GG 4.0. w ka¿dym +razie na to zapytanie serwer powinien odpowiedzieæ: + HTTP/1.0 200 OK 0 1 0 217.17.33.21:8074 217.17.33.21 217.17.33.21 @@ -47,10 +67,12 @@ przemy¶lany i w przysz³o¶ci bêdzie mo¿na u¿ywaæ ró¿nych serwerów do ró¿nych rzeczy, typu szukanie, obs³uga klientów itd. póki co, ³±czyæ siê trzeba na pierwszy adres (tak, ten z portem). +Je¿eli po³±czenie z portem 8074 nie wyjdzie z jaki¶ specyficznych powodów - +mo¿na siê ³±czyæ na port 443. --- 3) logowanie siê ------------------------------------------------------- -po po³±czeniu siê portem 8074 serwera g*du-g*du, dostajemy pakiet typu 0x0001, +po po³±czeniu siê portem serwera g*du-g*du, dostajemy pakiet typu 0x0001, który na potrzeby tego dokumentu nazwiemy: #define GG_WELCOME 0x0001 @@ -72,7 +94,7 @@ int uin; /* twój numerek */ int hash; /* hash has³a */ int status; /* status na dzieñ dobry */ - int dunno1; /* == 0x0b */ + int version; /* wersja klienta */ int local_ip; /* mój adres ip */ short local_port; /* port, na którym s³ucham */ }; @@ -84,9 +106,20 @@ for (hash = 1; *passwd; passwd++) hash *= (*passwd) + 1; -zrozumia³e, racja? je¶li wszystko siê powiedzie, dostaniemy w odpowiedzi -pakiet typu +zrozumia³e, racja? liczba oznaczaj±ca wersjê mo¿e byæ jedn± z poni¿szych: + 0x11 - 4.6.1 + 0x10 - 4.5.22, 4.5.21, 4.5.19, 4.5.17, 4.5.15 + 0x0f - 4.5.12 + 0x0b - 4.0.30, 4.0.29, 4.0.28, 4.0.25 + +oczywi¶cie nie s± to wszystkie mo¿liwe wersje klientów, lecz te, które +uda³o siê sprawdziæ. najbezpieczniej bêdzie przedstawiaæ siê jako ta +wersja, której ficzerów u¿ywamy. wiadomo, ¿e 4.0.x nie obs³ugiwa³y trybu +ukrytego, ani tylko dla znajomych itd. + +je¶li wszystko siê powiedzie, dostaniemy w odpowiedzi pakiet typu + #define GG_LOGIN_OK 0x0003 z polem header->length = 0, lub pakiet @@ -137,14 +170,16 @@ int status; /* status danej osoby */ int remote_ip; /* adres ip delikwenta */ short remote_port; /* port, na którym s³ucha klient */ - int dunno1; /* == 0x0b */ - short dunno2; /* znowu port? */ + int version; /* wersja klienta */ + short dunno1; /* znowu port? */ }; je¶li klient nie obs³uguje po³±czeñ miêdzy klientami (np. g*du-g*du 3.x) -zamiast adresu ip jest 0, zamiast portu jest 2. niewa¿ne ;) w ka¿dym razie, -je¶li kto¶ siê pojawi w trakcie pracy, równie¿ zostanie przys³any ten -pakiet. proste? proste :) +zamiast adresu ip jest 0, zamiast portu mo¿e byæ 0, 1, 2... niewa¿ne ;) +port mo¿e przyjmowaæ warto¶æ 1, je¶li klient znajduje siê za jakim¶ +firewallem lub innym urz±dzeniem robi±cym NAT. w ka¿dym razie, je¶li kto¶ +siê pojawi w trakcie pracy, równie¿ zostanie przys³any ten pakiet. +proste? proste :) ¿eby dodaæ kogo¶ do listy w trakcie pracy, trzeba wys³aæ ni¿ej opisany pakiet. jego format jest identyczny jak przy GG_NOTIFY. @@ -171,8 +206,10 @@ #define GG_SEND_MSG 0x000b + #define GG_CLASS_QUEUED 0x0001 /* tylko przy odbieraniu */ #define GG_CLASS_MSG 0x0004 #define GG_CLASS_CHAT 0x0008 + #define GG_CLASS_UNKNOWN_1 0x0020 struct gg_send_msg { int recipient; @@ -186,9 +223,28 @@ rozmowy za pomoc± czê¶ci bajtów, ale raczej nie ma znaczenia. klasa wiadomo¶ci pozwala odró¿niæ, czy wiadomo¶æ ma siê pokazaæ w osobym okienku czy jako kolejna linijka w okienku rozmowy. wygl±da na to, -¿e to jaka¶ bitmapa, wiêc najlepiej olaæ inne bity ni¿ 0x0f. (czasem -klienty wysy³aj± 0x04, czasem 0x24) +¿e to jaka¶ bitmapa, wiêc najlepiej olaæ inne bity ni¿ 0x0e. (czasem +klienty wysy³aj± 0x04, czasem 0x24 -- widocznie 0x20 to te¿ jaka¶ +flaga). je¶li odbiorca by³ niedostêpny podczas wysy³ania wiadomo¶ci, +zostanie zaznaczony bit 0x01. + +oryginalny klient wysy³aj±c wiadomo¶æ do kilku u¿ytkowników, wysy³a po +prostu kilka takich samych pakietów z ró¿nymi numerkami odbiorców. nie +ma osobnego pakietu do tego. natomiast je¶li chodzi o ,,konferencyjnê'' +do pakietu doklejana jest za ,,char message[];'' nastêpuj±ca struktura: + struct gg_send_recipients { + char flag; /* == 1 */ + int count; /* ilo¶æ odbiorców */ + int recipients[]; /* tablica odbiorców */ + }; + +na przyk³ad, by wys³aæ do trzech ludzi, nale¿y wys³aæ pakiet: + + - -- --- --+--+--+--+--+--+--+-----------+-----------+ + tre¶æ |\0|\1| 0x02 | uin1 | uin2 | + - -- -- ---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + serwer po otrzymaniu wiadomo¶ci odsy³a informacjê o tym. przy okazji mówi, czy wiadomo¶æ dotar³a do odbiorcy (status == GG_ACK_DELIVERED), czy mo¿e jest offline i zosta³a zakolejkowana (GG_ACK_QUEUED): @@ -208,26 +264,29 @@ --- 7) otrzymywanie wiadomo¶ci --------------------------------------------- -zbyt wiele wyja¶nieñ chyba nie trzeba. wiadomo od kogo. nieznane pola to -co¶ a'la numer sekwencyjny albo identyfikator okienka z rozmow± albo nowe -dane dla setiathome. klasa wiadomo¶ci taka sama jak przy wysy³aniu: +zbyt wiele wyja¶nieñ chyba nie trzeba. wiadomo od kogo. drugie pole to +najprawdopodobniej jaki¶ numerek sekwencyjny. trzecie oznacza czas nadania +wiadomo¶ci. klasa wiadomo¶ci taka sama jak przy wysy³aniu: #define GG_RECV_MSG 0x000a struct gg_recv_msg { int sender; - int dunno1; - int dunno2; + int seq; + int time; int class; char message[]; }; ---- 8) otrzymywanie wiadomo¶ci --------------------------------------------- +w przypadku pakietów ,,konferencyjnych'' na koncu pakietu doklejona jest +struktura identyczna ze struct gg_send_recipients zawieraj±ca pozosta³ych +rozmówców. + +--- 8) ping/pong ----------------------------------------------------------- od czasu do czasu klient wysy³a pakiet a'la ping do serwera i dostaje pust± -odpowied¼. ciê¿ko stwierdziæ, czy serwer wywala, je¶li nie dostanie pinga -przez jaki¶ czas, czy klient siê roz³±cza, je¶li serwer mu nie odpowie. -jako¶ nie chce mi siê sprawdzaæ ;) +odpowied¼. o ile dobrze pamiêtam, serwer roz³±cza siê po up³ywie 5 minut od +otrzymania ostatniej informacji. #define GG_PING 0x0008 @@ -239,8 +298,19 @@ --- 9) podziêkowania ------------------------------------------------------- -swój wk³ad w poznanie protoko³u mia³ Robert Wo¼ny, który opisa³ nowo¶ci -w GG 4.6. +swój wk³ad w poznanie protoko³u mieli: + - Robert J. Wo¼ny <sp...@at...>: + opis nowo¶ci w protokole GG 4.6, + - Tomasz Jarzynka <to...@cp...>: + badanie timeoutów, + - Adam Ludwikowski <ada...@wp...>: + wiele ró¿nych poprawek do tekstu, badanie wersji, + - Marek Kozina <kl...@hy...>: + czas otrzymania wiadomo¶ci, + - Rafa³ Florek <ra...@re...>: + konferencje, + - Igor Popik <ig...@ws...>: + klasy wiadomo¶ci przy odbieraniu zakolejkowanej. ---------------------------------------------------------------------------- |