You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1360 lines
32 KiB
1360 lines
32 KiB
/* xfr_srcv.c -- transfer service routines
|
|
*
|
|
* Copyright 1990 by Hilgraeve Inc. -- Monroe, MI
|
|
* All rights reserved
|
|
*
|
|
* $Revision: 13 $
|
|
* $Date: 5/21/02 9:58a $
|
|
*/
|
|
|
|
#include <windows.h>
|
|
#pragma hdrstop
|
|
|
|
#define BYTE char
|
|
|
|
#include <tdll\stdtyp.h>
|
|
#include <tdll\comdev.h>
|
|
#include <tdll\com.h>
|
|
#include <tdll\com.hh>
|
|
#include <tdll\session.h>
|
|
#include <tdll\assert.h>
|
|
#include <tdll\file_msc.h>
|
|
#include <tdll\xfer_msc.hh>
|
|
#include <tdll\file_io.h>
|
|
#include <tdll\tdll.h>
|
|
#include <tdll\htchar.h>
|
|
#include <tdll\misc.h>
|
|
#include <tdll\globals.h>
|
|
#include <tdll\errorbox.h>
|
|
#include <term\res.h>
|
|
|
|
#include "itime.h"
|
|
|
|
#include "xfer.h"
|
|
#include "xfer.hh"
|
|
|
|
#include "xfer_tsc.h"
|
|
#include "xfr_srvc.h"
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*
|
|
* *
|
|
* R E A D M E *
|
|
* *
|
|
* Everybody keeps changing the TIME standard to whatever they feel might be *
|
|
* a little bit better for them. So far I have found 3 different standards *
|
|
* in Microsoft functions. This does not even count the fact that HyperP *
|
|
* uses its own format for time. *
|
|
* *
|
|
* Henceforth, all time values that are passed around in the program will be *
|
|
* based on the old UCT format of the number of seconds since Jan 1, 1970. *
|
|
* *
|
|
* Please use an unsigned long for these values. *
|
|
* *
|
|
*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_set_pointer
|
|
*
|
|
* DESCRIPTION:
|
|
* When a transfer is started, it is passed a parameter block. This is
|
|
* where the address of that block gets stored.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* pV -- pointer to the parameter block
|
|
*
|
|
* RETURNS:
|
|
* Nothing.
|
|
*
|
|
*/
|
|
void xfer_set_pointer(HSESSION hSession, void *pV)
|
|
{
|
|
XD_TYPE *pX;
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX)
|
|
{
|
|
pX->pXferStuff = pV;
|
|
}
|
|
}
|
|
|
|
void *xfer_get_pointer(HSESSION hSession)
|
|
{
|
|
XD_TYPE *pX;
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX)
|
|
{
|
|
return (void *)pX->pXferStuff;
|
|
}
|
|
return (void *)0;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_idle
|
|
*
|
|
* DESCRIPTION:
|
|
* This function got called in Windows to make sure that the transfer
|
|
* display (and other tasks) got some time every now and then during a
|
|
* transfer. I don't know if this needs to be done under CHICAGO, with
|
|
* a pre-emptive multi-tasking design. The call is still here until it
|
|
* can be determined one way or another.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
*
|
|
* RETURNS:
|
|
* Nothing.
|
|
*
|
|
*/
|
|
|
|
#define IDLE_WAIT 150
|
|
|
|
void xfer_idle(HSESSION h, int nMode)
|
|
{
|
|
/*
|
|
* This is set up for the mode flags to be OR'ed together if necessary
|
|
*/
|
|
if (nMode & XFER_IDLE_IO)
|
|
{
|
|
HCOM hComHandle = sessQueryComHdl(h);
|
|
|
|
if (hComHandle && ComValidHandle(hComHandle) &&
|
|
(hComHandle->pfPortConnected)(hComHandle->pvDriverData) == COM_PORT_OPEN);
|
|
{
|
|
HANDLE hComEvent = ComGetRcvEvent(hComHandle);
|
|
|
|
if (hComEvent)
|
|
{
|
|
WaitForSingleObject(hComEvent, IDLE_WAIT);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nMode & XFER_IDLE_DISPLAY)
|
|
{
|
|
/*
|
|
* The documentation says that this caused the thread to yield,
|
|
* presumably back to the scheduler cycle. It tries to let the
|
|
* display update if possible.
|
|
*/
|
|
Sleep(0);
|
|
}
|
|
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_user_interrupt
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called by the transfer routines to determine if the user
|
|
* has hit any of the cancel or skip buttons in the display window.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle.
|
|
*
|
|
* RETURNS:
|
|
* ZERO if nothing to report, otherwise a CANCEL or SKIP indicator.
|
|
*
|
|
*/
|
|
int xfer_user_interrupt(HSESSION hSession)
|
|
{
|
|
INT nRetVal;
|
|
XD_TYPE *pX;
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX == NULL)
|
|
{
|
|
// DbgOutStr("xfer_user_interrupt returns an error\r\n", 0,0,0,0,0);
|
|
return FALSE;
|
|
}
|
|
|
|
switch (pX->nUserCancel)
|
|
{
|
|
case XFER_ABORT:
|
|
nRetVal = XFER_ABORT;
|
|
pX->nUserCancel = 0; // Reset to default value
|
|
// DbgOutStr("xfer_user_interrupt returns 1\r\n", 0,0,0,0,0);
|
|
break;
|
|
|
|
case XFER_SKIP:
|
|
nRetVal = XFER_SKIP;
|
|
pX->nUserCancel = 0; // Reset to default value
|
|
// DbgOutStr("xfer_user_interrupt returns 2\r\n", 0,0,0,0,0);
|
|
break;
|
|
|
|
default:
|
|
// DbgOutStr("xfer_user_interrupt returns 0\r\n", 0,0,0,0,0);
|
|
nRetVal = 0;
|
|
break;
|
|
}
|
|
return nRetVal;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_user_abort
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
int xfer_user_abort(HSESSION hSession, int p)
|
|
{
|
|
XD_TYPE *pX;
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX == NULL)
|
|
{
|
|
// TODO: decide if we need CLoopClearOutput
|
|
// CLoopClearOutput(sessQueryCLoopHdl(hSession));
|
|
return TRUE;
|
|
}
|
|
|
|
switch (p)
|
|
{
|
|
case 0:
|
|
case XFER_ABORT:
|
|
case XFER_SKIP:
|
|
pX->nUserCancel = p;
|
|
break;
|
|
default:
|
|
pX->nUserCancel = 0;
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_carrier_lost
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called by the transfer routines to determine if the
|
|
* session is still connected to something.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
*
|
|
* RETURNS:
|
|
* TRUE if carrier has been lost, otherwise FALSE;
|
|
*
|
|
*/
|
|
int xfer_carrier_lost(HSESSION hSession)
|
|
{
|
|
XD_TYPE *pX;
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX == NULL)
|
|
{
|
|
// DbgOutStr("xfer_user_interrupt returns an error\r\n", 0,0,0,0,0);
|
|
return FALSE;
|
|
}
|
|
|
|
return pX->nCarrierLost; // Set by the COM the driver (ComActivatePort()
|
|
// and ComDeactivatePort()) and the transfer
|
|
// display (WM_INITDIALOG and XFER_LOST_CARRIER
|
|
// messages to XfrDisplayDlg()). REV: 9/7/2001
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_purgefile
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called after a VIRUS has been detected. It is supposed
|
|
* to make sure that whatever was written out to disk from the infected file
|
|
* gets seriously blasted.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* fname -- the name of the file
|
|
*
|
|
* RETURNS:
|
|
* Nothing.
|
|
*
|
|
*/
|
|
void xfer_purgefile(HSESSION hSession, TCHAR *fname)
|
|
{
|
|
|
|
/*
|
|
* Given the way buffering and deletion recovery can be done in modern
|
|
* systems, I am not real sure what should be done here.
|
|
*/
|
|
DeleteFile(fname);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfrUniqueName
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to build a NEW (currently unused) file name from
|
|
* an existing file name by using a sequential numbering operation.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* pszSrc -- the origional file name
|
|
* pszDst -- where to put the new file name
|
|
*
|
|
* RETURNS:
|
|
* 0 if everything is OK, otherwise a negative number.
|
|
*
|
|
*/
|
|
static int xfrUniqueName(HSESSION hSession, LPTSTR pszSrc, LPTSTR pszDst)
|
|
{
|
|
int nRetVal = -1;
|
|
TCHAR szSrc[MAX_PATH];
|
|
TCHAR szName[MAX_PATH];
|
|
TCHAR szTag[10]; // big enough to hold "0" to "9999"
|
|
TCHAR *pszFName = NULL;
|
|
TCHAR *pszExtension = NULL;
|
|
TCHAR *pszScan = NULL;
|
|
long nComponentSize = 0L;
|
|
int nNameSpace;
|
|
int nTag = 0;
|
|
int nSize = 0;
|
|
|
|
// Let Operating system figure out full name. This will also set pszFName
|
|
// to point to the file name component of the path.
|
|
nSize = GetFullPathName(pszSrc, MAX_PATH, szSrc, &pszFName);
|
|
if (nSize)
|
|
{
|
|
if (pszFName)
|
|
{
|
|
// Copy name portion off for later manipulation and remove ext.
|
|
StrCharCopy(szName, pszFName);
|
|
mscStripExt(szName);
|
|
|
|
// Isolate the dir portion of the path
|
|
pszScan = StrCharPrev(szSrc, pszFName);
|
|
if (pszScan)
|
|
*pszScan = TEXT('\0');
|
|
|
|
// Keep pointer to extension, if any, in original string
|
|
pszExtension = StrCharFindLast(pszFName, TEXT('.'));
|
|
}
|
|
|
|
// Find maximum length of path component (this is platform dependent)
|
|
|
|
// TODO:jkh, 12/19/94 Different drives may use different sizes
|
|
if (!GetVolumeInformation(NULL, NULL, 0, NULL, &nComponentSize,
|
|
NULL, NULL, 0))
|
|
nComponentSize = 12; // Safest size if call fails
|
|
|
|
// Try attaching numeric tags to the name until name is unique
|
|
nNameSpace = nComponentSize - StrCharGetByteCount(pszExtension);
|
|
for (nTag = 0; nTag < 10000; ++nTag)
|
|
{
|
|
_itoa(nTag, szTag, 10);
|
|
// make sure tag will fit on filename
|
|
while (StrCharGetByteCount(szName) >
|
|
nNameSpace - StrCharGetByteCount(szTag))
|
|
{
|
|
pszScan = StrCharLast(szName);
|
|
*pszScan = TEXT('\0');
|
|
}
|
|
StrCharCopy(pszDst, szSrc); // start with dir portion
|
|
StrCharCat(pszDst, TEXT("\\")); // separator
|
|
StrCharCat(pszDst, szName); // original file name (truncated)
|
|
StrCharCat(pszDst, szTag); // numeric tag to make unique
|
|
StrCharCat(pszDst, pszExtension); // Extension (if any)
|
|
|
|
if (!mscIsDirectory(pszDst) && !GetFileSizeFromName(pszDst, 0))
|
|
{
|
|
nRetVal = 0;
|
|
break; /* Exit with good name */
|
|
}
|
|
}
|
|
}
|
|
|
|
return nRetVal;
|
|
}
|
|
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfrUniqueDateName
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to build a NEW (currently unused) file name from
|
|
* an existing file name by using the current data/time.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* pszSrc -- the origional file name
|
|
* pszDst -- where to put the new file name
|
|
*
|
|
* RETURNS:
|
|
* 0 if everything is OK, otherwise a negative number.
|
|
*
|
|
*/
|
|
static int xfrUniqueDateName(HSESSION hSession, LPTSTR pszSrc, LPTSTR pszDst)
|
|
{
|
|
int nRet = 0;
|
|
int nTag;
|
|
LPTSTR pszDir;
|
|
LPTSTR pszExt;
|
|
SYSTEMTIME stT;
|
|
TCHAR acDatestr[8];
|
|
TCHAR acFrm[16];
|
|
TCHAR acSrc[FNAME_LEN];
|
|
TCHAR acDst[FNAME_LEN];
|
|
|
|
/* Get a pointer to the path portion only */
|
|
StrCharCopy(acSrc, pszSrc);
|
|
pszDir = acSrc;
|
|
pszExt = StrCharFindLast(acSrc, TEXT('\\'));
|
|
|
|
/* Get a pointer to the file name section */
|
|
nTag = 0;
|
|
while ((*pszExt != TEXT('.')) && (nTag < 8))
|
|
acFrm[nTag++] = *pszExt++;
|
|
acFrm[nTag] = TEXT('\0');
|
|
if (StrCharGetByteCount(acFrm) == 0)
|
|
StrCharCopy(acFrm, TEXT("D"));
|
|
|
|
/* Get a pointer to the extension */
|
|
pszExt = StrCharFindLast(pszDst, TEXT('.'));
|
|
if (pszExt == NULL)
|
|
pszExt = ".FIL";
|
|
|
|
GetLocalTime(&stT);
|
|
wsprintf(acDatestr, "%x%02d%02d%1d",
|
|
stT.wMonth,
|
|
stT.wDay,
|
|
stT.wHour,
|
|
stT.wMinute % 10);
|
|
acFrm[8 - StrCharGetByteCount(acDatestr)] = TEXT('\0');
|
|
|
|
wsprintf(acDst, "%s%s%s%s",
|
|
pszDir,
|
|
acFrm,
|
|
acDatestr,
|
|
pszExt);
|
|
|
|
return xfrUniqueName(hSession, acDst, pszDst);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_modify_rcv_name
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to modify the name as necessary based on the users
|
|
* parameters.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* pszName -- the file name
|
|
* lTime -- our internal time format, see READ ME above
|
|
* lFlags -- flags
|
|
* pfFlags -- pointer to returned flags
|
|
*
|
|
* RETURNS:
|
|
* 0 -- everything was OK
|
|
* -1 -- file error
|
|
* -2 -- reject due to date
|
|
* -4 -- no date, time provided
|
|
* -6 -- unconditinally refuse file
|
|
* -7 -- general failure
|
|
*
|
|
*/
|
|
int xfer_modify_rcv_name(HSESSION hSession,
|
|
LPTSTR pszName,
|
|
unsigned long ulTime,
|
|
long lFlags,
|
|
int *pfFlags)
|
|
{
|
|
int nRetVal = 0;
|
|
int nOpenFlags = 0;
|
|
int isFile = 0;
|
|
unsigned long locTime;
|
|
TCHAR szNewName[FNAME_LEN];
|
|
DWORD dwRetVal;
|
|
|
|
isFile = GetFileSizeFromName(pszName, NULL);
|
|
|
|
if (isFile == FALSE)
|
|
{
|
|
nOpenFlags = 0;
|
|
}
|
|
else
|
|
{
|
|
switch (lFlags)
|
|
{
|
|
case XFR_RO_APPEND:
|
|
nOpenFlags = TRUE;
|
|
break;
|
|
|
|
case XFR_RO_ALWAYS:
|
|
nOpenFlags = 0;
|
|
break;
|
|
|
|
case XFR_RO_NEWER:
|
|
if (ulTime != 0) // Let's check the time.
|
|
{
|
|
locTime = itimeGetFileTime(pszName);
|
|
if (locTime != 0)
|
|
if (locTime <= ulTime) // File is newer, accept it.
|
|
nOpenFlags = 0;
|
|
else
|
|
nRetVal = -2; // Reject it due to date.
|
|
else
|
|
nRetVal = -1; // File error...
|
|
}
|
|
else
|
|
nRetVal = -4; // No date, time supplied.
|
|
break;
|
|
|
|
case XFR_RO_REN_DATE:
|
|
//
|
|
// Build a new name, based upon the date of the new file.
|
|
//
|
|
nRetVal = xfrUniqueDateName(hSession, pszName, pszName);
|
|
if (nRetVal < 0)
|
|
nRetVal = -7; // Ambiguous file name.
|
|
nOpenFlags = 0;
|
|
break;
|
|
|
|
default:
|
|
case XFR_RO_REN_SEQ:
|
|
//
|
|
// Build a new name, based upon a sequence number algorithm.
|
|
//
|
|
nRetVal = xfrUniqueName(hSession, pszName, szNewName);
|
|
if (nRetVal < 0)
|
|
nRetVal = -7; // Ambiguous file name.
|
|
else
|
|
{
|
|
dwRetVal = GetFileAttributes(pszName);
|
|
if (dwRetVal != 0xFFFFFFFF &&
|
|
(dwRetVal & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
|
{
|
|
nRetVal = -8; // File is a directory
|
|
}
|
|
else if (MoveFile(pszName, szNewName) == FALSE)
|
|
{
|
|
nRetVal = -8; // File is opened
|
|
}
|
|
}
|
|
nOpenFlags = 0;
|
|
break;
|
|
|
|
case XFR_RO_NEVER:
|
|
nRetVal = -6;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (nRetVal >= 0)
|
|
*pfFlags = nOpenFlags;
|
|
|
|
return nRetVal;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_makepaths
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to make sure that a pathname exists. It creates
|
|
* whatever portion of the pathname needs to be created.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* pszPath -- the path
|
|
*
|
|
* RETURNS:
|
|
* 0 -- everything was OK
|
|
* -1 -- bad path format
|
|
* -2 -- disk error of some sort
|
|
*
|
|
*/
|
|
int xfer_makepaths(HSESSION hSession, LPTSTR pszPath)
|
|
{
|
|
TCHAR ach[256];
|
|
TCHAR achFormat[256];
|
|
TCHAR ach2[50];
|
|
|
|
if (pszPath == 0)
|
|
return -1;
|
|
|
|
if (!mscIsDirectory(pszPath))
|
|
{
|
|
if (LoadString(glblQueryDllHinst(), IDS_GNRL_CREATE_PATH, achFormat,
|
|
sizeof(achFormat) / sizeof(TCHAR)) == 0)
|
|
{
|
|
DbgShowLastError();
|
|
return -3;
|
|
}
|
|
|
|
if (LoadString(glblQueryDllHinst(), IDS_MB_TITLE_WARN, ach2,
|
|
sizeof(ach2) / sizeof(TCHAR)) == 0)
|
|
{
|
|
DbgShowLastError();
|
|
return -4;
|
|
}
|
|
|
|
wsprintf(ach, achFormat, pszPath);
|
|
|
|
if (TimedMessageBox(sessQueryHwnd(hSession), ach, ach2,
|
|
MB_YESNO | MB_TASKMODAL | MB_ICONEXCLAMATION,
|
|
sessQueryTimeout(hSession)) == IDYES)
|
|
{
|
|
if (mscCreatePath(pszPath) != 0)
|
|
{
|
|
assert(0);
|
|
return -2;
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
return -5;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_create_rcv_file
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to open the file for receiving. It has the code
|
|
* to create the path to the file for those protocols that can transfer a
|
|
* path as well as a file name.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* pszName -- the complete path name of the file
|
|
* lOpenFlags -- the flags to pass to fio_open
|
|
* nowdays TRUE means APPEND, FALSE means overwrite
|
|
* phRet -- where to return the file handle
|
|
*
|
|
* RETURNS:
|
|
* 0 -- everything was OK
|
|
* -1 -- couldn't create the file
|
|
*
|
|
*/
|
|
int xfer_create_rcv_file(HSESSION hSession,
|
|
LPTSTR pszName,
|
|
long lOpenFlags,
|
|
HANDLE *phRet)
|
|
{
|
|
ST_IOBUF *hFile;
|
|
LPTSTR pszStr;
|
|
TCHAR acDir[FNAME_LEN];
|
|
|
|
StrCharCopy(acDir, pszName);
|
|
pszStr = StrCharLast(acDir);
|
|
while ((*pszStr != TEXT('\\')) && (pszStr > acDir))
|
|
pszStr = StrCharPrev(acDir, pszStr);
|
|
|
|
if (pszStr == acDir)
|
|
return -1;
|
|
|
|
*pszStr = TEXT('\0');
|
|
if (xfer_makepaths(hSession, acDir) < 0)
|
|
return -1;
|
|
|
|
if (lOpenFlags)
|
|
{
|
|
/* Open for appending */
|
|
hFile = fio_open(pszName, FIO_APPEND | FIO_WRITE);
|
|
}
|
|
else
|
|
{
|
|
hFile = fio_open(pszName, FIO_CREATE | FIO_WRITE);
|
|
}
|
|
if (hFile == NULL)
|
|
return -1;
|
|
|
|
*phRet = hFile;
|
|
return 0;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_open_rcv_file
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to actually do the open of the receive file. It
|
|
* calls a bunch of other stuff, fiddles with names, and eventually returns.
|
|
*
|
|
* PARAMETERS:
|
|
* hSesssion -- the session handle
|
|
* pstRcv -- pointer to the receive open structure
|
|
* ulOverRide -- if set, flags to use instead of contents of pstRcv
|
|
*
|
|
* RETURNS:
|
|
* 0 if A-OK
|
|
* -1 if error occurred
|
|
* -2 if rejected due to date
|
|
* -3 if rejected because it can't save file
|
|
* -4 if no date/time supplied when required
|
|
* -5 if unable to create needed directories
|
|
* -6 if file rejected unconditionally
|
|
* -7 if general failure
|
|
*
|
|
*/
|
|
int xfer_open_rcv_file(HSESSION hSession,
|
|
struct st_rcv_open *pstRcv,
|
|
unsigned long ulOverRide)
|
|
{
|
|
unsigned long ulFlags = 0;
|
|
int nOpenFlags;
|
|
int nRetVal = 0;
|
|
#if FALSE
|
|
// Lower Wacker does not support message logging
|
|
int msgIndex = -1;
|
|
#endif
|
|
XD_TYPE *pX;
|
|
XFR_PARAMS *pP;
|
|
|
|
pstRcv->bfHdl = NULL;
|
|
pstRcv->lInitialSize = 0;
|
|
|
|
xfer_build_rcv_name(hSession, pstRcv);
|
|
|
|
/* Get the overwrite parameters */
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX)
|
|
{
|
|
pP = (XFR_PARAMS *)pX->xfer_params;
|
|
if (pP)
|
|
{
|
|
ulFlags = pP->nRecOverwrite;
|
|
}
|
|
}
|
|
if (ulOverRide != 0)
|
|
ulFlags = ulOverRide;
|
|
|
|
nRetVal = xfer_modify_rcv_name(hSession,
|
|
pstRcv->pszActualName,
|
|
pstRcv->lFileTime,
|
|
ulFlags,
|
|
&nOpenFlags);
|
|
|
|
if (nRetVal >= 0)
|
|
{
|
|
HANDLE lRet;
|
|
unsigned long size;
|
|
|
|
size = 0;
|
|
// if (nOpenFlags & O_APPEND)
|
|
if (nOpenFlags)
|
|
{
|
|
if (!GetFileSizeFromName(pstRcv->pszActualName, &size))
|
|
{
|
|
size = 0;
|
|
}
|
|
}
|
|
|
|
nRetVal = xfer_create_rcv_file(hSession,
|
|
pstRcv->pszActualName,
|
|
nOpenFlags,
|
|
&lRet);
|
|
if (nRetVal >= 0)
|
|
{
|
|
pstRcv->bfHdl = lRet;
|
|
|
|
// if (nOpenFlags & O_APPEND)
|
|
if (nOpenFlags)
|
|
{
|
|
pstRcv->lInitialSize = size;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if FALSE
|
|
// Lower Wacker does not support logging
|
|
if (nRetVal < 0)
|
|
{
|
|
switch (nRetVal)
|
|
{
|
|
case -6: // File was rejected unconditionally
|
|
msgIndex = 23; // "User refused"
|
|
break;
|
|
case -5: // Were unable to create needed directories
|
|
msgIndex = 11; // "Fatal disk error"
|
|
break;
|
|
case -4: // No date, time supplied when required
|
|
msgIndex = 17; // "No file time available"
|
|
break;
|
|
case -3: // File could not be saved
|
|
msgIndex = 9; // "Cannot writ file to disk"
|
|
break;
|
|
case -2: // File was rejected due to date
|
|
msgIndex = 16; // "File is too old"
|
|
break;
|
|
case -1: // Some error occured
|
|
msgIndex = 10; // "Cannot open file"
|
|
break;
|
|
default: // Failed
|
|
msgIndex = 19; // "General failure"
|
|
break;
|
|
}
|
|
xfer_log_xfer( hSession,
|
|
FALSE,
|
|
pstRcv->pszSuggestedName,
|
|
pstRcv->pszActualName,
|
|
msgIndex );
|
|
}
|
|
#endif
|
|
|
|
return nRetVal;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_build_rcv_name
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to help build the name of the file that the
|
|
* transfer receive code is going to dump the data into.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* pstRcv -- pointer to the receive open structure (contains the name)
|
|
*
|
|
* RETURNS:
|
|
* Nothing.
|
|
*
|
|
*/
|
|
void xfer_build_rcv_name(HSESSION hSession,
|
|
struct st_rcv_open *pstRcv)
|
|
{
|
|
int nSingle;
|
|
XD_TYPE *pX;
|
|
XFR_PARAMS *pP;
|
|
XFR_RECEIVE *pR;
|
|
#if defined(INC_VSCAN)
|
|
SSHDLMCH ssVscanMch;
|
|
#endif
|
|
LPTSTR pszStr;
|
|
TCHAR acBuffer[FNAME_LEN];
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX)
|
|
{
|
|
pP = (XFR_PARAMS *)pX->xfer_params;
|
|
if (pP)
|
|
{
|
|
/* Just continue on to the rest of the function */
|
|
}
|
|
else
|
|
{
|
|
assert(FALSE);
|
|
return;
|
|
}
|
|
pR = pX->pXferStuff;
|
|
if (pR)
|
|
{
|
|
/* Just continue on to the rest of the function */
|
|
}
|
|
else
|
|
{
|
|
assert(FALSE);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert(FALSE);
|
|
return;
|
|
}
|
|
|
|
nSingle = !pP->fUseFilenames;
|
|
nSingle |= (pP->nRecProtocol == XF_XMODEM);
|
|
nSingle |= (pP->nRecProtocol == XF_XMODEM_1K);
|
|
|
|
if (nSingle)
|
|
{
|
|
/* User specified a single file */
|
|
StrCharCopy(acBuffer, pR->pszDir);
|
|
pszStr = (LPTSTR)StrCharLast(acBuffer);
|
|
if (*pszStr != TEXT('\\'))
|
|
{
|
|
pszStr += 1;
|
|
*pszStr = TEXT('\\');
|
|
pszStr += 1;
|
|
*pszStr = TEXT('\0');
|
|
}
|
|
StrCharCat(acBuffer, pR->pszName);
|
|
|
|
fileFinalizeName(
|
|
acBuffer, /* values to use */
|
|
pstRcv->pszSuggestedName, /* filler */
|
|
pstRcv->pszActualName,
|
|
MAX_PATH);
|
|
}
|
|
else if (!pP->fUseDirectory)
|
|
{
|
|
/* Use directory flag is not set */
|
|
//
|
|
// Ignore all paths sent to us in this case.
|
|
//
|
|
pszStr = StrCharLast(pstRcv->pszSuggestedName);
|
|
|
|
/* TODO: fix this up for wide characters */
|
|
while (pszStr >= pstRcv->pszSuggestedName)
|
|
{
|
|
if ((*pszStr == TEXT('\\')) || (*pszStr == TEXT(':')))
|
|
{
|
|
StrCharCopy(pstRcv->pszSuggestedName, ++pszStr);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (pszStr == pstRcv->pszSuggestedName)
|
|
break;
|
|
pszStr = (LPTSTR)StrCharPrev(pstRcv->pszSuggestedName, pszStr);
|
|
}
|
|
}
|
|
|
|
fileFinalizeName(
|
|
pstRcv->pszSuggestedName, /* values to use */
|
|
pR->pszDir, /* filler */
|
|
pstRcv->pszActualName,
|
|
MAX_PATH);
|
|
}
|
|
else
|
|
{
|
|
/* I am not a all sure about this stuff */
|
|
if ((pstRcv->pszSuggestedName[0] == TEXT('\\')) ||
|
|
(pstRcv->pszSuggestedName[1] == TEXT(':')))
|
|
{
|
|
/* if full path given */
|
|
StrCharCopy(pstRcv->pszActualName, pstRcv->pszSuggestedName);
|
|
}
|
|
else
|
|
{
|
|
/* else use our path 1st */
|
|
StrCharCopy(pstRcv->pszActualName, pR->pszDir);
|
|
if ((pR->pszName != NULL) &&
|
|
(StrCharGetByteCount(pR->pszName) > 0))
|
|
StrCharCat(pstRcv->pszActualName, pR->pszName);
|
|
else
|
|
StrCharCat(pstRcv->pszActualName, pstRcv->pszSuggestedName);
|
|
|
|
fileFinalizeName(
|
|
pstRcv->pszActualName, /* values to use */
|
|
pstRcv->pszSuggestedName, /* filler */
|
|
pstRcv->pszActualName,
|
|
MAX_PATH);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_close_rcv_file
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called at the end of a transfer. It does various things
|
|
* such as setting the file time/date, the size, saving partial files, and
|
|
* logging the transfer. A cleanup routine.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* fhdl -- the actual file handle
|
|
* nReason -- transfer status code
|
|
* pszRemoteName -- the file name as it was sent to us
|
|
* pszOurName -- the file name we actually used to save the data
|
|
* nSave -- partial save flag
|
|
* lFilesize -- size to set the file to
|
|
* lTime -- date/time value to use to set the file
|
|
*
|
|
* RETURNS:
|
|
* TRUE if the transfer was successful, otherwise FALSE.
|
|
*
|
|
*/
|
|
int xfer_close_rcv_file(HSESSION Hsession,
|
|
void *vhdl,
|
|
int nReason,
|
|
TCHAR *pszRemoteName,
|
|
TCHAR *pszOurName,
|
|
int nSave,
|
|
unsigned long lFilesize,
|
|
unsigned long lTime) /* Fix this later */
|
|
{
|
|
ST_IOBUF *fhdl = (ST_IOBUF *)vhdl;
|
|
|
|
if (nReason == TSC_COMPLETE)
|
|
nReason = TSC_OK;
|
|
|
|
if (fio_close(fhdl) == 0)
|
|
{
|
|
/* Set the size */
|
|
if (lFilesize > 0 && nReason == TSC_OK) /*lFilesize != 0 jmh 03-08-96 */
|
|
SetFileSize(pszOurName, lFilesize);
|
|
|
|
/* Set the date/time */
|
|
if (lTime != 0)
|
|
itimeSetFileTime(pszOurName, lTime);
|
|
}
|
|
else
|
|
{
|
|
nReason = TSC_DISK_ERROR;
|
|
}
|
|
|
|
#if FALSE
|
|
// Lower Wacker does not log transfers */
|
|
xfer_log_xfer(hSession, FALSE, pszRemoteName, pszOurName, nReason);
|
|
#endif
|
|
|
|
if (nReason == TSC_OLDER_FILE)
|
|
nReason = TSC_OK;
|
|
|
|
if (nReason != TSC_OK && pszOurName && *pszOurName)
|
|
{
|
|
if (nSave == FALSE)
|
|
DeleteFile(pszOurName);
|
|
}
|
|
|
|
if (nReason == TSC_LOST_CARRIER)
|
|
{
|
|
nReason = TSC_OK;
|
|
}
|
|
|
|
return (nReason == TSC_OK);
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_get_params
|
|
*
|
|
* DESCRIPTION:
|
|
* This function gets the protocol specific parameters for the transfer
|
|
* routines.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* nProtocol -- the protocol ID
|
|
*
|
|
* RETURNS:
|
|
* A pointer to the protocol block, or a NULL.
|
|
*
|
|
*/
|
|
VOID FAR * xfer_get_params(HSESSION hSession, int nProtocol)
|
|
{
|
|
void *pVret = (void *)0;
|
|
XD_TYPE *pX;
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX)
|
|
{
|
|
int nLimit = SFID_PROTO_PARAMS_END - SFID_PROTO_PARAMS;
|
|
if (nProtocol < nLimit)
|
|
{
|
|
if (pX->xfer_proto_params[nProtocol] == NULL)
|
|
{
|
|
int nRet = xfrInitializeParams(hSession,
|
|
nProtocol,
|
|
&pX->xfer_proto_params[nProtocol]);
|
|
assert(nRet == 0);
|
|
}
|
|
pVret = (VOID FAR *)pX->xfer_proto_params[nProtocol];
|
|
}
|
|
}
|
|
return pVret;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_set_comport
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to save the current com port settings so that the
|
|
* transfer code can go ahead and change them to whatever it likes.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* fSending -- TRUE if sending, FALSE if receiving
|
|
* puiOldOptions -- where to store the old settings
|
|
*
|
|
* RETURNS:
|
|
* TRUE if everything was OK, otherwise FALSE
|
|
*
|
|
*/
|
|
int xfer_set_comport(HSESSION hSession, int fSending, unsigned *puiOldOptions)
|
|
{
|
|
unsigned uiOptions = COM_OVERRIDE_8BIT;
|
|
unsigned uiOldOptions;
|
|
|
|
if (fSending)
|
|
bitset(uiOptions, COM_OVERRIDE_SNDALL);
|
|
else
|
|
bitset(uiOptions, COM_OVERRIDE_RCVALL);
|
|
|
|
/* TODO: find out how to decide which things need to be changed, BFMI */
|
|
if (ComOverride(sessQueryComHdl(hSession),
|
|
uiOptions,
|
|
&uiOldOptions) != COM_OK)
|
|
{
|
|
return FALSE;
|
|
}
|
|
if (puiOldOptions != NULL)
|
|
*puiOldOptions = uiOldOptions;
|
|
return TRUE;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_restore_comport
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to restore the parameters that the previous call
|
|
* saved.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* uiOldOptions -- the old comm parameters
|
|
*
|
|
* RETURNS:
|
|
* TRUE if everything was OK, otherwise FALSE
|
|
*
|
|
*/
|
|
int xfer_restore_comport(HSESSION hSession, unsigned uiOldOptions)
|
|
{
|
|
|
|
ComSndBufrWait(sessQueryComHdl(hSession), 10);
|
|
|
|
// Let any trailing data get sent
|
|
ComSndBufrWait(sessQueryComHdl(hSession), 10);
|
|
if (ComOverride(sessQueryComHdl(hSession), uiOldOptions, NULL) != COM_OK)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_save_partial
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called by the transfer routines to decide if it is
|
|
* OK to leave a partial file around if a transfer is aborted.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
*
|
|
* RETURNS:
|
|
* TRUE if it is OK, otherwise FALSE
|
|
*
|
|
*/
|
|
int xfer_save_partial(HSESSION hSession)
|
|
{
|
|
XD_TYPE *pX;
|
|
XFR_PARAMS *pP;
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX)
|
|
{
|
|
pP = (XFR_PARAMS *)pX->xfer_params;
|
|
if (pP)
|
|
{
|
|
return pP->fSavePartial;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_nextfile
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called by the transfer routines to get the name of the
|
|
* next file that is to be sent on over to the other side.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* filename -- where to copy the file name
|
|
*
|
|
* RETURNS:
|
|
* TRUE if there was a filename available, otherwise FALSE
|
|
*
|
|
*/
|
|
int xfer_nextfile(HSESSION hSession, TCHAR *filename)
|
|
{
|
|
XD_TYPE *pX;
|
|
XFR_SEND *pS;
|
|
LPTSTR pszStr;
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX)
|
|
{
|
|
pS = (XFR_SEND *)pX->pXferStuff;
|
|
if (pS)
|
|
{
|
|
if (pS->nIndex < pS->nCount)
|
|
{
|
|
pszStr = pS->pList[pS->nIndex].pszName;
|
|
StrCharCopy(filename, pszStr);
|
|
pS->nIndex += 1;
|
|
/*
|
|
* TODO: decide where the memory gets freed
|
|
*/
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_log_xfer
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called after a file is sent or received to place that
|
|
* information in the log file.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* sending -- TRUE if the file was sent, otherwise FALSE
|
|
* theirname -- the name that was given to the other system
|
|
* ourname -- the name of the file on this system
|
|
* result -- the final transfer status code
|
|
*
|
|
* RETURNS:
|
|
* Nothing.
|
|
*
|
|
*/
|
|
void xfer_log_xfer(HSESSION hSession,
|
|
int sending,
|
|
TCHAR *theirname,
|
|
TCHAR *ourname,
|
|
int result)
|
|
{
|
|
/*
|
|
* Lower Wacker does not do transfer logging. This is here mostly as a
|
|
* place holder and for the eventual conversion to Upper Wacker.
|
|
*/
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_opensendfile
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to open a file that is to be sent to another
|
|
* system.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* fp -- where to store the open file handle
|
|
* file_to_open -- the name of the file to open (duh!)
|
|
* size -- where to save the size of the file
|
|
* name_to_send -- what name to send to the other system
|
|
* ft -- currently unused
|
|
*
|
|
* RETURNS:
|
|
* 0 if everything is OK
|
|
* -1 if an error occurred
|
|
* -2 if the file was not found
|
|
*
|
|
*/
|
|
int xfer_opensendfile(HSESSION hSession,
|
|
HANDLE *fp,
|
|
TCHAR *file_to_open,
|
|
long *size,
|
|
TCHAR *name_to_send,
|
|
void *ft)
|
|
{
|
|
DWORD dwFoo;
|
|
|
|
*fp = (HANDLE)0;
|
|
|
|
/*
|
|
* Just try an open the file
|
|
*/
|
|
*fp = fio_open(file_to_open, FIO_READ);
|
|
|
|
if (*fp == NULL)
|
|
{
|
|
*fp = (HANDLE)0;
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* Got the file open, get the size
|
|
*/
|
|
*size = GetFileSize(fio_gethandle((ST_IOBUF *)*fp), &dwFoo);
|
|
|
|
/*
|
|
* TODO: do the date and time stuff
|
|
*/
|
|
|
|
/*
|
|
* Give them a file name
|
|
*/
|
|
if (name_to_send != NULL)
|
|
xfer_name_to_send(hSession, file_to_open, name_to_send);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
|
* FUNCTION:
|
|
* xfer_name_to_send
|
|
*
|
|
* DESCRIPTION:
|
|
* This function is called to modify the file name into some sort of form
|
|
* that should be sent over to the other side. Kind of sounds like an
|
|
* exchange of captured spys at Checkpoint Charlie.
|
|
*
|
|
* PARAMETERS:
|
|
* hSession -- the session handle
|
|
* local_name -- what the name is on this system
|
|
* name_to_send -- where to put the processed name
|
|
*
|
|
* RETURNS:
|
|
* Nothing.
|
|
*
|
|
*/
|
|
void xfer_name_to_send(HSESSION hSession,
|
|
TCHAR *local_name,
|
|
TCHAR *name_to_send)
|
|
{
|
|
TCHAR *pszStr;
|
|
XD_TYPE *pX;
|
|
XFR_PARAMS *pP;
|
|
|
|
if (local_name == NULL)
|
|
return;
|
|
if (name_to_send == NULL)
|
|
return;
|
|
|
|
pX = (XD_TYPE *)sessQueryXferHdl(hSession);
|
|
if (pX)
|
|
{
|
|
pP = (XFR_PARAMS *)pX->xfer_params;
|
|
if (pP)
|
|
{
|
|
if (pP->fIncPaths)
|
|
{
|
|
StrCharCopy(name_to_send, local_name);
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
* Otherwise, just do this
|
|
*/
|
|
pszStr = StrCharFindLast(local_name, TEXT('\\'));
|
|
if (*pszStr == TEXT('\\'))
|
|
pszStr += 1;
|
|
StrCharCopy(name_to_send, pszStr);
|
|
}
|