/* Xfer.h */

#ifndef _xfer_h_
#define _xfer_h_	1

#ifndef _ftp_h_
#include "FTP.h"
#endif

#ifndef _rcmd_h_
#include "RCmd.h"
#endif

#define kXferBufSize 32768

/* These coincide with the definitions of kAcceptForWriting, etc., in FTP.h. */
#define kNetWriting kAcceptForWriting
#define kNetReading kAcceptForReading

#define NETREADING(xp) ((xp)->netMode == kNetReading)
#define NETWRITING(xp) ((xp)->netMode == kNetWriting)

/* More stuff for XferSpec setup.
 * Typically, all of these are used at once when
 * you don't want progress reports.
 */
#define kNoReports 0
#define kFileSizeDontCare 0L
#define kLocalFileIsStdout	"-"

#define kNoTransfer ((XferSpecPtr) 0)

/* typedef struct XferSpec *XferSpecPtr;  done in RCmd.h.  */

typedef long (*GetBlockProc)(char *, size_t, XferSpecPtr);
typedef long (*PutBlockProc)(char *, size_t, XferSpecPtr);

/* Each progress meter function follows this calling format. */
typedef int (*ProgressMeterProc)(XferSpecPtr, int);

typedef struct XferSpec {
	/* These must be filled in by you. */
	int					netMode;		/* Reading or writing Net I/O? */
	GetBlockProc		getBlock;
	PutBlockProc		putBlock;
	int					inStream;
	int 				outStream;
	
	/* You can use this to point to another structure if you like. */
	void				*miscPtr;
	
	/* Filled in by you if you want progress reports. */
	int					doReports;
	char				*localFileName;
	char				*remoteFileName;
	long				expectedSize;
	long				startPoint;
	
	/* These are filled in by RDataCmd. */
	ResponsePtr			cmdResp;
	ResponsePtr			xferResp;
	
	/* These are filled in by Progress routines. */
	int					progMeterInUse;
	ProgressMeterProc	prProc;
	long				bytesTransferred;
	long				bytesLeft;
	double				frac;
	double				bytesPerSec;
	double				secsElap;
	struct timeval		startTime;
	struct timeval		endTime;
	long				timeOfNextUpdate;

	/* Needed to guarantee that the file times get set. */
	int					doUTime;
	time_t				remoteModTime;
} XferSpec;

#define CLEARXFERSPEC(R)	PTRZERO(R, sizeof(XferSpec))

#ifndef _xfer_c_
extern XferSpecPtr gCurXp;
#endif

void InitXferBuffer(void);
int BufferGets(char *, size_t, XferSpecPtr);
void XferSigHandler(int);
XferSpecPtr InitXferSpec(void);
void DoneWithXferSpec(XferSpecPtr);
void AbortDataTransfer(XferSpecPtr);
int DataTransfer(XferSpecPtr);

#endif
