Nie jestem na bieżąco z rozwojem EKG, więc zamiast commitować, podsyłam skleconego naprędce patcha, który dodaje obsługę połączeń bezpośrednich zgodnych z GG 7.x. Patch zakłada, że przy kompilacji jest brana libgadu z systemu (wymagana wersja cvsowa), nie lokalnych źródeł. Możliwe, że trzeba będzie dodać wykrywanie paru funkcji/stałych do configure, możliwe, że trzeba będzie dać parę #ifdefów. SOA#1 ;)
w.
Index: src/Makefile.in =================================================================== RCS file: /home/cvs/ekg/src/Makefile.in,v retrieving revision 1.49 diff -u -r1.49 Makefile.in --- src/Makefile.in 21 Mar 2007 04:51:07 -0000 1.49 +++ src/Makefile.in 3 Jun 2007 09:24:57 -0000 @@ -10,7 +10,7 @@ sysconfdir = @sysconfdir@ CC = @CC@ -CFLAGS = -I.. -I../lib @CFLAGS@ -DDATADIR=\"${datadir}/ekg\" -DSYSCONFDIR=\"${sysconfdir}\" +CFLAGS = -I.. @CFLAGS@ -DDATADIR=\"${datadir}/ekg\" -DSYSCONFDIR=\"${sysconfdir}\" LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ @@ -28,7 +28,7 @@ ekg: $(OBJS) comptime.c @libgadu_a@ $(CC) $(CFLAGS) -c -o comptime.o comptime.c - $(CC) $(CFLAGS) -o ekg $(OBJS) comptime.o -L../lib @lgadu@ @libgadu_a@ $(LDFLAGS) $(LIBS) + $(CC) $(CFLAGS) -o ekg $(OBJS) comptime.o @lgadu@ @libgadu_a@ $(LDFLAGS) $(LIBS) ioctld: ioctld.c $(CC) $(CFLAGS) ioctld.c -o ioctld $(LIBS) @IOCTLD_OBJS@ Index: src/commands.c =================================================================== RCS file: /home/cvs/ekg/src/commands.c,v retrieving revision 1.775 diff -u -r1.775 commands.c --- src/commands.c 27 Apr 2007 18:52:27 -0000 1.775 +++ src/commands.c 3 Jun 2007 09:24:58 -0000 @@ -2978,7 +2978,7 @@ for (l = transfers; l; l = l->next) { struct transfer *t = l->data; - if (!t->dcc || !t->dcc->established) { + if ((!t->dcc && !t->dcc7) || (t->dcc && !t->dcc->established) || (t->dcc7 && !t->dcc7->established)) { empty = 0; if (!passed) printq("dcc_show_pending_header"); @@ -2986,12 +2986,15 @@ switch (t->type) { case GG_SESSION_DCC_SEND: + case GG_SESSION_DCC7_SEND: printq("dcc_show_pending_send", itoa(t->id), format_user(t->uin), t->filename); break; case GG_SESSION_DCC_GET: + case GG_SESSION_DCC7_GET: printq("dcc_show_pending_get", itoa(t->id), format_user(t->uin), t->filename); break; case GG_SESSION_DCC_VOICE: + case GG_SESSION_DCC7_VOICE: printq("dcc_show_pending_voice", itoa(t->id), format_user(t->uin)); } } @@ -3002,8 +3005,22 @@ for (l = transfers; l; l = l->next) { struct transfer *t = l->data; - if (t->dcc && t->dcc->established) { + if ((t->dcc && t->dcc->established) || (t->dcc7 && t->dcc7->established)) { int eta_m = 0, eta_s = 0, speed_kb = 0; + unsigned int size = 0, offset = 0; + + if (t->dcc) { + size = t->dcc->file_info.size; + offset = t->dcc->offset; + } + + if (t->dcc7) { + size = t->dcc7->size; + offset = t->dcc7->offset; + } + + if (!size) + size = 1; // dzielimy przez size empty = 0; if (!passed) @@ -3019,9 +3036,9 @@ elapsed = cur - t->start; if (elapsed) { - speed = t->dcc->offset / elapsed; - if (t->dcc->offset && t->dcc->offset <= t->dcc->file_info.size) - eta = (t->dcc->file_info.size - t->dcc->offset) * elapsed / t->dcc->offset; + speed = offset / elapsed; + if (offset && offset <= size) + eta = (size - offset) * elapsed / offset; } /* teraz elapsed zawiera czas, który up³yn±³ @@ -3039,24 +3056,29 @@ switch (t->type) { case GG_SESSION_DCC_SEND: + case GG_SESSION_DCC7_SEND: if (speed_kb || eta_m || eta_s) { if (eta_m) - printq("dcc_show_active_send_speed_ms", itoa(t->id), format_user(t->uin), t->filename, itoa(t->dcc->offset), itoa(t->dcc->file_info.size), itoa((float)100*((float)t->dcc->offset/(float)t->dcc->file_info.size)), itoa(speed_kb), itoa(eta_m), itoa(eta_s)); + printq("dcc_show_active_send_speed_ms", itoa(t->id), format_user(t->uin), t->filename, itoa(offset), itoa(size), itoa((float)100*((float)offset/(float)size)), itoa(speed_kb), itoa(eta_m), itoa(eta_s)); else - printq("dcc_show_active_send_speed_s", itoa(t->id), format_user(t->uin), t->filename, itoa(t->dcc->offset), itoa(t->dcc->file_info.size), itoa((float)100*((float)t->dcc->offset/(float)t->dcc->file_info.size)), itoa(speed_kb), itoa(eta_s)); + printq("dcc_show_active_send_speed_s", itoa(t->id), format_user(t->uin), t->filename, itoa(offset), itoa(size), itoa((float)100*((float)offset/(float)size)), itoa(speed_kb), itoa(eta_s)); } else - printq("dcc_show_active_send", itoa(t->id), format_user(t->uin), t->filename, itoa(t->dcc->offset), itoa(t->dcc->file_info.size), itoa((float)100*((float)t->dcc->offset/(float)t->dcc->file_info.size))); + printq("dcc_show_active_send", itoa(t->id), format_user(t->uin), t->filename, itoa(offset), itoa(size), itoa((float)100*((float)offset/(float)size))); break; + case GG_SESSION_DCC_GET: + case GG_SESSION_DCC7_GET: if (speed_kb || eta_m || eta_s) { if (eta_m) - printq("dcc_show_active_get_speed_ms", itoa(t->id), format_user(t->uin), t->filename, itoa(t->dcc->offset), itoa(t->dcc->file_info.size), itoa((float)100*((float)t->dcc->offset/(float)t->dcc->file_info.size)), itoa(speed_kb), itoa(eta_m), itoa(eta_s)); + printq("dcc_show_active_get_speed_ms", itoa(t->id), format_user(t->uin), t->filename, itoa(offset), itoa(size), itoa((float)100*((float)offset/(float)size)), itoa(speed_kb), itoa(eta_m), itoa(eta_s)); else - printq("dcc_show_active_get_speed_s", itoa(t->id), format_user(t->uin), t->filename, itoa(t->dcc->offset), itoa(t->dcc->file_info.size), itoa((float)100*((float)t->dcc->offset/(float)t->dcc->file_info.size)), itoa(speed_kb), itoa(eta_s)); + printq("dcc_show_active_get_speed_s", itoa(t->id), format_user(t->uin), t->filename, itoa(offset), itoa(size), itoa((float)100*((float)offset/(float)size)), itoa(speed_kb), itoa(eta_s)); } else - printq("dcc_show_active_get", itoa(t->id), format_user(t->uin), t->filename, itoa(t->dcc->offset), itoa(t->dcc->file_info.size), itoa((float)100*((float)t->dcc->offset/(float)t->dcc->file_info.size))); + printq("dcc_show_active_get", itoa(t->id), format_user(t->uin), t->filename, itoa(offset), itoa(size), itoa((float)100*((float)offset/(float)size))); break; + case GG_SESSION_DCC_VOICE: + case GG_SESSION_DCC7_VOICE: printq("dcc_show_active_voice", itoa(t->id), format_user(t->uin)); } } @@ -3089,13 +3111,13 @@ printq("not_connected"); return -1; } - + if (!(GG_S_A(u->status) || GG_S_B(u->status)) && !(ignored_check(uin) & IGNORE_STATUS)) { printq("dcc_user_not_avail", format_user(u->uin), (u->first_name) ? u->first_name : u->display); return -1; } - if (!u->ip.s_addr && params[0][0] != 'r') { + if ((u->protocol < 0x2a && !u->ip.s_addr && params[0][0] != 'r') || (u->protocol >= 0x2a && !u->port)) { printq("dcc_user_aint_dcc", format_user(u->uin)); return -1; } @@ -3122,33 +3144,50 @@ if (t.start == -1) t.start = 0; - if (u->port < 10 || !strncasecmp(params[0], "rse", 3)) { - /* nie mo¿emy siê z nim po³±czyæ, wiêc on spróbuje */ - gg_dcc_request(sess, uin); + if (u->protocol < 0x2a) { + if (u->port < 10 || !strncasecmp(params[0], "rse", 3)) { + /* nie mo¿emy siê z nim po³±czyæ, wiêc on spróbuje */ + gg_dcc_request(sess, uin); + } else { + struct gg_dcc *d; + char *remote; + + if (!(d = gg_dcc_send_file(u->ip.s_addr, u->port, config_uin, uin))) { + printq("dcc_error", strerror(errno)); + return -1; + } + + remote = xstrdup(params[2]); + iso_to_cp((unsigned char *) remote); + + if (gg_dcc_fill_file_info2(d, remote, params[2]) == -1) { + printq("dcc_open_error", params[2], strerror(errno)); + gg_free_dcc(d); + xfree(remote); + return -1; + } + + xfree(remote); + + list_add(&watches, d, 0); + + t.dcc = d; + } } else { - struct gg_dcc *d; + struct gg_dcc7 *d; char *remote; - - if (!(d = gg_dcc_send_file(u->ip.s_addr, u->port, config_uin, uin))) { - printq("dcc_error", strerror(errno)); - return -1; - } - remote = xstrdup(params[2]); - iso_to_cp((unsigned char *) remote); - - if (gg_dcc_fill_file_info2(d, remote, params[2]) == -1) { - printq("dcc_open_error", params[2], strerror(errno)); - gg_free_dcc(d); - xfree(remote); + remote = xstrdup(t.filename); + iso_to_cp(remote); + + if (!(d = gg_dcc7_send_file(sess, u->uin, t.filename, remote, NULL))) { + printq("dcc_error", strerror(errno)); return -1; } - xfree(remote); - list_add(&watches, d, 0); - t.dcc = d; + t.dcc7 = d; } list_add(&transfers, &t, sizeof(t)); @@ -3280,16 +3319,27 @@ if (!strncasecmp(params[0], "g", 1) || !strncasecmp(params[0], "re", 2)) { /* get */ struct transfer *t = NULL; unsigned char *path, *tmp; + int fd; + unsigned int offset; for (l = transfers; l; l = l->next) { struct transfer *tt = l->data; struct userlist *u; - if (!tt->dcc || tt->type != GG_SESSION_DCC_GET || !tt->filename) + if (!tt->dcc && !tt->dcc7) + continue; + + if (tt->dcc && tt->type != GG_SESSION_DCC_GET) + continue; + + if (tt->dcc7 && tt->type != GG_SESSION_DCC7_GET) + continue; + + if (!tt->filename) continue; if (!params[1]) { - if (tt->dcc->established) + if ((tt->dcc && tt->dcc->established) || (tt->dcc7 && tt->dcc7->established)) continue; t = tt; @@ -3302,7 +3352,7 @@ } if ((u = userlist_find(tt->uin, NULL))) { - if (tt->dcc->established) + if ((tt->dcc && tt->dcc->established) || (tt->dcc7 && tt->dcc7->established)) continue; if (!strcasecmp(params[1], itoa(u->uin)) || (u->display && !strcasecmp(params[1], u->display))) { @@ -3312,16 +3362,15 @@ } } - if (!t || !t->dcc) { + if (!t || (!t->dcc && !t->dcc7)) { printq("dcc_not_found", (params[1]) ? params[1] : ""); return -1; } for (l = watches; l; l = l->next) { struct gg_common *c = l->data; - struct gg_dcc *d = l->data; - if (c->type == GG_SESSION_DCC_GET && t->dcc == d) { + if ((c->type == GG_SESSION_DCC_GET && t->dcc == l->data) || (c->type == GG_SESSION_DCC7_GET && t->dcc7 == l->data)) { printq("dcc_receiving_already", t->filename, format_user(t->uin)); return -1; } @@ -3339,7 +3388,10 @@ tmp = unique_name(path); if (!tmp) { printq("dcc_get_cant_overwrite", path); - gg_free_dcc(t->dcc); + if (t->dcc) + gg_dcc_free(t->dcc); + if (t->dcc7) + gg_dcc7_free(t->dcc7); list_remove(&transfers, t, 1); xfree(path); return -1; @@ -3350,25 +3402,49 @@ } if (params[0][0] == 'r') { - t->dcc->file_fd = open((char *) path, O_WRONLY); - t->dcc->offset = lseek(t->dcc->file_fd, 0, SEEK_END); - } else - t->dcc->file_fd = open((char *) path, O_WRONLY | O_CREAT, 0600); + fd = open((char *) path, O_WRONLY); + offset = lseek(fd, 0, SEEK_END); + } else { + fd = open((char *) path, O_WRONLY | O_CREAT, 0600); + offset = 0; + } - if (t->dcc->file_fd == -1) { + if (fd == -1) { printq("dcc_get_cant_create", path); - gg_free_dcc(t->dcc); + if (t->dcc) + gg_dcc_free(t->dcc); + if (t->dcc7) { + gg_dcc7_reject(t->dcc7, GG_DCC7_REJECT_USER); + gg_dcc7_free(t->dcc7); + } list_remove(&transfers, t, 1); xfree(path); return -1; } + + if (t->dcc) { + t->dcc->file_fd = fd; + t->dcc->offset = offset; + } + + if (t->dcc7) { + t->dcc7->file_fd = fd; + t->dcc7->offset = offset; + { char buf[256]; sprintf(buf, "%p %d", t->dcc7, t->dcc7->file_fd); print("generic", buf); } + } xfree(path); printq("dcc_get_getting", format_user(t->uin), t->filename); - list_add(&watches, t->dcc, 0); + if (t->dcc) + list_add(&watches, t->dcc, 0); + + if (t->dcc7) { + gg_dcc7_accept(t->dcc7, offset); + list_add(&watches, t->dcc7, 0); + } return 0; } @@ -3403,13 +3479,20 @@ return -1; } + if (t->dcc7) { + if (!t->dcc7->established) + gg_dcc7_reject(t->dcc7, GG_DCC7_REJECT_USER); + list_remove(&watches, t->dcc7, 0); + gg_dcc7_free(t->dcc7); + } + if (t->dcc) { list_remove(&watches, t->dcc, 0); gg_dcc_free(t->dcc); } #ifdef HAVE_VOIP - if (t->type == GG_SESSION_DCC_VOICE) + if (t->type == GG_SESSION_DCC_VOICE || t->type == GG_SESSION_DCC7_VOICE) voice_close(); #endif Index: src/ekg.c =================================================================== RCS file: /home/cvs/ekg/src/ekg.c,v retrieving revision 1.352 diff -u -r1.352 ekg.c --- src/ekg.c 27 Apr 2007 18:52:27 -0000 1.352 +++ src/ekg.c 3 Jun 2007 09:24:59 -0000 @@ -149,6 +149,10 @@ EKG_HANDLER(GG_SESSION_DCC_SEND, handle_dcc, gg_dcc_free) EKG_HANDLER(GG_SESSION_DCC_GET, handle_dcc, gg_dcc_free) EKG_HANDLER(GG_SESSION_DCC_VOICE, handle_dcc, gg_dcc_free) + EKG_HANDLER(GG_SESSION_DCC7_SOCKET, handle_dcc7, gg_dcc7_free) + EKG_HANDLER(GG_SESSION_DCC7_SEND, handle_dcc7, gg_dcc7_free) + EKG_HANDLER(GG_SESSION_DCC7_GET, handle_dcc7, gg_dcc7_free) + EKG_HANDLER(GG_SESSION_DCC7_VOICE, handle_dcc7, gg_dcc7_free) EKG_HANDLER(GG_SESSION_REGISTER, handle_pubdir, gg_register_free) EKG_HANDLER(GG_SESSION_UNREGISTER, handle_pubdir, gg_pubdir_free) EKG_HANDLER(GG_SESSION_PASSWD, handle_pubdir, gg_change_passwd_free) @@ -404,6 +408,7 @@ struct gg_common *c = l->data; struct gg_http *h = l->data; struct gg_dcc *d = l->data; + struct gg_dcc7 *d7 = l->data; static time_t last_check = 0; if (!c || c->timeout == -1 || time(NULL) == last_check) @@ -498,6 +503,32 @@ gg_free_dcc(d); break; } + + case GG_SESSION_DCC7_GET: + case GG_SESSION_DCC7_SEND: + { + struct in_addr addr; + unsigned short port = d7->remote_port; + char *tmp; + + addr.s_addr = d7->remote_addr; + + if (d7->peer_uin) { + struct userlist *u = userlist_find(d7->peer_uin, NULL); + if (!addr.s_addr && u) { + addr.s_addr = u->ip.s_addr; + port = u->port; + } + tmp = saprintf("%s (%s:%d)", format_user(d7->peer_uin), inet_ntoa(addr), port); + } else + tmp = saprintf("%s:%d", inet_ntoa(addr), port); + print("dcc_timeout", tmp); + xfree(tmp); + remove_transfer(d7); + list_remove(&watches, d7, 0); + gg_dcc7_free(d7); + break; + } } break; @@ -1533,6 +1564,7 @@ #endif changed_dcc("dcc"); + changed_dcc("dcc_ip"); #ifdef WITH_PYTHON python_autorun(); Index: src/events.c =================================================================== RCS file: /home/cvs/ekg/src/events.c,v retrieving revision 1.385 diff -u -r1.385 events.c --- src/events.c 27 Apr 2007 18:52:28 -0000 1.385 +++ src/events.c 3 Jun 2007 09:24:59 -0000 @@ -71,7 +71,8 @@ void handle_msg(), handle_ack(), handle_status(), handle_notify(), handle_success(), handle_failure(), handle_search50(), handle_change50(), handle_status60(), handle_notify60(), - handle_userlist(), handle_image_request(), handle_image_reply(); + handle_userlist(), handle_image_request(), handle_image_reply(), + handle_dcc7_new(), handle_dcc7_accept(), handle_dcc7_reject(); static int hide_notavail = 0; /* czy ma ukrywaæ niedostêpnych -- tylko zaraz po po³±czeniu */ @@ -96,6 +97,9 @@ { GG_EVENT_USERLIST, handle_userlist }, { GG_EVENT_IMAGE_REQUEST, handle_image_request }, { GG_EVENT_IMAGE_REPLY, handle_image_reply }, + { GG_EVENT_DCC7_NEW, handle_dcc7_new }, + { GG_EVENT_DCC7_ACCEPT, handle_dcc7_accept }, + { GG_EVENT_DCC7_REJECT, handle_dcc7_reject }, { 0, NULL } }; @@ -2232,18 +2236,18 @@ * * znajduje strukturê ,,transfer'' dotycz±c± danego po³±czenia. * - * - d - struktura gg_dcc, której szukamy. + * - d - struktura gg_dcc lub gg_dcc7, której szukamy. * * wska¼nik do struktury ,,transfer'' lub NULL, je¶li nie znalaz³. */ -static struct transfer *find_transfer(struct gg_dcc *d) +static struct transfer *find_transfer(void *d) { list_t l; for (l = transfers; l; l = l->next) { struct transfer *t = l->data; - if (t->dcc == d) + if (t->dcc == d || t->dcc7 == d) return t; } @@ -2259,7 +2263,7 @@ * * nie zwraca nic. */ -void remove_transfer(struct gg_dcc *d) +void remove_transfer(void *d) { struct transfer *t = find_transfer(d); @@ -2270,6 +2274,60 @@ } /* + * check_dcc_limit() + * + * sprawdza czy nie przekroczono limitu po³±czeñ bezpo¶rednich. je¶li tak, + * wy³±cza je i zwalnia strukturê gg_dcc przekazan± w zdarzeniu. + * + * - e - struktura zdarzenia. + * + * 0/-1. + */ +static int check_dcc_limit(struct gg_event *e) +{ + int c, t = 60; + char *tmp; + + if (!config_dcc_limit) + return 0; + + if ((tmp = strchr(config_dcc_limit, '/'))) + t = atoi(tmp + 1); + + c = atoi(config_dcc_limit); + + if (time(NULL) - dcc_limit_time > t) { + dcc_limit_time = time(NULL); + dcc_limit_count = 0; + } + + dcc_limit_count++; + + if (dcc_limit_count > c) { + print("dcc_limit"); + config_dcc = 0; + changed_dcc("dcc"); + + dcc_limit_time = 0; + dcc_limit_count = 0; + + if (e->type == GG_EVENT_DCC_NEW) { + gg_dcc_free(e->event.dcc_new); + e->event.dcc_new = NULL; + } + + if (e->type == GG_EVENT_DCC7_NEW) { + gg_dcc7_free(e->event.dcc7_new); + e->event.dcc7_new = NULL; + } + + return -1; + } + + return 0; +} + +/* * handle_dcc() * * funkcja zajmuje siê obs³ug± wszystkich zdarzeñ zwi±zanych z DCC. @@ -2303,37 +2361,10 @@ switch (e->type) { case GG_EVENT_DCC_NEW: - gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC_CLIENT_NEW\n"); - - if (config_dcc_limit) { - int c, t = 60; - char *tmp; - - if ((tmp = strchr(config_dcc_limit, '/'))) - t = atoi(tmp + 1); - - c = atoi(config_dcc_limit); - - if (time(NULL) - dcc_limit_time > t) { - dcc_limit_time = time(NULL); - dcc_limit_count = 0; - } + gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC_NEW\n"); - dcc_limit_count++; - - if (dcc_limit_count > c) { - print("dcc_limit"); - config_dcc = 0; - changed_dcc("dcc"); - - dcc_limit_time = 0; - dcc_limit_count = 0; - - gg_dcc_free(e->event.dcc_new); - e->event.dcc_new = NULL; - break; - } - } + if (check_dcc_limit(e) == -1) + break; list_add(&watches, e->event.dcc_new, 0); e->event.dcc_new = NULL; @@ -2578,6 +2609,236 @@ } /* + * handle_dcc7() + * + * funkcja zajmuje siê obs³ug± zdarzeñ zwi±zanych z DCC 7.x. + * + * - d - struktura danego po³±czenia. + * + * nie zwraca niczego. + */ +void handle_dcc7(struct gg_dcc7 *d) +{ + struct gg_event *e; + struct transfer *t; + + if (ignored_check(d->peer_uin) & IGNORE_DCC) { + remove_transfer(d); + list_remove(&watches, d, 0); + gg_dcc7_free(d); + return; + } + + if (!(e = gg_dcc7_watch_fd(d))) { + print("dcc_error", strerror(errno)); + if (d->type != GG_SESSION_DCC7_SOCKET) { + remove_transfer(d); + list_remove(&watches, d, 0); + gg_dcc7_free(d); + } + return; + } + + switch (e->type) { +#if 0 + case GG_EVENT_DCC_CLIENT_ACCEPT: + { + struct userlist *u; + + gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC_CLIENT_ACCEPT\n"); + + if (!(u = userlist_find(d->peer_uin, NULL)) || config_uin != d->uin) { + gg_debug(GG_DEBUG_MISC, "## unauthorized client (uin=%ld), closing connection\n", d->peer_uin); + list_remove(&watches, d, 0); + gg_free_dcc(d); + return; + } + + if (config_dcc_filter && d->remote_addr != u->ip.s_addr) { + char tmp[20]; + + snprintf(tmp, sizeof(tmp), "%s", inet_ntoa(*((struct in_addr*) &d->remote_addr))); + + print("dcc_spoof", format_user(d->peer_uin), inet_ntoa(u->ip), tmp); + } + + t = find_transfer(d); + if (t) { + t->start = time(NULL); + if (t->start == -1) + t->start = 0; + } + + break; + } + + case GG_EVENT_DCC_CALLBACK: + { + int found = 0; + + gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC_CALLBACK\n"); + + for (l = transfers; l; l = l->next) { + struct transfer *t = l->data; + + gg_debug(GG_DEBUG_MISC, "// transfer id=%d, uin=%d, type=%d\n", t->id, t->uin, t->type); + + if (t->uin == d->peer_uin && !t->dcc) { + gg_debug(GG_DEBUG_MISC, "## found transfer, uin=%d, type=%d\n", d->peer_uin, t->type); + t->dcc = d; + gg_dcc_set_type(d, t->type); + found = 1; + break; + } + } + + if (!found) { + gg_debug(GG_DEBUG_MISC, "## connection from %d not found\n", d->peer_uin); + list_remove(&watches, d, 0); + gg_dcc_free(d); + } + + break; + } + + case GG_EVENT_DCC_NEED_FILE_INFO: + gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC_NEED_FILE_INFO\n"); + + for (l = transfers; l; l = l->next) { + struct transfer *t = l->data; + + if (t->dcc == d) { + char *remote; + + remote = xstrdup(t->filename); + iso_to_cp(remote); + + if (gg_dcc_fill_file_info2(d, remote, t->filename) == -1) { + gg_debug(GG_DEBUG_MISC, "## gg_dcc_fill_file_info() failed (%s)\n", strerror(errno)); + print("dcc_open_error", t->filename); + remove_transfer(d); + list_remove(&watches, d, 0); + gg_free_dcc(d); + xfree(remote); + break; + } + + xfree(remote); + + break; + } + } + break; + + case GG_EVENT_DCC_NEED_VOICE_ACK: + gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC_NEED_VOICE_ACK\n"); +#ifdef HAVE_VOIP + /* ¿eby nie sprawdza³o, póki luser nie odpowie */ + list_remove(&watches, d, 0); + + if (!(t = find_transfer(d))) { + tt.uin = d->peer_uin; + tt.type = GG_SESSION_DCC_VOICE; + tt.filename = NULL; + tt.dcc = d; + tt.id = transfer_id(); + if (!(t = list_add(&transfers, &tt, sizeof(tt)))) { + gg_free_dcc(d); + break; + } + } + + t->type = GG_SESSION_DCC_VOICE; + + print("dcc_voice_offer", format_user(t->uin), itoa(t->id)); +#else + list_remove(&watches, d, 0); + remove_transfer(d); + gg_free_dcc(d); +#endif + break; + + case GG_EVENT_DCC_VOICE_DATA: + gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC_VOICE_DATA\n"); + +#ifdef HAVE_VOIP + voice_open(); + voice_play(e->event.dcc_voice_data.data, e->event.dcc_voice_data.length, 0); +#endif + break; + +#endif + case GG_EVENT_DCC7_DONE: + gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC7_DONE\n"); + + if (!(t = find_transfer(d))) { + gg_dcc7_free(d); + break; + } + + event_check(EVENT_DCCFINISH, t->uin, t->filename); + + print((t->dcc7->type == GG_SESSION_DCC7_SEND) ? "dcc_done_send" : "dcc_done_get", format_user(t->uin), t->filename); + + remove_transfer(d); + list_remove(&watches, d, 0); + gg_dcc7_free(d); + + break; + + case GG_EVENT_DCC7_ERROR: + { + struct in_addr addr; + unsigned short port = d->remote_port; + char *tmp; + + addr.s_addr = d->remote_addr; + + if (d->peer_uin) { + struct userlist *u = userlist_find(d->peer_uin, NULL); + if (!addr.s_addr && u) { + addr.s_addr = u->ip.s_addr; + port = u->port; + } + tmp = saprintf("%s (%s:%d)", format_user(d->peer_uin), inet_ntoa(addr), port); + } else + tmp = saprintf("%s:%d", inet_ntoa(addr), port); + + switch (e->event.dcc7_error) { + case GG_ERROR_DCC7_HANDSHAKE: + print("dcc_error_handshake", tmp); + break; + case GG_ERROR_DCC7_NET: + print("dcc_error_network", tmp); + break; + case GG_ERROR_DCC7_REFUSED: + print("dcc_error_refused", tmp); + break; + default: + print("dcc_error_unknown", tmp); + } + + xfree(tmp); + +#ifdef HAVE_VOIP + if (d->type == GG_SESSION_DCC7_VOICE) + voice_close(); +#endif /* HAVE_VOIP */ + + remove_transfer(d); + list_remove(&watches, d, 0); + gg_dcc7_free(d); + + break; + } + } + + gg_event_free(e); + + return; +} + +/* * handle_voice() * * obs³uga danych przychodz±cych z urz±dzenia wej¶ciowego. @@ -2928,3 +3189,116 @@ print("user_is_connected", format_user(e->event.image_reply.sender), itoa(e->event.image_reply.sender)); } } + +/* + * handle_dcc7_new() + * + * obs³uguje nowe po³±czenie dcc. + * + * - e - opis zdarzenia + */ +void handle_dcc7_new(struct gg_event *e) +{ + struct gg_dcc7 *dcc = e->event.dcc7_new; + struct transfer t; + + if (!config_dcc) { + gg_dcc7_reject(dcc, GG_DCC7_REJECT_USER); + gg_dcc7_free(dcc); + e->event.dcc7_new = NULL; + return; + } + + if (check_dcc_limit(e) == -1) + return; + + memset(&t, 0, sizeof(t)); + t.id = transfer_id(); + t.uin = dcc->peer_uin; + t.dcc7 = dcc; + + switch (dcc->dcc_type) { + case GG_DCC7_TYPE_FILE: + { + struct stat st; + char *path; + + t.type = GG_SESSION_DCC7_GET; + t.filename = xstrdup(dcc->filename); + cp_to_iso(t.filename); + fix_filename(t.filename); + + print("dcc_get_offer", format_user(t.uin), t.filename, itoa(dcc->size), itoa(t.id)); + + if (config_dcc_dir) + path = saprintf("%s/%s", config_dcc_dir, t.filename); + else + path = xstrdup(t.filename); + + if (!stat(path, &st) && st.st_size < dcc->size) + print("dcc_get_offer_resume", format_user(t.uin), t.filename, itoa(dcc->size), itoa(t.id)); + + xfree(path); + + break; + } + + case GG_DCC7_TYPE_VOICE: +#ifdef HAVE_VOIP + t.type = GG_SESSION_DCC7_VOICE; + + print("dcc_voice_offer", format_user(t.uin), itoa(t.id)); + break; +#else + gg_dcc7_free(dcc); + e->event.dcc7_new = NULL; + return; +#endif + + default: + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_handle_dcc7_new() unknown type %d\n", dcc->type); + + } + + list_add(&transfers, &t, sizeof(t)); + + if (!(ignored_check(t.uin) & IGNORE_EVENTS)) + event_check(EVENT_DCC, t.uin, t.filename); +} + +/* + * handle_dcc7_accept() + * + * obs³uguje akceptacjê po³±czenia dcc. + * + * - e - opis zdarzenia + */ +void handle_dcc7_accept(struct gg_event *e) +{ + + +} + +/* + * handle_dcc7_reject() + * + * obs³uguje odrzucenie po³±czenia dcc. + * + * - e - opis zdarzenia + */ +void handle_dcc7_reject(struct gg_event *e) +{ + struct gg_dcc7 *d = e->event.dcc7_accept.dcc7; + + print("dcc_error_refused", format_user(d->peer_uin)); + +#ifdef HAVE_VOIP + if (d->type == GG_SESSION_DCC7_VOICE) + voice_close(); +#endif /* HAVE_VOIP */ + + remove_transfer(d); + list_remove(&watches, d, 0); + gg_dcc7_free(d); +} + Index: src/events.h =================================================================== RCS file: /home/cvs/ekg/src/events.h,v retrieving revision 1.22 diff -u -r1.22 events.h --- src/events.h 18 Feb 2005 14:06:17 -0000 1.22 +++ src/events.h 3 Jun 2007 09:24:59 -0000 @@ -1,4 +1,4 @@ -/* $Id: events.h,v 1.22 2005-02-18 14:06:17 szalik Exp $ */ +/* $Id: events.h,v 1.22 2005/02/18 14:06:17 szalik Exp $ */ /* * (C) Copyright 2001-2002 Wojtek Kaniewski <[EMAIL PROTECTED]> @@ -31,6 +31,7 @@ void handle_event(struct gg_session *s); void handle_dcc(struct gg_dcc *s); +void handle_dcc7(struct gg_dcc7 *s); void handle_msg(struct gg_event *e); void handle_voice(struct gg_common *c); @@ -41,7 +42,7 @@ void print_message(struct gg_event *e, struct userlist *u, int chat, int secure); -void remove_transfer(struct gg_dcc *d); +void remove_transfer(void *d); void handle_common(uin_t uin, int status, const char *idescr, int dtime, uint32_t ip, uint16_t port, int version, int image_size); Index: src/stuff.c =================================================================== RCS file: /home/cvs/ekg/src/stuff.c,v retrieving revision 1.462 diff -u -r1.462 stuff.c --- src/stuff.c 27 Apr 2007 18:52:28 -0000 1.462 +++ src/stuff.c 3 Jun 2007 09:25:00 -0000 @@ -53,7 +53,7 @@ #include <unistd.h> #include "commands.h" -#include "compat.h" +#include "../compat/sunos.h" #include "dynstuff.h" #include "libgadu.h" #ifdef HAVE_OPENSSL Index: src/stuff.h =================================================================== RCS file: /home/cvs/ekg/src/stuff.h,v retrieving revision 1.288 diff -u -r1.288 stuff.h --- src/stuff.h 27 Apr 2007 18:52:28 -0000 1.288 +++ src/stuff.h 3 Jun 2007 09:25:00 -0000 @@ -100,6 +100,7 @@ uin_t uin; char *filename; struct gg_dcc *dcc; + struct gg_dcc7 *dcc7; time_t start; int type; int id; Index: src/themes.c =================================================================== RCS file: /home/cvs/ekg/src/themes.c,v retrieving revision 1.349 diff -u -r1.349 themes.c --- src/themes.c 8 May 2007 21:01:26 -0000 1.349 +++ src/themes.c 3 Jun 2007 09:25:01 -0000 @@ -1274,6 +1274,7 @@ format_add("dcc_spoof", "%! %|U¿ytkownik %1 poda³ serwerowi adres %T%2%n, ale po³±czy³ siê z nami z adresu %T%3%n. Mo¿liwe, ¿e kto¶ próbuje siê pod niego podszyæ. Zachowaj ostro¿no¶æ!\n", 1); format_add("dcc_limit", "%! %|Przekroczono limit bezpo¶rednich po³±czeñ i dla bezpieczeñstwa zosta³y one wy³±czone. Aby je w³±czyæ ponownie, nale¿y wpisaæ polecenie %Tset dcc 1%n i po³±czyæ siê ponownie. Limit mo¿na zmieniæ za pomoc± zmiennej %Tdcc_limit%n.\n", 1); format_add("dcc_create_error", "%! Nie mo¿na w³±czyæ po³±czeñ bezpo¶rednich: %1\n", 1); + format_add("dcc_error", "%! B³±d transmisji: %1\n", 1); format_add("dcc_error_network", "%! B³±d transmisji z %1\n", 1); format_add("dcc_error_refused", "%! Po³±czenie z %1 zosta³o odrzucone\n", 1); format_add("dcc_error_unknown", "%! Nieznany b³±d po³±czenia bezpo¶redniego\n", 1);
_______________________________________________ libgadu-devel mailing list libgadu-devel@lists.ziew.org http://lists.ziew.org/mailman/listinfo/libgadu-devel