1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.osjava.payload;
33
34 import java.util.jar.JarOutputStream;
35 import java.util.jar.JarEntry;
36 import java.util.jar.JarFile;
37
38 import java.util.Enumeration;
39 import java.util.Properties;
40
41 import java.io.IOException;
42 import java.io.File;
43 import java.io.FileOutputStream;
44 import java.io.FileInputStream;
45 import java.io.InputStream;
46
47 /***
48 * Builds a self-extracting jar.
49 */
50 public class PayloadContractor {
51
52 public static final boolean DEBUG = (System.getProperty("PAYLOAD.DEBUG")!=null);
53
54
55
56
57
58 public static void main(String[] args) {
59 System.out.print("Payload contraction setup");
60
61
62 String jarFile = System.getProperty("java.class.path");
63 if(jarFile.indexOf(":") != -1) {
64 jarFile = null;
65
66 }
67 System.out.println(".");
68 if(DEBUG) System.out.println("DEBUG turned on. ");
69
70 if(args.length == 0) {
71 System.err.println("\nUnable to contract a payload as no target jar has been specified. ");
72 System.exit(1);
73 }
74 if(!args[0].endsWith(".jar")) {
75 System.err.println("\nRefusing to target a non-jar file. " +
76 "Please use a .jar filename then rename afterwards. ");
77 System.exit(1);
78 }
79 String targetJar = args[0];
80 if(args.length == 1) {
81 System.err.println("\nUnable to contract a payload as no target files have been specified. ");
82 System.exit(1);
83 }
84
85
86 FileInputStream fin = null;
87 JarOutputStream jout = null;
88 try {
89 System.out.print("Contracting payload header");
90 fin = new FileInputStream(new File(jarFile));
91 jout = new JarOutputStream(new FileOutputStream(new File(targetJar)));
92
93 JarFile jar = new JarFile(new File(jarFile));
94 Enumeration enumeration = jar.entries();
95 while(enumeration.hasMoreElements()) {
96 JarEntry entry = (JarEntry) enumeration.nextElement();
97 InputStream in = jar.getInputStream( entry );
98 JarEntry entry2 = new JarEntry(entry.getName());
99 entry2.setTime(entry.getTime());
100 entry2.setSize(entry.getSize());
101 jout.putNextEntry(entry2);
102 if(entry.getName().equals("META-INF/MANIFEST.MF")) {
103 String mf = IOUtils.readToString(in);
104 mf = mf.replaceAll("Main-Class: org//.osjava//.payload//.PayloadContractor",
105 "Main-Class: org.osjava.payload.PayloadExtractor");
106 jout.write(mf.getBytes());
107 } else {
108 IOUtils.pushBytes(in, jout);
109 }
110 jout.closeEntry();
111 System.out.print(".");
112 }
113 System.out.println("");
114
115
116
117
118 int start = 1;
119 if(args[1].endsWith(".properties")) {
120 FileInputStream propsFin = null;
121 try {
122 File propsFile = new File(args[1]);
123 propsFin = new FileInputStream(propsFile);
124 Properties tmp = new Properties();
125 tmp.load(propsFin);
126 if("true".equals(tmp.getProperty("org.osjava.payload"))) {
127 System.out.print("Inlining "+args[1]+" as payload.properties");
128 storeFile(jout, propsFile, "payload.properties");
129 System.out.println("");
130 start = 2;
131 }
132 } catch(IOException ioe) {
133 ioe.printStackTrace();
134 } finally {
135 IOUtils.closeQuietly(propsFin);
136 }
137 }
138
139
140
141 System.out.print("Contracting payload body");
142 boolean expectingPayletJar = false;
143 for(int i=start; i<args.length; i++) {
144 if("-x".equals(args[i])) {
145 expectingPayletJar = true;
146 continue;
147 }
148 String filename = args[i];
149 File file = new File(filename);
150 if(expectingPayletJar) {
151 JarFile payletJar = new JarFile(file);
152 Enumeration payletEnum = payletJar.entries();
153 while(payletEnum.hasMoreElements()) {
154 JarEntry entry = (JarEntry) payletEnum.nextElement();
155
156
157 if(jar.getEntry(entry.getName()) != null) {
158 continue;
159 }
160 InputStream in = payletJar.getInputStream( entry );
161 JarEntry entry2 = new JarEntry(entry.getName());
162 entry2.setTime(entry.getTime());
163 entry2.setSize(entry.getSize());
164 jout.putNextEntry(entry2);
165 IOUtils.pushBytes(in, jout);
166 jout.closeEntry();
167 System.out.print(":");
168 }
169 expectingPayletJar = false;
170 } else {
171 storeFile(jout, file);
172 }
173 }
174
175 System.out.println("\nFinished. ");
176
177 } catch(IOException ioe) {
178 System.err.println("\nIOException in building new jar. ");
179 ioe.printStackTrace();
180 } finally {
181 IOUtils.closeQuietly(fin);
182 IOUtils.closeQuietly(jout);
183 }
184 }
185
186
187 private static void storeFile(JarOutputStream jout, File file) throws IOException {
188 String fileUnix = file.toString().replaceAll("////", "/");
189 storeFile(jout, file, "payload/"+fileUnix);
190 }
191 private static void storeFile(JarOutputStream jout, File file, String targetName) throws IOException {
192 if(file.isDirectory()) {
193
194 JarEntry entry = new JarEntry(targetName+"/");
195
196 entry.setTime(System.currentTimeMillis());
197 jout.putNextEntry(entry);
198
199
200 File[] children = file.listFiles();
201 int sz = children.length;
202 for(int i=0; i<sz; i++) {
203 storeFile(jout, children[i]);
204 }
205 } else {
206 FileInputStream fis = new FileInputStream(file);
207 JarEntry entry = new JarEntry(targetName);
208
209 entry.setTime(System.currentTimeMillis());
210 entry.setSize( file.length() );
211 jout.putNextEntry(entry);
212 IOUtils.pushBytes(fis, jout);
213 jout.closeEntry();
214 System.out.print(".");
215 }
216 }
217 }