diff options
Diffstat (limited to 'src/main/java/de/waldheinz/fs/fat/Dummy83BufferGenerator.java')
-rw-r--r-- | src/main/java/de/waldheinz/fs/fat/Dummy83BufferGenerator.java | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/main/java/de/waldheinz/fs/fat/Dummy83BufferGenerator.java b/src/main/java/de/waldheinz/fs/fat/Dummy83BufferGenerator.java new file mode 100644 index 0000000..d9848cc --- /dev/null +++ b/src/main/java/de/waldheinz/fs/fat/Dummy83BufferGenerator.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2012 Google, Inc. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package de.waldheinz.fs.fat; + +import java.security.SecureRandom; + +/** + * Generates dummy 8.3 buffers that are associated with the long names. + * + * @author Daniel Galpin <dgalpin@google.com> based upon the work of + * Andrew Tridgell <tridge@samba.org> + */ +final class Dummy83BufferGenerator { + final SecureRandom mRandom; + + /** + * Creates a new instance of {@code Dummy83BufferGenerator} that uses + * randomness only to avoid short name collisions. + */ + public Dummy83BufferGenerator() { + mRandom = new SecureRandom(); + } + + /* + * Its in the DOS manual!(DOS 5: page 72) Valid: A..Z 0..9 _ ^ $ ~ ! # % & - {} () @ ' ` + * + * Invalid: spaces/periods, + */ + public static boolean validChar(char toTest) { + if (toTest >= 'A' && toTest <= 'Z') return true; + if (toTest >= 'a' && toTest <= 'z') return true; + if (toTest >= '0' && toTest <= '9') return true; + if (toTest == '_' || toTest == '^' || toTest == '$' || toTest == '~' || + toTest == '!' || toTest == '#' || toTest == '%' || toTest == '&' || + toTest == '-' || toTest == '{' || toTest == '}' || toTest == '(' || + toTest == ')' || toTest == '@' || toTest == '\'' || toTest == '`') + return true; + + return false; + } + + public static boolean isSkipChar(char c) { + return (c == '.') || (c == ' '); + } + + public static String tidyString(String dirty) { + final StringBuilder result = new StringBuilder(); + + /* epurate it from alien characters */ + for (int src=0; src < dirty.length(); src++) { + final char toTest = Character.toUpperCase(dirty.charAt(src)); + if (isSkipChar(toTest)) continue; + + if (validChar(toTest)) { + result.append(toTest); + } else { + result.append('_'); + } + } + + return result.toString(); + } + + public static boolean cleanString(String s) { + for (int i=0; i < s.length(); i++) { + if (isSkipChar(s.charAt(i))) return false; + if (!validChar(s.charAt(i))) return false; + } + + return true; + } + + public static String stripLeadingPeriods(String str) { + final StringBuilder sb = new StringBuilder(str.length()); + + for (int i=0; i < str.length(); i++) { + if (str.charAt(i) != '.') { //NOI18N + sb.append(str.substring(i)); + break; + } + } + + return sb.toString(); + } /* + * These characters are all invalid in 8.3 names, plus have been shown to be + * harmless on all tested devices + */ + static final private char[] invalidchar = { + (char) 0x01, (char) 0x02, (char) 0x03, (char) 0x04, (char) 0x05, (char) 0x06, + (char) 0x0B, + (char) 0x0C, (char) 0x0E, (char) 0x0F, (char) 0x10, (char) 0x11, (char) 0x12, + (char) 0x13, + (char) 0x14, (char) 0x15, (char) 0x16, (char) 0x17, (char) 0x18, (char) 0x19, + (char) 0x1A, + (char) 0x1B, (char) 0x1C, (char) 0x1D, (char) 0x1E, (char) 0x1F, (char) 0x22, + (char) 0x2a, + (char) 0x3a, (char) 0x3c, (char) 0x3e, (char) 0x3f, (char) 0x5b, (char) 0x5d, + (char) 0x7c + }; + + /** + * See original C Linux patch by Andrew Tridgell <tridge@samba.org> + * build a 11 byte 8.3 buffer which is not a short filename. We want 11 + * bytes which: - will be seen as a constant string to all APIs on Linux and + * Windows - cannot be matched with wildcard patterns - cannot be used to + * access the file - has a low probability of collision within a directory - + * has an invalid 3 byte extension - contains at least one non-space and + * non-nul byte + * + * @param longFullName the long file name to generate the buffer for + * @return the generated 8.3 buffer + */ + public ShortName generate83BufferNew(String longFullName) + throws IllegalStateException { + + char[] retBuffer = new char[11]; + + boolean hasRealShortName = false;// getRealShortNameInstead(longFullName, + // retBuffer); + if (!hasRealShortName) { + int i, tilde_pos, slash_pos; + int randomNumber = Math.abs(mRandom.nextInt()); + + /* + * the '/' makes sure that even unpatched Linux systems can't get at + * files by the 8.3 entry. + */ + + slash_pos = randomNumber % 8; + randomNumber >>= 3; + + /* + * fill in the first 8 bytes with invalid characters. Note that we + * need to be careful not to run out of randomness. We use the same + * extension for all buffers. + */ + for (i = 0; i < 8; i++) { + if (i == slash_pos) + retBuffer[i] = '/'; + else { + retBuffer[i] = + invalidchar[randomNumber % invalidchar.length]; + randomNumber /= invalidchar.length; + if (randomNumber < invalidchar.length) + randomNumber = Math.abs(mRandom.nextInt()); + } + } + + for ( i = 0; i < 8; i ++ ) { + if (retBuffer[i] == 0xe5) { + throw new RuntimeException(); + } + } + + retBuffer[8] = 'i'; + retBuffer[9] = 'f'; + retBuffer[10] = 'l'; + } + ShortName retName = new ShortName(retBuffer); + retName.setHasShortNameOnly(hasRealShortName); + return retName; + } + +} |