1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.waarp.gateway.ftp.exec;
22
23 import org.apache.commons.exec.CommandLine;
24 import org.apache.commons.exec.DefaultExecutor;
25 import org.apache.commons.exec.ExecuteException;
26 import org.apache.commons.exec.ExecuteWatchdog;
27 import org.apache.commons.exec.PumpStreamHandler;
28 import org.waarp.common.command.exception.Reply421Exception;
29 import org.waarp.common.future.WaarpFuture;
30 import org.waarp.common.logging.SysErrLogger;
31 import org.waarp.common.logging.WaarpLogger;
32 import org.waarp.common.logging.WaarpLoggerFactory;
33 import org.waarp.common.utility.WaarpStringUtils;
34 import org.waarp.openr66.protocol.configuration.Configuration;
35
36 import java.io.File;
37 import java.io.IOException;
38 import java.util.regex.Pattern;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public class ExecuteExecutor extends AbstractExecutor {
62 private static final String EXCEPTION = "Exception: ";
63 private static final String EXEC_IN_ERROR_WITH = "\n Exec in error with ";
64 private static final String CANNOT_EXECUTE_PRE_COMMAND =
65 "Cannot execute Pre command";
66
67
68
69 private static final WaarpLogger logger =
70 WaarpLoggerFactory.getLogger(ExecuteExecutor.class);
71 private static final Pattern BLANK = WaarpStringUtils.BLANK;
72 private final String[] args;
73 private final String arg;
74 private final WaarpFuture futureCompletion;
75 private final long delay;
76
77
78
79
80
81
82 public ExecuteExecutor(final String command, final long delay,
83 final WaarpFuture futureCompletion) {
84 args = BLANK.split(command);
85 arg = command;
86 this.futureCompletion = futureCompletion;
87 this.delay = delay;
88 }
89
90 @Override
91 public final void run() throws Reply421Exception {
92
93 if (AbstractExecutor.useLocalExec) {
94 final LocalExecClient localExecClient = new LocalExecClient();
95 if (localExecClient.connect()) {
96 localExecClient.runOneCommand(arg, delay, futureCompletion);
97 localExecClient.disconnect();
98 return;
99 }
100 }
101
102 final File exec = new File(args[0]);
103 if (exec.isAbsolute() && !exec.canExecute()) {
104 logger.error("Exec command is not executable: " + args[0]);
105 throw new Reply421Exception("Pre Exec command is not executable");
106 }
107 final CommandLine commandLine = new CommandLine(args[0]);
108 for (int i = 1; i < args.length; i++) {
109 commandLine.addArgument(args[i]);
110 }
111 final DefaultExecutor defaultExecutor = new DefaultExecutor();
112 final PumpStreamHandler pumpStreamHandler =
113 new PumpStreamHandler(null, null);
114 defaultExecutor.setStreamHandler(pumpStreamHandler);
115 final int[] correctValues = { 0, 1 };
116 defaultExecutor.setExitValues(correctValues);
117 ExecuteWatchdog watchdog = null;
118 if (delay > 0) {
119 watchdog = new ExecuteWatchdog(delay);
120 defaultExecutor.setWatchdog(watchdog);
121 }
122 int status;
123 try {
124 status = defaultExecutor.execute(commandLine);
125 } catch (final ExecuteException e) {
126 if (e.getExitValue() == -559038737) {
127
128 try {
129 Thread.sleep(Configuration.RETRYINMS);
130 } catch (final InterruptedException e1) {
131 SysErrLogger.FAKE_LOGGER.ignoreLog(e1);
132 }
133 try {
134 status = defaultExecutor.execute(commandLine);
135 } catch (final ExecuteException e2) {
136 try {
137 pumpStreamHandler.stop();
138 } catch (final IOException ignored) {
139
140 }
141 logger.error("System Exception: " + e.getMessage() +
142 "\n Exec cannot execute command " + commandLine);
143 throw new Reply421Exception(CANNOT_EXECUTE_PRE_COMMAND);
144 } catch (final IOException e2) {
145 try {
146 pumpStreamHandler.stop();
147 } catch (final IOException ignored) {
148
149 }
150 logger.error(
151 EXCEPTION + e.getMessage() + EXEC_IN_ERROR_WITH + commandLine);
152 throw new Reply421Exception(CANNOT_EXECUTE_PRE_COMMAND);
153 }
154 logger.info(
155 "System Exception: {} but finally get the command executed {}",
156 e.getMessage(), commandLine);
157 } else {
158 try {
159 pumpStreamHandler.stop();
160 } catch (final IOException ignored) {
161
162 }
163 logger.error(
164 EXCEPTION + e.getMessage() + EXEC_IN_ERROR_WITH + commandLine);
165 throw new Reply421Exception(CANNOT_EXECUTE_PRE_COMMAND);
166 }
167 } catch (final IOException e) {
168 try {
169 pumpStreamHandler.stop();
170 } catch (final IOException ignored) {
171
172 }
173 logger.error(
174 EXCEPTION + e.getMessage() + EXEC_IN_ERROR_WITH + commandLine);
175 throw new Reply421Exception(CANNOT_EXECUTE_PRE_COMMAND);
176 }
177 try {
178 pumpStreamHandler.stop();
179 } catch (final IOException ignored) {
180
181 }
182 if (watchdog != null && watchdog.killedProcess()) {
183
184 logger.error("Exec is in Time Out");
185 status = -1;
186 }
187 if (status == 0) {
188 futureCompletion.setSuccess();
189 logger.info("Exec OK with {}", commandLine);
190 } else if (status == 1) {
191 logger.warn("Exec in warning with {}", commandLine);
192 futureCompletion.setSuccess();
193 } else {
194 logger.debug("Status: {}{} Exec in error with {}", status,
195 status == -1? " Timeout" : "", commandLine);
196 throw new Reply421Exception("Pre command executed in error");
197 }
198 }
199 }