package de.nplusc.izc.senabitwiggler; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.TypeDescription; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; import org.yaml.snakeyaml.nodes.Tag; import org.yaml.snakeyaml.representer.Representer; import javax.swing.plaf.nimbus.State; import java.io.*; import java.nio.file.CopyOption; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.*; public class FirmwareAutoDumper { static Statefile state = null; static File outfolder_base; public static final boolean IA_UPLOAD_ENABLED = false; public static void pullFirmwares(File statefile, File outfolder, boolean deepmode) { outfolder_base=outfolder; try{ Representer representer = new Representer(); representer.addClassTag(Firmware.class, new Tag("!FW")); representer.addClassTag(FirmwareVersion.class, new Tag("!FWV")); Yaml y = new Yaml(representer, new DumperOptions()); if(statefile.exists()) { try { Constructor constructor = new Constructor(); constructor.addTypeDescription(new TypeDescription(Firmware.class, "!FW")); constructor.addTypeDescription(new TypeDescription(FirmwareVersion.class, "!FWV")); Yaml internal = new Yaml(constructor); state = (Statefile) internal.load(new FileReader(statefile)); } catch (FileNotFoundException e) { System.err.println("Hurz"); e.printStackTrace(); } } else { state = new Statefile(); state.setFirmwares(new LinkedHashMap<>()); } File outfolder_tmp = new File(outfolder,"tmp"); outfolder_tmp.mkdirs(); Utils.runTool(outfolder_tmp, "wget", "http://firmware.sena.com/senabluetoothmanager/Firmware" ); BufferedReader br = new BufferedReader(new FileReader(new File(outfolder_tmp,"Firmware"))); final HashMap basenamelookup = new HashMap<>(); // filename --> real basename br.lines().forEach((line)-> { String[] linesplitted = line.split(":"); String FWFileName; String FWBAsename = "ZĂ–INKS!"; if(linesplitted.length==4) { FWBAsename = linesplitted[0]+"-"+linesplitted[2]; FWFileName = linesplitted[3]; } else if(linesplitted.length==3) { FWBAsename = linesplitted[0]+"-NOLNG"; FWFileName = linesplitted[2]; } else { return; } if(basenamelookup.containsKey(FWFileName)) { return; //languageless file, no need to handle multiple times. } else { basenamelookup.put(FWFileName,FWBAsename); } if(!state.getFirmwares().containsKey(FWBAsename)) { Firmware tmp = new Firmware(); tmp.setDeviceId(FWBAsename); tmp.setInitialDLDone(false); tmp.setVersions(new HashMap<>()); state.getFirmwares().put(FWBAsename,tmp); } Firmware f = state.getFirmwares().get(FWBAsename); try { int[] fwnumber = splitVersionAndPullFW(FWFileName,f.getVersions()); f.setMajor(fwnumber[0]); f.setMinor(fwnumber[1]); f.setPatch(fwnumber[2]); } catch (IOException e) { e.printStackTrace(); } }); br.close(); y.dump(state,new FileWriter(statefile)); new File(outfolder_tmp,"firmware").delete(); } catch (IOException ex) { ex.printStackTrace(); } } private static int[] splitVersionAndPullFW(String filename,HashMap knownVersions) throws IOException { String[] magic = filename.split("-v"); boolean fuckingoddity = false; if(magic.length==1) { fuckingoddity = true; magic = filename.split("_v"); } String version = magic[1]; String[] vsplit = version.split("\\."); String suffix = ""; int major=0,minor=0,patch=0; major=Integer.valueOf(vsplit[0]); if(vsplit.length==4) { minor = Integer.valueOf(vsplit[1]); patch = Integer.valueOf(vsplit[2].substring(0,1)); if(vsplit[2].length()>1) { suffix = vsplit[2].substring(1)+"."+vsplit[3]; } else { suffix = "."+vsplit[3]; } } else { if(vsplit[1].length()>1) { minor = Integer.valueOf(vsplit[1].substring(0,1)); suffix = vsplit[1].substring(1)+"."+vsplit[2]; } else { minor = Integer.valueOf(vsplit[1].substring(0,1)); suffix = "."+vsplit[2]; } } String prefix = magic[0]+(fuckingoddity?"_":"-")+"v"; //suffix = suffix+".img"; scanDownwards(major,minor,patch,prefix,suffix,knownVersions); return new int[]{major,minor,patch}; } private static void scanDownwards( int major, int minor, int patch, String prefix, String suffix, HashMap knownVersions) throws IOException { System.out.println(major+"--"+minor+"--"+patch); List temp = new ArrayList<>(); //temp.add(prefix+(major+1)+".0.0"); // poking for next major //temp.add(prefix+(major+1)+".0"); // poking for next major //temp.add(prefix+(major)+"."+(minor+1)+".0"); // poking for next minor //temp.add(prefix+(major)+"."+(minor+1)); // poking for next minor //temp.add(prefix+(major)+"."+minor+"."+(patch+1)); // poking for next patch System.out.println(prefix+"."+major+"."+minor+"."+patch+"."+suffix); while(major>=1&&minor>=0&&patch>=0) //older versions won't be bruteforced, check for existence in the index prevents a redownload. { String synthesizedFileName = prefix+(major)+"."+minor+"."+(patch)+suffix; if(knownVersions.containsKey(synthesizedFileName)) //skipping redownload and setting it as "not hidden" if it was a hidden version { knownVersions.get(synthesizedFileName).setHidden(false); } else { FirmwareVersion f = getFirmware(major,minor,patch,false,synthesizedFileName); knownVersions.put(synthesizedFileName,f); } if(patch==0) { synthesizedFileName = prefix+(major)+"."+minor+suffix; if(knownVersions.containsKey(synthesizedFileName)) //skipping redownload and setting it as "not hidden" if it was a hidden version { knownVersions.get(synthesizedFileName).setHidden(false); } else { FirmwareVersion f2 = getFirmware(major,minor,patch,false,synthesizedFileName); knownVersions.put(synthesizedFileName,f2); } } patch--; if(patch<0) { patch=9; minor--; } if(minor<0) { minor=9; major--; } }/**/ } private static FirmwareVersion getFirmware(int major, int minor, int patch, boolean hidden, String fwname) throws IOException { FirmwareVersion f = new FirmwareVersion(); f.setFilename(fwname); f.setHidden(hidden); f.setMajor(major); f.setMinor(minor); f.setPatch(patch); File downloadFolderBase = new File(outfolder_base,"downloadstage"); //if(true) return f; Utils.runTool(downloadFolderBase, "wget", "http://firmware.sena.com/senabluetoothmanager/"+fwname ); System.err.println("New Version spotted:"+fwname); //intentionally a output. that should be mailed by the cron daemon if its File dlf = new File(downloadFolderBase,fwname); File dst = new File(outfolder_base,fwname); if(dlf.exists()&&!dst.exists()) { f.setFiller(false); f.setServerCreationDate(new Date(dlf.lastModified())); Files.copy(dlf.toPath(),dst.toPath()); if(IA_UPLOAD_ENABLED) { Utils.runTool(downloadFolderBase, "ia", "upload", "sena-firmware-files", "--no-derive", fwname ); } } else { f.setFiller(true); f.setServerCreationDate(new Date(0)); } return f; } }