#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: "< 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; }