public TorrentFileSystem(int numHashes, TorrentFileSystemMemento torrentFileSystemMemento) { this._name = torrentFileSystemMemento.getName(); this._totalSize = torrentFileSystemMemento.getTotalSize(); this._files = torrentFileSystemMemento.getFiles(); // BEGIN TODO remove this code after releasing a few versions Sept 2nd 2008. // There was a bug, where the file end piece would be set to numhashes instead of numhashes-1 // the piece index is zero based. old code used to ignore these propblems, some of the newer // code throws an illegal argument exception. for (TorrentFile file : _files) { if (file.getEndPiece() == numHashes) { file.setEndPiece(numHashes - 1); } } // END TODO this._unmodFiles = Collections.unmodifiableList(_files); _folders.addAll(torrentFileSystemMemento.getFolders()); this._incompleteFile = torrentFileSystemMemento.getIncompleteFile(); this._completeFile = torrentFileSystemMemento.getCompleteFile(); }
/** * Constructs the file system using the given BTData & hash information. If any of the information * is malformed, throws a ValueException. * * @param data contains all the data about a .torrent file * @param numHashes number of pieces the torrent was divided into * @param pieceLength size of divided up torrent file * @param infoHash a string of alphanumeric characters in the .torrent file that the client uses * to verify the data that is being transferred * @throws ValueException */ TorrentFileSystem(BTData data, int numHashes, long pieceLength, byte[] infoHash) throws IOException { // name of the torrent, also specifying the directory under which to save the torrents. _name = CommonUtils.convertFileName(data.getName()); // we need to check the name of the torrent, security risk! if (_name.length() == 0) throw new ValueException("bad torrent name"); _incompleteFile = new File( SharingSettings.INCOMPLETE_DIRECTORY.get(), Base32.encode(infoHash) + File.separator + _name); _completeFile = new File(SharingSettings.getSaveDirectory(_name), _name); if (!FileUtils.isReallyParent(SharingSettings.getSaveDirectory(_name), _completeFile)) { throw new SaveLocationException(LocationCode.SECURITY_VIOLATION, _completeFile); } if (data.getFiles() != null) { List<BTData.BTFileData> files = data.getFiles(); List<TorrentFile> torrents = new ArrayList<TorrentFile>(files.size()); long position = 0; for (BTData.BTFileData file : files) { String torrentPath = _name + file.getPath(); TorrentFile f = new TorrentFile( file.getLength(), new File(_completeFile, file.getPath()).getAbsolutePath(), torrentPath); f.setBeginPiece((int) (position / pieceLength)); f.setStartByte(position); position += f.length(); f.setEndPiece((int) (position / pieceLength)); f.setEndByte(position - 1); if (!FileUtils.isReallyInParentPath(_completeFile, f)) throw new SaveLocationException(LocationCode.SECURITY_VIOLATION, f); torrents.add(f); } if (files.size() == 0) throw new ValueException("bad metainfo, no files!"); _files = torrents; // add folders, for easier conflict checking later on for (String folderPath : data.getFolders()) _folders.add(new File(_completeFile, folderPath)); _folders.add(_completeFile); } else { String torrentPath = data.getName(); TorrentFile f = new TorrentFile(data.getLength(), _completeFile.getAbsolutePath(), torrentPath); f.setBeginPiece(0); f.setStartByte(0); f.setEndPiece(numHashes - 1); f.setEndByte(f.length()); _files = new ArrayList<TorrentFile>(1); _files.add(f); } _unmodFiles = Collections.unmodifiableList(_files); _totalSize = calculateTotalSize(_files); if (_totalSize <= 0) throw new ValueException("invalid size " + _totalSize); }
/** * Updates the files in the specified collection to start at the new base path. The files must * already be absolute and be children of _completeFile. * * @param completeBase the new base path */ private void updateReferences(File completeBase, List<TorrentFile> l) { int offset = _completeFile.getAbsolutePath().length(); String newPath = completeBase.getAbsolutePath(); for (int i = 0; i < l.size(); i++) { TorrentFile current = l.get(i); TorrentFile updated = new TorrentFile( current.length(), newPath + current.getPath().substring(offset), current.getTorrentPath()); updated.setBeginPiece(current.getBeginPiece()); updated.setEndPiece(current.getEndPiece()); updated.setStartByte(current.getStartByte()); updated.setEndByte(current.getEndByte()); l.set(i, updated); } }