--- a/libpurple/protocols/gg/lib/dcc.c Sun Mar 02 10:34:51 2014 +0100 +++ b/libpurple/protocols/gg/lib/dcc.c Fri Mar 07 23:17:08 2014 +0100 @@ -138,19 +138,24 @@ return -1; } - if (stat(local_filename, &st) == -1) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() stat() failed (%s)\n", strerror(errno)); + if ((d->file_fd = open(local_filename, O_RDONLY)) == -1) { + gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() open() failed (%s)\n", strerror(errno)); + return -1; + } + + if (fstat(d->file_fd, &st) == -1) { + gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() " + "fstat() failed (%s)\n", strerror(errno)); + close(d->file_fd); + d->file_fd = -1; return -1; } if ((st.st_mode & S_IFDIR)) { gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() that's a directory\n"); errno = EINVAL; - return -1; - } - - if ((d->file_fd = open(local_filename, O_RDONLY)) == -1) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() open() failed (%s)\n", strerror(errno)); + close(d->file_fd); + d->file_fd = -1; return -1; } @@ -209,7 +214,8 @@ } } - gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() short name \"%s\", dos name \"%s\"\n", name, d->file_info.short_filename); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() short name \"%s\"," + " dos name \"%s\"\n", name, d->file_info.short_filename); strncpy((char*) d->file_info.filename, name, sizeof(d->file_info.filename) - 1); return 0; @@ -233,7 +239,9 @@ addr.s_addr = ip; - gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_transfer(%s, %d, %ld, %ld, %s);\n", inet_ntoa(addr), port, my_uin, peer_uin, (type == GG_SESSION_DCC_SEND) ? "SEND" : "GET"); + gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_transfer(%s, %d, %u, %u, " + "%s);\n", inet_ntoa(addr), port, my_uin, peer_uin, + (type == GG_SESSION_DCC_SEND) ? "SEND" : "GET"); if (!ip || ip == INADDR_NONE || !port || !my_uin || !peer_uin) { gg_debug(GG_DEBUG_MISC, "// gg_dcc_transfer() invalid arguments\n"); @@ -504,11 +512,15 @@ \ if (_tmp < (int) size) { \ if (_tmp == -1) { \ - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed (errno=%d, %s)\n", errno, strerror(errno)); \ + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed " \ + "(errno=%d, %s)\n", errno, strerror(errno)); \ } else if (_tmp == 0) { \ - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed, connection broken\n"); \ + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed, " \ + "connection broken\n"); \ } else { \ - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed (%d bytes, %d needed)\n", _tmp, size); \ + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed " \ + "(%d bytes, %" GG_SIZE_FMT " needed)\n", \ + _tmp, size); \ } \ e->type = GG_EVENT_DCC_ERROR; \ e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; \ @@ -531,9 +543,12 @@ write_res = send(fd, buf, size, 0); \ if (write_res < (int) size) { \ if (write_res == -1) { \ - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() send() failed (errno=%d, %s)\n", errno, strerror(errno)); \ + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() send() " \ + "failed (errno=%d, %s)\n", errno, strerror(errno)); \ } else { \ - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() send() failed (%d needed, %d done)\n", size, write_res); \ + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() send() " \ + "failed (%" GG_SIZE_FMT " needed, %d done)\n", \ + size, write_res); \ } \ e->type = GG_EVENT_DCC_ERROR; \ e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; \ @@ -561,7 +576,12 @@ gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_watch_fd(%p);\n", h); - if (!h || (h->type != GG_SESSION_DCC && h->type != GG_SESSION_DCC_SOCKET && h->type != GG_SESSION_DCC_SEND && h->type != GG_SESSION_DCC_GET && h->type != GG_SESSION_DCC_VOICE)) { + if (!h || (h->type != GG_SESSION_DCC && + h->type != GG_SESSION_DCC_SOCKET && + h->type != GG_SESSION_DCC_SEND && + h->type != GG_SESSION_DCC_GET && + h->type != GG_SESSION_DCC_VOICE)) + { gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() invalid argument\n"); errno = EINVAL; return NULL; @@ -578,24 +598,23 @@ struct sockaddr_in sin; struct gg_dcc *c; int fd; -#ifdef FIONBIO - int one = 1; -#endif socklen_t sin_len = sizeof(sin); if ((fd = accept(h->fd, (struct sockaddr*) &sin, &sin_len)) == -1) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() can't accept() new connection (errno=%d, %s)\n", errno, strerror(errno)); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() can't " + "accept() new connection (errno=%d, %s)\n", + errno, strerror(errno)); return e; } - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() new direct connection from %s:%d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() new direct " + "connection from %s:%d\n", inet_ntoa(sin.sin_addr), + htons(sin.sin_port)); -#ifdef FIONBIO - if (ioctl(fd, FIONBIO, &one) == -1) { -#else - if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { -#endif - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() can't set nonblocking (errno=%d, %s)\n", errno, strerror(errno)); + if (!gg_fd_set_nonblocking(fd)) { + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() can't set" + " nonblocking (errno=%d, %s)\n", + errno, strerror(errno)); close(fd); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; @@ -644,7 +663,9 @@ { uin_t uin; - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_READING_UIN_%d\n", (h->state == GG_STATE_READING_UIN_1) ? 1 : 2); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() GG_READING_UIN_%d\n", + (h->state == GG_STATE_READING_UIN_1) ? 1 : 2); gg_dcc_read(h->fd, &uin, sizeof(uin)); @@ -667,7 +688,7 @@ case GG_STATE_SENDING_ACK: gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_SENDING_ACK\n"); - gg_dcc_write(h->fd, ack, 4); + gg_dcc_write(h->fd, ack, (size_t)4); h->state = GG_STATE_READING_TYPE; h->check = GG_CHECK_READ; @@ -705,7 +726,8 @@ break; default: - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown dcc type (%.4x) from %ld\n", small_pkt.type, h->peer_uin); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown dcc type " + "(%.4x) from %u\n", small_pkt.type, h->peer_uin); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; } @@ -738,7 +760,9 @@ break; default: - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown dcc request (%.4x) from %ld\n", small_pkt.type, h->peer_uin); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown " + "dcc request (%.4x) from %u\n", + small_pkt.type, h->peer_uin); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; } @@ -806,13 +830,16 @@ tmp = recv(h->fd, h->chunk_buf + h->chunk_offset, h->chunk_size - h->chunk_offset, 0); if (tmp == -1) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed (errno=%d, %s)\n", errno, strerror(errno)); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() " + "failed (errno=%d, %s)\n", errno, strerror(errno)); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_NET; return e; } - gg_dcc_debug_data("read", h->fd, h->chunk_buf + h->chunk_offset, h->chunk_size - h->chunk_offset); + gg_dcc_debug_data("read", h->fd, + h->chunk_buf + h->chunk_offset, + h->chunk_size - h->chunk_offset); h->chunk_offset += tmp; @@ -860,10 +887,12 @@ h->established = 1; break; case 0x04: /* XXX */ - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() peer breaking connection\n"); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() " + "peer breaking connection\n"); /* XXX zwracać odpowiedni event */ default: - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown request (%.2x)\n", tiny_pkt.type); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() " + "unknown request (%.2x)\n", tiny_pkt.type); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; } @@ -878,7 +907,8 @@ small_pkt.type = gg_fix32(small_pkt.type); if (small_pkt.type < 16 || small_pkt.type > sizeof(buf)) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() invalid voice frame size (%d)\n", small_pkt.type); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() " + "invalid voice frame size (%d)\n", small_pkt.type); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_NET; @@ -906,9 +936,12 @@ tmp = recv(h->fd, h->voice_buf + h->chunk_offset, h->chunk_size - h->chunk_offset, 0); if (tmp < 1) { if (tmp == -1) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed (errno=%d, %s)\n", errno, strerror(errno)); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() " + "recv() failed (errno=%d, %s)\n", + errno, strerror(errno)); } else { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed, connection broken\n"); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() " + "recv() failed, connection broken\n"); } e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_NET; @@ -940,7 +973,10 @@ res = 0; if ((foo = getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &res, &res_size)) || res) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() connection failed (fd=%d,errno=%d(%s),foo=%d,res=%d(%s))\n", h->fd, errno, strerror(errno), foo, res, strerror(res)); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() connection failed " + "(fd=%d,errno=%d(%s),foo=%d,res=%d(%s))\n", + h->fd, errno, strerror(errno), foo, res, strerror(res)); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; return e; @@ -963,7 +999,7 @@ case GG_STATE_READING_ACK: gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_ACK\n"); - gg_dcc_read(h->fd, buf, 4); + gg_dcc_read(h->fd, buf, (size_t)4); if (strncmp(buf, ack, 4)) { gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() did't get ack\n"); @@ -995,7 +1031,8 @@ case GG_STATE_SENDING_REQUEST: gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_REQUEST\n"); - small_pkt.type = (h->type == GG_SESSION_DCC_GET) ? gg_fix32(0x0003) : gg_fix32(0x0002); /* XXX */ + small_pkt.type = (h->type == GG_SESSION_DCC_GET) ? + gg_fix32(0x0003) : gg_fix32(0x0002); /* XXX */ gg_dcc_write(h->fd, &small_pkt, sizeof(small_pkt)); @@ -1076,7 +1113,9 @@ gg_dcc_read(h->fd, &tiny_pkt, sizeof(tiny_pkt)); if (tiny_pkt.type != 0x01) { - gg_debug(GG_DEBUG_MISC, "// invalid reply (%.2x), connection refused\n", tiny_pkt.type); + gg_debug(GG_DEBUG_MISC, "// invalid " + "reply (%.2x), connection " + "refused\n", tiny_pkt.type); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_REFUSED; return e; @@ -1119,11 +1158,15 @@ if ((utmp = h->chunk_size - h->chunk_offset) > sizeof(buf)) utmp = sizeof(buf); - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() offset=%d, size=%d\n", h->offset, h->file_info.size); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() " + "offset=%d, size=%d\n", + h->offset, h->file_info.size); /* koniec pliku? */ if (h->file_info.size == 0) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() reached eof on empty file\n"); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() read()" + "reached eof on empty file\n"); e->type = GG_EVENT_DCC_DONE; return e; @@ -1135,13 +1178,26 @@ return e; } - lseek(h->file_fd, h->offset, SEEK_SET); + if (lseek(h->file_fd, h->offset, SEEK_SET) != (off_t)h->offset) { + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() lseek() " + "failed. (errno=%d, %s)\n", + errno, strerror(errno)); + + e->type = GG_EVENT_DCC_ERROR; + e->event.dcc_error = GG_ERROR_DCC_FILE; + + return e; + } size = read(h->file_fd, buf, utmp); /* błąd */ if (size == -1) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() failed. (errno=%d, %s)\n", errno, strerror(errno)); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() read() " + "failed. (errno=%d, %s)\n", + errno, strerror(errno)); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_FILE; @@ -1160,11 +1216,17 @@ /* jeśli wczytaliśmy więcej, utnijmy. */ if (h->offset + size > h->file_info.size) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() too much (read=%d, ofs=%d, size=%d)\n", size, h->offset, h->file_info.size); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() read() " + "too much (read=%d, ofs=%d, " + "size=%d)\n", size, h->offset, + h->file_info.size); size = h->file_info.size - h->offset; if (size < 1) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() reached EOF after cutting\n"); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() " + "reached EOF after cutting\n"); e->type = GG_EVENT_DCC_DONE; return e; } @@ -1173,14 +1235,18 @@ tmp = send(h->fd, buf, size, 0); if (tmp == -1) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() send() failed (%s)\n", strerror(errno)); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() send() " + "failed (%s)\n", strerror(errno)); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_NET; return e; } if (tmp == 0) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() send() failed (connection reset)\n"); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() send() " + "failed (connection reset)\n"); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_NET; return e; @@ -1222,11 +1288,16 @@ size = recv(h->fd, buf, utmp, 0); - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() ofs=%d, size=%d, recv()=%d\n", h->offset, h->file_info.size, size); + gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() " + "ofs=%d, size=%d, recv()=%d\n", + h->offset, h->file_info.size, size); /* błąd */ if (size == -1) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() recv() failed. (errno=%d, %s)\n", errno, strerror(errno)); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() recv() " + "failed. (errno=%d, %s)\n", + errno, strerror(errno)); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_NET; @@ -1246,7 +1317,11 @@ tmp = write(h->file_fd, buf, size); if (tmp == -1 || tmp < size) { - gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() write() failed (%d:fd=%d:res=%d:%s)\n", tmp, h->file_fd, size, strerror(errno)); + gg_debug(GG_DEBUG_MISC, + "// gg_dcc_watch_fd() write() " + "failed (%d:fd=%d:res=%d:%s)\n", + tmp, h->file_fd, size, + strerror(errno)); e->type = GG_EVENT_DCC_ERROR; e->event.dcc_error = GG_ERROR_DCC_NET; return e;