int main(int argc, char **argv) { struct gg_session *gs; struct gg_login_params glp; struct gg_dcc7 *gd = NULL; time_t ping = 0, last = 0; int once = 0; if (argc != 2) usage(argv[0]); /* strtol() ? */ if (!(argv[1][0] >= '0' && argv[1][0] <= '9')) usage(argv[0]); if (atoi(argv[1]) >= TEST_MODE_LAST) usage(argv[0]); test_mode = atoi(argv[1]); signal(SIGPIPE, SIG_IGN); gg_debug_file = stdout; gg_debug_level = ~0; if (config_read() == -1 || config_peer == 0) { perror("config"); exit(1); } memset(&glp, 0, sizeof(glp)); glp.uin = config_uin; glp.password = config_password; glp.async = 1; glp.status = GG_STATUS_AVAIL; #if 0 glp.client_addr = config_ip; glp.client_port = config_port; #endif glp.protocol_version = 0x2a; glp.has_audio = 1; glp.last_sysmsg = -1; gg_dcc_ip = config_ip; debug("Connecting...\n"); if (!(gs = gg_login(&glp))) { perror("gg_login"); exit(1); } for (;;) { fd_set rds, wds; struct timeval tv; time_t now; int res, maxfd = -1; FD_ZERO(&rds); FD_ZERO(&wds); tv.tv_sec = 1; tv.tv_usec = 0; maxfd = gs->fd; if ((gs->check & GG_CHECK_READ)) FD_SET(gs->fd, &rds); if ((gs->check & GG_CHECK_WRITE)) FD_SET(gs->fd, &wds); if (gd && gd->fd != -1) { if (gd->fd > maxfd) maxfd = gd->fd; if ((gd->check & GG_CHECK_READ)) FD_SET(gd->fd, &rds); if ((gd->check & GG_CHECK_WRITE)) FD_SET(gd->fd, &wds); } if (voice_fd != -1) { FD_SET(voice_fd, &rds); if (voice_fd > maxfd) maxfd = voice_fd; } if ((res = select(maxfd + 1, &rds, &wds, NULL, &tv)) == -1) { if (errno == EINTR) continue; perror("select"); exit(1); } now = time(NULL); if (last != now) { if (gs->timeout != -1 && gs->timeout-- == 0 && !gs->soft_timeout) { debug("Timeout\n"); exit(1); } /* vvvv XXX */ if (gd && gd->timeout && gd->timeout != -1 && gd->timeout-- == 0 && !gd->soft_timeout) { debug("Timeout\n"); exit(1); } last = now; } if (gs->state == GG_STATE_CONNECTED && ping && now - ping > 60) { ping = now; gg_ping(gs); } if (FD_ISSET(gs->fd, &rds) || FD_ISSET(gs->fd, &wds) || (gs->timeout == 0 && gs->soft_timeout)) { struct gg_event *ge; uin_t uin; int status; if (!(ge = gg_watch_fd(gs))) { debug("Connection broken\n"); exit(1); } switch (ge->type) { case GG_EVENT_CONN_SUCCESS: debug("Connected\n"); connected = 1; gg_notify(gs, &config_peer, 1); ping = time(NULL); break; case GG_EVENT_CONN_FAILED: debug("Connection failed\n"); exit(1); case GG_EVENT_NONE: break; case GG_EVENT_MSG: debug("Message from %d: %s\n", ge->event.msg.sender, ge->event.msg.message); break; case GG_EVENT_DISCONNECT: debug("Forced to disconnect\n"); exit(1); case GG_EVENT_NOTIFY60: uin = ge->event.notify60[0].uin; status = ge->event.notify60[0].status; /* fall-through */ case GG_EVENT_STATUS60: if (ge->type == GG_EVENT_STATUS60) { uin = ge->event.status60.uin; status = ge->event.status60.status; } if (!once && uin == config_peer && (GG_S_A(status) || GG_S_B(status)) && test_mode == TEST_MODE_SEND) { debug("Sending voice request...\n"); if (voice_open_ext("/dev/dsp", 8000, 16, 2, EKG_CODEC_GSM) == -1) { printf("voice_open_ext('/dev/dsp', " "8000, 16, 2, CODEC_GSM) failed\n"); exit(1); } printf("+OK\n"); gd = gg_dcc7_voice_chat(gs, config_peer, 0x00); if (!gd) { perror("gg_dcc7_voice_chat"); exit(1); } once = 1; } gg_change_status(gs, GG_STATUS_AVAIL); /* XXX, libgadu sobie nie radzi */ break; case GG_EVENT_DCC7_NEW: debug("Incoming direct connection\n"); if (test_mode == TEST_MODE_RECEIVE) { gd = ge->event.dcc7_new; if (voice_open_ext("/dev/dsp", 8000, 16, 2, EKG_CODEC_GSM) == -1) { printf("voice_open_ext('/dev/dsp', " "8000, 16, 2, CODEC_GSM) failed\n"); exit(1); } printf("+OK\n"); gg_dcc7_accept_voice(gd, 0x00); } break; case GG_EVENT_DCC7_ERROR: debug("Direct connection error\n"); exit(1); case GG_EVENT_DCC7_ACCEPT: debug("Accepted\n"); break; case GG_EVENT_DCC7_REJECT: debug("Rejected\n"); exit(1); default: debug("Unsupported event %d\n", ge->type); break; } gg_event_free(ge); } if (gd && gd->fd != -1 && (FD_ISSET(gd->fd, &rds) || FD_ISSET(gd->fd, &wds) || (gd->timeout == 0 && gd->soft_timeout))) { struct gg_event *ge; if (!(ge = gg_dcc7_watch_fd(gd))) { debug("Direct connection broken\n"); exit(1); } switch (ge->type) { case GG_EVENT_DCC7_ERROR: debug("Direct connection error\n"); exit(1); case GG_EVENT_DCC7_CONNECTED: debug("Direct connection established\n"); break; case GG_EVENT_DCC7_DONE: debug("Finished"); gg_event_free(ge); gg_dcc7_free(gd); gg_free_session(gs); config_free(); exit(1); case GG_EVENT_DCC7_VOICE_DATA: gg_debug(GG_DEBUG_MISC, "## GG_EVENT_DCC7_VOICE_DATA [%u]\n", ge->event.dcc7_voice_data.length); printf("## GG_EVENT_DCC7_VOICE_DATA [%u]\n", ge->event.dcc7_voice_data.length); if (voice_fd == -1) { printf("voice_fd == -1\n"); exit(1); } if (ge->event.dcc7_voice_data.length == GG_DCC7_VOICE_FRAME_GSM_LENGTH) voice_play(ge->event.dcc7_voice_data.data, ge->event.dcc7_voice_data.length, EKG_CODEC_GSM); else if (ge->event.dcc7_voice_data.length == GG_DCC7_VOICE_FRAME_SPEEX_LENGTH) voice_play(ge->event.dcc7_voice_data.data, ge->event.dcc7_voice_data.length, EKG_CODEC_SPEEX); else if (ge->event.dcc7_voice_data.length == GG_DCC7_VOICE_FRAME_MELP_LENGTH) voice_play(ge->event.dcc7_voice_data.data, ge->event.dcc7_voice_data.length, EKG_CODEC_MELP); break; case GG_EVENT_NONE: break; default: debug("Unsupported event %d\n", ge->type); break; } gg_event_free(ge); } if (voice_fd != -1 && FD_ISSET(voice_fd, &rds)) { char buf[GG_DCC_VOICE_FRAME_LENGTH]; /* dłuższy z buforów */ int length = GG_DCC_VOICE_FRAME_LENGTH; if (gd) { if (gd->state == GG_STATE_READING_VOICE_DATA) { /* XXX, implementowac speex */ length = GG_DCC7_VOICE_FRAME_GSM_LENGTH; voice_record(buf, length, EKG_CODEC_GSM); if (1) gg_dcc7_voice_send(gd, buf, length); else { /* ten pakiet mamy wysylac co 1s */ gg_dcc7_voice_mic_off(gd); } } else voice_record(buf, length, EKG_CODEC_NONE); } else voice_record(buf, length, EKG_CODEC_NONE); } } if (gg_debug_file != stdout) /* w sumie stdout, tez moglibysmy zamknac.. czemu nie. */ fclose(gg_debug_file); return 0; }
int main(int argc, char **argv) { struct gg_login_params glp; struct gg_session *gs; time_t last = 0; int hide_sysmsg = 0; int ch; gg_debug_level = 255; memset(&glp, 0, sizeof(glp)); glp.async = 1; config_read(); while ((ch = getopt(argc, argv, "DShHLs:p:l:y")) != -1) { switch (ch) { case 'D': gg_debug_level = 0; break; case 'S': glp.async = 0; break; case 'L': glp.tls = 1; break; case 's': free(config_server); config_server = strdup(optarg); break; case 'p': free(config_proxy); config_proxy = strdup(optarg); break; case 'H': gg_proxy_http_only = 1; break; case 'l': glp.last_sysmsg = atoi(optarg); break; case 'h': usage(argv[0]); return 0; case 'y': hide_sysmsg = 1; break; default: usage(argv[0]); return 1; } } if (argc - optind >= 1) { config_uin = atoi(argv[optind]); optind++; if (argc - optind >= 1) { free(config_password); config_password = strdup(argv[optind]); } } if (config_uin == 0 || config_password == NULL) { usage(argv[0]); return 1; } if (config_server != NULL) { char *host; int port; parse_address(config_server, &host, &port); glp.server_addr = inet_addr(host); glp.server_port = port; free(host); } if (config_proxy != NULL) { char *host; int port; parse_address(optarg, &host, &port); gg_proxy_enabled = 1; gg_proxy_host = host; gg_proxy_port = port; free(config_proxy); } glp.uin = config_uin; glp.password = config_password; signal(SIGINT, sigint); gs = gg_login(&glp); if (gs == NULL) { perror("gg_login"); free(gg_proxy_host); return 1; } for (;;) { struct timeval tv; fd_set rd, wd; int ret, fd, check; time_t now; if (disconnect_flag) { gg_change_status(gs, GG_STATUS_NOT_AVAIL); disconnect_flag = 0; } FD_ZERO(&rd); FD_ZERO(&wd); fd = gs->fd; check = gs->check; if ((check & GG_CHECK_READ)) FD_SET(fd, &rd); if ((check & GG_CHECK_WRITE)) FD_SET(fd, &wd); tv.tv_sec = 1; tv.tv_usec = 0; ret = select(fd + 1, &rd, &wd, NULL, &tv); if (ret == -1) { if (errno == EINTR) continue; perror("select"); break; } now = time(NULL); if (now != last) { if (gs->timeout != -1 && gs->timeout-- == 0 && !gs->soft_timeout) { printf("Timeout!\n"); break; } } if (gs != NULL && (FD_ISSET(fd, &rd) || FD_ISSET(fd, &wd) || (gs->timeout == 0 && gs->soft_timeout))) { struct gg_event *ge; ge = gg_watch_fd(gs); if (ge == NULL) { printf("Connection broken!\n"); break; } if (ge->type == GG_EVENT_CONN_SUCCESS) { printf("Connected (press Ctrl-C to disconnect)\n"); gg_notify(gs, NULL, 0); } if (ge->type == GG_EVENT_CONN_FAILED) { printf("Connection failed!\n"); gg_event_free(ge); break; } if (ge->type == GG_EVENT_DISCONNECT_ACK) { printf("Connection closed\n"); gg_event_free(ge); break; } if (ge->type == GG_EVENT_MSG) { if (ge->event.msg.sender != 0 || !hide_sysmsg) printf("Received message from %d:\n- plain text: %s\n- html: %s\n", ge->event.msg.sender, ge->event.msg.message, ge->event.msg.xhtml_message); } gg_event_free(ge); } } free(gg_proxy_host); gg_free_session(gs); config_free(); return 0; }
int session_io_handler(Session *s){ struct gg_event *event; char *jid,*str; int chat; GIOCondition condition=s->g_pollfd.revents; time_t timestamp; gboolean state; user_load_locale(s->user); debug(L_("Checking error conditions...")); if (condition&(G_IO_ERR|G_IO_NVAL)){ if (condition&G_IO_ERR) g_warning(N_("Error on connection for %s, GGid: %i"),s->jid,s->ggs->uin); if (condition&G_IO_HUP){ g_warning(N_("Hangup on connection for %s, GGid: %i"),s->jid,s->ggs->uin); return session_error(s); } if (condition&G_IO_NVAL) g_warning(N_("Invalid channel on connection for %s"),s->jid); session_broken(s); return FALSE; } debug(L_("watching fd (gg_debug_level=%i)..."),gg_debug_level); event=gg_watch_fd(s->ggs); if (!event){ g_warning(N_("Connection broken. Session of %s, GGid: %i"),s->jid,s->ggs->uin); return session_error(s); } switch(event->type){ case GG_EVENT_DISCONNECT: g_warning(N_("Server closed connection of %s, GGid: %i"),s->jid,s->ggs->uin); session_error(s); gg_event_free(event); return FALSE; case GG_EVENT_CONN_FAILED: g_message(N_("Login failed (%d:%s) for %s, GGid: %i"), event->event.failure, (event->event.failure>GG_FAILURE_NUM_REASONS||event->event.failure<1)?"-UNKNOWN-":gg_failure_reason[event->event.failure-1], s->jid, s->ggs->uin); if (s->req_id) jabber_iq_send_error(s->s,s->jid,NULL,s->req_id,401,_("Unauthorized")); else { str=g_strdup(from_utf8(gg_failure_reason_txt[event->event.failure-1])); presence_send(s->s,NULL,s->user->jid,0,NULL,str,0); g_free(str); } state = FALSE; if (!s->req_id) switch(event->event.failure){ case GG_FAILURE_RESOLVING: case GG_FAILURE_CONNECTING: case GG_FAILURE_INVALID: case GG_FAILURE_READING: case GG_FAILURE_WRITING: case GG_FAILURE_TLS: state = session_try_next(s); default: break; } if (state) { s->connected=0; session_schedule_reconnect(s); } else session_remove(s); gg_event_free(event); return FALSE; case GG_EVENT_CONN_SUCCESS: g_message(L_("Login succeed for %s, GGid: %i"),s->jid,s->ggs->uin); if (s->req_id) jabber_iq_send_result(s->s,s->jid,NULL,s->req_id,NULL); if (s->req_id){ g_free(s->req_id); s->req_id=NULL; } if (s->query){ xmlnode_free(s->query); s->query=NULL; } if (!s->user->confirmed){ s->user->confirmed=1; user_save(s->user); } s->connected=1; session_send_status(s); session_send_notify(s); presence_send(s->s,NULL,s->user->jid,s->user->invisible?-1:1,NULL,s->gg_status_descr,0); if (s->timeout_func) g_source_remove(s->timeout_func); s->timeout_func=NULL; if (s->ping_timeout_func) g_source_remove(s->ping_timeout_func); s->ping_timeout_func=g_timeout_add(ping_interval*1000,session_ping,s); if (s->pubdir_change){ add_request(RT_CHANGE,s->jid,NULL,s->req_id, NULL,s->pubdir_change,s->s); gg_pubdir50_free(s->pubdir_change); s->pubdir_change=NULL; } if (s->get_roster){ gg_userlist_request(s->ggs, GG_USERLIST_GET, NULL); } break; case GG_EVENT_NOTIFY: session_event_notify(s,event); break; case GG_EVENT_NOTIFY_DESCR: session_event_notify_descr(s,event); break; case GG_EVENT_NOTIFY60: session_event_notify60(s,event); break; case GG_EVENT_STATUS: session_event_status(s, event->event.status.status, event->event.status.uin, event->event.status.descr, 0,0,0,0); break; case GG_EVENT_STATUS60: session_event_status(s, event->event.status60.status, event->event.status60.uin, event->event.status60.descr, 1, event->event.status60.remote_ip, event->event.status60.remote_port, event->event.status60.version); break; case GG_EVENT_MSG: if (event->event.msg.recipients_count>1){ debug(L_("Dropped conference message: sender: %i class: %i time: %lu"), event->event.msg.sender, event->event.msg.msgclass, (unsigned long)event->event.msg.time); break; } gg_messages_in++; debug(L_("Message: sender: %i class: %i time: %lu"), event->event.msg.sender, event->event.msg.msgclass, (unsigned long)event->event.msg.time); if (event->event.msg.sender==0){ if (!user_sys_msg_received(s->user,event->event.msg.msgclass)) break; if (ignore_system_messages == ISM_IGNORE_ALL) break; if (ignore_system_messages == ISM_IGNORE_HTML && strstr((const char *)event->event.msg.message, "<HTML>")) break; timestamp=event->event.msg.time; str=g_strdup_printf(_("GG System message #%i"), event->event.msg.msgclass); message_send_subject(s->s,jid, s->user->jid, str, string_from_gg((const char *)event->event.msg.message), timestamp); g_free(str); break; } else{ Contact *c=user_get_contact(s->user, event->event.msg.sender,0); if ((!c && s->user->ignore_unknown) || (c && c->ignored)) { debug(L_("Ignoring the message.")); break; } jid=jid_build_full(event->event.msg.sender); if ((event->event.msg.msgclass&GG_CLASS_CHAT)!=0) chat=1; else chat=0; } if ((event->event.msg.msgclass&GG_CLASS_QUEUED)!=0){ timestamp=event->event.msg.time; } else timestamp=0; if(event->event.msg.formats_length>0) message_send_rich(s->s,jid,s->user->jid,chat, (char *)event->event.msg.message,timestamp, event->event.msg.formats_length,(void *)event->event.msg.formats); else message_send(s->s,jid,s->user->jid,chat, string_from_gg((const char *)event->event.msg.message),timestamp); g_free(jid); break; case GG_EVENT_PONG: s->waiting_for_pong=FALSE; if (s->ping_timer){ g_timer_stop(s->ping_timer); debug(L_("Pong! ping time: %fs"), g_timer_elapsed(s->ping_timer,NULL)); } if (s->timeout_func) g_source_remove(s->timeout_func); s->timeout_func=NULL; break; case GG_EVENT_PUBDIR50_SEARCH_REPLY: request_response_search(event); break; case GG_EVENT_PUBDIR50_WRITE: request_response_write(event); break; case GG_EVENT_ACK: debug("GG_EVENT_ACK"); break; case GG_EVENT_NONE: debug("GG_EVENT_NONE"); break; case GG_EVENT_USERLIST: if(event->event.userlist.type==GG_USERLIST_GET_REPLY) get_roster_done(s,event); else g_warning(N_("Wrong gg userlist type: %i"),event->event.userlist.type); break; default: g_warning(N_("Unknown GG event: %i"),event->type); break; } session_setup_g_source(s); gg_event_free(event); debug(L_("io handler done...")); return FALSE; }
static int test(int resolver, int delay) { struct gg_session *gs; struct gg_login_params glp; int loops = 0; delay_flag = delay; connect_flag = 0; memset(&glp, 0, sizeof(glp)); glp.uin = 1; glp.password = ""; glp.resolver = resolver; glp.async = 1; gs = gg_login(&glp); if (gs == NULL) return 0; if (!delay_flag) { for (loops = 0; loops < 5; loops++) { struct gg_event *ge; struct timeval tv; fd_set fds; FD_ZERO(&fds); FD_SET(gs->fd, &fds); tv.tv_sec = 1; tv.tv_usec = 0; if (select(gs->fd + 1, &fds, NULL, NULL, &tv) == -1) { if (errno == EAGAIN) continue; gg_free_session(gs); return 0; } ge = gg_watch_fd(gs); if (ge == NULL) { gg_free_session(gs); return 0; } if (ge->type == GG_EVENT_CONN_FAILED) { gg_event_free(ge); gg_free_session(gs); return 0; } if (gs->hub_addr != 0 && gs->hub_addr != inet_addr(LOCALHOST)) { struct in_addr hub_addr; hub_addr.s_addr = gs->hub_addr; printf("gethostbyname hook failed %s != %s\n", LOCALHOST, inet_ntoa(hub_addr)); gg_event_free(ge); gg_free_session(gs); return 0; } gg_event_free(ge); if (connect_flag == 1) break; } } else { sleep(1); } gg_free_session(gs); if (loops == 5) { printf("timeout\n"); return 0; } return 1; }
int main(int argc, char **argv) { struct gg_session *gs; struct gg_login_params glp; struct gg_dcc7 *gd = NULL; time_t ping = 0, last = 0; int fds[2] = { -1, -1 }; if (argc != 2 || atoi(argv[1]) >= TEST_MODE_LAST) { fprintf(stderr, "usage: %s <mode>\n" "\n" "mode: 0 - send file\n" " 1 - send file, simulate NAT\n" " 2 - receive file\n" " 3 - receive file, simulate NAT\n" " 4 - receive file, resume at the end\n" "\n", argv[0]); exit(1); } test_mode = atoi(argv[1]); if (config_read() == -1 || config_peer == 0) { perror("config"); exit(1); } #ifdef _WIN32 gg_win32_init_network(); gg_win32_hook(connect, my_connect, &connect_hook); #else signal(SIGPIPE, SIG_IGN); #endif gg_debug_file = stdout; gg_debug_level = ~0; if (!config_file && socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) == -1) { perror("pipe"); exit(1); } memset(&glp, 0, sizeof(glp)); glp.uin = config_uin; glp.password = config_password; glp.async = 1; glp.client_addr = config_ip; glp.client_port = config_port; glp.protocol_version = GG_PROTOCOL_VERSION_100; if (config_dir && (test_mode == TEST_MODE_RECEIVE || test_mode == TEST_MODE_RECEIVE_NAT || test_mode == TEST_MODE_RECEIVE_RESUME)) { if (chdir(config_dir) == -1) { perror("chdir"); exit(1); } } debug("Connecting...\n"); if (!(gs = gg_login(&glp))) { perror("gg_login"); exit(1); } for (;;) { fd_set rds, wds; struct timeval tv; time_t now; int res, maxfd = -1; FD_ZERO(&rds); FD_ZERO(&wds); tv.tv_sec = 1; tv.tv_usec = 0; maxfd = gs->fd; if ((gs->check & GG_CHECK_READ)) FD_SET(gs->fd, &rds); if ((gs->check & GG_CHECK_WRITE)) FD_SET(gs->fd, &wds); if (gd && gd->fd != -1) { if (gd->fd > maxfd) maxfd = gd->fd; if ((gd->check & GG_CHECK_READ)) FD_SET(gd->fd, &rds); if ((gd->check & GG_CHECK_WRITE)) FD_SET(gd->fd, &wds); } if (fds[1] != -1) { if (fds[1] > maxfd) maxfd = fds[1]; FD_SET(fds[1], &wds); } if ((res = select(maxfd + 1, &rds, &wds, NULL, &tv)) == -1) { if (errno == EINTR) continue; perror("select"); exit(1); } now = time(NULL); if (last != now) { if (gs->timeout != -1 && gs->timeout-- == 0 && !gs->soft_timeout) { debug("Timeout\n"); exit(1); } if (gd && gd->timeout != -1 && gd->timeout-- == 0 && !gd->soft_timeout) { debug("Timeout\n"); exit(1); } last = now; } if (gs->state == GG_STATE_CONNECTED && ping && now - ping > 60) { ping = now; gg_ping(gs); } if (FD_ISSET(gs->fd, &rds) || FD_ISSET(gs->fd, &wds) || (gs->timeout == 0 && gs->soft_timeout)) { struct gg_event *ge; uin_t uin; int status; if (!(ge = gg_watch_fd(gs))) { debug("Connection broken\n"); exit(1); } switch (ge->type) { case GG_EVENT_CONN_SUCCESS: debug("Connected\n"); connected = 1; gg_notify(gs, &config_peer, 1); if (test_mode == TEST_MODE_RECEIVE_NAT) gs->client_addr = INADDR_NONE; ping = time(NULL); break; case GG_EVENT_CONN_FAILED: debug("Connection failed\n"); exit(1); case GG_EVENT_MSG: debug("Message from %d: %s\n", ge->event.msg.sender, ge->event.msg.message); break; case GG_EVENT_DISCONNECT: debug("Forced to disconnect\n"); exit(1); case GG_EVENT_USER_DATA: debug("User data\n"); break; case GG_EVENT_NOTIFY60: uin = ge->event.notify60[0].uin; status = ge->event.notify60[0].status; /* fall-through */ case GG_EVENT_STATUS60: if (ge->type == GG_EVENT_STATUS60) { uin = ge->event.status60.uin; status = ge->event.status60.status; } if (uin == config_peer && (GG_S_A(status) || GG_S_B(status)) && (test_mode == TEST_MODE_SEND || test_mode == TEST_MODE_SEND_NAT)) { debug("Sending file...\n"); if (config_file) { gd = gg_dcc7_send_file(gs, config_peer, config_file, NULL, NULL); } else { gd = gg_dcc7_send_file_fd(gs, config_peer, fds[0], config_size, "test.bin", "DummySHA1HashOfAAAAA"); } if (!gd) { perror("gg_dcc7_send_file"); exit(1); } } break; case GG_EVENT_DCC7_NEW: debug("Incoming direct connection\n"); if (test_mode == TEST_MODE_RECEIVE || test_mode == TEST_MODE_RECEIVE_NAT || test_mode == TEST_MODE_RECEIVE_RESUME) { gd = ge->event.dcc7_new; if (config_dir) { gd->file_fd = open((char*) gd->filename, O_WRONLY | O_CREAT, 0600); #if 0 lseek(gd->file_fd, gd->size, SEEK_SET); #endif } else gd->file_fd = open("/dev/null", O_WRONLY); if (gd->file_fd == -1) { perror("open"); exit(1); } if (test_mode != TEST_MODE_RECEIVE_RESUME) gg_dcc7_accept(gd, 0); else gg_dcc7_accept(gd, gd->size); } break; case GG_EVENT_DCC7_ERROR: debug("Direct connection error\n"); exit(1); case GG_EVENT_DCC7_ACCEPT: debug("Accepted\n"); break; case GG_EVENT_DCC7_REJECT: debug("Rejected\n"); exit(1); case GG_EVENT_DCC7_PENDING: debug("Pending\n"); break; case GG_EVENT_NONE: break; default: debug("Unsupported event %d\n", ge->type); break; } gg_event_free(ge); } if (gd && gd->fd != -1 && (FD_ISSET(gd->fd, &rds) || FD_ISSET(gd->fd, &wds) || (gd->timeout == 0 && gd->soft_timeout))) { struct gg_event *ge; if (!(ge = gg_dcc7_watch_fd(gd))) { debug("Direct connection broken\n"); exit(1); } switch (ge->type) { case GG_EVENT_DCC7_ERROR: debug("Direct connection error\n"); exit(1); case GG_EVENT_DCC7_CONNECTED: debug("Direct connection established\n"); break; case GG_EVENT_DCC7_DONE: debug("Finished"); gg_event_free(ge); gg_dcc7_free(gd); gg_free_session(gs); config_free(); exit(1); case GG_EVENT_NONE: break; default: debug("Unsupported event %d\n", ge->type); break; } gg_event_free(ge); } if (fds[1] != -1 && FD_ISSET(fds[1], &wds)) { char buf[4096]; memset(buf, 'A', sizeof(buf)); if (write(fds[1], buf, sizeof(buf)) < 1) { perror("write"); exit(1); } } } return 0; }