001: /*
002: * This file is part of DrFTPD, Distributed FTP Daemon.
003: *
004: * DrFTPD is free software; you can redistribute it and/or modify it under the
005: * terms of the GNU General Public License as published by the Free Software
006: * Foundation; either version 2 of the License, or (at your option) any later
007: * version.
008: *
009: * DrFTPD is distributed in the hope that it will be useful, but WITHOUT ANY
010: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
011: * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
012: *
013: * You should have received a copy of the GNU General Public License along with
014: * DrFTPD; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
015: * Suite 330, Boston, MA 02111-1307 USA
016: */
017: package net.sf.drftpd.mirroring;
018:
019: import net.sf.drftpd.NoAvailableSlaveException;
020: import net.sf.drftpd.SlaveUnavailableException;
021:
022: import org.apache.log4j.Logger;
023:
024: import org.drftpd.master.RemoteSlave;
025: import org.drftpd.master.RemoteTransfer;
026: import org.drftpd.remotefile.LinkedRemoteFileInterface;
027: import org.drftpd.slave.ConnectInfo;
028: import org.drftpd.slave.RemoteIOException;
029: import org.drftpd.slave.TransferFailedException;
030:
031: import java.io.IOException;
032:
033: import java.net.InetSocketAddress;
034:
035: /**
036: * @author mog
037: * @author zubov
038: * @version $Id: SlaveTransfer.java 1482 2006-06-16 04:50:07Z fr0w $
039: */
040: public class SlaveTransfer {
041: private static final Logger logger = Logger
042: .getLogger(SlaveTransfer.class);
043: private RemoteSlave _destSlave;
044: private LinkedRemoteFileInterface _file;
045: private RemoteSlave _srcSlave;
046: private RemoteTransfer _destTransfer = null;
047: private RemoteTransfer _srcTransfer = null;
048: private boolean _secureTransfer = false;
049:
050: /**
051: * Slave to Slave Transfers
052: */
053: public SlaveTransfer(LinkedRemoteFileInterface file,
054: RemoteSlave sourceSlave, RemoteSlave destSlave,
055: boolean secureTransfer) {
056: _file = file;
057: _srcSlave = sourceSlave;
058: _destSlave = destSlave;
059: _secureTransfer = secureTransfer;
060: }
061:
062: long getTransfered() {
063: if (_srcTransfer == null || _destTransfer == null)
064: return 0;
065: return (_srcTransfer.getTransfered() + _destTransfer
066: .getTransfered()) / 2;
067: }
068:
069: public void abort(String reason) {
070: if (_srcTransfer != null) {
071: _srcTransfer.abort(reason);
072: }
073: if (_destTransfer != null) {
074: _destTransfer.abort(reason);
075: }
076: }
077:
078: long getXferSpeed() {
079: if (_srcTransfer == null || _destTransfer == null)
080: return 0;
081: return (_srcTransfer.getXferSpeed() + _destTransfer
082: .getXferSpeed()) / 2;
083: }
084:
085: /**
086: * Returns the crc checksum of the destination transfer
087: * If CRC is disabled on the destination slave, checksum = 0
088: */
089: protected boolean transfer() throws SlaveException {
090: // can do encrypted slave2slave transfers by modifying the
091: // first argument in issueListenToSlave() and the third option
092: // in issueConnectToSlave(), maybe do an option later, is this wanted?
093:
094: try {
095: String destIndex = _destSlave.issueListenToSlave(
096: _secureTransfer, false);
097: ConnectInfo ci = _destSlave
098: .fetchTransferResponseFromIndex(destIndex);
099: _destTransfer = _destSlave.getTransfer(ci
100: .getTransferIndex());
101: } catch (SlaveUnavailableException e) {
102: throw new DestinationSlaveException(e);
103: } catch (RemoteIOException e) {
104: throw new DestinationSlaveException(e);
105: }
106:
107: try {
108: String srcIndex = _srcSlave.issueConnectToSlave(
109: _destTransfer.getAddress().getAddress()
110: .getHostAddress(), _destTransfer
111: .getLocalPort(), _secureTransfer, true);
112: ConnectInfo ci = _srcSlave
113: .fetchTransferResponseFromIndex(srcIndex);
114: _srcTransfer = _srcSlave.getTransfer(ci.getTransferIndex());
115: } catch (SlaveUnavailableException e) {
116: throw new SourceSlaveException(e);
117: } catch (RemoteIOException e) {
118: throw new SourceSlaveException(e);
119: }
120:
121: try {
122: _destTransfer.receiveFile(_file.getPath(), 'I', 0);
123: } catch (IOException e1) {
124: throw new DestinationSlaveException(e1);
125: } catch (SlaveUnavailableException e1) {
126: throw new DestinationSlaveException(e1);
127: }
128:
129: try {
130: _srcTransfer.sendFile(_file.getPath(), 'I', 0);
131: } catch (IOException e2) {
132: throw new SourceSlaveException(e2);
133: } catch (SlaveUnavailableException e2) {
134: throw new SourceSlaveException(e2);
135: }
136:
137: boolean srcIsDone = false;
138: boolean destIsDone = false;
139:
140: while (!(srcIsDone && destIsDone)) {
141: try {
142: if (_srcTransfer.getTransferStatus().isFinished()) {
143: srcIsDone = true;
144: }
145: } catch (TransferFailedException e7) {
146: _destTransfer.abort("srcSlave had an error");
147: throw new SourceSlaveException(e7.getCause());
148: }
149:
150: try {
151: if (_destTransfer.getTransferStatus().isFinished()) {
152: destIsDone = true;
153: }
154: } catch (TransferFailedException e6) {
155: _srcTransfer.abort("destSlave had an error");
156: throw new DestinationSlaveException(e6.getCause());
157: }
158:
159: try {
160: Thread.sleep(100);
161: } catch (InterruptedException e5) {
162: }
163: }
164: long srcChecksum = _srcTransfer.getChecksum();
165: long destChecksum = _destTransfer.getChecksum();
166: // may as well set the checksum, we know this one is right
167: if (_srcTransfer.getChecksum() != 0) {
168: _file.setCheckSum(_srcTransfer.getChecksum());
169: }
170:
171: if (_srcTransfer.getChecksum() == _destTransfer.getChecksum()
172: || _destTransfer.getChecksum() == 0
173: || _srcTransfer.getChecksum() == 0) {
174: return true;
175: } else {
176: return false;
177: }
178: }
179:
180: /**
181: * @return Returns the _destSlave.
182: */
183: public RemoteSlave getDestinationSlave() {
184: return _destSlave;
185: }
186:
187: /**
188: * @return Returns the _srcSlave.
189: */
190: public RemoteSlave getSourceSlave() {
191: return _srcSlave;
192: }
193: }
|