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;
}