| /* java.lang.FilePermission | |
| Copyright (C) 1998, 2000 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 final 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; | |
| } | |
| } |