Sleuth Kit Java Bindings (JNI) 4.14.0
Java bindings for using The Sleuth Kit
Loading...
Searching...
No Matches
LibraryLock.java
Go to the documentation of this file.
1/*
2 * Sleuth Kit Data Model
3 *
4 * Copyright 2024 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package org.sleuthkit.datamodel;
20
21import java.io.File;
22import java.io.IOException;
23import java.io.RandomAccessFile;
24import java.nio.channels.FileChannel;
25import java.nio.channels.FileLock;
26import java.util.Arrays;
27import java.util.logging.Level;
28
38public class LibraryLock implements AutoCloseable {
39
40 private static final String LIB_FILE_LOCK_TEXT = "lib_lock";
41
42 private static final String TMP_DIR_KEY = "java.io.tmpdir";
43 private static final String USER_NAME_KEY = "user.name";
44
45 private static final byte[] UTF8_BOM = {(byte) 0XEF, (byte) 0xBB, (byte) 0XBF};
46
47 private static LibraryLock libLock = null;
48
59 public static LibraryLock acquireLibLock() {
60 if (libLock == null) {
61 libLock = getLibLock();
62 }
63 return libLock;
64 }
65
71 public static void removeLibLock() throws Exception {
72 if (libLock != null) {
73 libLock.close();
74 }
75 }
76
86 private static LibraryLock getLibLock() {
87 File libTskJniFile = LibraryUtils.getTempFile(
88 System.getProperty(TMP_DIR_KEY, ""),
89 LibraryUtils.Lib.TSK_JNI.getLibName(),
90 System.getProperty(USER_NAME_KEY, ""),
91 LibraryUtils.getExtByPlatform());
92
93 // if the lock file exists
94 if (libTskJniFile.isFile() && !libTskJniFile.canWrite()) {
95 // get the random access file as read only
96 try (RandomAccessFile lockFileRaf = new RandomAccessFile(libTskJniFile, "r")) {
97 LockState lockState = isNewLock(lockFileRaf)
98 ? LockState.HELD_BY_NEW
99 : LockState.HELD_BY_OLD;
100
101 return new LibraryLock(lockState, libTskJniFile, lockFileRaf, null, null);
102 } catch (IOException ex) {
103 // if there is an error getting read only access, then it is the old application dll
104 java.util.logging.Logger.getLogger(LibraryLock.class.getCanonicalName()).log(Level.WARNING, "An error occurred while acquiring the TSK lib lock", ex);
105 return new LibraryLock(LockState.HELD_BY_OLD, libTskJniFile, null, null, null);
106 }
107 } else {
108 // make directories leading up to that
109 libTskJniFile.getParentFile().mkdirs();
110
111 // get file access to the file
112 RandomAccessFile lockFileRaf = null;
113 FileChannel lockFileChannel = null;
114 FileLock lockFileLock = null;
115 try {
116 lockFileRaf = new RandomAccessFile(libTskJniFile, "rw");
117 lockFileChannel = lockFileRaf.getChannel();
118 lockFileLock = lockFileChannel == null
119 ? null
120 : lockFileChannel.tryLock(1024L, 1L, false);
121
122 if (lockFileLock != null) {
123 lockFileRaf.setLength(0);
124 lockFileRaf.write(UTF8_BOM);
125 lockFileRaf.writeChars(LIB_FILE_LOCK_TEXT);
126
127 return new LibraryLock(LockState.ACQUIRED, libTskJniFile, lockFileRaf, lockFileChannel, lockFileLock);
128 } else {
129 LockState lockState = isNewLock(lockFileRaf)
132
133 return new LibraryLock(lockState, libTskJniFile, lockFileRaf, lockFileChannel, null);
134 }
135 } catch (IOException ex) {
136 // if there is an error getting read only access, then it is the old application dll
137 java.util.logging.Logger.getLogger(LibraryLock.class.getCanonicalName()).log(Level.WARNING, "An error occurred while acquiring the TSK lib lock", ex);
138 return new LibraryLock(LockState.HELD_BY_OLD, libTskJniFile, lockFileRaf, lockFileChannel, lockFileLock);
139 }
140 }
141 }
142
153 private static boolean isNewLock(RandomAccessFile libRaf) throws IOException {
154 libRaf.seek(0);
155 byte[] startFileArr = new byte[UTF8_BOM.length];
156 int read = libRaf.read(startFileArr);
157 return read == startFileArr.length && Arrays.equals(UTF8_BOM, startFileArr);
158
159 }
160
161 private File libTskJniFile;
162 private RandomAccessFile lockFileRaf;
163 private FileChannel lockFileChannel;
164 private FileLock lockFileLock;
165 private LockState lockState;
166
176 private LibraryLock(
177 LockState lockState,
178 File lockFile,
179 RandomAccessFile lockFileRaf,
180 FileChannel lockFileChannel,
181 FileLock lockFileLock) {
182
183 this.libTskJniFile = lockFile;
184 this.lockFileRaf = lockFileRaf;
185 this.lockFileChannel = lockFileChannel;
186 this.lockFileLock = lockFileLock;
187 this.lockState = lockState;
188 }
189
197 return lockState;
198 }
199
206 return libTskJniFile;
207 }
208
209 @Override
210 public void close() throws Exception {
211 // close lock file resources in reverse acquisition order
212 if (this.lockFileLock != null) {
213 this.lockFileLock.close();
214 this.lockFileLock = null;
215 }
216
217 if (this.lockFileChannel != null) {
218 this.lockFileChannel.close();
219 this.lockFileChannel = null;
220 }
221
222 if (this.lockFileRaf != null) {
223 this.lockFileRaf.close();
224 this.lockFileRaf = null;
225 }
226
227 if (this.libTskJniFile != null) {
228 this.libTskJniFile.delete();
229 this.libTskJniFile = null;
230 }
231 }
232
250}
static LibraryLock acquireLibLock()

Copyright © 2011-2024 Brian Carrier. (carrier -at- sleuthkit -dot- org)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.