/* * Really handle signals */ void ReadLineHandleSig (void) { UBYTE sig; while ((sig = (rl_signal & 30))) { rl_signal &= 1; if (sig & 2) { s_init (&rl_operate, "", 0); rl_key_end (); printf ("%s %s^C%s\n", rl_operate.txt, COLERROR, COLNONE); rl_print ("\r"); rl_prompt_stat = 0; rl_historyadd (); rl_tab_state = 0; s_init (&rl_input, "", 0); CmdUserInterrupt (); ReadLinePromptReset (); ReadLinePrompt (); } #if defined(SIGTSTP) && defined(SIGCONT) if (sig & 4) { ReadLineTtySet (); rl_print ("\r"); ReadLinePrompt (); } if (sig & 8) { int gpos; s_init (&rl_operate, "", 0); gpos = rl_colpos; rl_key_end (); rl_colpos = gpos; printf ("%s", rl_operate.txt); printf (" %s^Z%s", COLERROR, COLNONE); ReadLineTtyUnset (); signal (SIGTSTP, SIG_DFL); raise (SIGTSTP); } #endif #if defined(SIGWINCH) if (sig & 16) { if (rl_columns != rl_getcolumns ()) { ReadLinePromptHide (); rl_columns = rl_getcolumns (); } } #endif } }
/* * Print a given SNAC. */ void SnacPrint (Packet *pak) { UWORD fam, cmd, flag, opos = pak->rpos; UDWORD ref, len; pak->rpos = 6; fam = PacketReadB2 (pak); cmd = PacketReadB2 (pak); flag = PacketReadB2 (pak); ref = PacketReadB4 (pak); len = PacketReadAtB2 (pak, pak->rpos); rl_printf ("%s %sSNAC (%x,%x) [%s] flags %x ref %lx", s_dumpnd (pak->data + 6, flag & 0x8000 ? 10 + len : 10), COLDEBUG, fam, cmd, SnacName (fam, cmd), flag, ref); if (flag & 0x8000) { rl_printf (" extra (%ld)", len); pak->rpos += len + 2; } rl_printf ("%s\n", COLNONE); if (prG->verbose & DEB_PACK8DATA || ~prG->verbose & DEB_PACK8) { char *f, *syn = strdup (s_sprintf ("gs%dx%ds", fam, cmd)); rl_print (f = PacketDump (pak, syn, COLDEBUG, COLNONE)); free (f); free (syn); } pak->rpos = opos; }
void TablePrintLang (void) { UBYTE i; const char *p; for (i = 1; i < TableLangSize; i++) { p = i18n (-1, TableLang[i]); rl_printf ("%2d. %-7s", i, p); if ((i + 1) & 3) rl_print ("\t"); else rl_print ("\n"); } rl_print ("\n"); }
/* * Shows the prompt */ void ReadLinePrompt () { int gpos = rl_colpos; if (rl_prompt_stat == 1) return; #if DEBUG_RL fprintf (stderr, "killoper: %s\n", s_qquote (rl_operate.txt)); #endif s_init (&rl_operate, "", 0); if (rl_prompt_stat == 2) rl_goto (0); if (rl_prompt_stat == 2) { s_catc (&rl_operate, '\r'); #ifdef ANSI_TERM s_cat (&rl_operate, ANSI_CLEAR); #endif rl_prompt_stat = 0; } #if DEBUG_RL fprintf (stderr, "oper(rm): %s\n", s_qquote (rl_operate.txt)); #endif printf ("%s", rl_operate.txt); if (rl_prompt_stat == 0) { rl_print ("\r"); rl_print (rl_prompt.txt); rl_prompt_len = rl_pos (); rl_prompt_stat = 1; rl_colpos = 0; } s_init (&rl_operate, "", 0); rl_recheck (TRUE); rl_goto (gpos); printf ("%s", rl_operate.txt); }
/* * Hides the prompt */ void ReadLinePromptHide () { int pos = rl_colpos; ReadLineHandleSig (); if (rl_prompt_stat == 0) return; s_init (&rl_operate, "", 0); rl_goto (0); s_catc (&rl_operate, '\r'); #ifdef ANSI_TERM s_cat (&rl_operate, ANSI_CLEAR); #endif printf ("%s", rl_operate.txt); rl_prompt_stat = 0; rl_colpos = pos; rl_print ("\r"); }
/* * Dispatches incoming packets on the file transfer connection. */ void PeerFileDispatch (Connection *fpeer) { Contact *cont; Packet *pak; int err = 0; ASSERT_FILEDIRECT (fpeer); assert (fpeer->cont); cont = fpeer->cont; if (fpeer->connect & CONNECT_SELECT_W && UtilIOSelectIs (fpeer->sok, WRITEFDS)) { fpeer->connect &= ~CONNECT_SELECT_W; 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>"))); UtilIOSendTCP2 (fpeer, NULL); QueueRetry (fpeer, QUEUE_PEER_FILE, fpeer->cont); if (!UtilIOSelectIs (fpeer->sok, READFDS)) return; } if (!(pak = UtilIOReceiveTCP2 (fpeer))) return; if (prG->verbose & DEB_PACKTCP) TCPPrint (pak, fpeer, FALSE); switch (PacketRead1 (pak)) { strc_t name, text; UDWORD len, off, nr, speed; case 0: PacketRead4 (pak); /* EMPTY */ nr = PacketRead4 (pak); /* COUNT */ len = PacketRead4 (pak); /* BYTES */ speed= PacketRead4 (pak); /* SPEED */ name = PacketReadL2Str (pak, NULL); /* NICK */ PacketD (pak); rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2161, "Receiving %ld files with total size %ld bytes at speed %lx from %s.\n"), UD2UL (nr), UD2UL (len), UD2UL (speed), ConvFromCont (name, cont)); if (len != fpeer->oscar_file_len) { rl_printf ("FIXME: byte len different than in file request: requested %ld, sending %ld.\n", UD2UL (fpeer->oscar_file_len), UD2UL (len)); fpeer->oscar_file_len = len; } pak = PeerPacketC (fpeer, 1); PacketWrite4 (pak, 64); PacketWriteLNTS (pak, cont->nick); PeerPacketSend (fpeer, pak); PacketD (pak); return; case 1: speed = PacketRead4 (pak); /* SPEED */ name = PacketReadL2Str (pak, NULL); /* NICK */ PacketD (pak); rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2170, "Sending file at speed %lx to %s.\n"), UD2UL (speed), s_wordquote (ConvFromCont (name, cont))); fpeer->oscar_dc_seq = 1; QueueRetry (fpeer, QUEUE_PEER_FILE, cont); return; case 2: PacketRead1 (pak); /* EMPTY */ name = PacketReadL2Str (pak, NULL); text = PacketReadL2Str (pak, NULL); len = PacketRead4 (pak); PacketRead4 (pak); /* EMPTY */ PacketRead4 (pak); /* SPEED */ off = 0; PacketD (pak); { Connection *ffile = ServerChild (fpeer->serv, fpeer->cont, TYPE_FILE); char buf[200], *p; int pos = 0; struct stat finfo; assert (ffile); pos = snprintf (buf, sizeof (buf), "%sfiles" _OS_PATHSEPSTR "%s" _OS_PATHSEPSTR, PrefUserDir (prG), cont->screen); snprintf (buf + pos, sizeof (buf) - pos, "%s", ConvFromCont (name, cont)); for (p = buf + pos; *p; p++) if (*p == '/') *p = '_'; finfo.st_size = 0; if (!stat (buf, &finfo)) if ((UDWORD)finfo.st_size < len) off = finfo.st_size; fpeer->oscar_file = ffile; ffile->sok = open (buf, O_CREAT | O_WRONLY | (off ? O_APPEND : O_TRUNC), 0660); if (ffile->sok == -1) { int rc = errno; if (rc == ENOENT) { mkdir (s_sprintf ("%sfiles", PrefUserDir (prG)), 0700); mkdir (s_sprintf ("%sfiles" _OS_PATHSEPSTR "%s", PrefUserDir (prG), cont->screen), 0700); ffile->sok = open (buf, O_CREAT | O_WRONLY | (off ? O_APPEND : O_TRUNC), 0660); } if (ffile->sok == -1) { rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2083, "Cannot open file %s: %s (%d).\n"), buf, strerror (rc), rc); ConnectionD (fpeer); return; } } ffile->connect = CONNECT_OK; ffile->oscar_file_len = len; ffile->oscar_file_done = off; rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2162, "Receiving file %s (%s) with %ld bytes as %s.\n"), name->txt, text->txt, UD2UL (len), buf); } pak = PeerPacketC (fpeer, 3); PacketWrite4 (pak, off); PacketWrite4 (pak, 0); PacketWrite4 (pak, 64); PacketWrite4 (pak, 1); PeerPacketSend (fpeer, pak); PacketD (pak); return; case 3: off = PacketRead4 (pak); PacketRead4 (pak); /* EMPTY */ PacketRead4 (pak); /* SPEED */ nr = PacketRead4 (pak); /* NR */ PacketD (pak); rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2163, "Sending file %ld at offset %ld.\n"), UD2UL (nr), UD2UL (off)); err = lseek (fpeer->oscar_file->sok, off, SEEK_SET); if (err == -1) { err = errno; rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2084, "Error while seeking to offset %ld: %s (%d).\n"), UD2UL (off), strerror (err), err); TCPClose (fpeer); return; } fpeer->oscar_file->oscar_file_done = off; fpeer->oscar_file->connect = CONNECT_OK; QueueRetry (fpeer, QUEUE_PEER_FILE, cont); return; case 4: rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2169, "File transfer aborted by peer (%d).\n"), PacketRead1 (pak)); PacketD (pak); PeerFileClose (fpeer); return; case 5: rl_printf ("FIXME: Ignoring speed change to %d.\n", PacketRead1 (pak)); PacketD (pak); return; case 6: if (fpeer->oscar_file->oscar_file_done + pak->len - 1 > fpeer->oscar_file->oscar_file_len) { rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2165, "The peer sent more bytes (%ld) than the file length (%ld).\n"), UD2UL (fpeer->oscar_file->oscar_file_done + pak->len - 1), UD2UL (fpeer->oscar_file->oscar_file_len)); PacketD (pak); TCPClose (fpeer); return; } if (pak->len <= 1) { PacketD (pak); return; } len = write (fpeer->oscar_file->sok, pak->data + 1, pak->len - 1); if (len + 1 != pak->len) { rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2575, "Error writing to file (%lu bytes written out of %u).\n"), UD2UL (len), pak->len - 1); PacketD (pak); TCPClose (fpeer); return; } fpeer->oscar_file->oscar_file_done += len; if (fpeer->oscar_file->oscar_file_len == fpeer->oscar_file->oscar_file_done) { ReadLinePromptReset (); rl_log_for (cont->nick, COLCONTACT); rl_print (i18n (2166, "Finished receiving file.\n")); #if HAVE_FSYNC fsync (fpeer->oscar_file->sok); #endif close (fpeer->oscar_file->sok); fpeer->oscar_file->sok = -1; fpeer->oscar_file->connect = CONNECT_OK; } else if (fpeer->oscar_file->oscar_file_len) { ReadLinePromptUpdate (s_sprintf ("[%s%ld %02d%%%s] %s%s", COLINCOMING, 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>"))); } PacketD (pak); return; default: rl_log_for (cont->nick, COLCONTACT); rl_print (i18n (2167, "Error - unknown packet.\n")); rl_print (s_dump (pak->data, pak->len)); PacketD (pak); PeerFileClose (fpeer); } if ((prG->verbose & DEB_TCP) && err) { rl_printf ("%s %s: %d\n", s_now, i18n (2029, "Protocol error on peer-to-peer connection"), err); PeerFileClose (fpeer); } }
io_err_t UtilIOShowError (Connection *conn, io_err_t rc) { int e = errno; const char *t = NULL; switch (rc) { case IO_CONNECTED: rl_print (""); if (prG->verbose || (conn->serv && conn == conn->serv->conn)) if (rl_pos () > 0) rl_print (i18n (1634, "ok.\n")); return IO_CONNECTED; case IO_OK: return IO_OK; case IO_NO_MEM: case IO_NO_PARAM: assert (0); case IO_NO_SOCKET: if (1) t = i18n (1638, "Couldn't create socket"); else case IO_NO_NONBLOCK: if (1) t = i18n (1950, "Couldn't set socket nonblocking"); else case IO_NO_HOSTNAME: if (1) t = i18n (2743, "Can't find hostname"); else case IO_CONN_TO: if (1) t = i18n (2744, "Connection timed out"); else case IO_NO_CONN: t = i18n (1952, "Couldn't open connection"); if (prG->verbose || (conn->serv && conn == conn->serv->conn)) { Contact *cont = conn->cont; char *semi = strchr (conn->server, ';'); if (semi) *semi = 0; rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (2745, "Opening connection to %s:%s%ld%s "), s_wordquote (conn->server), COLQUOTE, UD2UL (conn->port), COLNONE); if (semi) *semi = ';'; rl_print (i18n (1949, "failed:\n")); rl_printf ("%s [%d]\n", s_sprintf ("%s: %s (%d).", t, conn->dispatcher->funcs->f_err (conn, conn->dispatcher), e), __LINE__); } UtilIOClose (conn); return IO_RW; case IO_CLOSED: #ifdef ECONNRESET if (!errno) errno = ECONNRESET; #endif case IO_RW: if (prG->verbose || (conn->serv && conn == conn->serv->conn)) { Contact *cont; if ((cont = conn->cont)) { rl_log_for (cont->nick, COLCONTACT); rl_printf (i18n (1878, "Error while reading from socket: %s (%d, %d)\n"), conn->dispatcher->funcs->f_err (conn, conn->dispatcher), rc, errno); } } UtilIOClose (conn); return IO_RW; default: assert (0); } }