ChModTask.java
/*
* This file is part of Waarp Project (named also Waarp or GG).
*
* Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
* tags. See the COPYRIGHT.txt in the distribution for a full listing of
* individual contributors.
*
* All Waarp Project 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 3 of the License, or (at your
* option) any later version.
*
* Waarp 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
* Waarp . If not, see <http://www.gnu.org/licenses/>.
*/
package org.waarp.openr66.context.task;
import org.waarp.common.file.AbstractDir;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
import org.waarp.common.utility.WaarpStringUtils;
import org.waarp.openr66.context.R66Session;
import org.waarp.openr66.context.task.exception.OpenR66RunnerException;
import java.io.File;
import java.util.regex.Pattern;
/**
* This task allows to change the mode of the file (as in Unix CHMOD command)
* according to the following
* argument:<br>
* - the full path is get from the current file<br>
* - the arg path is transformed as usual (static and dynamic from information
* transfer)<br>
* - this final path arg should be of the form [ua][+-=][rwx] where multiple
* elements could be specified,
* separated by blank character<br>
* - u/a meaning user(Waarp system user)/all (group and other do not exist in
* Java), +/-/= meaning
* add/remove/set (set means all other values are removed), r/w/x meaning
* Read/Write/Execute<br>
* <br>
* For instance, the final path arg could be:<br>
* <ul>
* <li>u=rwx a=r</li>
* <li>ua+rw</li>
* <li>u=rw a-wx</li>
* <li>a+rw</li>
* </ul>
* Current access mode for the application will be applied as default "user"
* access mode, and no access mode
* (-rwx) will be the default for "all" access mode.<br>
* If several access mode are set in sequence, the result will be the sum of the
* results, step by step.<br>
* "a=r a+w a-r" will result in a=w (first step is r--, second step is rw-,
* third step is -w-)
*/
public class ChModTask extends AbstractTask {
/**
* Internal Logger
*/
private static final WaarpLogger logger =
WaarpLoggerFactory.getLogger(ChModTask.class);
private static final Pattern BLANK = WaarpStringUtils.BLANK;
/**
* @param argRule
* @param delay
* @param argTransfer
* @param session
*/
public ChModTask(final String argRule, final int delay,
final String argTransfer, final R66Session session) {
super(TaskType.CHMOD, delay, argRule, argTransfer, session);
}
@Override
public final void run() {
String finalname = argRule;
finalname = AbstractDir.normalizePath(
getReplacedValue(finalname, BLANK.split(argTransfer))).trim()
.toLowerCase();
logger.info("ChMod with arg {} from {}", finalname, session);
final File file = session.getFile().getTrueFile();
boolean user;
boolean all;
boolean isall = false;
boolean ur;
boolean uw;
boolean ux;
boolean ar = false;
boolean aw = false;
boolean ax = false;
ur = file.canRead();
uw = file.canWrite();
ux = file.canExecute();
final String[] chmods = BLANK.split(finalname);
for (final String chmod : chmods) {
user = chmod.indexOf('u') >= 0;
all = chmod.indexOf('a') >= 0;
if (!user && !all) {
// ignore
continue;
}
isall |= all;
boolean isp = false;
boolean ism = false;
boolean ise = false;
if (chmod.indexOf('=') >= 0) {
ise = true;
} else if (chmod.indexOf('+') >= 0) {
isp = true;
} else if (chmod.indexOf('-') >= 0) {
ism = true;
} else {
// ignore
continue;
}
final boolean isr;
final boolean isw;
final boolean isx;
isr = chmod.indexOf('r') >= 0;
isw = chmod.indexOf('w') >= 0;
isx = chmod.indexOf('x') >= 0;
if (!isr && !isw && !isx) {
// ignore
continue;
}
if (user) {
ur = ise && isr || isp && (isr || ur) || ism && !isr && ur;
uw = ise && isw || isp && (isw || uw) || ism && !isw && uw;
ux = ise && isx || isp && (isx || ux) || ism && !isx && ux;
}
if (all) {
ar = ise && isr || isp && (isr || ar) || ism && !isr && ar;
aw = ise && isw || isp && (isw || aw) || ism && !isw && aw;
ax = ise && isx || isp && (isx || ax) || ism && !isx && ax;
}
}
boolean result = true;
if (isall) {
result &= file.setReadable(ar, false);
result &= file.setWritable(aw, false);
result &= file.setExecutable(ax, false);
}
result &= file.setReadable(ur, true);
result &= file.setWritable(uw, true);
result &= file.setExecutable(ux, true);
if (result) {
futureCompletion.setSuccess();
} else {
logger.error(
"ChMod " + finalname + " on file : " + file + " " + session);
futureCompletion.setFailure(
new OpenR66RunnerException("Chmod not fully applied on File"));
}
}
}