package uc.protocols.client; import java.io.IOException; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import logger.LoggerFactory; import org.apache.log4j.Logger; import uc.crypto.HashValue; import uc.files.transfer.FileTransferInformation; import uc.protocols.AbstractADCCommand; import uc.protocols.Compression; import uc.protocols.TransferType; public class ADCGET extends AbstractNMDCClientProtocolCommand { private static Logger logger = LoggerFactory.make(); private Pattern file; private Pattern interleaves; private Pattern filelist; public ADCGET() { file = Pattern.compile(prefix + " file TTH/("+TTH+") ("+FILESIZE+") ("+FILESIZE+"|-1)(.*)"); interleaves = Pattern.compile(prefix + " tthl TTH/("+TTH+") 0 -1(.*)"); String filelista = "file files\\.xml\\.bz2"; String filelistb = "list /"+TEXT_NOSPACE; String filelists = "(?:(?:"+filelista+")|(?:"+filelistb+"))"; filelist = Pattern.compile(prefix + " ("+filelists+") 0 -1(.*)"); } @Override public void handle(ClientProtocol client,String command) throws IOException { //client.removeCommand(this); Matcher m = null; FileTransferInformation fti = client.getFti(); if ((m = file.matcher(command)).matches()) { fti.setType(TransferType.FILE); HashValue what = HashValue.createHash(m.group(1)); fti.setHashValue(what); long startpos = Long.parseLong(m.group(2)); fti.setStartposition(startpos); long length = Long.parseLong(m.group(3)); fti.setLength(length); Map<String,String> flags= AbstractADCClientProtocolCommand.getCCFlagMap(m.group(4)); Compression comp = Compression.parseAttributeMap(flags); fti.setCompression(comp); client.transfer(); //FileRequested(what, startpos, length, comp); } else if ( (m = interleaves.matcher(command)).matches()) { HashValue what = HashValue.createHash(m.group(1)); fti.setType(TransferType.TTHL); fti.setHashValue(what); Map<String,String> flags= AbstractADCClientProtocolCommand.getCCFlagMap(m.group(2)); Compression comp = Compression.parseAttributeMap(flags); fti.setCompression(comp); client.transfer(); } else if ( (m = filelist.matcher(command)).matches()) { fti.setType(TransferType.FILELIST); Map<String,String> flags= AbstractADCClientProtocolCommand.getCCFlagMap(m.group(2)); Compression comp = Compression.parseAttributeMap(flags); fti.setCompression(comp); boolean partialList = m.group(1).startsWith("list /"); fti.setPartialList(partialList); fti.setBz2Compressed(m.group(1).equals("file files.xml.bz2")); if (partialList) { String path = AbstractADCCommand.revReplaces(m.group(1).substring(5)); fti.setPartialFileList(path, "1".equals(flags.get("RE"))); } client.transfer(); } else { logger.debug("invalid ADCGET received "+command + " "+client.getUser()); } } public static void sendADCGET(ClientProtocol client) throws IOException { if (!client.getOthersSupports().contains("ADCGet")) { client.sendError(DisconnectReason.CLIENTTOOOLD); } FileTransferInformation fti = client.getFti(); if (fti.isValidForGet()) { logger.debug("valid fti for get"); client.addCommand(new MaxedOut()); //TODO maxedOut received should trigger warning if received on FileList or tthl switch(fti.getType()) { case FILE: client.addCommand(new ADCSND(fti.getHashValue(),fti.getStartposition(),fti.getLength())); break; case FILELIST: client.addCommand(new ADCSND()); break; case TTHL: if (client.getOthersSupports().contains("TTHL")) { client.addCommand(new ADCSND(fti.getHashValue())); } else { client.disconnect(DisconnectReason.CLIENTTOOOLD); return; } break; } //bad workaround -> use simple connection for sending this and next command.. //client.setSimpleConnection(); // SimpleConnection simple = (SimpleConnection)client.getConnection(); logger.debug("sending ADCGET channelIsOpen? " ); //+simple.retrieveChannel().isOpen()); String adcget="$ADCGET " + fti.getType().toNMDCString() + " " + (fti.getType() == TransferType.FILELIST ? "files.xml.bz2": "TTH/" + fti.getHashValue())+ " " + fti.getStartposition() + " " + fti.getLength() + fti.getCompression() + "|" ; client.sendUnmodifiedRaw(adcget); // simple.send(adcget); // Request all bytes from current position to end of file logger.debug("read one nmdc command"); //now read just one more command -> either MaxedOut or it is ADCSND // simple.readOneCommand(30000,true); logger.debug("finished reading one nmdc command"); } else { logger.debug("invalid fti"); client.disconnect(DisconnectReason.ILLEGALSTATEERROR); } } // public static void main(String[] args) { // String adcget = "$ADCGET file TTH/4CLZLU7TCB6C4YTHN7JNOIA7F7VQVJV5762AYJA 0 457864 ZL1" ; // String adcget2 = "$ADCGET file files.xml.bz2 0 -1 ZL1"; // // ADCGET a = new ADCGET(); // // Matcher m = a.file.matcher(adcget); // boolean matches = m.matches(); // // System.out.println(matches); // if (matches) { // for (int i=0 ; i <= 4;i++) { // System.out.println(m.group(i)); // } // } // Matcher m2 = a.filelist.matcher(adcget2); // boolean matches2 = m2.matches(); // System.out.println(matches2); // if (matches) { // System.out.println(m2.group(1)); // } // // } }