summaryrefslogtreecommitdiff
path: root/protocols/IcqOscarJ/icq_filetransfer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/IcqOscarJ/icq_filetransfer.cpp')
-rw-r--r--protocols/IcqOscarJ/icq_filetransfer.cpp515
1 files changed, 0 insertions, 515 deletions
diff --git a/protocols/IcqOscarJ/icq_filetransfer.cpp b/protocols/IcqOscarJ/icq_filetransfer.cpp
deleted file mode 100644
index 61484c3987..0000000000
--- a/protocols/IcqOscarJ/icq_filetransfer.cpp
+++ /dev/null
@@ -1,515 +0,0 @@
-// ---------------------------------------------------------------------------80
-// ICQ plugin for Miranda Instant Messenger
-// ________________________________________
-//
-// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
-// Copyright © 2001-2002 Jon Keating, Richard Hughes
-// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
-// Copyright © 2004-2009 Joe Kucera
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-// -----------------------------------------------------------------------------
-// DESCRIPTION:
-//
-// Describe me here please...
-//
-// -----------------------------------------------------------------------------
-#include "icqoscar.h"
-
-
-static void file_buildProtoFileTransferStatus(filetransfer* ft, PROTOFILETRANSFERSTATUS* pfts)
-{
- ZeroMemory(pfts, sizeof(PROTOFILETRANSFERSTATUS));
- pfts->cbSize = sizeof(PROTOFILETRANSFERSTATUS);
- pfts->hContact = ft->hContact;
- pfts->flags = PFTS_UTF | (ft->sending ? PFTS_SENDING : PFTS_RECEIVING); /* Standard FT is Ansi only */
- if (ft->sending)
- pfts->pszFiles = ft->pszFiles;
- else
- pfts->pszFiles = NULL; /* FIXME */
- pfts->totalFiles = ft->dwFileCount;
- pfts->currentFileNumber = ft->iCurrentFile;
- pfts->totalBytes = ft->dwTotalSize;
- pfts->totalProgress = ft->dwBytesDone;
- pfts->szWorkingDir = ft->szSavePath;
- pfts->szCurrentFile = ft->szThisFile;
- pfts->currentFileSize = ft->dwThisFileSize;
- pfts->currentFileTime = ft->dwThisFileDate;
- pfts->currentFileProgress = ft->dwFileBytesDone;
-}
-
-
-static void file_sendTransferSpeed(CIcqProto* ppro, directconnect* dc)
-{
- icq_packet packet;
-
- directPacketInit(&packet, 5);
- packByte(&packet, PEER_FILE_SPEED); /* Ident */
- packLEDWord(&packet, dc->ft->dwTransferSpeed);
- ppro->sendDirectPacket(dc, &packet);
-}
-
-
-static void file_sendNick(CIcqProto* ppro, directconnect* dc)
-{
- icq_packet packet;
- char* szNick;
- WORD wNickLen;
- DBVARIANT dbv = {DBVT_DELETED};
-
- if (ppro->getSettingString(NULL, "Nick", &dbv))
- szNick = "";
- else
- szNick = dbv.pszVal;
-
- wNickLen = strlennull(szNick);
-
- directPacketInit(&packet, (WORD)(8 + wNickLen));
- packByte(&packet, PEER_FILE_INIT_ACK); /* Ident */
- packLEDWord(&packet, dc->ft->dwTransferSpeed);
- packLEWord(&packet, (WORD)(wNickLen + 1));
- packBuffer(&packet, (LPBYTE)szNick, (WORD)(wNickLen + 1));
- ppro->sendDirectPacket(dc, &packet);
- ICQFreeVariant(&dbv);
-}
-
-
-static void file_sendNextFile(CIcqProto* ppro, directconnect* dc)
-{
- icq_packet packet;
- struct _stati64 statbuf;
- char szThisSubDir[MAX_PATH];
-
- if (dc->ft->iCurrentFile >= (int)dc->ft->dwFileCount)
- {
- ppro->BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dc->ft, 0);
- ppro->CloseDirectConnection(dc);
- dc->ft->hConnection = NULL;
- return;
- }
-
- dc->ft->szThisFile = dc->ft->pszFiles[dc->ft->iCurrentFile];
- if (FileStatUtf(dc->ft->szThisFile, &statbuf))
- {
- ppro->icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it."));
- ppro->CloseDirectConnection(dc);
- dc->ft->hConnection = NULL;
- return;
- }
-
- char *pszThisFileName = FindFilePathContainer((LPCSTR*)dc->ft->pszFiles, dc->ft->iCurrentFile, szThisSubDir);
-
- if (statbuf.st_mode&_S_IFDIR)
- {
- dc->ft->currentIsDir = 1;
- }
- else
- {
- dc->ft->currentIsDir = 0;
- dc->ft->fileId = OpenFileUtf(dc->ft->szThisFile, _O_BINARY | _O_RDONLY, _S_IREAD);
- if (dc->ft->fileId == -1)
- {
- ppro->icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it."));
- ppro->CloseDirectConnection(dc);
- dc->ft->hConnection = NULL;
- return;
- }
-
- }
- dc->ft->dwThisFileSize = statbuf.st_size;
- dc->ft->dwThisFileDate = statbuf.st_mtime;
- dc->ft->dwFileBytesDone = 0;
-
- char *szThisFileNameAnsi = NULL, *szThisSubDirAnsi = NULL;
- if (!utf8_decode(pszThisFileName, &szThisFileNameAnsi))
- szThisFileNameAnsi = NULL;
- if (!utf8_decode(szThisSubDir, &szThisSubDirAnsi))
- szThisSubDirAnsi = NULL;
- WORD wThisFileNameLen = strlennull(szThisFileNameAnsi);
- WORD wThisSubDirLen = strlennull(szThisSubDirAnsi);
-
- directPacketInit(&packet, (WORD)(20 + wThisFileNameLen + wThisSubDirLen));
- packByte(&packet, PEER_FILE_NEXTFILE); /* Ident */
- packByte(&packet, (BYTE)((statbuf.st_mode & _S_IFDIR) != 0)); // Is subdir
- packLEWord(&packet, (WORD)(wThisFileNameLen + 1));
- packBuffer(&packet, (LPBYTE)szThisFileNameAnsi, (WORD)(wThisFileNameLen + 1));
- packLEWord(&packet, (WORD)(wThisSubDirLen + 1));
- packBuffer(&packet, (LPBYTE)szThisSubDirAnsi, (WORD)(wThisSubDirLen + 1));
- packLEDWord(&packet, dc->ft->dwThisFileSize);
- packLEDWord(&packet, statbuf.st_mtime);
- packLEDWord(&packet, dc->ft->dwTransferSpeed);
- SAFE_FREE(&szThisFileNameAnsi);
- SAFE_FREE(&szThisSubDirAnsi);
- ppro->sendDirectPacket(dc, &packet);
-
- ppro->BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, dc->ft, 0);
-}
-
-
-static void file_sendResume(CIcqProto* ppro, directconnect* dc)
-{
- icq_packet packet;
-
- directPacketInit(&packet, 17);
- packByte(&packet, PEER_FILE_RESUME); /* Ident */
- packLEDWord(&packet, dc->ft->dwFileBytesDone); /* file resume */
- packLEDWord(&packet, 0); /* unknown */
- packLEDWord(&packet, dc->ft->dwTransferSpeed);
- packLEDWord(&packet, dc->ft->iCurrentFile + 1); /* file number */
- ppro->sendDirectPacket(dc, &packet);
-}
-
-
-static void file_sendData(CIcqProto* ppro, directconnect* dc)
-{
- BYTE buf[2048];
- int bytesRead = 0;
-
- if (!dc->ft->currentIsDir)
- {
- icq_packet packet;
-
- if (dc->ft->fileId == -1)
- return;
- bytesRead = _read(dc->ft->fileId, buf, sizeof(buf));
- if (bytesRead == -1)
- return;
-
- directPacketInit(&packet, (WORD)(1 + bytesRead));
- packByte(&packet, PEER_FILE_DATA); /* Ident */
- packBuffer(&packet, buf, (WORD)bytesRead);
- ppro->sendDirectPacket(dc, &packet);
- }
-
- dc->ft->dwBytesDone += bytesRead;
- dc->ft->dwFileBytesDone += bytesRead;
-
- if (GetTickCount() > dc->ft->dwLastNotify + 500 || bytesRead == 0)
- {
- PROTOFILETRANSFERSTATUS pfts;
-
- file_buildProtoFileTransferStatus(dc->ft, &pfts);
- ppro->BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, dc->ft, (LPARAM)&pfts);
-
- dc->ft->dwLastNotify = GetTickCount();
- }
-
- if (bytesRead == 0)
- {
- if (!dc->ft->currentIsDir) _close(dc->ft->fileId);
- dc->ft->fileId = -1;
- dc->wantIdleTime = 0;
- dc->ft->iCurrentFile++;
- file_sendNextFile(ppro, dc); /* this will close the socket if no more files */
- }
-}
-
-
-void CIcqProto::handleFileTransferIdle(directconnect* dc)
-{
- file_sendData(this, dc);
-}
-
-
-void CIcqProto::icq_sendFileResume(filetransfer *ft, int action, const char *szFilename)
-{
- if (ft->hConnection == NULL)
- return;
-
- directconnect *dc = FindFileTransferDC(ft);
- if (!dc) return; // something is broken...
-
- int openFlags;
-
- switch (action)
- {
- case FILERESUME_RESUME:
- openFlags = _O_BINARY | _O_WRONLY;
- break;
-
- case FILERESUME_OVERWRITE:
- openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY;
- ft->dwFileBytesDone = 0;
- break;
-
- case FILERESUME_SKIP:
- openFlags = _O_BINARY | _O_WRONLY;
- ft->dwFileBytesDone = ft->dwThisFileSize;
- break;
-
- case FILERESUME_RENAME:
- openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY;
- SAFE_FREE(&ft->szThisFile);
- ft->szThisFile = null_strdup(szFilename);
- ft->dwFileBytesDone = 0;
- break;
- }
-
- ft->fileId = OpenFileUtf(ft->szThisFile, openFlags, _S_IREAD | _S_IWRITE);
- if (ft->fileId == -1)
- {
- icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder."));
- NetLib_CloseConnection(&ft->hConnection, FALSE);
- return;
- }
-
- if (action == FILERESUME_RESUME)
- ft->dwFileBytesDone = _lseek(ft->fileId, 0, SEEK_END);
- else
- _lseek(ft->fileId, ft->dwFileBytesDone, SEEK_SET);
-
- ft->dwBytesDone += ft->dwFileBytesDone;
-
- file_sendResume(this, dc);
-
- BroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
-}
-
-
-// small utility function
-void NormalizeBackslash(char* path)
-{
- int len = strlennull(path);
-
- if (len && path[len-1] != '\\') strcat(path, "\\");
-}
-
-/* a file transfer looks like this:
-S: 0
-R: 5
-R: 1
-S: 2
-R: 3
-S: 6 * many
-(for more files, send 2, 3, 6*many)
-*/
-
-void CIcqProto::handleFileTransferPacket(directconnect* dc, PBYTE buf, WORD wLen)
-{
- if (wLen < 1)
- return;
-
- NetLog_Direct("Handling file packet");
-
- switch (buf[0])
- {
- case PEER_FILE_INIT: /* first packet of a file transfer */
- if (dc->initialised)
- return;
- if (wLen < 19)
- return;
- buf += 5; /* id, and unknown 0 */
- dc->type = DIRECTCONN_FILE;
- {
- DWORD dwFileCount;
- DWORD dwTotalSize;
- DWORD dwTransferSpeed;
- WORD wNickLength;
- int bAdded;
-
- unpackLEDWord(&buf, &dwFileCount);
- unpackLEDWord(&buf, &dwTotalSize);
- unpackLEDWord(&buf, &dwTransferSpeed);
- unpackLEWord(&buf, &wNickLength);
-
- dc->ft = FindExpectedFileRecv(dc->dwRemoteUin, dwTotalSize);
- if (dc->ft == NULL)
- {
- NetLog_Direct("Unexpected file receive");
- CloseDirectConnection(dc);
- return;
- }
- dc->ft->dwFileCount = dwFileCount;
- dc->ft->dwTransferSpeed = dwTransferSpeed;
- dc->ft->hContact = HContactFromUIN(dc->ft->dwUin, &bAdded);
- dc->ft->dwBytesDone = 0;
- dc->ft->iCurrentFile = -1;
- dc->ft->fileId = -1;
- dc->ft->hConnection = dc->hConnection;
- dc->ft->dwLastNotify = GetTickCount();
-
- dc->initialised = 1;
-
- file_sendTransferSpeed(this, dc);
- file_sendNick(this, dc);
- }
- BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, dc->ft, 0);
- break;
-
- case PEER_FILE_INIT_ACK:
- if (wLen < 8)
- return;
- buf++;
- unpackLEDWord(&buf, &dc->ft->dwTransferSpeed);
- /* followed by nick */
- file_sendNextFile(this, dc);
- break;
-
- case PEER_FILE_NEXTFILE:
- if (wLen < 20)
- return;
- buf++; /* id */
- {
- char *szAnsi;
- WORD wThisFilenameLen, wSubdirLen;
- BYTE isDirectory;
-
- unpackByte(&buf, &isDirectory);
- unpackLEWord(&buf, &wThisFilenameLen);
- if (wLen < 19 + wThisFilenameLen)
- return;
- SAFE_FREE(&dc->ft->szThisFile);
- szAnsi = (char *)_alloca(wThisFilenameLen + 1);
- memcpy(szAnsi, buf, wThisFilenameLen);
- szAnsi[wThisFilenameLen] = '\0';
- dc->ft->szThisFile = ansi_to_utf8(szAnsi);
- buf += wThisFilenameLen;
-
- unpackLEWord(&buf, &wSubdirLen);
- if (wLen < 18 + wThisFilenameLen + wSubdirLen)
- return;
- SAFE_FREE(&dc->ft->szThisSubdir);
- szAnsi = (char *)_alloca(wSubdirLen + 1);
- memcpy(szAnsi, buf, wSubdirLen);
- szAnsi[wSubdirLen] = '\0';
- dc->ft->szThisSubdir = ansi_to_utf8(szAnsi);
- buf += wSubdirLen;
-
- unpackLEDWord(&buf, &dc->ft->dwThisFileSize);
- unpackLEDWord(&buf, &dc->ft->dwThisFileDate);
- unpackLEDWord(&buf, &dc->ft->dwTransferSpeed);
-
- /* no cheating with paths */
- if (!IsValidRelativePath(dc->ft->szThisFile) || !IsValidRelativePath(dc->ft->szThisSubdir))
- {
- NetLog_Direct("Invalid path information");
- break;
- }
-
- char *szFullPath = (char*)SAFE_MALLOC(strlennull(dc->ft->szSavePath)+strlennull(dc->ft->szThisSubdir)+strlennull(dc->ft->szThisFile)+3);
- strcpy(szFullPath, dc->ft->szSavePath);
- NormalizeBackslash(szFullPath);
- strcat(szFullPath, dc->ft->szThisSubdir);
- NormalizeBackslash(szFullPath);
-// _chdir(szFullPath); // set current dir - not very useful
- strcat(szFullPath, dc->ft->szThisFile);
- // we joined the full path to dest file
- SAFE_FREE(&dc->ft->szThisFile);
- dc->ft->szThisFile = szFullPath;
-
- dc->ft->dwFileBytesDone = 0;
- dc->ft->iCurrentFile++;
-
- if (isDirectory)
- {
- MakeDirUtf(dc->ft->szThisFile);
- dc->ft->fileId = -1;
- }
- else
- {
- /* file resume */
- PROTOFILETRANSFERSTATUS pfts = {0};
-
- file_buildProtoFileTransferStatus(dc->ft, &pfts);
- if (BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, dc->ft, (LPARAM)&pfts))
- break; /* UI supports resume: it will call PS_FILERESUME */
-
- dc->ft->fileId = OpenFileUtf(dc->ft->szThisFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE);
- if (dc->ft->fileId == -1)
- {
- icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder."));
- CloseDirectConnection(dc);
- dc->ft->hConnection = NULL;
- break;
- }
- }
- }
- file_sendResume(this, dc);
- BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, dc->ft, 0);
- break;
-
- case PEER_FILE_RESUME:
- if (dc->ft->fileId == -1 && !dc->ft->currentIsDir)
- return;
- if (wLen < 13)
- return;
- if (wLen < 17)
- NetLog_Direct("Warning: Received short PEER_FILE_RESUME");
- buf++;
- {
- DWORD dwRestartFrom;
-
- unpackLEDWord(&buf, &dwRestartFrom);
- if (dwRestartFrom > dc->ft->dwThisFileSize)
- return;
- buf += 4; /* unknown. 0 */
- unpackLEDWord(&buf, &dc->ft->dwTransferSpeed);
- buf += 4; /* unknown. 1 */
- if (!dc->ft->currentIsDir)
- _lseek(dc->ft->fileId, dwRestartFrom, 0);
- dc->wantIdleTime = 1;
- dc->ft->dwBytesDone += dwRestartFrom;
- dc->ft->dwFileBytesDone += dwRestartFrom;
- }
- break;
-
- case PEER_FILE_SPEED:
- if (wLen < 5)
- return;
- buf++;
- unpackLEDWord(&buf, &dc->ft->dwTransferSpeed);
- dc->ft->dwLastNotify = GetTickCount();
- break;
-
- case PEER_FILE_DATA:
- if (!dc->ft->currentIsDir)
- {
- if (dc->ft->fileId == -1)
- break;
- buf++; wLen--;
- _write(dc->ft->fileId, buf, wLen);
- }
- else
- wLen = 0;
- dc->ft->dwBytesDone += wLen;
- dc->ft->dwFileBytesDone += wLen;
- if (GetTickCount() > dc->ft->dwLastNotify + 500 || wLen < 2048)
- {
- PROTOFILETRANSFERSTATUS pfts;
-
- file_buildProtoFileTransferStatus(dc->ft, &pfts);
- BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, dc->ft, (LPARAM)&pfts);
- dc->ft->dwLastNotify = GetTickCount();
- }
- if (wLen < 2048)
- {
- /* EOF */
- if (!dc->ft->currentIsDir)
- _close(dc->ft->fileId);
- dc->ft->fileId = -1;
- if ((DWORD)dc->ft->iCurrentFile == dc->ft->dwFileCount - 1)
- {
- dc->type = DIRECTCONN_CLOSING; /* this guarantees that we won't accept any more data but that the sender is still free to closesocket() neatly */
- BroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dc->ft, 0);
- }
- }
- break;
-
- default:
- NetLog_Direct("Unknown file transfer packet ignored.");
- break;
- }
-}