/* * Interprets the given SNAC. */ void SnacCallback (Event *event) { Packet *pak = event->pak; SNAC *s; UWORD family; ASSERT_SERVER(event->conn); family = PacketReadB2 (pak); pak->cmd = PacketReadB2 (pak); pak->flags = PacketReadB2 (pak); pak->ref = PacketReadB4 (pak); if (pak->flags & 0x8000) PacketReadData (pak, NULL, PacketReadB2 (pak)); for (s = SNACS; s->fam; s++) if (s->fam == family && s->cmd == pak->cmd) break; if (s->f) s->f (event); else SnacSrvUnknown (event); EventD (event); }
void PeerFileResend (Event *event) { Contact *cont; Connection *fpeer = event->conn; Packet *pak; Event *event2; int rc; const char *opt_text; if (!fpeer) { EventD (event); return; } ASSERT_FILEDIRECT (fpeer); cont = event->cont; assert (cont); if (!OptGetStr (event->opt, CO_FILENAME, &opt_text)) opt_text = ""; if (event->attempts >= MAX_RETRY_P2PFILE_ATTEMPTS || (!event->pak && !event->seq)) { rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2168, "File transfer #%ld (%s) dropped after %ld attempts because of timeout.\n"), UD2UL (event->seq), opt_text, UD2UL (event->attempts)); TCPClose (fpeer); } else if (!(fpeer->connect & CONNECT_MASK)) { rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2072, "File transfer #%ld (%s) canceled because of closed connection.\n"), UD2UL (event->seq), opt_text); } else if (~fpeer->connect & CONNECT_OK) { if (!event->seq) event->attempts++; event->due = time (NULL) + 20; QueueEnqueue (event); return; } else if (!event->seq) { fpeer->oscar_dc_seq = 0; PeerPacketSend (fpeer, event->pak); PacketD (event->pak); event->pak = NULL; } else if (event->seq != fpeer->oscar_dc_seq) { event->due = time (NULL) + 10; QueueEnqueue (event); return; } else if (event->pak) { Connection *ffile; struct stat finfo; PeerPacketSend (fpeer, event->pak); PacketD (event->pak); event->pak = NULL; QueueEnqueue (event); ffile = ServerChild (fpeer->serv, fpeer->cont, TYPE_FILE); fpeer->oscar_file = ffile; if (stat (opt_text, &finfo)) { rc = errno; rl_printf (i18n (2071, "Couldn't stat file %s: %s (%d)\n"), s_wordquote (opt_text), strerror (rc), rc); } ffile->oscar_file_len = finfo.st_size; ffile->sok = open (opt_text, O_RDONLY); if (ffile->sok == -1) { int rc = errno; rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2083, "Cannot open file %s: %s (%d).\n"), opt_text, strerror (rc), rc); TCPClose (fpeer); ConnectionD (ffile); ConnectionD (fpeer); return; } return; } else if (!fpeer->oscar_file || fpeer->connect & CONNECT_SELECT_W) { event->attempts++; event->due = time (NULL) + 3; QueueEnqueue (event); return; } else { int len = 0; pak = PeerPacketC (fpeer, 6); len = read (fpeer->oscar_file->sok, pak->data + 1, 2048); if (len == -1) { len = errno; rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2086, "Error while reading file %s: %s (%d).\n"), opt_text, strerror (len), len); TCPClose (fpeer); } else { pak->len += len; fpeer->oscar_file->oscar_file_done += len; PeerPacketSend (fpeer, pak); PacketD (pak); if (len > 0) { if (fpeer->oscar_file->oscar_file_len) ReadLinePromptUpdate (s_sprintf ("[%s%ld %02d%%%s] %s%s", COLCONTACT, UD2UL (fpeer->oscar_file->oscar_file_done), (int)((100.0 * fpeer->oscar_file->oscar_file_done) / fpeer->oscar_file->oscar_file_len), COLNONE, COLSERVER, i18n (2467, "climm>"))); else ReadLinePromptUpdate (s_sprintf ("[%s%ld%s] %s%s", COLCONTACT, UD2UL (fpeer->oscar_file->oscar_file_done), COLNONE, COLSERVER, i18n (2467, "climm>"))); event->attempts = 0; QueueEnqueue (event); return; } ReadLinePromptReset (); rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2087, "Finished sending file %s.\n"), opt_text); ConnectionD (fpeer->oscar_file); fpeer->oscar_dc_seq++; event2 = QueueDequeue (fpeer, QUEUE_PEER_FILE, fpeer->oscar_dc_seq); if (event2) { QueueEnqueue (event2); QueueRetry (fpeer, QUEUE_PEER_FILE, fpeer->cont); return; } else { rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2088, "Finished sending all %d files.\n"), fpeer->oscar_dc_seq - 1); ConnectionD (fpeer); } } } EventD (event); }