FsShellPermissions.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:10k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.fs;
  19. import java.io.IOException;
  20. import java.util.regex.Matcher;
  21. import java.util.regex.Pattern;
  22. import org.apache.hadoop.fs.FsShell.CmdHandler;
  23. import org.apache.hadoop.fs.permission.FsPermission;
  24. /**
  25.  * This class is the home for file permissions related commands.
  26.  * Moved to this seperate class since FsShell is getting too large.
  27.  */
  28. class FsShellPermissions {
  29.   
  30.   /*========== chmod ==========*/
  31.    
  32.   /* The pattern is alsmost as flexible as mode allowed by 
  33.    * chmod shell command. The main restriction is that we recognize only rwxX.
  34.    * To reduce errors we also enforce 3 digits for octal mode.
  35.    */  
  36.   private static Pattern chmodNormalPattern = 
  37.              Pattern.compile("\G\s*([ugoa]*)([+=-]+)([rwxX]+)([,\s]*)\s*");
  38.   private static Pattern chmodOctalPattern =
  39.             Pattern.compile("^\s*[+]?([0-7]{3})\s*$");
  40.   
  41.   static String CHMOD_USAGE = 
  42.                             "-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...";
  43.   private static class ChmodHandler extends CmdHandler {
  44.     private short userMode, groupMode, othersMode;
  45.     private char userType = '+', groupType = '+', othersType='+';
  46.     private void applyNormalPattern(String modeStr, Matcher matcher)
  47.                                     throws IOException {
  48.       boolean commaSeperated = false;
  49.       for(int i=0; i < 1 || matcher.end() < modeStr.length(); i++) {
  50.         if (i>0 && (!commaSeperated || !matcher.find())) {
  51.           patternError(modeStr);
  52.         }
  53.         /* groups : 1 : [ugoa]*
  54.          *          2 : [+-=]
  55.          *          3 : [rwxX]+
  56.          *          4 : [,s]*
  57.          */
  58.         String str = matcher.group(2);
  59.         char type = str.charAt(str.length() - 1);
  60.         boolean user, group, others;
  61.         user = group = others = false;
  62.         for(char c : matcher.group(1).toCharArray()) {
  63.           switch (c) {
  64.           case 'u' : user = true; break;
  65.           case 'g' : group = true; break;
  66.           case 'o' : others = true; break;
  67.           case 'a' : break;
  68.           default  : throw new RuntimeException("Unexpected");          
  69.           }
  70.         }
  71.         if (!(user || group || others)) { // same as specifying 'a'
  72.           user = group = others = true;
  73.         }
  74.         short  mode = 0;
  75.         for(char c : matcher.group(3).toCharArray()) {
  76.           switch (c) {
  77.           case 'r' : mode |= 4; break;
  78.           case 'w' : mode |= 2; break;
  79.           case 'x' : mode |= 1; break;
  80.           case 'X' : mode |= 8; break;
  81.           default  : throw new RuntimeException("Unexpected");
  82.           }
  83.         }
  84.         if ( user ) {
  85.           userMode = mode;
  86.           userType = type;
  87.         }
  88.         if ( group ) {
  89.           groupMode = mode;
  90.           groupType = type;
  91.         }
  92.         if ( others ) {
  93.           othersMode = mode;
  94.           othersType = type;
  95.         }
  96.         commaSeperated = matcher.group(4).contains(",");
  97.       }
  98.     }
  99.     private void applyOctalPattern(String modeStr, Matcher matcher) {
  100.       userType = groupType = othersType = '=';
  101.       String str = matcher.group(1);
  102.       userMode = Short.valueOf(str.substring(0, 1));
  103.       groupMode = Short.valueOf(str.substring(1, 2));
  104.       othersMode = Short.valueOf(str.substring(2, 3));      
  105.     }
  106.     private void patternError(String mode) throws IOException {
  107.       throw new IOException("chmod : mode '" + mode + 
  108.                             "' does not match the expected pattern.");      
  109.     }
  110.     ChmodHandler(FileSystem fs, String modeStr) throws IOException {
  111.       super("chmod", fs);
  112.       Matcher matcher = null;
  113.       if ((matcher = chmodNormalPattern.matcher(modeStr)).find()) {
  114.         applyNormalPattern(modeStr, matcher);
  115.       } else if ((matcher = chmodOctalPattern.matcher(modeStr)).matches()) {
  116.         applyOctalPattern(modeStr, matcher);
  117.       } else {
  118.         patternError(modeStr);
  119.       }
  120.     }
  121.     private int applyChmod(char type, int mode, int existing, boolean exeOk) {
  122.       boolean capX = false;
  123.       if ((mode&8) != 0) { // convert X to x;
  124.         capX = true;
  125.         mode &= ~8;
  126.         mode |= 1;
  127.       }
  128.       switch (type) {
  129.       case '+' : mode = mode | existing; break;
  130.       case '-' : mode = (~mode) & existing; break;
  131.       case '=' : break;
  132.       default  : throw new RuntimeException("Unexpected");      
  133.       }
  134.       // if X is specified add 'x' only if exeOk or x was already set.
  135.       if (capX && !exeOk && (mode&1) != 0 && (existing&1) == 0) {
  136.         mode &= ~1; // remove x
  137.       }
  138.       return mode;
  139.     }
  140.     @Override
  141.     public void run(FileStatus file, FileSystem srcFs) throws IOException {
  142.       FsPermission perms = file.getPermission();
  143.       int existing = perms.toShort();
  144.       boolean exeOk = file.isDir() || (existing & 0111) != 0;
  145.       int newperms = ( applyChmod(userType, userMode, 
  146.                                   (existing>>>6)&7, exeOk) << 6 |
  147.                        applyChmod(groupType, groupMode, 
  148.                                   (existing>>>3)&7, exeOk) << 3 |
  149.                        applyChmod(othersType, othersMode, existing&7, exeOk) );
  150.       if (existing != newperms) {
  151.         try {
  152.           srcFs.setPermission(file.getPath(), 
  153.                                 new FsPermission((short)newperms));
  154.         } catch (IOException e) {
  155.           System.err.println(getName() + ": changing permissions of '" + 
  156.                              file.getPath() + "':" + e.getMessage());
  157.         }
  158.       }
  159.     }
  160.   }
  161.   /*========== chown ==========*/
  162.   
  163.   static private String allowedChars = "[-_./@a-zA-Z0-9]";
  164.   ///allows only "allowedChars" above in names for owner and group
  165.   static private Pattern chownPattern = 
  166.          Pattern.compile("^\s*(" + allowedChars + "+)?" +
  167.                           "([:](" + allowedChars + "*))?\s*$");
  168.   static private Pattern chgrpPattern = 
  169.          Pattern.compile("^\s*(" + allowedChars + "+)\s*$");
  170.   
  171.   static String CHOWN_USAGE = "-chown [-R] [OWNER][:[GROUP]] PATH...";
  172.   static String CHGRP_USAGE = "-chgrp [-R] GROUP PATH...";  
  173.   private static class ChownHandler extends CmdHandler {
  174.     protected String owner = null;
  175.     protected String group = null;
  176.     protected ChownHandler(String cmd, FileSystem fs) { //for chgrp
  177.       super(cmd, fs);
  178.     }
  179.     ChownHandler(FileSystem fs, String ownerStr) throws IOException {
  180.       super("chown", fs);
  181.       Matcher matcher = chownPattern.matcher(ownerStr);
  182.       if (!matcher.matches()) {
  183.         throw new IOException("'" + ownerStr + "' does not match " +
  184.                               "expected pattern for [owner][:group].");
  185.       }
  186.       owner = matcher.group(1);
  187.       group = matcher.group(3);
  188.       if (group != null && group.length() == 0) {
  189.         group = null;
  190.       }
  191.       if (owner == null && group == null) {
  192.         throw new IOException("'" + ownerStr + "' does not specify " +
  193.                               " onwer or group.");
  194.       }
  195.     }
  196.     @Override
  197.     public void run(FileStatus file, FileSystem srcFs) throws IOException {
  198.       //Should we do case insensitive match?  
  199.       String newOwner = (owner == null || owner.equals(file.getOwner())) ?
  200.                         null : owner;
  201.       String newGroup = (group == null || group.equals(file.getGroup())) ?
  202.                         null : group;
  203.       if (newOwner != null || newGroup != null) {
  204.         try {
  205.           srcFs.setOwner(file.getPath(), newOwner, newGroup);
  206.         } catch (IOException e) {
  207.           System.err.println(getName() + ": changing ownership of '" + 
  208.                              file.getPath() + "':" + e.getMessage());
  209.         }
  210.       }
  211.     }
  212.   }
  213.   /*========== chgrp ==========*/    
  214.   
  215.   private static class ChgrpHandler extends ChownHandler {
  216.     ChgrpHandler(FileSystem fs, String groupStr) throws IOException {
  217.       super("chgrp", fs);
  218.       Matcher matcher = chgrpPattern.matcher(groupStr);
  219.       if (!matcher.matches()) {
  220.         throw new IOException("'" + groupStr + "' does not match " +
  221.         "expected pattern for group");
  222.       }
  223.       group = matcher.group(1);
  224.     }
  225.   }
  226.   static void changePermissions(FileSystem fs, String cmd, 
  227.                                 String argv[], int startIndex, FsShell shell)
  228.                                 throws IOException {
  229.     CmdHandler handler = null;
  230.     boolean recursive = false;
  231.     // handle common arguments, currently only "-R" 
  232.     for (; startIndex < argv.length && argv[startIndex].equals("-R"); 
  233.     startIndex++) {
  234.       recursive = true;
  235.     }
  236.     if ( startIndex >= argv.length ) {
  237.       throw new IOException("Not enough arguments for the command");
  238.     }
  239.     if (cmd.equals("-chmod")) {
  240.       handler = new ChmodHandler(fs, argv[startIndex++]);
  241.     } else if (cmd.equals("-chown")) {
  242.       handler = new ChownHandler(fs, argv[startIndex++]);
  243.     } else if (cmd.equals("-chgrp")) {
  244.       handler = new ChgrpHandler(fs, argv[startIndex++]);
  245.     }
  246.     shell.runCmdHandler(handler, argv, startIndex, recursive);
  247.   } 
  248. }