All pastes #730194 Raw Edit

Anonymous

public text v1 · immutable
·published 2007-10-08 23:59 UTC
rendered paste body
#define MAX_GETFILE_BUFFER (67108864/2)
void get_file(struct shell_state *sh, char *local_path, char *remote_path, unsigned int remote_file_size)
{
	FILE *f;
	unsigned char *buf;
	afc_file_ref ref;
	afc_error_t ret;
	
	// here we assume we are being passed absolute paths 
	// in both remote and local paths
	
	ifVerbose cout	<< "AFCFileRefOpen: opening remote path '" << remote_path << "'" << endl;
	ret = AFCFileRefOpen(sh->conn, remote_path, 1, &ref);
	if (ret)
	{
		ifNotQuiet cout << "getfile: Failed to open remote file: " << ret << endl;
		return;
	}
	
	if (remote_file_size < 0)
		remote_file_size = get_file_size(sh->conn, remote_path);

	ifVerbose cout	<< "AFCFileRefRead: reading " << remote_file_size
			<< " bytes into buffer" << endl;
	
	unsigned int buffer_size = remote_file_size;
	if (remote_file_size > MAX_GETFILE_BUFFER)
	{
		ifVerbose cout << "File is too large for single call. Buffering.";
		buffer_size = MAX_GETFILE_BUFFER;
	}
	
	buf = (unsigned char *)malloc(buffer_size);
	
	if (!buf)
	{
		ifNotQuiet cout << "getfile: could not allocate buffer. Aborting." << endl;
		return;
	}
	
	unsigned int bytes_remaining = remote_file_size;
	
	D("Opening local_path: "<<local_path);
	f = fopen(local_path, "w+b");
	if (f == NULL) {
		ifNotQuiet cout << "getfile: Failed to open local file '" << local_path << "'" << endl;;
		free(buf);
		return;
	}
	
	while (bytes_remaining > 0)
	{
		unsigned int read_size = bytes_remaining;
		if (read_size > buffer_size)
			read_size = buffer_size;
	
		bytes_remaining -= read_size;
		
		ifNotQuiet cout << "Reading " << read_size << " bytes, " << bytes_remaining << " bytes remain" << endl; 
		D("AFCFileRead");
		ret = AFCFileRefRead(sh->conn, ref, buf, &read_size);
		if (ret)
		{
			ifNotQuiet cout << "getfile: Failed to read from remote file: " << ret << endl;
			return;
		}
		
		D("writing local file.");
		fwrite(buf, read_size, 1, f);
	}
	
	
	ret = AFCFileRefClose(sh->conn, ref);
	if (ret) {
		ifNotQuiet cout << "getfile: Failed to close remote file: " << ret << endl;
		fclose(f);
		free(buf);
		return;
	}
	
	
	ifVerbose cout << "getfile: Writing file to local path '" << local_path << "'" << endl;
	
	D("closing local file.");
	fclose(f);
	D("freeing file buffer.");
	free(buf);

	ifVerbose cout << "getfile: Transfer successful." << endl;
}