Beispiel #1
0
char* TLV::dupw(void) 
{ 
    wchar_t *str = (wchar_t*)part(0, length_);
    wcs_htons(str);

    char* stru = mir_utf8encodeW(str);
    mir_free(str);

    return stru; 
}
Beispiel #2
0
int CAimProto::receiving_file(file_transfer *ft, HANDLE hServerPacketRecver, NETLIBPACKETRECVER &packetRecv)
{
	debugLogA("P2P: Entered file receiving thread.");
	bool failed = true;
	bool failed_conn = false;
	bool accepted_file = false;
	int fid = -1;

	oft2 *oft = NULL;

	ft->pfts.tszWorkingDir = mir_utf8decodeT(ft->file);

	//start listen for packets stuff
	for (;;) {
		int recvResult = packetRecv.bytesAvailable - packetRecv.bytesUsed;
		if (recvResult <= 0)
			recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hServerPacketRecver, (LPARAM)&packetRecv);
		if (recvResult == 0) {
			debugLogA("P2P: File transfer connection Error: 0");
			break;
		}
		if (recvResult == SOCKET_ERROR) {
			failed_conn = true;
			debugLogA("P2P: File transfer connection Error: -1");
			break;
		}
		if (recvResult > 0) {
			if (!accepted_file) {
				if (recvResult < 0x100) continue;

				oft2* recv_ft = (oft2*)&packetRecv.buffer[packetRecv.bytesUsed];
				unsigned short pkt_len = _htons(recv_ft->length);

				if (recvResult < pkt_len) continue;
				packetRecv.bytesUsed += pkt_len;

				unsigned short type = _htons(recv_ft->type);
				if (type == 0x0101) {
					debugLogA("P2P: Buddy Ready to begin transfer.");
					oft = (oft2*)mir_realloc(oft, pkt_len);
					memcpy(oft, recv_ft, pkt_len);
					memcpy(oft->icbm_cookie, ft->icbm_cookie, 8);

					int buflen = pkt_len - 0x100 + 64;
					char *buf = (char*)mir_calloc(buflen + 2);
					unsigned short enc;

					ft->pfts.currentFileSize = _htonl(recv_ft->size);
					ft->pfts.totalBytes = _htonl(recv_ft->total_size);
					ft->pfts.currentFileTime = _htonl(recv_ft->mod_time);
					memcpy(buf, recv_ft->filename, buflen);
					enc = _htons(recv_ft->encoding);

					TCHAR *name;
					if (enc == 2) {
						wchar_t* wbuf = (wchar_t*)buf;
						wcs_htons(wbuf);
						for (wchar_t *p = wbuf; *p; ++p) { if (*p == 1) *p = '\\'; }
						name = mir_u2t(wbuf);
					}
					else {
						for (char *p = buf; *p; ++p) { if (*p == 1) *p = '\\'; }
						name = mir_a2t(buf);
					}

					mir_free(buf);

					TCHAR fname[256];
					mir_sntprintf(fname, _T("%s%s"), ft->pfts.tszWorkingDir, name);
					mir_free(name);
					mir_free(ft->pfts.tszCurrentFile);
					ft->pfts.tszCurrentFile = mir_tstrdup(fname);

					ResetEvent(ft->hResumeEvent);
					if (ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, ft, (LPARAM)&ft->pfts))
						WaitForSingleObject(ft->hResumeEvent, INFINITE);

					if (ft->pfts.tszCurrentFile) {
						TCHAR* dir = get_dir(ft->pfts.tszCurrentFile);
						CreateDirectoryTreeT(dir);
						mir_free(dir);

						oft->type = _htons(ft->pfts.currentFileProgress ? 0x0205 : 0x0202);

						const int flag = ft->pfts.currentFileProgress ? 0 : _O_TRUNC;
						fid = _topen(ft->pfts.tszCurrentFile, _O_CREAT | _O_WRONLY | _O_BINARY | flag, _S_IREAD | _S_IWRITE);

						if (fid < 0) {
							report_file_error(fname);
							break;
						}

						accepted_file = ft->pfts.currentFileProgress == 0;

						if (ft->pfts.currentFileProgress) {
							bool the_same;
							oft->recv_bytes = _htonl(ft->pfts.currentFileProgress);
							oft->recv_checksum = _htonl(aim_oft_checksum_file(ft->pfts.tszCurrentFile));
							the_same = oft->size == oft->recv_bytes && oft->checksum == oft->recv_checksum;
							if (the_same) {
								ft->pfts.totalProgress += ft->pfts.currentFileProgress;
								oft->type = _htons(0x0204);
								_close(fid);

								ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
								++ft->pfts.currentFileNumber;
								ft->pfts.currentFileProgress = 0;
							}
						}
					}
					else {
						oft->type = _htons(0x0204);

						ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
						++ft->pfts.currentFileNumber;
						ft->pfts.currentFileProgress = 0;
					}

					if (Netlib_Send(ft->hConn, (char*)oft, pkt_len, 0) == SOCKET_ERROR)
						break;

					if (ft->pfts.currentFileNumber >= ft->pfts.totalFiles && _htons(oft->type) == 0x0204) {
						failed = false;
						break;
					}
				}
				else if (type == 0x0106) {
					oft = (oft2*)mir_realloc(oft, pkt_len);
					memcpy(oft, recv_ft, pkt_len);

					ft->pfts.currentFileProgress = _htonl(oft->recv_bytes);
					ft->pfts.totalProgress += ft->pfts.currentFileProgress;

					_lseeki64(fid, ft->pfts.currentFileProgress, SEEK_SET);
					accepted_file = true;

					oft->type = _htons(0x0207);
					if (Netlib_Send(ft->hConn, (char*)oft, pkt_len, 0) == SOCKET_ERROR)
						break;
				}
				else break;
			}
			else {
				packetRecv.bytesUsed = packetRecv.bytesAvailable;
				_write(fid, packetRecv.buffer, packetRecv.bytesAvailable);
				ft->pfts.currentFileProgress += packetRecv.bytesAvailable;
				ft->pfts.totalProgress += packetRecv.bytesAvailable;
				ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->pfts);
				if (ft->pfts.currentFileSize == ft->pfts.currentFileProgress) {
					oft->type = _htons(0x0204);
					oft->recv_bytes = _htonl(ft->pfts.currentFileProgress);
					oft->recv_checksum = _htonl(aim_oft_checksum_file(ft->pfts.tszCurrentFile));

					debugLogA("P2P: We got the file successfully");
					Netlib_Send(ft->hConn, (char*)oft, _htons(oft->length), 0);
					if (_htons(oft->num_files_left) == 1) {
						failed = false;
						break;
					}
					else {
						accepted_file = false;
						_close(fid);

						ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
						++ft->pfts.currentFileNumber;
						ft->pfts.currentFileProgress = 0;
					}
				}
			}
		}
	}

	if (accepted_file) _close(fid);
	mir_free(oft);

	ft->success = !failed;
	return failed ? (failed_conn ? 1 : 2) : 0;
}