/*
 * Copyright (C) 2014 The Android Open Source Project
 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.util.prefs;
import java.util.*;
import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;

import sun.util.logging.PlatformLogger;

/**
 * Preferences implementation for Unix.  Preferences are stored in the file
 * system, with one directory per preferences node.  All of the preferences
 * at each node are stored in a single file.  Atomic file system operations
 * (e.g. File.renameTo) are used to ensure integrity.  An in-memory cache of
 * the "explored" portion of the tree is maintained for performance, and
 * written back to the disk periodically.  File-locking is used to ensure
 * reasonable behavior when multiple VMs are running at the same time.
 * (The file lock is obtained only for sync(), flush() and removeNode().)
 *
 * @author  Josh Bloch
 * @see     Preferences
 * @since   1.4
 *
 * @hide
 */
// Android-changed: @hide.
public class FileSystemPreferences extends AbstractPreferences {
    /**
     * Returns logger for error messages. Backing store exceptions are logged at
     * WARNING level.
     */
    private static PlatformLogger getLogger() {
        return PlatformLogger.getLogger("java.util.prefs");
    }

    /**
     * Directory for system preferences.
     */
    private static File systemRootDir;

    /*
     * Flag, indicating whether systemRoot  directory is writable
     */
    private static boolean isSystemRootWritable;

    /**
     * Directory for user preferences.
     */
    private static File userRootDir;

    /*
     * Flag, indicating whether userRoot  directory is writable
     */
    private static boolean isUserRootWritable;

   /**
     * The user root.
     */
    static Preferences userRoot = null;

    static synchronized Preferences getUserRoot() {
        if (userRoot == null) {
            setupUserRoot();
            userRoot = new FileSystemPreferences(true);
        }
        return userRoot;
    }

    private static void setupUserRoot() {
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                userRootDir =
                      new File(System.getProperty("java.util.prefs.userRoot",
                      System.getProperty("user.home")), ".java/.userPrefs");
                // Attempt to create root dir if it does not yet exist.
                if (!userRootDir.exists()) {
                    if (userRootDir.mkdirs()) {
                        try {
                            chmod(userRootDir.getCanonicalPath(), USER_RWX);
                        } catch (IOException e) {
                            getLogger().warning("Could not change permissions" +
                                " on userRoot directory. ");
                        }
                        getLogger().info("Created user preferences directory.");
                    }
                    else
                        getLogger().warning("Couldn't create user preferences" +
                        " directory. User preferences are unusable.");
                }
                isUserRootWritable = userRootDir.canWrite();
                String USER_NAME = System.getProperty("user.name");
                userLockFile = new File (userRootDir,".user.lock." + USER_NAME);
                userRootModFile = new File (userRootDir,
                                               ".userRootModFile." + USER_NAME);
                if (!userRootModFile.exists())
                try {
                    // create if does not exist.
                    userRootModFile.createNewFile();
                    // Only user can read/write userRootModFile.
                    int result = chmod(userRootModFile.getCanonicalPath(),
                                                               USER_READ_WRITE);
                    if (result !=0)
                        getLogger().warning("Problem creating userRoot " +
                            "mod file. Chmod failed on " +
                             userRootModFile.getCanonicalPath() +
                             " Unix error code " + result);
                } catch (IOException e) {
                    getLogger().warning(e.toString());
                }
                userRootModTime = userRootModFile.lastModified();
                return null;
            }
        });
    }


    /**
     * The system root.
     */
    static Preferences systemRoot;

    static synchronized Preferences getSystemRoot() {
        if (systemRoot == null) {
            setupSystemRoot();
            systemRoot = new FileSystemPreferences(false);
        }
        return systemRoot;
    }

    private static void setupSystemRoot() {
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                String systemPrefsDirName =
                  System.getProperty("java.util.prefs.systemRoot","/etc/.java");
                systemRootDir =
                     new File(systemPrefsDirName, ".systemPrefs");
                // Attempt to create root dir if it does not yet exist.
                if (!systemRootDir.exists()) {
                    // system root does not exist in /etc/.java
                    // Switching  to java.home
                    systemRootDir =
                                  new File(System.getProperty("java.home"),
                                                            ".systemPrefs");
                    if (!systemRootDir.exists()) {
                        if (systemRootDir.mkdirs()) {
                            getLogger().info(
                                "Created system preferences directory "
                                + "in java.home.");
                            try {
                                chmod(systemRootDir.getCanonicalPath(),
                                                          USER_RWX_ALL_RX);
                            } catch (IOException e) {
                            }
                        } else {
                            getLogger().warning("Could not create "
                                + "system preferences directory. System "
                                + "preferences are unusable.");
                        }
                    }
                }
                isSystemRootWritable = systemRootDir.canWrite();
                systemLockFile = new File(systemRootDir, ".system.lock");
                systemRootModFile =
                               new File (systemRootDir,".systemRootModFile");
                if (!systemRootModFile.exists() && isSystemRootWritable)
                try {
                    // create if does not exist.
                    systemRootModFile.createNewFile();
                    int result = chmod(systemRootModFile.getCanonicalPath(),
                                                          USER_RW_ALL_READ);
                    if (result !=0)
                        getLogger().warning("Chmod failed on " +
                               systemRootModFile.getCanonicalPath() +
                              " Unix error code " + result);
                } catch (IOException e) { getLogger().warning(e.toString());
                }
                systemRootModTime = systemRootModFile.lastModified();
                return null;
            }
        });
    }


    /**
     * Unix user write/read permission
     */
    private static final int USER_READ_WRITE = 0600;

    private static final int USER_RW_ALL_READ = 0644;


    private static final int USER_RWX_ALL_RX = 0755;

    private static final int USER_RWX = 0700;

    /**
     * The lock file for the user tree.
     */
    static File userLockFile;



    /**
     * The lock file for the system tree.
     */
    static File systemLockFile;

    /**
     * Unix lock handle for userRoot.
     * Zero, if unlocked.
     */

    private static int userRootLockHandle = 0;

    /**
     * Unix lock handle for systemRoot.
     * Zero, if unlocked.
     */

    private static int systemRootLockHandle = 0;

    /**
     * The directory representing this preference node.  There is no guarantee
     * that this directory exits, as another VM can delete it at any time
     * that it (the other VM) holds the file-lock.  While the root node cannot
     * be deleted, it may not yet have been created, or the underlying
     * directory could have been deleted accidentally.
     */
    private final File dir;

    /**
     * The file representing this preference node's preferences.
     * The file format is undocumented, and subject to change
     * from release to release, but I'm sure that you can figure
     * it out if you try real hard.
     */
    private final File prefsFile;

    /**
     * A temporary file used for saving changes to preferences.  As part of
     * the sync operation, changes are first saved into this file, and then
     * atomically renamed to prefsFile.  This results in an atomic state
     * change from one valid set of preferences to another.  The
     * the file-lock is held for the duration of this transformation.
     */
    private final File tmpFile;

    /**
     * File, which keeps track of global modifications of userRoot.
     */
    private static  File userRootModFile;

    /**
     * Flag, which indicated whether userRoot was modified by another VM
     */
    private static boolean isUserRootModified = false;

    /**
     * Keeps track of userRoot modification time. This time is reset to
     * zero after UNIX reboot, and is increased by 1 second each time
     * userRoot is modified.
     */
    private static long userRootModTime;


    /*
     * File, which keeps track of global modifications of systemRoot
     */
    private static File systemRootModFile;
    /*
     * Flag, which indicates whether systemRoot was modified by another VM
     */
    private static boolean isSystemRootModified = false;

    /**
     * Keeps track of systemRoot modification time. This time is reset to
     * zero after system reboot, and is increased by 1 second each time
     * systemRoot is modified.
     */
    private static long systemRootModTime;

    /**
     * Locally cached preferences for this node (includes uncommitted
     * changes).  This map is initialized with from disk when the first get or
     * put operation occurs on this node.  It is synchronized with the
     * corresponding disk file (prefsFile) by the sync operation.  The initial
     * value is read *without* acquiring the file-lock.
     */
    private Map<String, String> prefsCache = null;

    /**
     * The last modification time of the file backing this node at the time
     * that prefCache was last synchronized (or initially read).  This
     * value is set *before* reading the file, so it's conservative; the
     * actual timestamp could be (slightly) higher.  A value of zero indicates
     * that we were unable to initialize prefsCache from the disk, or
     * have not yet attempted to do so.  (If prefsCache is non-null, it
     * indicates the former; if it's null, the latter.)
     */
    private long lastSyncTime = 0;

   /**
    * Unix error code for locked file.
    */
    private static final int EAGAIN = 11;

   /**
    * Unix error code for denied access.
    */
    private static final int EACCES = 13;

    /* Used to interpret results of native functions */
    private static final int LOCK_HANDLE = 0;
    private static final int ERROR_CODE = 1;

    /**
     * A list of all uncommitted preference changes.  The elements in this
     * list are of type PrefChange.  If this node is concurrently modified on
     * disk by another VM, the two sets of changes are merged when this node
     * is sync'ed by overwriting our prefsCache with the preference map last
     * written out to disk (by the other VM), and then replaying this change
     * log against that map.  The resulting map is then written back
     * to the disk.
     */
    final List<Change> changeLog = new ArrayList<>();

    /**
     * Represents a change to a preference.
     */
    private abstract class Change {
        /**
         * Reapplies the change to prefsCache.
         */
        abstract void replay();
    };

    /**
     * Represents a preference put.
     */
    private class Put extends Change {
        String key, value;

        Put(String key, String value) {
            this.key = key;
            this.value = value;
        }

        void replay() {
            prefsCache.put(key, value);
        }
    }

    /**
     * Represents a preference remove.
     */
    private class Remove extends Change {
        String key;

        Remove(String key) {
            this.key = key;
        }

        void replay() {
            prefsCache.remove(key);
        }
    }

    /**
     * Represents the creation of this node.
     */
    private class NodeCreate extends Change {
        /**
         * Performs no action, but the presence of this object in changeLog
         * will force the node and its ancestors to be made permanent at the
         * next sync.
         */
        void replay() {
        }
    }

    /**
     * NodeCreate object for this node.
     */
    NodeCreate nodeCreate = null;

    /**
     * Replay changeLog against prefsCache.
     */
    private void replayChanges() {
        for (int i = 0, n = changeLog.size(); i<n; i++)
            changeLog.get(i).replay();
    }

    static {
        // Add shutdown hook to flush cached prefs on normal termination
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                syncWorld();
            }
        });
    }

    private static void syncWorld() {
        /*
         * Synchronization necessary because userRoot and systemRoot are
         * lazily initialized.
         */
        Preferences userRt;
        Preferences systemRt;
        synchronized(FileSystemPreferences.class) {
            userRt   = userRoot;
            systemRt = systemRoot;
        }

        try {
            if (userRt != null)
                userRt.flush();
        } catch(BackingStoreException e) {
            getLogger().warning("Couldn't flush user prefs: " + e);
        }

        try {
            if (systemRt != null)
                systemRt.flush();
        } catch(BackingStoreException e) {
            getLogger().warning("Couldn't flush system prefs: " + e);
        }
    }

    private final boolean isUserNode;

    /**
     * Special constructor for roots (both user and system).  This constructor
     * will only be called twice, by the static initializer.
     */
    private FileSystemPreferences(boolean user) {
        super(null, "");
        isUserNode = user;
        dir = (user ? userRootDir: systemRootDir);
        prefsFile = new File(dir, "prefs.xml");
        tmpFile   = new File(dir, "prefs.tmp");
    }

    /** @hide for unit testing only */
    // Android-added constructor for testing.
    public FileSystemPreferences(String path, File lockFile, boolean isUserNode) {
        super(null, "");
        this.isUserNode = isUserNode;
        this.dir = new File(path);
        prefsFile = new File(dir, "prefs.xml");
        tmpFile = new File(dir, "prefs.tmp");
        newNode = !dir.exists();
        if (newNode) {
            // These 2 things guarantee node will get wrtten at next flush/sync
            prefsCache = new TreeMap<>();
            nodeCreate = new NodeCreate();
            changeLog.add(nodeCreate);
        }

        if (isUserNode) {
            userLockFile = lockFile;
            userRootModFile = new File(lockFile.getParentFile(), lockFile.getName() + ".rootmod");
        } else {
            systemLockFile = lockFile;
            systemRootModFile = new File(lockFile.getParentFile(), lockFile.getName() + ".rootmod");
        }
    }

    /**
     * Construct a new FileSystemPreferences instance with the specified
     * parent node and name.  This constructor, called from childSpi,
     * is used to make every node except for the two //roots.
     */
    private FileSystemPreferences(FileSystemPreferences parent, String name) {
        super(parent, name);
        isUserNode = parent.isUserNode;
        dir  = new File(parent.dir, dirName(name));
        prefsFile = new File(dir, "prefs.xml");
        tmpFile  = new File(dir, "prefs.tmp");
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                newNode = !dir.exists();
                return null;
            }
        });
        if (newNode) {
            // These 2 things guarantee node will get wrtten at next flush/sync
            prefsCache = new TreeMap<>();
            nodeCreate = new NodeCreate();
            changeLog.add(nodeCreate);
        }
    }

    public boolean isUserNode() {
        return isUserNode;
    }

    protected void putSpi(String key, String value) {
        initCacheIfNecessary();
        changeLog.add(new Put(key, value));
        prefsCache.put(key, value);
    }

    protected String getSpi(String key) {
        initCacheIfNecessary();
        return prefsCache.get(key);
    }

    protected void removeSpi(String key) {
        initCacheIfNecessary();
        changeLog.add(new Remove(key));
        prefsCache.remove(key);
    }

    /**
     * Initialize prefsCache if it has yet to be initialized.  When this method
     * returns, prefsCache will be non-null.  If the data was successfully
     * read from the file, lastSyncTime will be updated.  If prefsCache was
     * null, but it was impossible to read the file (because it didn't
     * exist or for any other reason) prefsCache will be initialized to an
     * empty, modifiable Map, and lastSyncTime remain zero.
     */
    private void initCacheIfNecessary() {
        if (prefsCache != null)
            return;

        try {
            loadCache();
        } catch(Exception e) {
            // assert lastSyncTime == 0;
            prefsCache = new TreeMap<>();
        }
    }

    /**
     * Attempt to load prefsCache from the backing store.  If the attempt
     * succeeds, lastSyncTime will be updated (the new value will typically
     * correspond to the data loaded into the map, but it may be less,
     * if another VM is updating this node concurrently).  If the attempt
     * fails, a BackingStoreException is thrown and both prefsCache and
     * lastSyncTime are unaffected by the call.
     */
    private void loadCache() throws BackingStoreException {
        Map<String, String> m = new TreeMap<>();
        long newLastSyncTime = 0;
        try {
            newLastSyncTime = prefsFile.lastModified();
            try (FileInputStream fis = new FileInputStream(prefsFile)) {
                XmlSupport.importMap(fis, m);
            }
        } catch(Exception e) {
            if (e instanceof InvalidPreferencesFormatException) {
                getLogger().warning("Invalid preferences format in "
                                    +  prefsFile.getPath());
                prefsFile.renameTo( new File(
                                             prefsFile.getParentFile(),
                                             "IncorrectFormatPrefs.xml"));
                m = new TreeMap<>();
            } else if (e instanceof FileNotFoundException) {
                getLogger().warning("Prefs file removed in background "
                                    + prefsFile.getPath());
            } else {
                // Android-added: This exception may be ignored by some callers,
                // added a logger entry to prevent omitting it completely.
                getLogger().warning("Exception while reading cache: "
                                    + e.getMessage());
                throw new BackingStoreException(e);
            }
        }
        // Attempt succeeded; update state
        prefsCache = m;
        lastSyncTime = newLastSyncTime;
    }

    /**
     * Attempt to write back prefsCache to the backing store.  If the attempt
     * succeeds, lastSyncTime will be updated (the new value will correspond
     * exactly to the data thust written back, as we hold the file lock, which
     * prevents a concurrent write.  If the attempt fails, a
     * BackingStoreException is thrown and both the backing store (prefsFile)
     * and lastSyncTime will be unaffected by this call.  This call will
     * NEVER leave prefsFile in a corrupt state.
     */
    private void writeBackCache() throws BackingStoreException {
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction<Void>() {
                public Void run() throws BackingStoreException {
                    try {
                        if (!dir.exists() && !dir.mkdirs())
                            throw new BackingStoreException(dir +
                                                             " create failed.");
                        try (FileOutputStream fos = new FileOutputStream(tmpFile)) {
                            XmlSupport.exportMap(fos, prefsCache);
                        }
                        if (!tmpFile.renameTo(prefsFile))
                            throw new BackingStoreException("Can't rename " +
                            tmpFile + " to " + prefsFile);
                    } catch(Exception e) {
                        if (e instanceof BackingStoreException)
                            throw (BackingStoreException)e;
                        throw new BackingStoreException(e);
                    }
                    return null;
                }
            });
        } catch (PrivilegedActionException e) {
            throw (BackingStoreException) e.getException();
        }
    }

    protected String[] keysSpi() {
        initCacheIfNecessary();
        return prefsCache.keySet().toArray(new String[prefsCache.size()]);
    }

    protected String[] childrenNamesSpi() {
        return AccessController.doPrivileged(
            new PrivilegedAction<String[]>() {
                public String[] run() {
                    List<String> result = new ArrayList<>();
                    File[] dirContents = dir.listFiles();
                    if (dirContents != null) {
                        for (int i = 0; i < dirContents.length; i++)
                            if (dirContents[i].isDirectory())
                                result.add(nodeName(dirContents[i].getName()));
                    }
                    return result.toArray(EMPTY_STRING_ARRAY);
               }
            });
    }

    private static final String[] EMPTY_STRING_ARRAY = new String[0];

    protected AbstractPreferences childSpi(String name) {
        return new FileSystemPreferences(this, name);
    }

    public void removeNode() throws BackingStoreException {
        synchronized (isUserNode()? userLockFile: systemLockFile) {
            // to remove a node we need an exclusive lock
            if (!lockFile(false))
                throw(new BackingStoreException("Couldn't get file lock."));
           try {
                super.removeNode();
           } finally {
                unlockFile();
           }
        }
    }

    /**
     * Called with file lock held (in addition to node locks).
     */
    protected void removeNodeSpi() throws BackingStoreException {
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction<Void>() {
                public Void run() throws BackingStoreException {
                    if (changeLog.contains(nodeCreate)) {
                        changeLog.remove(nodeCreate);
                        nodeCreate = null;
                        return null;
                    }
                    if (!dir.exists())
                        return null;
                    prefsFile.delete();
                    tmpFile.delete();
                    // dir should be empty now.  If it's not, empty it
                    File[] junk = dir.listFiles();
                    if (junk.length != 0) {
                        getLogger().warning(
                           "Found extraneous files when removing node: "
                            + Arrays.asList(junk));
                        for (int i=0; i<junk.length; i++)
                            junk[i].delete();
                    }
                    if (!dir.delete())
                        throw new BackingStoreException("Couldn't delete dir: "
                                                                         + dir);
                    return null;
                }
            });
        } catch (PrivilegedActionException e) {
            throw (BackingStoreException) e.getException();
        }
    }

    public synchronized void sync() throws BackingStoreException {
        boolean userNode = isUserNode();
        boolean shared;

        if (userNode) {
            shared = false; /* use exclusive lock for user prefs */
        } else {
            /* if can write to system root, use exclusive lock.
               otherwise use shared lock. */
            shared = !isSystemRootWritable;
        }
        synchronized (isUserNode()? userLockFile:systemLockFile) {
           if (!lockFile(shared))
               throw(new BackingStoreException("Couldn't get file lock."));
           final Long newModTime =
                AccessController.doPrivileged(
                    new PrivilegedAction<Long>() {
               public Long run() {
                   long nmt;
                   if (isUserNode()) {
                       nmt = userRootModFile.lastModified();
                       isUserRootModified = userRootModTime == nmt;
                   } else {
                       nmt = systemRootModFile.lastModified();
                       isSystemRootModified = systemRootModTime == nmt;
                   }
                   return new Long(nmt);
               }
           });
           try {
               super.sync();
               AccessController.doPrivileged(new PrivilegedAction<Void>() {
                   public Void run() {
                   if (isUserNode()) {
                       userRootModTime = newModTime.longValue() + 1000;
                       userRootModFile.setLastModified(userRootModTime);
                   } else {
                       systemRootModTime = newModTime.longValue() + 1000;
                       systemRootModFile.setLastModified(systemRootModTime);
                   }
                   return null;
                   }
               });
           } finally {
                unlockFile();
           }
        }
    }

    protected void syncSpi() throws BackingStoreException {
        syncSpiPrivileged();
    }

    private void syncSpiPrivileged() throws BackingStoreException {
        if (isRemoved())
            throw new IllegalStateException("Node has been removed");
        if (prefsCache == null)
            return;  // We've never been used, don't bother syncing
        long lastModifiedTime;
        if ((isUserNode() ? isUserRootModified : isSystemRootModified)) {
            lastModifiedTime = prefsFile.lastModified();
            if (lastModifiedTime  != lastSyncTime) {
                // Prefs at this node were externally modified; read in node and
                // playback any local mods since last sync
                loadCache();
                replayChanges();
                lastSyncTime = lastModifiedTime;
            }
        } else if (lastSyncTime != 0 && !dir.exists()) {
            // This node was removed in the background.  Playback any changes
            // against a virgin (empty) Map.
            prefsCache = new TreeMap<>();
            replayChanges();
        }
        if (!changeLog.isEmpty()) {
            writeBackCache();  // Creates directory & file if necessary
           /*
            * Attempt succeeded; it's barely possible that the call to
            * lastModified might fail (i.e., return 0), but this would not
            * be a disaster, as lastSyncTime is allowed to lag.
            */
            lastModifiedTime = prefsFile.lastModified();
            /* If lastSyncTime did not change, or went back
             * increment by 1 second. Since we hold the lock
             * lastSyncTime always monotonically encreases in the
             * atomic sense.
             */
            if (lastSyncTime <= lastModifiedTime) {
                lastSyncTime = lastModifiedTime + 1000;
                prefsFile.setLastModified(lastSyncTime);
            }
            changeLog.clear();
        }
    }

    public void flush() throws BackingStoreException {
        if (isRemoved())
            return;
        sync();
    }

    protected void flushSpi() throws BackingStoreException {
        // assert false;
    }

    /**
     * Returns true if the specified character is appropriate for use in
     * Unix directory names.  A character is appropriate if it's a printable
     * ASCII character (> 0x1f && < 0x7f) and unequal to slash ('/', 0x2f),
     * dot ('.', 0x2e), or underscore ('_', 0x5f).
     */
    private static boolean isDirChar(char ch) {
        return ch > 0x1f && ch < 0x7f && ch != '/' && ch != '.' && ch != '_';
    }

    /**
     * Returns the directory name corresponding to the specified node name.
     * Generally, this is just the node name.  If the node name includes
     * inappropriate characters (as per isDirChar) it is translated to Base64.
     * with the underscore  character ('_', 0x5f) prepended.
     */
    private static String dirName(String nodeName) {
        for (int i=0, n=nodeName.length(); i < n; i++)
            if (!isDirChar(nodeName.charAt(i)))
                return "_" + Base64.byteArrayToAltBase64(byteArray(nodeName));
        return nodeName;
    }

    /**
     * Translate a string into a byte array by translating each character
     * into two bytes, high-byte first ("big-endian").
     */
    private static byte[] byteArray(String s) {
        int len = s.length();
        byte[] result = new byte[2*len];
        for (int i=0, j=0; i<len; i++) {
            char c = s.charAt(i);
            result[j++] = (byte) (c>>8);
            result[j++] = (byte) c;
        }
        return result;
    }

    /**
     * Returns the node name corresponding to the specified directory name.
 * (Inverts the transformation of dirName(String).
     */
    private static String nodeName(String dirName) {
        if (dirName.charAt(0) != '_')
            return dirName;
        byte a[] = Base64.altBase64ToByteArray(dirName.substring(1));
        StringBuffer result = new StringBuffer(a.length/2);
        for (int i = 0; i < a.length; ) {
            int highByte = a[i++] & 0xff;
            int lowByte =  a[i++] & 0xff;
            result.append((char) ((highByte << 8) | lowByte));
        }
        return result.toString();
    }

    /**
     * Try to acquire the appropriate file lock (user or system).  If
     * the initial attempt fails, several more attempts are made using
     * an exponential backoff strategy.  If all attempts fail, this method
     * returns false.
     * @throws SecurityException if file access denied.
     */
    private boolean lockFile(boolean shared) throws SecurityException{
        boolean usernode = isUserNode();
        int[] result;
        int errorCode = 0;
        File lockFile = (usernode ? userLockFile : systemLockFile);
        long sleepTime = INIT_SLEEP_TIME;
        for (int i = 0; i < MAX_ATTEMPTS; i++) {
            try {
                  int perm = (usernode? USER_READ_WRITE: USER_RW_ALL_READ);
                  result = lockFile0(lockFile.getCanonicalPath(), perm, shared);

                  errorCode = result[ERROR_CODE];
                  if (result[LOCK_HANDLE] != 0) {
                     if (usernode) {
                         userRootLockHandle = result[LOCK_HANDLE];
                     } else {
                         systemRootLockHandle = result[LOCK_HANDLE];
                     }
                     return true;
                  }
            } catch(IOException e) {
//                // If at first, you don't succeed...
            }

            try {
                Thread.sleep(sleepTime);
            } catch(InterruptedException e) {
                checkLockFile0ErrorCode(errorCode);
                return false;
            }
            sleepTime *= 2;
        }
        checkLockFile0ErrorCode(errorCode);
        return false;
    }

    /**
     * Checks if unlockFile0() returned an error. Throws a SecurityException,
     * if access denied. Logs a warning otherwise.
     */
    private void checkLockFile0ErrorCode (int errorCode)
                                                      throws SecurityException {
        if (errorCode == EACCES)
            throw new SecurityException("Could not lock " +
            (isUserNode()? "User prefs." : "System prefs.") +
             " Lock file access denied.");
        if (errorCode != EAGAIN)
            getLogger().warning("Could not lock " +
                             (isUserNode()? "User prefs. " : "System prefs.") +
                             " Unix error code " + errorCode + ".");
    }

    /**
     * Locks file using UNIX file locking.
     * @param fileName Absolute file name of the lock file.
     * @return Returns a lock handle, used to unlock the file.
     */
    private static native int[]
            lockFile0(String fileName, int permission, boolean shared);

    /**
     * Unlocks file previously locked by lockFile0().
     * @param lockHandle Handle to the file lock.
     * @return Returns zero if OK, UNIX error code if failure.
     */
    private  static native int unlockFile0(int lockHandle);

    /**
     * Changes UNIX file permissions.
     */
    private static native int chmod(String fileName, int permission);

    /**
     * Initial time between lock attempts, in ms.  The time is doubled
     * after each failing attempt (except the first).
     */
    private static int INIT_SLEEP_TIME = 50;

    /**
     * Maximum number of lock attempts.
     */
    private static int MAX_ATTEMPTS = 5;

    /**
     * Release the the appropriate file lock (user or system).
     * @throws SecurityException if file access denied.
     */
    private void unlockFile() {
        int result;
        boolean usernode = isUserNode();
        File lockFile = (usernode ? userLockFile : systemLockFile);
        int lockHandle = ( usernode ? userRootLockHandle:systemRootLockHandle);
        if (lockHandle == 0) {
            getLogger().warning("Unlock: zero lockHandle for " +
                           (usernode ? "user":"system") + " preferences.)");
            return;
        }
        result = unlockFile0(lockHandle);
        if (result != 0) {
            getLogger().warning("Could not drop file-lock on " +
            (isUserNode() ? "user" : "system") + " preferences." +
            " Unix error code " + result + ".");
            if (result == EACCES)
                throw new SecurityException("Could not unlock" +
                (isUserNode()? "User prefs." : "System prefs.") +
                " Lock file access denied.");
        }
        if (isUserNode()) {
            userRootLockHandle = 0;
        } else {
            systemRootLockHandle = 0;
        }
    }
}
