View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
5    *  tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    *
8    *  All Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  package org.waarp.openr66.context.task;
21  
22  import org.waarp.common.file.AbstractDir;
23  import org.waarp.common.logging.WaarpLogger;
24  import org.waarp.common.logging.WaarpLoggerFactory;
25  import org.waarp.common.utility.WaarpStringUtils;
26  import org.waarp.openr66.context.R66Session;
27  import org.waarp.openr66.context.task.exception.OpenR66RunnerException;
28  
29  import java.io.File;
30  import java.util.regex.Pattern;
31  
32  /**
33   * This task allows to change the mode of the file (as in Unix CHMOD command)
34   * according to the following
35   * argument:<br>
36   * - the full path is get from the current file<br>
37   * - the arg path is transformed as usual (static and dynamic from information
38   * transfer)<br>
39   * - this final path arg should be of the form [ua][+-=][rwx] where multiple
40   * elements could be specified,
41   * separated by blank character<br>
42   * - u/a meaning user(Waarp system user)/all (group and other do not exist in
43   * Java), +/-/= meaning
44   * add/remove/set (set means all other values are removed), r/w/x meaning
45   * Read/Write/Execute<br>
46   * <br>
47   * For instance, the final path arg could be:<br>
48   * <ul>
49   * <li>u=rwx a=r</li>
50   * <li>ua+rw</li>
51   * <li>u=rw a-wx</li>
52   * <li>a+rw</li>
53   * </ul>
54   * Current access mode for the application will be applied as default "user"
55   * access mode, and no access mode
56   * (-rwx) will be the default for "all" access mode.<br>
57   * If several access mode are set in sequence, the result will be the sum of the
58   * results, step by step.<br>
59   * "a=r a+w a-r" will result in a=w (first step is r--, second step is rw-,
60   * third step is -w-)
61   */
62  public class ChModTask extends AbstractTask {
63    /**
64     * Internal Logger
65     */
66    private static final WaarpLogger logger =
67        WaarpLoggerFactory.getLogger(ChModTask.class);
68    private static final Pattern BLANK = WaarpStringUtils.BLANK;
69  
70    /**
71     * @param argRule
72     * @param delay
73     * @param argTransfer
74     * @param session
75     */
76    public ChModTask(final String argRule, final int delay,
77                     final String argTransfer, final R66Session session) {
78      super(TaskType.CHMOD, delay, argRule, argTransfer, session);
79    }
80  
81    @Override
82    public final void run() {
83      String finalname = argRule;
84      finalname = AbstractDir.normalizePath(
85                                 getReplacedValue(finalname, BLANK.split(argTransfer))).trim()
86                             .toLowerCase();
87      logger.info("ChMod with arg {} from {}", finalname, session);
88      final File file = session.getFile().getTrueFile();
89      boolean user;
90      boolean all;
91      boolean isall = false;
92      boolean ur;
93      boolean uw;
94      boolean ux;
95      boolean ar = false;
96      boolean aw = false;
97      boolean ax = false;
98      ur = file.canRead();
99      uw = file.canWrite();
100     ux = file.canExecute();
101     final String[] chmods = BLANK.split(finalname);
102     for (final String chmod : chmods) {
103       user = chmod.indexOf('u') >= 0;
104       all = chmod.indexOf('a') >= 0;
105       if (!user && !all) {
106         // ignore
107         continue;
108       }
109       isall |= all;
110       boolean isp = false;
111       boolean ism = false;
112       boolean ise = false;
113       if (chmod.indexOf('=') >= 0) {
114         ise = true;
115       } else if (chmod.indexOf('+') >= 0) {
116         isp = true;
117       } else if (chmod.indexOf('-') >= 0) {
118         ism = true;
119       } else {
120         // ignore
121         continue;
122       }
123       final boolean isr;
124       final boolean isw;
125       final boolean isx;
126       isr = chmod.indexOf('r') >= 0;
127       isw = chmod.indexOf('w') >= 0;
128       isx = chmod.indexOf('x') >= 0;
129       if (!isr && !isw && !isx) {
130         // ignore
131         continue;
132       }
133       if (user) {
134         ur = ise && isr || isp && (isr || ur) || ism && !isr && ur;
135         uw = ise && isw || isp && (isw || uw) || ism && !isw && uw;
136         ux = ise && isx || isp && (isx || ux) || ism && !isx && ux;
137       }
138       if (all) {
139         ar = ise && isr || isp && (isr || ar) || ism && !isr && ar;
140         aw = ise && isw || isp && (isw || aw) || ism && !isw && aw;
141         ax = ise && isx || isp && (isx || ax) || ism && !isx && ax;
142       }
143     }
144     boolean result = true;
145     if (isall) {
146       result &= file.setReadable(ar, false);
147       result &= file.setWritable(aw, false);
148       result &= file.setExecutable(ax, false);
149     }
150     result &= file.setReadable(ur, true);
151     result &= file.setWritable(uw, true);
152     result &= file.setExecutable(ux, true);
153     if (result) {
154       futureCompletion.setSuccess();
155     } else {
156       logger.error(
157           "ChMod " + finalname + " on file : " + file + "     " + session);
158       futureCompletion.setFailure(
159           new OpenR66RunnerException("Chmod not fully applied on File"));
160     }
161   }
162 
163 }