int n_getstr(string *args, struct shell_state *sh) { string remote_path; if( args[1] == "" ) { ifNotQuiet cout << "putstr: please specify a file to send" << endl; return SHELL_CONTINUE; } else if ( args[1].at(0) == '/' ) { remote_path = args[1]; } else { remote_path = sh->remote_path; processRelativePath(&remote_path, &args[1]); } unsigned int offset = atoi((char*) args[2].c_str()); unsigned int size = atoi((char*) args[3].c_str()); afc_file_ref ref; afc_error_t ret; ifVerbose cout << "About to get " << size << " bytes of data at " << offset << " in " << remote_path << endl; ifVerbose cout << "AFCFileRefOpen: opening remote file '" << remote_path << "'" << endl; ret = AFCFileRefOpen(sh->conn, (char*)remote_path.c_str(), 1, &ref); if (ret) { ifNotQuiet cout << "putstr: Failed to open remote file: " << ret << endl; return SHELL_CONTINUE; } unsigned int data_offset = (offset % 1024); offset -= data_offset; ifVerbose cout << "AFCFileRefSeek: Seeking to " << offset << " in remote file" << endl; ret = AFCFileRefSeek(sh->conn, ref, offset, 0); if (ret) { ifNotQuiet cout << "getstr: Failed to seek file: " << ret << endl; return SHELL_CONTINUE; } unsigned int desired_size = size; if ((size % 10240) != 0) size += 10240 - (size % 10240); unsigned char* buffer = (unsigned char*) malloc(size); ifVerbose cout << "AFCFileRefRead: Reading " << size << " from remote file" << endl; if (!buffer) { ifNotQuiet cout << "getstr: Failed to allocate buffer" << endl; return SHELL_CONTINUE; } ret = AFCFileRefRead(sh->conn, ref, buffer, &size); if (ret) { ifNotQuiet cout << "getstr: Failed to read from remote file: " << ret << endl; free(buffer); return SHELL_CONTINUE; } unsigned char* data = (unsigned char*) malloc(desired_size); memcpy(data, buffer + data_offset, desired_size); cout << data << endl; free(data); free(buffer); ifVerbose cout << "AFCFileRefClose: Closing remote file. " << endl; ret = AFCFileRefClose(sh->conn, ref); if (ret) { ifNotQuiet cout << "putfile: Failed to close remote file: " << ret << endl; return SHELL_CONTINUE; } return SHELL_CONTINUE; }