1a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot/* 2a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. 3a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 4a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * Redistribution and use in source and binary forms, with or without 5a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * modification, are permitted provided that the following conditions 6a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * are met: 7a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 8a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * - Redistributions of source code must retain the above copyright 9a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * notice, this list of conditions and the following disclaimer. 10a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 11a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * - Redistributions in binary form must reproduce the above copyright 12a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * notice, this list of conditions and the following disclaimer in the 13a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * documentation and/or other materials provided with the distribution. 14a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 15a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * - Neither the name of Oracle nor the names of its 16a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * contributors may be used to endorse or promote products derived 17a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * from this software without specific prior written permission. 18a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 19a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot */ 31a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 32a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot/* 33a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * This source code is provided to illustrate the usage of a given feature 34a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * or technique and has been deliberately simplified. Additional steps 35a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * required for a production-quality application, such as security checks, 36a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * input validation and proper error handling, might not be present in 37a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * this sample code. 38a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot */ 39a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 40a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 41a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robotimport java.nio.file.*; 42a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robotimport java.nio.file.attribute.*; 43a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robotimport static java.nio.file.attribute.PosixFilePermission.*; 44a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robotimport static java.nio.file.FileVisitResult.*; 45a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robotimport java.io.IOException; 46a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robotimport java.util.*; 47a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 48a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot/** 49a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * Sample code that changes the permissions of files in a similar manner to the 50a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * chmod(1) program. 51a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot */ 52a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 53a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robotpublic class Chmod { 54a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 55a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot /** 56a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * Compiles a list of one or more <em>symbolic mode expressions</em> that 57a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * may be used to change a set of file permissions. This method is 58a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * intended for use where file permissions are required to be changed in 59a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * a manner similar to the UNIX <i>chmod</i> program. 60a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 61a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <p> The {@code exprs} parameter is a comma separated list of expressions 62a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * where each takes the form: 63a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <blockquote> 64a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <i>who operator</i> [<i>permissions</i>] 65a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * </blockquote> 66a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * where <i>who</i> is one or more of the characters {@code 'u'}, {@code 'g'}, 67a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * {@code 'o'}, or {@code 'a'} meaning the owner (user), group, others, or 68a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * all (owner, group, and others) respectively. 69a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 70a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <p> <i>operator</i> is the character {@code '+'}, {@code '-'}, or {@code 71a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * '='} signifying how permissions are to be changed. {@code '+'} means the 72a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * permissions are added, {@code '-'} means the permissions are removed, and 73a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * {@code '='} means the permissions are assigned absolutely. 74a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 75a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <p> <i>permissions</i> is a sequence of zero or more of the following: 76a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * {@code 'r'} for read permission, {@code 'w'} for write permission, and 77a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * {@code 'x'} for execute permission. If <i>permissions</i> is omitted 78a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * when assigned absolutely, then the permissions are cleared for 79a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * the owner, group, or others as identified by <i>who</i>. When omitted 80a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * when adding or removing then the expression is ignored. 81a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 82a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <p> The following examples demonstrate possible values for the {@code 83a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * exprs} parameter: 84a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 85a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <table border="0"> 86a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <tr> 87a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <td> {@code u=rw} </td> 88a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <td> Sets the owner permissions to be read and write. </td> 89a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * </tr> 90a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <tr> 91a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <td> {@code ug+w} </td> 92a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <td> Sets the owner write and group write permissions. </td> 93a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * </tr> 94a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <tr> 95a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <td> {@code u+w,o-rwx} </td> 96a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <td> Sets the owner write, and removes the others read, others write 97a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * and others execute permissions. </td> 98a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * </tr> 99a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <tr> 100a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <td> {@code o=} </td> 101a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * <td> Sets the others permission to none (others read, others write and 102a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * others execute permissions are removed if set) </td> 103a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * </tr> 104a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * </table> 105a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 106a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * @param exprs 107a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * List of one or more <em>symbolic mode expressions</em> 108a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 109a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * @return A {@code Changer} that may be used to changer a set of 110a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * file permissions 111a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 112a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * @throws IllegalArgumentException 113a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * If the value of the {@code exprs} parameter is invalid 114a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot */ 115a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot public static Changer compile(String exprs) { 116a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // minimum is who and operator (u= for example) 117a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (exprs.length() < 2) 118a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot throw new IllegalArgumentException("Invalid mode"); 119a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 120a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // permissions that the changer will add or remove 121a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot final Set<PosixFilePermission> toAdd = new HashSet<PosixFilePermission>(); 122a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot final Set<PosixFilePermission> toRemove = new HashSet<PosixFilePermission>(); 123a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 124a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // iterate over each of expression modes 125a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot for (String expr: exprs.split(",")) { 126a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // minimum of who and operator 127a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (expr.length() < 2) 128a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot throw new IllegalArgumentException("Invalid mode"); 129a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 130a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot int pos = 0; 131a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 132a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // who 133a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean u = false; 134a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean g = false; 135a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean o = false; 136a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean done = false; 137a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot for (;;) { 138a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot switch (expr.charAt(pos)) { 139a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot case 'u' : u = true; break; 140a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot case 'g' : g = true; break; 141a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot case 'o' : o = true; break; 142a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot case 'a' : u = true; g = true; o = true; break; 143a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot default : done = true; 144a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 145a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (done) 146a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot break; 147a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot pos++; 148a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 149a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (!u && !g && !o) 150a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot throw new IllegalArgumentException("Invalid mode"); 151a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 152a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // get operator and permissions 153a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot char op = expr.charAt(pos++); 154a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot String mask = (expr.length() == pos) ? "" : expr.substring(pos); 155a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 156a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // operator 157a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean add = (op == '+'); 158a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean remove = (op == '-'); 159a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean assign = (op == '='); 160a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (!add && !remove && !assign) 161a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot throw new IllegalArgumentException("Invalid mode"); 162a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 163a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // who= means remove all 164a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (assign && mask.length() == 0) { 165a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot assign = false; 166a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot remove = true; 167a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot mask = "rwx"; 168a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 169a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 170a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // permissions 171a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean r = false; 172a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean w = false; 173a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot boolean x = false; 174a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot for (int i=0; i<mask.length(); i++) { 175a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot switch (mask.charAt(i)) { 176a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot case 'r' : r = true; break; 177a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot case 'w' : w = true; break; 178a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot case 'x' : x = true; break; 179a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot default: 180a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot throw new IllegalArgumentException("Invalid mode"); 181a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 182a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 183a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 184a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // update permissions set 185a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (add) { 186a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (u) { 187a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (r) toAdd.add(OWNER_READ); 188a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (w) toAdd.add(OWNER_WRITE); 189a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (x) toAdd.add(OWNER_EXECUTE); 190a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 191a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (g) { 192a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (r) toAdd.add(GROUP_READ); 193a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (w) toAdd.add(GROUP_WRITE); 194a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (x) toAdd.add(GROUP_EXECUTE); 195a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 196a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (o) { 197a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (r) toAdd.add(OTHERS_READ); 198a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (w) toAdd.add(OTHERS_WRITE); 199a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (x) toAdd.add(OTHERS_EXECUTE); 200a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 201a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 202a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (remove) { 203a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (u) { 204a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (r) toRemove.add(OWNER_READ); 205a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (w) toRemove.add(OWNER_WRITE); 206a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (x) toRemove.add(OWNER_EXECUTE); 207a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 208a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (g) { 209a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (r) toRemove.add(GROUP_READ); 210a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (w) toRemove.add(GROUP_WRITE); 211a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (x) toRemove.add(GROUP_EXECUTE); 212a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 213a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (o) { 214a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (r) toRemove.add(OTHERS_READ); 215a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (w) toRemove.add(OTHERS_WRITE); 216a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (x) toRemove.add(OTHERS_EXECUTE); 217a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 218a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 219a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (assign) { 220a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (u) { 221a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (r) toAdd.add(OWNER_READ); 222a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot else toRemove.add(OWNER_READ); 223a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (w) toAdd.add(OWNER_WRITE); 224a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot else toRemove.add(OWNER_WRITE); 225a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (x) toAdd.add(OWNER_EXECUTE); 226a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot else toRemove.add(OWNER_EXECUTE); 227a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 228a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (g) { 229a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (r) toAdd.add(GROUP_READ); 230a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot else toRemove.add(GROUP_READ); 231a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (w) toAdd.add(GROUP_WRITE); 232a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot else toRemove.add(GROUP_WRITE); 233a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (x) toAdd.add(GROUP_EXECUTE); 234a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot else toRemove.add(GROUP_EXECUTE); 235a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 236a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (o) { 237a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (r) toAdd.add(OTHERS_READ); 238a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot else toRemove.add(OTHERS_READ); 239a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (w) toAdd.add(OTHERS_WRITE); 240a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot else toRemove.add(OTHERS_WRITE); 241a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (x) toAdd.add(OTHERS_EXECUTE); 242a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot else toRemove.add(OTHERS_EXECUTE); 243a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 244a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 245a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 246a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 247a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // return changer 248a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot return new Changer() { 249a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot @Override 250a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot public Set<PosixFilePermission> change(Set<PosixFilePermission> perms) { 251a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot perms.addAll(toAdd); 252a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot perms.removeAll(toRemove); 253a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot return perms; 254a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 255a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot }; 256a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 257a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 258a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot /** 259a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * A task that <i>changes</i> a set of {@link PosixFilePermission} elements. 260a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot */ 261a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot public interface Changer { 262a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot /** 263a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * Applies the changes to the given set of permissions. 264a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 265a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * @param perms 266a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * The set of permissions to change 267a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * 268a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * @return The {@code perms} parameter 269a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot */ 270a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot Set<PosixFilePermission> change(Set<PosixFilePermission> perms); 271a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 272a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 273a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot /** 274a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * Changes the permissions of the file using the given Changer. 275a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot */ 276a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot static void chmod(Path file, Changer changer) { 277a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot try { 278a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file); 279a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot Files.setPosixFilePermissions(file, changer.change(perms)); 280a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } catch (IOException x) { 281a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot System.err.println(x); 282a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 283a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 284a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 285a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot /** 286a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot * Changes the permission of each file and directory visited 287a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot */ 288a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot static class TreeVisitor implements FileVisitor<Path> { 289a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot private final Changer changer; 290a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 291a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot TreeVisitor(Changer changer) { 292a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot this.changer = changer; 293a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 294a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 295a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot @Override 296a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { 297a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot chmod(dir, changer); 298a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot return CONTINUE; 299a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 300a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 301a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot @Override 302a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { 303a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot chmod(file, changer); 304a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot return CONTINUE; 305a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 306a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 307a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot @Override 308a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot public FileVisitResult postVisitDirectory(Path dir, IOException exc) { 309a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (exc != null) 310a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot System.err.println("WARNING: " + exc); 311a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot return CONTINUE; 312a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 313a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 314a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot @Override 315a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot public FileVisitResult visitFileFailed(Path file, IOException exc) { 316a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot System.err.println("WARNING: " + exc); 317a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot return CONTINUE; 318a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 319a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 320a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 321a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot static void usage() { 322a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot System.err.println("java Chmod [-R] symbolic-mode-list file..."); 323a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot System.exit(-1); 324a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 325a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 326a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot public static void main(String[] args) throws IOException { 327a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (args.length < 2) 328a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot usage(); 329a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot int argi = 0; 330a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot int maxDepth = 0; 331a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (args[argi].equals("-R")) { 332a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot if (args.length < 3) 333a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot usage(); 334a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot argi++; 335a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot maxDepth = Integer.MAX_VALUE; 336a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 337a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 338a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot // compile the symbolic mode expressions 339a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot Changer changer = compile(args[argi++]); 340a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot TreeVisitor visitor = new TreeVisitor(changer); 341a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot 342a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot Set<FileVisitOption> opts = Collections.emptySet(); 343a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot while (argi < args.length) { 344a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot Path file = Paths.get(args[argi]); 345a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot Files.walkFileTree(file, opts, maxDepth, visitor); 346a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot argi++; 347a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 348a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot } 349a782115c262f0bc08ed2b8ffcd7d85c72c894adandroid-build-team Robot} 350