summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/btr/proxy/search/desktop/win/DLLManager.java
blob: 8d6798462e6aba80c8b12466586096a2ca8f5dae (plain) (blame)
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package com.btr.proxy.search.desktop.win;

import java.io.Closeable;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.btr.proxy.util.Logger;
import com.btr.proxy.util.Logger.LogLevel;

/*****************************************************************************
 * This class provides some helper methods to work with the dll 
 * extracting /loading for windows.
 *  
 * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
 ****************************************************************************/

final class DLLManager {

	private static final class TempDLLFileFilter implements FileFilter {
		public boolean accept(File pathname) {
			String name = pathname.getName();
			return pathname.isFile() && 
				name.startsWith(TEMP_FILE_PREFIX) && 
				name.endsWith(DLL_EXTENSION);
		}
	}

	public static final String LIB_DIR_OVERRIDE = "proxy_vole_lib_dir";
	
	static final String TEMP_FILE_PREFIX = "proxy_vole";
	static final String DLL_EXTENSION = ".dll";
	static String LIB_NAME_BASE = "proxy_util_";
	static final String DEFAULT_LIB_FOLDER = "lib";
	
	/*************************************************************************
	 * Find the location of the native code dll file.
	 * @return the File pointing to the dll.
	 * @throws IOException on IO error.
	 ************************************************************************/
	
	static File findLibFile() throws IOException {
		String libName = buildLibName();
		File libFile = getOverrideLibFile(libName);
		if (libFile == null || libFile.exists() == false) {
			libFile = getDefaultLibFile(libName);
		} 
		if (libFile == null || libFile.exists() == false) {
			libFile = extractToTempFile(libName);
		}
		return libFile;
	}

	/*************************************************************************
	 * Delete old temp files that may be there because they were extracted
	 * from the jar but could not be deleted on VM shutdown because they
	 * are still locked by windows.
	 * This is here to prevent a lot of temp dll files on disk.
	 ************************************************************************/
	
	static void cleanupTempFiles() {
		try {
			String tempFolder = System.getProperty("java.io.tmpdir");
			if (tempFolder == null || tempFolder.trim().length() == 0) { 
				return;
			}
			File fldr = new File(tempFolder);
			File[] oldFiles = fldr.listFiles(new TempDLLFileFilter());
			if (oldFiles == null) {
				return;
			}
			for (File tmp : oldFiles) {
				tmp.delete();
			}
		} catch (Exception e) {
			Logger.log(DLLManager.class, LogLevel.DEBUG, "Error cleaning up temporary dll files. ", e);
		}
	}

	/*************************************************************************
	 * @param libName
	 * @return  
	 ************************************************************************/
	
	private static File getDefaultLibFile(String libName) {
		return new File(DEFAULT_LIB_FOLDER, libName);
	}
	
	/*************************************************************************
	 * Gets the file name that was overriden via system property.
	 * @param libName
	 * @return the file, null if it is not existing.
	 ************************************************************************/
	
	private static File getOverrideLibFile(String libName) {
		String libDir = System.getProperty(LIB_DIR_OVERRIDE);
		if (libDir == null || libDir.trim().length() == 0) {
			return null;
		}
		return new File(libDir, libName);
	}

	/*************************************************************************
	 * @param libName
	 * @return
	 * @throws IOException
	 * @throws FileNotFoundException
	 ************************************************************************/
	
	static File extractToTempFile(String libName) throws IOException {
		InputStream source = Win32ProxyUtils.class.getResourceAsStream("/"+DEFAULT_LIB_FOLDER+"/"+libName);
		File tempFile = File.createTempFile(TEMP_FILE_PREFIX, DLL_EXTENSION);
		tempFile.deleteOnExit();
		FileOutputStream destination = new FileOutputStream(tempFile);
		copy(source, destination);
		return tempFile;
	}

	/*************************************************************************
	 * @param c a closeable to cleanup ignoring all errors.
	 ************************************************************************/
	
	private static void closeStream(Closeable c) {
		try {
			c.close();
		} catch (IOException e) {
			// Ignore cleanup errors
		}
	}

	/*************************************************************************
	 * Copies the content from source to destination.
	 * @param source
	 * @param dest
	 * @throws IOException
	 ************************************************************************/
	
	static void copy(InputStream source, OutputStream dest)
			throws IOException {
		try {
			byte[] buffer = new byte[1024];
			int read = 0;
			while (read >= 0) {
				dest.write(buffer, 0, read);
				read = source.read(buffer);
			}
			dest.flush();
		} finally {
			closeStream(source);
			closeStream(dest);
		}
	}

	/*************************************************************************
	 * @return the name of the dll valid for the current architecture.
	 ************************************************************************/
	
	private static String buildLibName() {
		String arch = "w32";
		if(!System.getProperty("os.arch").equals("x86") ) {
			arch = System.getProperty("os.arch");
		}
		return LIB_NAME_BASE + arch + DLL_EXTENSION;
	}
	
}