/************************************************************************** * Copyright (c) 2001 Southeastern Universities Research Association, * Thomas Jefferson National Accelerator Facility * * This software was developed under a United States Government license * described in the NOTICE file included as part of this distribution. * * Jefferson Lab HPC Group, 12000 Jefferson Ave., Newport News, VA 23606 ************************************************************************** * * Description: * File utility class to handle some functionalities that are missing * from java.io.File * * Author: * Jie Chen * Jefferson Lab HPC Group * * 2/?/04 - isLink and getLinkTarget (ychen) * 8/23/05 - add crc32Checksum (ychen). * */ package jlab.hpc.util; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.zip.CRC32; public class JFile extends File { /** * Determines if a de-serialized file is compatible with this class. * * Maintainers must change this value if and only if the new version * of this class is not compatible with old versions. */ private static final long serialVersionUID = 81L; public native static int createFile (String filename, String username); public native static int deleteFile (String filename, String username); public native static int createDirs (String path, String username); public native static int createDir (String path, String username); //public native static int deleteDirs (String path, String username); public native static String getOwner (String path); public native static String getGroup (String path); public native static int changeOwner (String path, String new_ower); public native static boolean isLink (String path); public native static String getLinkTarget (String path); public native static boolean allocate (String path, String username, long bytes); public native static String homeDir (String username); public native static long getTotalSpace (String path); public native static long getAvailableSpace (String path); static final int BUFFER = 4*128*1024; static { System.loadLibrary("JFile"); } /** * Flag to tell whether this java virtual machines is operated * in privileged mode. */ private static boolean privilegedVM = privilegedJavaVM (); private String user = null; public JFile (String pathname, String a_user) { super(pathname); setUser(a_user); } /** * Check whether root started this Java virtual machine. */ public static boolean privilegedJavaVM () { String user = System.getProperty ("user.name"); String filesep = System.getProperty ("file.separator"); if (filesep.equals ("/") == true) {// Unix if (user.equals ("root") == true) return true; } else { // windows if (user.equals ("Administrator") == true) return true; } return false; } public void setUser (String a_user) { user = a_user; } public String getUser() { return user; } public String owner () { return getOwner(getAbsolutePath()); } public String group () { return getGroup(getAbsolutePath()); } /** * Create the file with a given local user name. * * @return true if a file is created, otherwise, false. * @exception SecurityException if create file fail */ public boolean createNewFile () throws SecurityException, IOException { int status; if (privilegedVM == false) { return super.createNewFile (); } else { status = createFile (getAbsolutePath(), user); if (status != 0) {// file is created ok with user as owner return true; } else { throw new SecurityException("failed to create the file "+ getName()+" as user "+user+"."); } } } /** * Make the directory with a given local user name. * * @return true if a file is created, otherwise, false. * @exception SecurityException if mkdir fail */ public boolean mkdir () throws SecurityException { int status; if (privilegedVM == false) { return super.mkdir (); } else { status = createDir (getAbsolutePath(), user); if (status != 0) return true; else throw new SecurityException("failed to create the directory "+ getName()+" as user "+user+"."); } } /** * Make the directory with a given local user name, including any * necessary but nonexistent parent directories * * @return true if a file is created, otherwise, false. * @exception SecurityException if fail */ public boolean mkdirs () throws SecurityException { int status; if (privilegedVM == false) { return super.mkdirs (); } else { status = createDirs (getAbsolutePath(), user); if (status != 0) { return true; } else { throw new SecurityException("failed to create the directory "+ getName()+" as user "+user+"."); } } } /** * Delete file or directoty with a given local user name. * If it is directory, then the directory must be empty. * * @return true if the directory is created, otherwise, false. * @exception SecurityException if delete fail */ public boolean delete() throws SecurityException { int status; if (privilegedVM == false) { return super.delete (); } else { if (isDirectory() && list().length != 0) throw new SecurityException("Directory is not empty"); else { status = deleteFile (getAbsolutePath(), user); if (status != 0) { return true; } else { throw new SecurityException("failed to delete the file "+ getName()+" as user "+user+"."); } } } } /** * Tests whether the file denoted by this abstract pathname is a symbolic link. * * @return true if and only if it is a symbolic link; false otherwise * */ public boolean isLink () { return isLink(getPath()); } public String getLinkTarget() { return getLinkTarget(getPath()); } public boolean allocateSpace(long bytes) { String path = getPath(); if (!exists() || isFile()) path = path.substring(0, path.lastIndexOf("/")); return allocate(path, user, bytes); } /** * Calculate CRC32 checksum of the file denoted by this abstract pathname * * @return CRC32 checksum value in Hex String * @throws IOException If an I/O error occurs */ public String crc32Checksum()throws IOException { CRC32 crc32 = new CRC32(); FileInputStream in = new FileInputStream(getPath()); byte[] b = new byte[BUFFER]; int len = in.read(b); while (len != -1) { crc32.update(b, 0, len); len = in.read(b); } in.close(); return Long.toHexString(crc32.getValue()); } } /** * Return a real path name from a relative path name. * E.G. return ftp/data0 to /home/xyz/ftp/data0 where xyz is a user name. * @param path relative path. * @param user username. * returns an absolute path name. public static String absolutePath (String path, String user) { if (path == null) return null; if (path.startsWith (File.separator) == true) // this is an real path return path; String rpath, home; if (privilegedVM == false || PConfig.usejni == false) { home = System.getProperty ("user.home"); if (home.endsWith (File.separator) == true) rpath = home + path; else rpath = home + File.separator + path; } else { // this is root home = FileUtil.homeDir (user); if (home.equals ("UNKNOWN") == true) return path; if (home.endsWith (File.separator) == true) rpath = home + path; else rpath = home + File.separator + path; } return rpath; } */