/* Copyright 2009 Hauke Rehfeld This file is part of QuakeInjector. QuakeInjector is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QuakeInjector is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QuakeInjector. If not, see <http://www.gnu.org/licenses/>. */ package de.haukerehfeld.quakeinjector; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Console; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.util.AbstractMap; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import java.util.zip.ZipEntry; /** * Create an xml of all the files in the zips */ public class ZipInspect { private final static String file = "zipFiles.xml"; private final static String oldSelectionsFile = "essentialfiles.cfg"; public static void main(String[] args) { Console con = System.console(); if (con == null) { System.err.println("Don't start from ant, it doesn't support an interactive console!"); System.exit(1); } if (args.length < 1) { System.err.println("First parameter need's to be a valid directory!"); System.exit(1); } String parentDir = args[0]; if (!(new File(parentDir).exists())) { System.err.println("First parameter need's to be a valid directory!"); System.exit(1); } Configuration config = new Configuration(QuakeInjector.configFile); List<Requirement> requirements = null; { final PackageDatabaseParserWorker requirementsParser = new PackageDatabaseParserWorker(config.RepositoryDatabasePath.get()); requirementsParser.execute(); try { requirements = requirementsParser.get(); } catch (Exception e) { System.err.println("Couldn't get packages " + e); e.printStackTrace(); System.exit(1); } } java.util.Collections.sort(requirements); Map<Package, Iterable<FileInfo>> packageFiles = new TreeMap<Package,Iterable<FileInfo>>(); SortedMap<String, List<Map.Entry<Package,FileInfo>>> duplicateFiles = new TreeMap<String, List<Map.Entry<Package,FileInfo>>>(); for (Requirement r: requirements) { //only check where package exists if (!(r instanceof Package)) { continue; } Package p = (Package) r; p.setInstalled(true); File f = new File(parentDir + File.separator + r.getId() + ".zip"); if (!f.exists()) { System.out.println("WARNING: " + f + " doesn't exist!"); continue; } System.out.println(f); try { FileInputStream in = new FileInputStream(f); InspectZipWorker inspector = new InspectZipWorker(in); inspector.execute(); final List<ZipEntry> entries = inspector.get(); final PackageFileList zipFiles = new PackageFileList(p.getId()); String dir = p.getRelativeBaseDir(); for (ZipEntry e: entries) { String file = ""; if (dir != null) { file = dir; } file += e.getName(); FileInfo info = new FileInfo(file, e.getCrc()); zipFiles.add(info); List<Map.Entry<Package,FileInfo>> dupMaps = duplicateFiles.get(file.toLowerCase()); if (dupMaps == null) { dupMaps = new ArrayList<Map.Entry<Package,FileInfo>>(); duplicateFiles.put(file.toLowerCase(), dupMaps); } dupMaps.add(new AbstractMap.SimpleEntry<Package,FileInfo>(p, info)); } p.setFileList(zipFiles); packageFiles.put(p, zipFiles); } catch (Exception e) { e.printStackTrace(); } } Map<String, Boolean> oldSelections = new HashMap<String, Boolean>(); if (new File(oldSelectionsFile).exists()) { //load old selections try { BufferedReader in = new BufferedReader(new FileReader(oldSelectionsFile)); String line; while ((line = in.readLine()) != null) { String[] l = line.split(","); oldSelections.put(l[0], Boolean.parseBoolean(l[1])); } in.close(); } catch (java.io.IOException e) { System.err.println("Couldn't read old selections file"); } } StringBuilder selectionsFile = new StringBuilder(); for (String file: duplicateFiles.keySet()) { List<Map.Entry<Package,FileInfo>> dups = duplicateFiles.get(file); int count = dups.size(); if (count > 1) { List<String> packages = new ArrayList<String>(); boolean crcDiffers = false; long crc = -1; for (Map.Entry<Package,FileInfo> e: dups) { if (crc != -1 && crc != e.getValue().getChecksum()) { crcDiffers = true; } crc = e.getValue().getChecksum(); packages.add(e.getKey().getId() + " (crc: " + crc + ")"); } boolean essential = true; if (!crcDiffers && crc == 0) { System.out.println(file + " has duplicates, but all with crc == 0," + " setting to inessential"); essential = false; } else if (oldSelections.get(file) != null) { essential = oldSelections.get(file); System.out.println(file + " has duplicates, but was previously declared:" + " essential = " + essential); } else { System.out.println(file + " has " + (crcDiffers ? " differing CRC " : " equal ") + "duplicates in " + Utils.join(packages, ", ")); System.out.println("Is this an essential file? (No: n + RETURN, Yes: RETURN)"); String yes = con.readLine(); if (yes != null && yes.equals("n")) { essential = false; } } for (Map.Entry<Package,FileInfo> e: dups) { e.getValue().setEssential(essential); } selectionsFile.append(file + "," + essential + "\n"); } } //write old selections try { BufferedWriter out = new BufferedWriter(new FileWriter(oldSelectionsFile)); out.write(selectionsFile.toString()); out.close(); } catch (java.io.IOException e) { System.err.println("Couldn't write selections to outfile! " + e); } try { new InstalledPackageList().write(new BufferedOutputStream(new FileOutputStream(file)), packageFiles.keySet()); } catch (Exception e) { e.printStackTrace(); } } }