From: Eric W. <war...@us...> - 2001-12-05 09:48:59
|
Update of /cvsroot/gaim/gaim/src/protocols/gg In directory usw-pr-cvs1:/tmp/cvs-serv14191 Modified Files: .cvsignore Makefile.am gg.c libgg.c libgg.h Added Files: common.c Log Message: so here it comes - some bugs fixed, new ones introduced: - password changing (was in part 1) - update to latest libgg (fixes password change on alpha) - auto away on idle (remembers GG_STATE_FRIENDS_MASK) - handle_errcode() can now use hide_login_progress() - remove encode_postdata() and use gg_urlencode() from libgg + encode only fields (not whole url) - fixed status related ugly bug in GG_EVENT_NOTIFY (!!!) - remove linefeed from messages Thanks, Arkadiusz Miskiewicz --- NEW FILE: common.c --- /* $Id: common.c,v 1.1 2001/12/05 09:48:56 warmenhoven Exp $ */ /* * (C) Copyright 2001 Wojtek Kaniewski <woj...@ir...>, * Robert J. Wo¼ny <sp...@zi...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/ioctl.h> #include <sys/wait.h> #include <sys/time.h> #include <netdb.h> #include <errno.h> #ifndef _AIX # include <string.h> #endif #include <stdarg.h> #include <pwd.h> #include <time.h> #ifdef sun #include <sys/filio.h> #endif #include "libgg.h" #include "config.h" /* * gg_debug() * * wyrzuca komunikat o danym poziomie, o ile u¿ytkownik sobie tego ¿yczy. * * - level - poziom wiadomo¶ci, * - format... - tre¶æ wiadomo¶ci (printf-alike.) * * niczego nie zwraca. */ void gg_debug(int level, char *format, ...) { va_list ap; if ((gg_debug_level & level)) { va_start(ap, format); vprintf(format, ap); va_end(ap); } } /* * gg_alloc_sprintf() * * robi dok³adnie to samo, co sprintf(), tyle ¿e alokuje sobie wcze¶niej * miejsce na dane. powinno dzia³aæ na tych maszynach, które maj± funkcjê * vsnprintf() zgodn± z C99, jak i na wcze¶niejszych. * * - format, ... - parametry takie same jak w innych funkcjach *printf() * * zwraca zaalokowany buforek, który wypada³oby pó¼niej zwolniæ, lub NULL * je¶li nie uda³o siê wykonaæ zadania. */ char *gg_alloc_sprintf(char *format, ...) { va_list ap; char *buf = NULL, *tmp; int size = 0, res; va_start(ap, format); if ((size = vsnprintf(buf, 0, format, ap)) < 1) { size = 128; do { size *= 2; if (!(tmp = realloc(buf, size))) { free(buf); return NULL; } buf = tmp; res = vsnprintf(buf, size, format, ap); } while (res == size - 1); } else { if (!(buf = malloc(size + 1))) return NULL; } vsnprintf(buf, size + 1, format, ap); va_end(ap); return buf; } /* * gg_get_line() * * podaje kolejn± liniê z bufora tekstowego. psuje co bezpowrotnie, dziel±c * na kolejne stringi. zdarza siê, nie ma potrzeby pisania funkcji dubluj±cej * bufor ¿eby tylko mieæ nieruszone dane wej¶ciowe, skoro i tak nie bêd± nam * po¼niej potrzebne. obcina `\r\n'. * * - ptr - wska¼nik do zmiennej, która przechowuje aktualn± pozycjê * w przemiatanym buforze. * * wska¼nik do kolejnej linii tekstu lub NULL, je¶li to ju¿ koniec bufora. */ char *gg_get_line(char **ptr) { char *foo, *res; if (!ptr || !*ptr || !strcmp(*ptr, "")) return NULL; res = *ptr; if (!(foo = strchr(*ptr, '\n'))) *ptr += strlen(*ptr); else { *ptr = foo + 1; *foo = 0; if (res[strlen(res) - 1] == '\r') res[strlen(res) - 1] = 0; } return res; } /* * gg_connect() * * ³±czy siê z serwerem. pierwszy argument jest typu (void *), ¿eby nie * musieæ niczego inkludowaæ w libgg.h i nie psuæ jaki¶ g³upich zale¿no¶ci * na dziwnych systemach. * * - addr - adres serwera (struct in_addr *), * - port - port serwera, * - async - ma byæ asynchroniczne po³±czenie? * * zwraca po³±czonego socketa lub -1 w przypadku b³êdu. zobacz errno. */ int gg_connect(void *addr, int port, int async) { int sock, one = 1; struct sockaddr_in sin; struct in_addr *a = addr; gg_debug(GG_DEBUG_FUNCTION, "** gg_connect(%s, %d, %d);\n", inet_ntoa(*a), port, async); if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { gg_debug(GG_DEBUG_MISC, "-- socket() failed. errno = %d (%s)\n", errno, strerror(errno)); return -1; } if (async) { if (ioctl(sock, FIONBIO, &one) == -1) { gg_debug(GG_DEBUG_MISC, "-- ioctl() failed. errno = %d (%s)\n", errno, strerror(errno)); return -1; } } sin.sin_port = htons(port); sin.sin_family = AF_INET; sin.sin_addr.s_addr = a->s_addr; if (connect(sock, (struct sockaddr*) &sin, sizeof(sin)) == -1) { if (errno && (!async || errno != EINPROGRESS)) { gg_debug(GG_DEBUG_MISC, "-- connect() failed. errno = %d (%s)\n", errno, strerror(errno)); return -1; } gg_debug(GG_DEBUG_MISC, "-- connect() in progress\n"); } return sock; } /* * gg_read_line() * * czyta jedn± liniê tekstu z socketa. * * - sock - socket, * - buf - wska¼nik bufora, * - length - d³ugo¶æ bufora. * * olewa b³êdy. je¶li na jaki¶ trafi, potraktuje go jako koniec linii. */ void gg_read_line(int sock, char *buf, int length) { int ret; gg_debug(GG_DEBUG_FUNCTION, "** gg_read_line(...);\n"); for (; length > 1; buf++, length--) { do { if ((ret = read(sock, buf, 1)) == -1 && errno != EINTR) { *buf = 0; return; } } while (ret == -1 && errno == EINTR); if (*buf == '\n') { buf++; break; } } *buf = 0; return; } /* * gg_chomp() * * ucina "\r\n" lub "\n" z koñca linii. * * - line - ofiara operacji plastycznej. * * niczego nie zwraca. */ void gg_chomp(char *line) { if (!line || strlen(line) < 1) return; if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = 0; if (line[strlen(line) - 1] == '\r') line[strlen(line) - 1] = 0; } /* * gg_urlencode() // funkcja wewnêtrzna * * zamienia podany tekst na ci±g znaków do formularza http. przydaje siê * przy szukaniu userów z dziwnymi znaczkami. * * - str - ci±g znaków do poprawki. * * zwraca zaalokowany bufor, który wypada³oby kiedy¶ zwolniæ albo NULL * w przypadku b³êdu. */ char *gg_urlencode(char *str) { char *p, *q, *buf, hex[] = "0123456789abcdef"; int size = 0; if (!str) str = strdup(""); for (p = str; *p; p++, size++) { if (!((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9'))) size += 2; } if (!(buf = malloc(size + 1))) return NULL; for (p = str, q = buf; *p; p++, q++) { if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9')) *q = *p; else { *q++ = '%'; *q++ = hex[*p >> 4 & 15]; *q = hex[*p & 15]; } } *q = 0; return buf; } /* * gg_http_hash() * * funkcja, która liczy hash dla adresu e-mail i has³a. * * - email - adres email, * - password - has³o. * * zwraca hash wykorzystywany przy rejestracji i wszelkich * manipulacjach w³asnego wpisu w katalogu publicznym. */ int gg_http_hash(unsigned char *email, unsigned char *password) { unsigned int a, c; int b, i; b = (-1); i = 0; while ((c = (int) email[i++]) != 0) { a = (c ^ b) + (c << 8); b = (a >> 24) | (a << 8); } i = 0; while ((c = (int) password[i++]) != 0) { a = (c ^ b) + (c << 8); b = (a >> 24) | (a << 8); } return (b < 0 ? -b : b); } /* * Local variables: * c-indentation-style: k&r * c-basic-offset: 8 * indent-tabs-mode: notnil * End: * * vim: shiftwidth=8: */ Index: .cvsignore =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/gg/.cvsignore,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- .cvsignore 2001/10/18 20:56:59 1.2 +++ .cvsignore 2001/12/05 09:48:55 1.3 @@ -6,3 +6,4 @@ libgg.la libgg.lo iconv_string.lo +common.lo Index: Makefile.am =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/gg/Makefile.am,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- Makefile.am 2001/10/18 20:56:59 1.2 +++ Makefile.am 2001/12/05 09:48:56 1.3 @@ -13,6 +13,7 @@ libgg_a_SOURCES = libgg.c \ libgg.h \ + common.c \ iconv_string.c \ iconv_string.h \ gg.c @@ -25,6 +26,7 @@ libgg_la_SOURCES = libgg.c \ libgg.h \ + common.c \ iconv_string.c \ iconv_string.h \ gg.c Index: gg.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/gg/gg.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- gg.c 2001/12/02 20:42:30 1.14 +++ gg.c 2001/12/05 09:48:56 1.15 @@ -65,6 +65,7 @@ #define AGG_PUBDIR_USERLIST_EXPORT_FORM "/appsvc/fmcontactsput.asp" #define AGG_PUBDIR_USERLIST_IMPORT_FORM "/appsvc/fmcontactsget.asp" #define AGG_PUBDIR_SEARCH_FORM "/appsvc/fmpubquery2.asp" +#define AGG_REGISTER_DATA_FORM "/appsvc/fmregister.asp" #define AGG_PUBDIR_MAX_ENTRIES 200 #define AGG_STATUS_AVAIL _("Available") @@ -80,11 +81,13 @@ #define AGG_HTTP_USERLIST_IMPORT 2 #define AGG_HTTP_USERLIST_EXPORT 3 #define AGG_HTTP_USERLIST_DELETE 4 +#define AGG_HTTP_PASSWORD_CHANGE 5 #define UC_NORMAL 2 struct agg_data { struct gg_session *sess; + int own_status; }; struct agg_http { @@ -170,7 +173,7 @@ return gg_localenc; } -static char *handle_errcode(int errcode, gboolean show) +static char *handle_errcode(struct gaim_connection *gc, int errcode) { static char msg[AGG_BUF_LEN]; @@ -198,73 +201,51 @@ break; } - if (show) - do_error_dialog(msg, _("Gadu-Gadu Error")); + hide_login_progress(gc, msg); return msg; } -static gchar *encode_postdata(const gchar *data) -{ - gchar *p = NULL; - int i, j = 0; - for (i = 0; i < strlen(data); i++) { - /* locale insensitive, doesn't reflect RFC (1738 section 2.2, 1866 section 8.2.1) */ - if ((data[i] >= 'a' && data[i] <= 'z') - || (data[i] >= 'A' && data[i] <= 'Z') - || (data[i] >= '0' && data[i] <= '9') - || data[i] == '=' || data[i] == '&') { - p = g_realloc(p, j + 1); - p[j] = data[i]; - j++; - } else { - p = g_realloc(p, j + 4); /* remember, sprintf appends a '\0' */ - sprintf(p + j, "%%%02x", (unsigned char)data[i]); - j += 3; - } - } - p = g_realloc(p, j + 1); - p[j] = '\0'; - - if (p && strlen(p)) - return p; - else - return g_strdup(data); -} - static void agg_set_away(struct gaim_connection *gc, char *state, char *msg) { struct agg_data *gd = (struct agg_data *)gc->proto_data; + int status = gd->own_status; if (gc->away) gc->away = NULL; if (!g_strcasecmp(state, AGG_STATUS_AVAIL)) - gg_change_status(gd->sess, GG_STATUS_AVAIL); + status = GG_STATUS_AVAIL; else if (!g_strcasecmp(state, AGG_STATUS_AVAIL_FRIENDS)) - gg_change_status(gd->sess, GG_STATUS_AVAIL | GG_STATUS_FRIENDS_MASK); + status = GG_STATUS_AVAIL | GG_STATUS_FRIENDS_MASK; else if (!g_strcasecmp(state, AGG_STATUS_BUSY)) { - gg_change_status(gd->sess, GG_STATUS_BUSY); + status = GG_STATUS_BUSY; gc->away = ""; } else if (!g_strcasecmp(state, AGG_STATUS_BUSY_FRIENDS)) { - gg_change_status(gd->sess, GG_STATUS_BUSY | GG_STATUS_FRIENDS_MASK); + status = GG_STATUS_BUSY | GG_STATUS_FRIENDS_MASK; gc->away = ""; } else if (!g_strcasecmp(state, AGG_STATUS_INVISIBLE)) { - gg_change_status(gd->sess, GG_STATUS_INVISIBLE); + status = GG_STATUS_INVISIBLE; gc->away = ""; } else if (!g_strcasecmp(state, AGG_STATUS_INVISIBLE_FRIENDS)) { - gg_change_status(gd->sess, GG_STATUS_INVISIBLE | GG_STATUS_FRIENDS_MASK); + status = GG_STATUS_INVISIBLE | GG_STATUS_FRIENDS_MASK; gc->away = ""; } else if (!g_strcasecmp(state, AGG_STATUS_NOT_AVAIL)) { - gg_change_status(gd->sess, GG_STATUS_NOT_AVAIL); + status = GG_STATUS_NOT_AVAIL; gc->away = ""; } else if (!g_strcasecmp(state, GAIM_AWAY_CUSTOM)) { if (msg) { - gg_change_status(gd->sess, GG_STATUS_BUSY); + status = GG_STATUS_BUSY; gc->away = ""; } else - gg_change_status(gd->sess, GG_STATUS_AVAIL); + status = GG_STATUS_AVAIL; + + if (gd->own_status & GG_STATUS_FRIENDS_MASK) + status |= GG_STATUS_FRIENDS_MASK; } + + gd->own_status = status; + gg_change_status(gd->sess, status); } static gchar *get_away_text(int uc) @@ -359,6 +340,7 @@ if (!(e = gg_watch_fd(gd->sess))) { debug_printf("main_callback: gg_watch_fd failed - CRITICAL!\n"); + hide_login_progress(gc, _("Unable to read socket")); signoff(gc); return; } @@ -373,7 +355,7 @@ case GG_EVENT_CONN_FAILED: if (gc->inpa) gaim_input_remove(gc->inpa); - handle_errcode(e->event.failure, TRUE); + handle_errcode(gc, e->event.failure); signoff(gc); break; case GG_EVENT_MSG: @@ -385,6 +367,7 @@ if (!allowed_uin(gc, user)) break; imsg = charset_convert(e->event.msg.message, "CP1250", find_local_charset()); + strip_linefeed(imsg); /* e->event.msg.time - we don't know what this time is for */ serv_got_im(gc, user, imsg, 0, time((time_t) NULL)); g_free(imsg); @@ -404,8 +387,7 @@ case GG_STATUS_AVAIL: case GG_STATUS_BUSY: case GG_STATUS_INVISIBLE: - case GG_STATUS_FRIENDS_MASK: - status = UC_NORMAL | (e->event.status.status << 5); + status = UC_NORMAL | (n->status << 5); break; default: status = UC_NORMAL; @@ -431,7 +413,6 @@ case GG_STATUS_AVAIL: case GG_STATUS_BUSY: case GG_STATUS_INVISIBLE: - case GG_STATUS_FRIENDS_MASK: status = UC_NORMAL | (e->event.status.status << 5); break; default: @@ -440,8 +421,8 @@ } g_snprintf(user, sizeof(user), "%lu", e->event.status.uin); - serv_got_update(gc, user, (status == UC_UNAVAILABLE) ? 0 : 1, 0, 0, 0, status, - 0); + serv_got_update(gc, user, (status == UC_UNAVAILABLE) ? 0 : 1, 0, 0, 0, + status, 0); } break; case GG_EVENT_ACK: @@ -479,18 +460,17 @@ gc->inpa = gaim_input_add(gd->sess->fd, GAIM_INPUT_READ, login_callback, gc); switch (gd->sess->state) { - case GG_STATE_CONNECTING_HTTP: - case GG_STATE_WRITING_HTTP: - set_login_progress(gc, 2, _("Handshake")); + case GG_STATE_READING_DATA: + set_login_progress(gc, 2, _("Reading data")); break; case GG_STATE_CONNECTING_GG: - set_login_progress(gc, 3, _("Connecting to GG server")); + set_login_progress(gc, 3, _("Balancer handshake")); break; - case GG_STATE_WAITING_FOR_KEY: - set_login_progress(gc, 4, _("Waiting for server key")); + case GG_STATE_READING_KEY: + set_login_progress(gc, 4, _("Reading server key")); break; - case GG_STATE_SENDING_KEY: - set_login_progress(gc, 5, _("Sending key")); + case GG_STATE_READING_REPLY: + set_login_progress(gc, 5, _("Exchanging key hash")); break; default: break; @@ -498,6 +478,7 @@ if (!(e = gg_watch_fd(gd->sess))) { debug_printf("login_callback: gg_watch_fd failed - CRITICAL!\n"); + hide_login_progress(gc, _("Critical error in GG library\n")); signoff(gc); return; } @@ -522,7 +503,7 @@ case GG_EVENT_CONN_FAILED: gaim_input_remove(gc->inpa); gc->inpa = 0; - handle_errcode(e->event.failure, TRUE); + handle_errcode(gc, e->event.failure); signoff(gc); break; default: @@ -536,6 +517,7 @@ { struct agg_data *gd = (struct agg_data *)gc->proto_data; if (gg_ping(gd->sess) < 0) { + hide_login_progress(gc, _("Unable to ping server")); signoff(gc); return; } @@ -578,7 +560,7 @@ gd->sess->uin = (uin_t) strtol(user->username, (char **)NULL, 10); gd->sess->password = g_strdup(user->password); - gd->sess->state = GG_STATE_CONNECTING_HTTP; + gd->sess->state = GG_STATE_CONNECTING; gd->sess->check = GG_CHECK_WRITE; gd->sess->async = 1; gd->sess->fd = proxy_connect(GG_APPMSG_HOST, GG_APPMSG_PORT, login_callback, gc); @@ -599,6 +581,7 @@ gg_logoff(gd->sess); gg_free_session(gd->sess); g_free(gc->proto_data); + gd->own_status = GG_STATUS_NOT_AVAIL; } static int agg_send_im(struct gaim_connection *gc, char *who, char *msg, int flags) @@ -614,7 +597,8 @@ if (strlen(msg) > 0) { imsg = charset_convert(msg, find_local_charset(), "CP1250"); - if (gg_send_message(gd->sess, (flags & IM_FLAG_CHECKBOX) ? GG_CLASS_MSG : GG_CLASS_CHAT, + if (gg_send_message(gd->sess, (flags & IM_FLAG_CHECKBOX) + ? GG_CLASS_MSG : GG_CLASS_CHAT, strtol(who, (char **)NULL, 10), imsg) < 0) return -1; g_free(imsg); @@ -848,6 +832,18 @@ do_error_dialog(_("Couldn't delete Buddies List from Server"), _("Gadu-Gadu Error")); } +static void password_change_server_results(struct gaim_connection *gc, gchar *webdata) +{ + if (strstr(webdata, "reg_success:")) { + do_error_dialog(_("Password changed sucessfully"), + _("Gadu-Gadu Information")); + return; + } + + debug_printf("delete_buddies_server_results: webdata [%s]\n", webdata); + do_error_dialog(_("Password couldn't be changed"), _("Gadu-Gadu Error")); +} + static void http_results(gpointer data, gint source, GaimInputCondition cond) { struct agg_http *hdata = data; @@ -904,6 +900,9 @@ case AGG_HTTP_USERLIST_DELETE: delete_buddies_server_results(gc, webdata); break; + case AGG_HTTP_PASSWORD_CHANGE: + password_change_server_results(gc, webdata); + break; case AGG_HTTP_NONE: default: debug_printf("http_results: unsupported type %d\n", hdata->type); @@ -920,7 +919,6 @@ struct gaim_connection *gc = hdata->gc; gchar *request = hdata->request; gchar *buf; - char *ptr; debug_printf("http_req_callback: begin\n"); @@ -938,10 +936,7 @@ return; } - ptr = encode_postdata(request); - g_free(request); - - debug_printf("http_req_callback: http request [%s]\n", ptr); + debug_printf("http_req_callback: http request [%s]\n", request); buf = g_strdup_printf("POST %s HTTP/1.0\r\n" "Host: %s\r\n" @@ -949,9 +944,9 @@ "User-Agent: " GG_HTTP_USERAGENT "\r\n" "Content-Length: %d\r\n" "Pragma: no-cache\r\n" "\r\n" "%s\r\n", - hdata->form, hdata->host, strlen(ptr), ptr); + hdata->form, hdata->host, strlen(request), request); - g_free(ptr); + g_free(request); if (write(source, buf, strlen(buf)) < strlen(buf)) { g_free(buf); @@ -970,12 +965,17 @@ { struct agg_http *hi = g_new0(struct agg_http, 1); static char msg[AGG_BUF_LEN]; + gchar *u = gg_urlencode(gc->username); + gchar *p = gg_urlencode(gc->password); hi->gc = gc; hi->type = AGG_HTTP_USERLIST_IMPORT; hi->form = AGG_PUBDIR_USERLIST_IMPORT_FORM; hi->host = GG_PUBDIR_HOST; - hi->request = g_strdup_printf("FmNum=%s&Pass=%s", gc->username, gc->password); + hi->request = g_strdup_printf("FmNum=%s&Pass=%s", u, p); + + g_free(u); + g_free(p); if (proxy_connect(GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, hi) < 0) { g_snprintf(msg, sizeof(msg), _("Buddies List import from Server failed (%s)"), @@ -992,13 +992,19 @@ struct agg_http *he = g_new0(struct agg_http, 1); static char msg[AGG_BUF_LEN]; gchar *ptr; + gchar *u = gg_urlencode(gc->username); + gchar *p = gg_urlencode(gc->password); + GSList *gr = gc->groups; he->gc = gc; he->type = AGG_HTTP_USERLIST_EXPORT; he->form = AGG_PUBDIR_USERLIST_EXPORT_FORM; he->host = GG_PUBDIR_HOST; - he->request = g_strdup_printf("FmNum=%s&Pass=%s&Contacts=", gc->username, gc->password); + he->request = g_strdup_printf("FmNum=%s&Pass=%s&Contacts=", u, p); + + g_free(u); + g_free(p); while (gr) { struct group *g = gr->data; @@ -1007,17 +1013,24 @@ struct buddy *b = m->data; gchar *newdata; /* GG Number */ - gchar *name = b->name; + gchar *name = gg_urlencode(b->name); /* GG Pseudo */ - gchar *show = strlen(b->show) ? b->show : b->name; + gchar *show = gg_urlencode(strlen(b->show) ? b->show : b->name); + /* Group Name */ + gchar *gname = gg_urlencode(g->name); ptr = he->request; newdata = g_strdup_printf("%s;%s;%s;%s;%s;%s;%s\r\n", - show, show, show, show, "", g->name, name); + show, show, show, show, "", gname, name); he->request = g_strconcat(ptr, newdata, NULL); + g_free(newdata); g_free(ptr); + g_free(gname); + g_free(show); + g_free(name); + m = g_slist_next(m); } gr = g_slist_next(gr); @@ -1037,12 +1050,14 @@ { struct agg_http *he = g_new0(struct agg_http, 1); static char msg[AGG_BUF_LEN]; + gchar *u = gg_urlencode(gc->username); + gchar *p = gg_urlencode(gc->password); 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); + he->request = g_strdup_printf("FmNum=%s&Pass=%s&Delete=1", u, p); 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)"), @@ -1055,7 +1070,8 @@ } 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) + char *last, char *maiden, char *city, char *state, + char *country, char *email) { struct agg_http *srch = g_new0(struct agg_http, 1); static char msg[AGG_BUF_LEN]; @@ -1066,25 +1082,36 @@ srch->host = GG_PUBDIR_HOST; if (email && strlen(email)) { - srch->request = g_strdup_printf("Mode=1&Email=%s", email); + gchar *eemail = gg_urlencode(email); + srch->request = g_strdup_printf("Mode=1&Email=%s", eemail); + g_free(eemail); } else { gchar *new_first = charset_convert(first, find_local_charset(), "CP1250"); gchar *new_last = charset_convert(last, find_local_charset(), "CP1250"); gchar *new_city = charset_convert(city, find_local_charset(), "CP1250"); - /* For active only add &ActiveOnly= */ - srch->request = g_strdup_printf("Mode=0&FirstName=%s&LastName=%s&Gender=%d" - "&NickName=%s&City=%s&MinBirth=%d&MaxBirth=%d", - new_first, new_last, AGG_GENDER_NONE, - "", new_city, 0, 0); + gchar *enew_first = gg_urlencode(new_first); + gchar *enew_last = gg_urlencode(new_last); + gchar *enew_city = gg_urlencode(new_city); g_free(new_first); g_free(new_last); g_free(new_city); + + /* For active only add &ActiveOnly= */ + srch->request = g_strdup_printf("Mode=0&FirstName=%s&LastName=%s&Gender=%d" + "&NickName=%s&City=%s&MinBirth=%d&MaxBirth=%d", + enew_first, enew_last, AGG_GENDER_NONE, + "", enew_city, 0, 0); + + g_free(enew_first); + g_free(enew_last); + g_free(enew_city); } if (proxy_connect(GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, srch) < 0) { - g_snprintf(msg, sizeof(msg), _("Connect to search service failed (%s)"), GG_PUBDIR_HOST); + g_snprintf(msg, sizeof(msg), _("Connect to search service failed (%s)"), + GG_PUBDIR_HOST); do_error_dialog(msg, _("Gadu-Gadu Error")); g_free(srch->request); g_free(srch); @@ -1092,10 +1119,45 @@ } } +static void agg_change_passwd(struct gaim_connection *gc, char *old, char *new) +{ + struct agg_http *hpass = g_new0(struct agg_http, 1); + static char msg[AGG_BUF_LEN]; + gchar *u = gg_urlencode(gc->username); + gchar *p = gg_urlencode(gc->password); + gchar *enew = gg_urlencode(new); + gchar *eold = gg_urlencode(old); + + hpass->gc = gc; + hpass->type = AGG_HTTP_PASSWORD_CHANGE; + hpass->form = AGG_REGISTER_DATA_FORM; + hpass->host = GG_REGISTER_HOST; + + /* We are using old password as place for email - it's ugly */ + hpass->request = g_strdup_printf("fmnumber=%s&fmpwd=%s&pwd=%s&email=%s&code=%u", + u, p, enew, eold, gg_http_hash(old, new)); + + g_free(u); + g_free(p); + g_free(enew); + g_free(eold); + + if (proxy_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, http_req_callback, hpass) < 0) { + g_snprintf(msg, sizeof(msg), _("Changing Password failed (%s)"), + GG_REGISTER_HOST); + do_error_dialog(msg, _("Gadu-Gadu Error")); + g_free(hpass->request); + g_free(hpass); + return; + } +} + static void agg_do_action(struct gaim_connection *gc, char *action) { if (!strcmp(action, _("Directory Search"))) { show_find_info(gc); + } else if (!strcmp(action, _("Change Password"))) { + show_change_passwd(gc); } else if (!strcmp(action, _("Import Buddies List from Server"))) { import_buddies_server(gc); } else if (!strcmp(action, _("Export Buddies List to Server"))) { @@ -1110,6 +1172,9 @@ GList *m = NULL; m = g_list_append(m, _("Directory Search")); + m = g_list_append(m, NULL); + m = g_list_append(m, _("Change Password")); + m = g_list_append(m, NULL); 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")); @@ -1130,17 +1195,21 @@ /* If it's invalid uin then maybe it's nickname? */ if (invalid_uin(who)) { gchar *new_who = charset_convert(who, find_local_charset(), "CP1250"); + gchar *enew_who = gg_urlencode(new_who); + + g_free(new_who); srch->request = g_strdup_printf("Mode=0&FirstName=%s&LastName=%s&Gender=%d" "&NickName=%s&City=%s&MinBirth=%d&MaxBirth=%d", - "", "", AGG_GENDER_NONE, new_who, "", 0, 0); + "", "", AGG_GENDER_NONE, enew_who, "", 0, 0); - g_free(new_who); + g_free(enew_who); } else srch->request = g_strdup_printf("Mode=3&UserId=%s", who); if (proxy_connect(GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, srch) < 0) { - g_snprintf(msg, sizeof(msg), _("Connect to search service failed (%s)"), GG_PUBDIR_HOST); + g_snprintf(msg, sizeof(msg), _("Connect to search service failed (%s)"), + GG_PUBDIR_HOST); do_error_dialog(msg, _("Gadu-Gadu Error")); g_free(srch->request); g_free(srch); @@ -1199,7 +1268,7 @@ ret->get_dir = agg_get_info; ret->dir_search = agg_dir_search; ret->set_idle = NULL; - ret->change_passwd = NULL; + ret->change_passwd = agg_change_passwd; ret->add_buddy = agg_add_buddy; ret->add_buddies = agg_add_buddies; ret->remove_buddy = agg_rem_buddy; @@ -1245,3 +1314,13 @@ } #endif + +/* + * Local variables: + * c-indentation-style: k&r + * c-basic-offset: 8 + * indent-tabs-mode: notnil + * End: + * + * vim: shiftwidth=8: + */ Index: libgg.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/gg/libgg.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- libgg.c 2001/11/26 21:22:56 1.5 +++ libgg.c 2001/12/05 09:48:56 1.6 @@ -2,7 +2,7 @@ /* * (C) Copyright 2001 Wojtek Kaniewski <woj...@ir...>, - * Robert J. Wo¼ny <sp...@at...> + * Robert J. Wo¼ny <sp...@zi...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -37,7 +37,7 @@ #include <pwd.h> #include <time.h> [...1030 lines suppressed...] - if (errno == EAGAIN) { + if (errno == EAGAIN) { e->type = GG_EVENT_NONE; res = 0; } else @@ -1390,3 +1193,13 @@ return e; } + +/* + * Local variables: + * c-indentation-style: k&r + * c-basic-offset: 8 + * indent-tabs-mode: notnil + * End: + * + * vim: shiftwidth=8: + */ Index: libgg.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/protocols/gg/libgg.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- libgg.h 2001/11/26 21:22:56 1.5 +++ libgg.h 2001/12/05 09:48:56 1.6 @@ -2,7 +2,7 @@ /* * (C) Copyright 2001 Wojtek Kaniewski <woj...@ir...>, - * Robert J. Wo¼ny <sp...@at...> + * Robert J. Wo¼ny <sp...@zi...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -18,15 +18,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef __LIBGG_H -#define __LIBGG_H +#ifndef __GG_LIBGG_H +#define __GG_LIBGG_H #ifdef __cplusplus extern "C" { #endif #if defined(sun) && !defined(INADDR_NONE) -#define INADDR_NONE 0xffffffff + #define INADDR_NONE 0xffffffff #endif #include <sys/types.h> @@ -34,184 +34,305 @@ /* * typ zmiennej okre¶laj±cej numerek danej osoby. */ - typedef unsigned long uin_t; +typedef unsigned long uin_t; /* - * co¶tam. + * struktura opisuj±ca dan± sesjê. tworzona przez gg_login(). */ - struct gg_session { - int state, check; - int fd, pid; - int port; - int seq, async; - int last_pong; +struct gg_session { + int fd; /* podgl±dany deskryptor */ + int check; /* sprawdzamy zapis czy odczyt */ + int state; /* aktualny stan maszynki */ + int error; /* kod b³êdu dla GG_STATE_ERROR */ + int type; /* rodzaj sesji. == GG_SESSION_GG */ + + int async; /* czy po³±czenie jest asynchroniczne */ + int pid; /* pid procesu resolvera */ + int port; /* port, z którym siê ³±czymy */ + int seq; /* numer sekwencyjny ostatniej wiadomo¶ci */ + int last_pong; /* czas otrzymania ostatniego ping/pong */ - /* powinno byæ ,,in_addr'', ale nie chcê inkludowaæ sieci tutaj */ - unsigned long server_ip; + unsigned int server_ip; /* adres serwera */ + unsigned int client_ip; /* adres klienta */ + int client_port; /* port, na którym klient s³ucha */ - uin_t uin; - char *password; - int initial_status; + uin_t uin; /* numerek klienta */ + char *password; /* i jego has³o. zwalniane automagicznie */ + + int initial_status; /* pocz±tkowy stan klienta */ - char *recv_buf; - int recv_done, recv_left; - }; + char *recv_buf; /* bufor na otrzymywane pakiety */ + int recv_done; /* ile ju¿ wczytano do bufora */ + int recv_left; /* i ile jeszcze trzeba wczytaæ */ +}; + +/* + * ogólna struktura opisuj±ca stan wszystkich operacji http. + */ +struct gg_http { + int fd; /* podgl±dany deskryptor */ + int check; /* sprawdzamy zapis czy odczyt */ + int state; /* aktualny stan maszynki */ + int error; /* kod b³êdu dla GG_STATE_ERROR */ + int type; /* rodzaj sesji. == GG_SESSION_HTTP */ + + int async; /* czy po³±czenie asynchroniczne */ + int pid; /* pid procesu resolvera */ + int port; /* port, z którym siê ³±czymy */ + + char *query; /* bufor zapytania http */ + char *header; /* bufor nag³ówka */ + int header_size; /* rozmiar wczytanego nag³ówka */ + char *body; /* bufor otrzymanych informacji */ + int body_size; /* ilo¶æ informacji */ + void *data; /* dane danej operacji http */ +}; + +/* + * ogólna struktura opisuj±ca ró¿ne sesje. przydatna w klientach. + */ +struct gg_common { + int fd; /* podgl±dany deskryptor */ + int check; /* sprawdzamy zapis czy odczyt */ + int state; /* aktualny stan maszynki */ + int error; /* kod b³êdu dla GG_STATE_ERROR */ + int type; /* rodzaj sesji */ +}; + /* + * rodzaje sesji. + */ +enum { + GG_SESSION_GG = 1, /* po³±czenie z serwerem gg */ + GG_SESSION_HTTP, /* ogólna sesja http */ + GG_SESSION_SEARCH, /* szukanie */ + GG_SESSION_REGISTER, /* rejestrowanie */ +}; + +/* * ró¿ne stany asynchronicznej maszynki. */ - enum { - GG_STATE_IDLE = 0, /* wspólne */ - GG_STATE_RESOLVING, - GG_STATE_CONNECTING_HTTP, +enum { + /* wspólne */ + GG_STATE_IDLE = 0, /* nie powinno wyst±piæ. */ + GG_STATE_RESOLVING, /* wywo³a³ gethostbyname() */ + GG_STATE_CONNECTING, /* wywo³a³ connect() */ + GG_STATE_READING_DATA, /* czeka na dane http */ + GG_STATE_ERROR, /* wyst±pi³ b³±d. kod w x->error */ - GG_STATE_WRITING_HTTP, /* gg_login */ - GG_STATE_CONNECTING_GG, - GG_STATE_WAITING_FOR_KEY, - GG_STATE_SENDING_KEY, - GG_STATE_CONNECTED, + /* gg_session */ + GG_STATE_CONNECTING_GG, /* wywo³a³ connect() */ + GG_STATE_READING_KEY, /* czeka na klucz */ + GG_STATE_READING_REPLY, /* czeka na odpowied¼ */ + GG_STATE_CONNECTED, /* po³±czy³ siê */ - GG_STATE_READING_HEADER, /* gg_search */ - GG_STATE_READING_DATA, - GG_STATE_PARSING, - GG_STATE_FINISHED, - }; + /* gg_http */ + GG_STATE_READING_HEADER, /* czeka na nag³ówek http */ + GG_STATE_PARSING, /* przetwarza dane */ + GG_STATE_DONE, /* skoñczy³ */ +}; /* + * dla zachowania kompatybilno¶ci wstecz. w wersji 1.0 bêdzie usuniête. oby. + */ +#define GG_STATE_WRITING_HTTP GG_STATE_READING_DATA +#define GG_STATE_WAITING_FOR_KEY GG_STATE_READING_KEY +#define GG_STATE_SENDING_KEY GG_STATE_READING_REPLY +#define GG_STATE_FINISHED GG_STATE_DONE + +/* * co proces klienta powinien sprawdzaæ w deskryptorach? */ - enum { - GG_CHECK_NONE = 0, - GG_CHECK_WRITE = 1, - GG_CHECK_READ = 2, - }; +enum { + GG_CHECK_NONE = 0, /* nic. nie powinno wyst±piæ */ + GG_CHECK_WRITE = 1, /* sprawdzamy mo¿liwo¶æ zapisu */ + GG_CHECK_READ = 2, /* sprawdzamy mo¿liwo¶æ odczytu */ +}; - struct gg_session *gg_login(uin_t uin, char *password, int async); - void gg_free_session(struct gg_session *sess); - void gg_logoff(struct gg_session *sess); - int gg_change_status(struct gg_session *sess, int status); - int gg_send_message(struct gg_session *sess, int msgclass, uin_t recipient, - unsigned char *message); - int gg_ping(struct gg_session *sess); +struct gg_session *gg_login(uin_t uin, char *password, int async); +void gg_free_session(struct gg_session *sess); +void gg_logoff(struct gg_session *sess); +int gg_change_status(struct gg_session *sess, int status); +int gg_send_message(struct gg_session *sess, int msgclass, uin_t recipient, unsigned char *message); +int gg_ping(struct gg_session *sess); - struct gg_notify_reply { - uin_t uin; /* numerek */ - unsigned long status; /* status danej osoby */ - unsigned long remote_ip; /* adres ip delikwenta */ - unsigned short remote_port; /* port, na którym s³ucha klient */ - unsigned long dunno1; /* == 0x0b */ - unsigned short dunno2; /* znowu port? */ - } __attribute__ ((packed)); +struct gg_notify_reply { + uin_t uin; /* numerek */ + unsigned long status; /* status danej osoby */ + unsigned long remote_ip; /* adres ip delikwenta */ + unsigned short remote_port; /* port, na którym s³ucha klient */ + unsigned long version; /* == 0x0b */ + unsigned short dunno2; /* znowu port? */ +} __attribute__ ((packed)); - struct gg_status { - uin_t uin; /* numerek */ - unsigned long status; /* nowy stan */ - } __attribute__ ((packed)); +struct gg_status { + uin_t uin; /* numerek */ + unsigned long status; /* nowy stan */ +} __attribute__ ((packed)); - enum { - GG_EVENT_NONE = 0, - GG_EVENT_MSG, - GG_EVENT_NOTIFY, - GG_EVENT_STATUS, - GG_EVENT_ACK, - GG_EVENT_CONN_FAILED, - GG_EVENT_CONN_SUCCESS, - }; +enum { + GG_EVENT_NONE = 0, + GG_EVENT_MSG, + GG_EVENT_NOTIFY, + GG_EVENT_STATUS, + GG_EVENT_ACK, + GG_EVENT_CONN_FAILED, + GG_EVENT_CONN_SUCCESS, +}; - enum { - GG_FAILURE_RESOLVING = 1, - GG_FAILURE_CONNECTING, - GG_FAILURE_INVALID, - GG_FAILURE_READING, - GG_FAILURE_WRITING, - GG_FAILURE_PASSWORD, - }; +/* + * nied³ugo siê tego pozbêdê na rzecz sensownej obs³ugi b³êdów. --w + */ +enum { + GG_FAILURE_RESOLVING = 1, + GG_FAILURE_CONNECTING, + GG_FAILURE_INVALID, + GG_FAILURE_READING, + GG_FAILURE_WRITING, + GG_FAILURE_PASSWORD, + GG_FAILURE_404, +}; - struct gg_event { - int type; - union { - struct { - uin_t sender; - int msgclass; - time_t time; - unsigned char *message; - } msg; - struct gg_notify_reply *notify; - struct gg_status status; - struct { - uin_t recipient; - int status; - int seq; - } ack; - int failure; - } event; - }; +/* + * rodzaje b³êdów, na razie u¿ywane przez http. bez rozczulania siê nad + * powodami. klient powie, ¿e albo nie znalaz³ hosta, albo nie móg³ siê + * po³±czyæ, albo nie móg³ wys³aæ, albo nie móg³ odebrac. i tyle. jak + * kto¶ bêdzie chcia³, to bêdzie móg³ sprawdziæ errno. ale po co? + */ +enum { + GG_ERROR_RESOLVING = 1, + GG_ERROR_CONNECTING, + GG_ERROR_READING, + GG_ERROR_WRITING, +}; - struct gg_event *gg_watch_fd(struct gg_session *sess); - void gg_free_event(struct gg_event *e); +/* + * struktura opisuj±ca rodzaj zdarzenia. wychodzi z gg_watch_fd() + */ +struct gg_event { + int type; + union { + struct { + uin_t sender; + int msgclass; + time_t time; + unsigned char *message; + } msg; + struct gg_notify_reply *notify; + struct gg_status status; + struct { + uin_t recipient; + int status; + int seq; + } ack; + int failure; + } event; +}; - int gg_notify(struct gg_session *sess, uin_t * userlist, int count); - int gg_add_notify(struct gg_session *sess, uin_t uin); - int gg_remove_notify(struct gg_session *sess, uin_t uin); +struct gg_event *gg_watch_fd(struct gg_session *sess); +void gg_free_event(struct gg_event *e); +int gg_notify(struct gg_session *sess, uin_t *userlist, int count); +int gg_add_notify(struct gg_session *sess, uin_t uin); +int gg_remove_notify(struct gg_session *sess, uin_t uin); + + /* - * jakie¶tam bzdurki dotycz±ce szukania userów. + * OBS£UGA HTTP */ - struct gg_search_result { - uin_t uin; - char *first_name; - char *last_name; - char *nickname; - int born; - int gender; - char *city; - int active; - }; +struct gg_http *gg_http_connect(char *hostname, int port, int async, char *method, char *path, char *header); +int gg_http_watch_fd(struct gg_http *h); +void gg_http_stop(struct gg_http *h); +void gg_free_http(struct gg_http *h); - struct gg_search_request { - /* czy ma szukaæ tylko aktywnych? */ - int active; - /* mode 0 */ - char *nickname, *first_name, *last_name, *city; - int gender, min_birth, max_birth; - /* mode 1 */ - char *email; - /* mode 2 */ - char *phone; - /* mode 3 */ - uin_t uin; - }; +/* + * SZUKANIE U¯YTKOWNIKÓW + */ - struct gg_search { - struct gg_search_request request; +/* + * struktura opisuj±ca kryteria wyszukiwania. argument gg_search(). + */ +struct gg_search_request { + int active; /* czy ma szukaæ tylko aktywnych? */ - /* bzdurki */ - int mode, fd, async, state, check, error, pid; - char *header_buf, *data_buf; - int header_size, data_size; + /* mode 0 */ + char *nickname; /* pseudonim */ + char *first_name; /* imiê */ + char *last_name; /* nazwisko */ + char *city; /* miasto */ + int gender; /* p³eæ */ + int min_birth; /* urodzony od roku... */ + int max_birth; /* urodzony do roku... */ + + /* mode 1 */ + char *email; /* adres e-mail */ - /* wyniki */ - int count; - struct gg_search_result *results; - }; + /* mode 2 */ + char *phone; /* numer telefonu */ + + /* mode 3 */ + uin_t uin; /* numerek */ +}; -#define GG_GENDER_NONE 0 -#define GG_GENDER_FEMALE 1 -#define GG_GENDER_MALE 2 +/* + * struktura opisuj±ca rezultat wyszukiwania. pole gg_http. + */ +struct gg_search { + int count; /* ilo¶æ znalezionych */ + struct gg_search_result *results; /* tabelka z nimi */ +}; - struct gg_search *gg_search(struct gg_search_request *r, int async); - int gg_search_watch_fd(struct gg_search *f); - void gg_free_search(struct gg_search *f); - void gg_search_cancel(struct gg_search *f); +/* + * pojedynczy rezultat wyszukiwania. + */ +struct gg_search_result { + uin_t uin; /* numerek */ + char *first_name; /* imiê */ + char *last_name; /* nazwisko */ + char *nickname; /* pseudonim */ + int born; /* rok urodzenia */ + int gender; /* p³eæ */ + char *city; /* miasto */ + int active; /* czy jest aktywny */ +}; + +#define GG_GENDER_NONE 0 /* nie podano lub bez znaczenia */ +#define GG_GENDER_FEMALE 1 /* kobieta */ +#define GG_GENDER_MALE 2 /* mê¿czyzna */ + +struct gg_http *gg_search(struct gg_search_request *r, int async); +int gg_search_watch_fd(struct gg_http *f); +void gg_free_search(struct gg_http *f); + +struct gg_search_request *gg_search_request_mode_0(char *nickname, char *first_name, char *last_name, char *city, int gender, int min_birth, int max_birth, int active); +struct gg_search_request *gg_search_request_mode_1(char *email, int active); +struct gg_search_request *gg_search_request_mode_2(char *phone, int active); +struct gg_search_request *gg_search_request_mode_3(uin_t uin, int active); + +/* + * OPERACJE NA KATALOGU PUBLICZNYM + */ + +struct gg_pubdir { + int success; /* czy siê uda³o */ + uin_t uin; /* otrzymany numerek. 0 je¶li b³±d */ +}; +struct gg_http *gg_register(char *email, char *password, int async); +void gg_free_register(struct gg_http *f); + +int gg_pubdir_watch_fd(struct gg_http *f); +#define gg_register_watch_fd gg_pubdir_watch_fd + /* * je¶li chcemy sobie podebugowaæ, wystarczy ustawiæ `gg_debug_level'. * niestety w miarê przybywania wpisów `gg_debug(...)' nie chcia³o mi * siê ustawiaæ odpowiednich leveli, wiêc wiêkszo¶æ sz³a do _MISC. */ - extern int gg_debug_level; +extern int gg_debug_level; #define GG_DEBUG_NET 1 #define GG_DEBUG_TRAFFIC 2 @@ -219,7 +340,16 @@ #define GG_DEBUG_FUNCTION 8 #define GG_DEBUG_MISC 16 - void gg_debug(int level, char *format, ...); +void gg_debug(int level, char *format, ...); + +/* + * Pare ma³ych zmiennych do obs³ugi "http proxy" + * + */ + +extern int gg_http_use_proxy; +extern char *gg_http_proxy_host; +extern int gg_http_proxy_port; /* * ------------------------------------------------------------------------- @@ -230,41 +360,47 @@ * ------------------------------------------------------------------------- */ - int gg_resolve(int *fd, int *pid, char *hostname); - int gg_connect(void *addr, int port, int async); - char *gg_alloc_sprintf(char *format, ...); - char *gg_get_line(char **ptr); - char *gg_urlencode(char *str); +int gg_resolve(int *fd, int *pid, char *hostname); +void gg_debug(int level, char *format, ...); +char *gg_alloc_sprintf(char *format, ...); +char *gg_get_line(char **ptr); +int gg_connect(void *addr, int port, int async); +void gg_read_line(int sock, char *buf, int length); +void gg_chomp(char *line); +char *gg_urlencode(char *str); +int gg_http_hash(unsigned char *email, unsigned char *password); #define GG_APPMSG_HOST "appmsg.gadu-gadu.pl" #define GG_APPMSG_PORT 80 #define GG_PUBDIR_HOST "pubdir.gadu-gadu.pl" #define GG_PUBDIR_PORT 80 +#define GG_REGISTER_HOST "register.gadu-gadu.pl" +#define GG_REGISTER_PORT 80 #define GG_DEFAULT_PORT 8074 #define GG_HTTPS_PORT 443 #define GG_HTTP_USERAGENT "Mozilla/4.7 [en] (Win98; I)" - struct gg_header { - unsigned long type; /* typ pakietu */ - unsigned long length; /* d³ugo¶æ reszty pakietu */ - } __attribute__ ((packed)); +struct gg_header { + unsigned long type; /* typ pakietu */ + unsigned long length; /* d³ugo¶æ reszty pakietu */ +} __attribute__ ((packed)); #define GG_WELCOME 0x0001 - struct gg_welcome { - unsigned long key; /* klucz szyfrowania has³a */ - } __attribute__ ((packed)); - +struct gg_welcome { + unsigned long key; /* klucz szyfrowania has³a */ +} __attribute__ ((packed)); + #define GG_LOGIN 0x000c - struct gg_login { - uin_t uin; /* twój numerek */ - unsigned long hash; /* hash has³a */ - unsigned long status; /* status na dzieñ dobry */ - unsigned long dunno; /* == 0x0b */ - unsigned long local_ip; /* mój adres ip */ - unsigned short local_port; /* port, na którym s³ucham */ - } __attribute__ ((packed)); +struct gg_login { + uin_t uin; /* twój numerek */ + unsigned long hash; /* hash has³a */ + unsigned long status; /* status na dzieñ dobry */ + unsigned long dunno; /* == 0x0b */ + unsigned long local_ip; /* mój adres ip */ + unsigned short local_port; /* port, na którym s³ucham */ +} __attribute__ ((packed)); #define GG_LOGIN_OK 0x0003 @@ -273,39 +409,39 @@ #define GG_NEW_STATUS 0x0002 #define GG_STATUS_NOT_AVAIL 0x0001 /* roz³±czony */ -#define GG_STATUS_AVAIL 0x0002 /* dostêpny */ -#define GG_STATUS_BUSY 0x0003 /* zajêty */ +#define GG_STATUS_AVAIL 0x0002 /* dostêpny */ +#define GG_STATUS_BUSY 0x0003 /* zajêty */ #define GG_STATUS_INVISIBLE 0x0014 /* niewidoczny (GG 4.6) */ #define GG_STATUS_FRIENDS_MASK 0x8000 /* tylko dla znajomych (GG 4.6) */ - struct gg_new_status { - unsigned long status; /* na jaki zmieniæ? */ - } __attribute__ ((packed)); +struct gg_new_status { + unsigned long status; /* na jaki zmieniæ? */ +} __attribute__ ((packed)); #define GG_NOTIFY 0x0010 - - struct gg_notify { - uin_t uin; /* numerek danej osoby */ - char dunno1; /* == 3 */ - } __attribute__ ((packed)); - + +struct gg_notify { + uin_t uin; /* numerek danej osoby */ + char dunno1; /* == 3 */ +} __attribute__ ((packed)); + #define GG_NOTIFY_REPLY 0x000c /* tak, to samo co GG_LOGIN */ - + /* struct gg_notify_reply zadeklarowane wy¿ej */ #define GG_ADD_NOTIFY 0x000d #define GG_REMOVE_NOTIFY 0x000e - - struct gg_add_remove { - uin_t uin; /* numerek */ - char dunno1; /* == 3 */ - } __attribute__ ((packed)); + +struct gg_add_remove { + uin_t uin; /* numerek */ + char dunno1; /* == 3 */ +} __attribute__ ((packed)); #define GG_STATUS 0x0002 /* struct gg_status zadeklarowane wcze¶niej */ - + #define GG_SEND_MSG 0x000b #define GG_CLASS_QUEUED 0x0001 @@ -313,37 +449,48 @@ #define GG_CLASS_MSG 0x0004 #define GG_CLASS_CHAT 0x0008 - struct gg_send_msg { - unsigned long recipient; - unsigned long seq; - unsigned long msgclass; - } __attribute__ ((packed)); +struct gg_send_msg { + unsigned long recipient; + unsigned long seq; + unsigned long msgclass; +} __attribute__ ((packed)); #define GG_SEND_MSG_ACK 0x0005 #define GG_ACK_DELIVERED 0x0002 #define GG_ACK_QUEUED 0x0003 - - struct gg_send_msg_ack { - unsigned long status; - unsigned long recipient; - unsigned long seq; - } __attribute__ ((packed)); + +struct gg_send_msg_ack { + unsigned long status; + unsigned long recipient; + unsigned long seq; +} __attribute__ ((packed)); #define GG_RECV_MSG 0x000a - - struct gg_recv_msg { - unsigned long sender; - unsigned long seq; - unsigned long time; - unsigned long msgclass; - } __attribute__ ((packed)); + +struct gg_recv_msg { + unsigned long sender; + unsigned long seq; + unsigned long time; + unsigned long msgclass; +} __attribute__ ((packed)); #define GG_PING 0x0008 - + #define GG_PONG 0x0007 #ifdef __cplusplus } -#endif #endif + +#endif /* __GG_LIBGG_H */ + +/* + * Local variables: + * c-indentation-style: k&r + * c-basic-offset: 8 + * indent-tabs-mode: notnil + * End: + * + * vim: shiftwidth=8: + */ |