/*
 * Copyright (c) 2000, 2008, 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
 */
class FileSystemPreferences extends AbstractPreferences {
    /**
     * Sync interval in seconds.
     */
    private static final int SYNC_INTERVAL = Math.max(1,
        Integer.parseInt(
            AccessController.doPrivileged(
                new sun.security.action.GetPropertyAction(
                    "java.util.prefs.syncInterval", "30"))));

    /**
     * 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<Change>();

    /**
     * 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();
    }

    private static Timer syncTimer = new Timer(true); // Daemon Thread

    static {
        // Add periodic timer task to periodically sync cached prefs
        syncTimer.schedule(new TimerTask() {
            public void run() {
                syncWorld();
            }
        }, SYNC_INTERVAL*1000, SYNC_INTERVAL*1000);

        // Add shutdown hook to flush cached prefs on normal termination
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                Runtime.getRuntime().addShutdownHook(new Thread() {
                    public void run() {
                        syncTimer.cancel();
                        syncWorld();
                    }
                });
                return null;
            }
        });
    }

    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");
    }

    /**
     * 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<String, String>();
            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<String, String>();
        }
    }

    /**
     * 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 {
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction<Void>() {
                public Void run() throws BackingStoreException {
                    Map<String, String> m = new TreeMap<String, String>();
                    long newLastSyncTime = 0;
                    try {
                        newLastSyncTime = prefsFile.lastModified();
                        FileInputStream fis = new FileInputStream(prefsFile);
                        XmlSupport.importMap(fis, m);
                        fis.close();
                    } 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<String, String>();
                        } else if (e instanceof FileNotFoundException) {
                        getLogger().warning("Prefs file removed in background "
                                           + prefsFile.getPath());
                        } else {
                            throw new BackingStoreException(e);
                        }
                    }
                    // Attempt succeeded; update state
                    prefsCache = m;
                    lastSyncTime = newLastSyncTime;
                    return null;
                }
            });
        } catch (PrivilegedActionException e) {
            throw (BackingStoreException) e.getException();
        }
    }

    /**
     * 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.");
                        FileOutputStream fos = new FileOutputStream(tmpFile);
                        XmlSupport.exportMap(fos, prefsCache);
                        fos.close();
                        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<String>();
                    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 {
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction<Void>() {
                public Void run() throws BackingStoreException {
                    syncSpiPrivileged();
                    return null;
                }
            });
        } catch (PrivilegedActionException e) {
            throw (BackingStoreException) e.getException();
        }
    }
    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<String, String>();
            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;
        }
    }
}
