diff options
Diffstat (limited to 'libjava/java/io/FilePermission.java')
-rw-r--r-- | libjava/java/io/FilePermission.java | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/libjava/java/io/FilePermission.java b/libjava/java/io/FilePermission.java new file mode 100644 index 0000000..21bb556 --- /dev/null +++ b/libjava/java/io/FilePermission.java @@ -0,0 +1,243 @@ +/* java.lang.FilePermission + Copyright (C) 1998 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package java.io; + +import java.security.*; + + +public class FilePermission extends Permission implements Serializable { + private static final String CURRENT_DIRECTORY = System.getProperty("user.dir"); + private boolean usingPerms = false; + private boolean readPerm = false; + private boolean writePerm = false; + private boolean executePerm = false; + private boolean deletePerm = false; + private String actionsString; + + private void cachePerms() { + // While race conditions could occur, they don't matter at all. + + String action; + int i = actionsString.indexOf(','); + int startI = 0; + while(i != -1) { + action = actionsString.substring(startI,i); + if(action.equals("read")) + readPerm = true; + else if(action.equals("write")) + writePerm = true; + else if(action.equals("execute")) + executePerm = true; + else if(action.equals("delete")) + deletePerm = true; + + startI = i+1; + i = actionsString.indexOf(',',startI); + } + + action = actionsString.substring(startI); + if(action.equals("read")) + readPerm = true; + else if(action.equals("write")) + writePerm = true; + else if(action.equals("execute")) + executePerm = true; + else if(action.equals("delete")) + deletePerm = true; + } + + /** Create a new FilePermission. + ** @param pathExpression an expression specifying the paths this + ** permission represents. + ** @param actionsString a comma-separated list of the actions this + ** permission represents. + ** @XXX what to do when the file string is malformed? + **/ + public FilePermission(String pathExpression, String actionsString) + { + super(pathExpression); + this.actionsString = actionsString; + } + + /** Get the actions this FilePermission supports. + ** @return the String representing the actions this FilePermission supports. + **/ + public String getActions() { + return actionsString; + } + + /** Get the hash code for this Object.<P> + ** FilePermission's hash code is calculated as the exclusive or of the target + ** String's hash code and the action String's hash code. + ** @specnote Sun did not specify how to calculate the hash code; I made this up. + ** @return the hash code for this Object. + **/ + public int hashCode() { + return getName().hashCode() ^ actionsString.hashCode(); + } + + /** Check two FilePermissions for semantic equality. + ** Two FilePermissions are exactly equivalent if they have identical path + ** expressions and have exactly the same access permissions. + ** @param o the Object to compare to. + ** @return whether the Objects are semantically equivalent. + **/ + public boolean equals(Object o) { + if(!(o instanceof FilePermission)) + return false; + FilePermission p = (FilePermission)o; + if(!usingPerms) + cachePerms(); + if(!p.usingPerms) + p.cachePerms(); + + String f1 = getName(); + String f2 = p.getName(); + + /* Compare names, taking into account if they refer to a + * directory and one has a separator and the other does not. + */ + if(f1.charAt(f1.length()) == File.separatorChar) { + if(f2.charAt(f2.length()) == File.separatorChar) { + if(!f2.equals(f1)) + return false; + } else { + if(!f2.equals(f1.substring(0,f1.length()-1))) + return false; + } + } else { + if(f2.charAt(f2.length()) == File.separatorChar) { + if(!f1.equals(f2.substring(0,f2.length()-1))) + return false; + } else { + if(!f1.equals(f2)) + return false; + } + } + return readPerm == p.readPerm && writePerm == p.writePerm && executePerm == p.executePerm && deletePerm == p.deletePerm; + } + + /** Check to see if this permission implies another. + ** Permission A implies permission B if these things are all true: + ** <OL> + ** <LI>A and B are both FilePermissions.</LI> + ** <LI>All possible files in B are included in A (possibly more are in A).</LI> + ** <LI>All actions B supports, A also supports.</LI> + ** </OL> + ** @param p the Permission to compare against. + ** @return whether this Permission implies p + **/ + public boolean implies(Permission p) { + FilePermission fp; + if(!(p instanceof FilePermission)) + return false; + fp = (FilePermission)p; + + String f1 = getName(); + String f2 = fp.getName(); + if(f1.charAt(0) != File.separatorChar) { + f1 = CURRENT_DIRECTORY + f1; + } + if(f2.charAt(0) != File.separatorChar) { + f2 = CURRENT_DIRECTORY + f2; + } + + String sub1, sub2a, sub2b; + switch(f1.charAt(f1.length() - 1)) { + case '*': + sub1 = f1.substring(0,f1.length() - 1); // chop off "*" + if(f2.length() <= sub1.length()) { + /* If it's smaller, there is no way it could be part of this directory. + * If it's the same (or length - 1), it could be the same directory but + * specifies access to the directory rather than the files in it. + */ + return false; + } else if(f2.charAt(sub1.length() - 1) == File.separatorChar) { + /* Make sure the part before the "/" is the same */ + if(!f2.substring(0,sub1.length()).equals(sub1)) + return false; + /* Make sure there are no subdirectories specified underneath this one */ + String sub2 = f2.substring(sub1.length()+1); + if(f2.substring(sub1.length()+1).indexOf(File.separatorChar) != -1) + return false; + } else { + /* Obviously not equal: f2 is either not a directory or is not + * the same directory (its name continues further than we want) + */ + return false; + } + break; + case '-': + sub1 = f1.substring(0,f1.length() - 2); // chop off "/-" + if(f2.length() < sub1.length()) { + /* If it's smaller, there is no way it could be part of this directory. */ + return false; + } else if(f2.length() > sub1.length() && f2.charAt(sub1.length()) != File.separatorChar) { + return false; + } else if(!f2.substring(0,sub1.length()).equals(sub1)) + return false; + break; +/* Looks redundant with default case and won't compile anyway - arenn + case File.separatorChar: + if(f2.charAt(f2.length()) == File.separatorChar) { + if(!f2.equals(f1)) + return false; + } else { + if(!f2.equals(f1.substring(0,f1.length()-1))) + return false; + } + break; +*/ + default: + if(f2.charAt(f2.length()) == File.separatorChar) { + if(!f1.equals(f2.substring(0,f2.length()-1))) + return false; + } else { + if(!f1.equals(f2)) + return false; + } + break; + } + + if(!usingPerms) + cachePerms(); + if(!fp.usingPerms) + fp.cachePerms(); + + if(readPerm && !fp.readPerm) + return false; + if(writePerm && !fp.writePerm) + return false; + if(executePerm && !fp.executePerm) + return false; + if(deletePerm && !fp.deletePerm) + return false; + + return true; + } +} |