OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 93 | Rev 180 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 93 Rev 132
Line 18... Line 18...
18
 
18
 
19
import java.io.BufferedReader;
19
import java.io.BufferedReader;
20
import java.io.File;
20
import java.io.File;
21
import java.io.IOException;
21
import java.io.IOException;
22
import java.io.InputStreamReader;
22
import java.io.InputStreamReader;
-
 
23
import java.math.BigDecimal;
23
import java.net.InetAddress;
24
import java.net.InetAddress;
24
import java.net.SocketException;
25
import java.net.SocketException;
25
import java.util.ArrayList;
26
import java.util.ArrayList;
26
import java.util.List;
27
import java.util.List;
27
import java.util.logging.Level;
28
import java.util.logging.Level;
-
 
29
import java.util.regex.Matcher;
-
 
30
import java.util.regex.Pattern;
28
 
31
 
29
/**
32
/**
30
 * To abstract differences between platform for non java tasks.
33
 * To abstract differences between platform for non java tasks.
31
 * 
34
 * 
32
 * @author Sylvain
35
 * @author Sylvain
Line 126... Line 129...
126
 
129
 
127
    public final PingBuilder createPingBuilder() {
130
    public final PingBuilder createPingBuilder() {
128
        return new PingBuilder(this);
131
        return new PingBuilder(this);
129
    }
132
    }
130
 
133
 
131
    protected abstract boolean ping(InetAddress host, final PingBuilder pingBuilder, final int routingTableIndex) throws IOException;
134
    protected abstract PingResult ping(InetAddress host, final PingBuilder pingBuilder, final int routingTableIndex) throws IOException;
132
 
135
 
-
 
136
    protected abstract BigDecimal parsePingAverageRT(String statsLine);
-
 
137
 
133
    protected final boolean ping(final List<String> command, final String successMarker, final int totalCount, int requiredCount) throws IOException {
138
    protected final PingResult ping(final String command, final int totalCount, int requiredCount) throws IOException {
134
        if (requiredCount <= 0)
139
        if (requiredCount <= 0)
135
            requiredCount = totalCount;
140
            requiredCount = totalCount;
-
 
141
        final List<String> countAndLastLine = StringUtils.splitIntoLines(cmdSubstitution(eval(command)));
-
 
142
        if (countAndLastLine.size() != 2)
-
 
143
            throw new IllegalStateException("Not 2 lines in " + countAndLastLine);
136
        final int replied = Integer.parseInt(cmdSubstitution(eval(CollectionUtils.join(command, " ") + " | grep -c " + successMarker)).trim());
144
        final int replied = Integer.parseInt(countAndLastLine.get(0));
137
        assert replied <= totalCount;
145
        assert replied <= totalCount;
-
 
146
        final PingResult res = new PingResult(totalCount, replied, requiredCount, replied == 0 ? null : parsePingAverageRT(countAndLastLine.get(1).trim()));
138
        return replied >= requiredCount;
147
        return res;
139
    }
148
    }
140
 
149
 
141
    /**
150
    /**
142
     * Eval the passed string with bash.
151
     * Eval the passed string with bash.
143
     * 
152
     * 
Line 200... Line 209...
200
                Log.get().log(Level.FINER, "Swallow exception", e);
209
                Log.get().log(Level.FINER, "Swallow exception", e);
201
                return false;
210
                return false;
202
            }
211
            }
203
        }
212
        }
204
 
213
 
-
 
214
        // Linux : rtt min/avg/max/mdev = 12.552/13.399/14.247/0.855 ms
-
 
215
        // FreeBSD : round-trip min/avg/max/stddev = 0.301/0.371/0.442/0.071 ms
-
 
216
        private static final Pattern PING_STATS_PATTERN = Pattern
-
 
217
                .compile("^\\p{Blank}*(?:rtt|round-trip)\\p{Blank}+min/avg/max/(?:mdev|stddev)\\p{Blank}+=\\p{Blank}+([0-9\\.]+)/([0-9\\.]+)/([0-9\\.]+)/([0-9\\.]+)\\p{Blank}+ms$");
-
 
218
 
-
 
219
        @Override
-
 
220
        protected BigDecimal parsePingAverageRT(String statsLine) {
-
 
221
            final Matcher m = PING_STATS_PATTERN.matcher(statsLine);
-
 
222
            if (!m.matches())
-
 
223
                throw new IllegalArgumentException("Not matching " + PING_STATS_PATTERN + " : " + statsLine);
-
 
224
            return new BigDecimal(m.group(2));
-
 
225
        }
-
 
226
 
205
        @Override
227
        @Override
206
        public boolean isAdmin() throws IOException {
228
        public boolean isAdmin() throws IOException {
207
            // root is uid 0
229
            // root is uid 0
208
            return cmdSubstitution(this.eval("id -u")).trim().equals("0");
230
            return cmdSubstitution(this.eval("id -u")).trim().equals("0");
209
        }
231
        }
210
    }
232
    }
211
 
233
 
212
    private static final Platform LINUX = new UnixPlatform() {
234
    private static final Platform LINUX = new UnixPlatform() {
213
        @Override
235
        @Override
214
        public boolean ping(final InetAddress host, final PingBuilder pingBuilder, final int routingTableIndex) throws IOException {
236
        public PingResult ping(final InetAddress host, final PingBuilder pingBuilder, final int routingTableIndex) throws IOException {
215
            if (routingTableIndex > 0)
237
            if (routingTableIndex > 0)
216
                throw new UnsupportedOperationException("On Linux, choosing a different routing table requires changing the system policy");
238
                throw new UnsupportedOperationException("On Linux, choosing a different routing table requires changing the system policy");
217
            final List<String> command = new ArrayList<String>(16);
239
            final List<String> command = new ArrayList<String>(16);
218
            command.add("ping");
240
            command.add("ping");
219
            final int totalCount = pingBuilder.getTotalCount();
241
            final int totalCount = pingBuilder.getTotalCount();
Line 235... Line 257...
235
            }
257
            }
236
            if (pingBuilder.getTTL() > 0) {
258
            if (pingBuilder.getTTL() > 0) {
237
                command.add("-t");
259
                command.add("-t");
238
                command.add(String.valueOf(pingBuilder.getTTL()));
260
                command.add(String.valueOf(pingBuilder.getTTL()));
239
            }
261
            }
-
 
262
            if (pingBuilder.getSourceAddress() != null) {
-
 
263
                command.add("-I");
-
 
264
                command.add(pingBuilder.getSourceAddress());
-
 
265
            }
240
 
266
 
241
            command.add(host.getHostAddress());
267
            command.add(host.getHostAddress());
242
 
268
 
243
            return ping(command, "ttl=", totalCount, pingBuilder.getRequiredReplies());
269
            return ping("out=$(" + CollectionUtils.join(command, " ") + ") ; grep -c ttl= <<< \"$out\" ; tail -n1 <<< \"$out\"", totalCount, pingBuilder.getRequiredReplies());
244
        }
270
        }
245
    };
271
    };
246
 
272
 
247
    private static final Platform FREEBSD = new UnixPlatform() {
273
    private static final Platform FREEBSD = new UnixPlatform() {
248
        @Override
274
        @Override
249
        public boolean ping(final InetAddress host, final PingBuilder pingBuilder, final int routingTableIndex) throws IOException {
275
        public PingResult ping(final InetAddress host, final PingBuilder pingBuilder, final int routingTableIndex) throws IOException {
250
            final List<String> command = new ArrayList<String>(16);
276
            final List<String> command = new ArrayList<String>(16);
251
            command.add("setfib");
277
            command.add("setfib");
252
            command.add(String.valueOf(routingTableIndex));
278
            command.add(String.valueOf(routingTableIndex));
253
            command.add("ping");
279
            command.add("ping");
254
            final int totalCount = pingBuilder.getTotalCount();
280
            final int totalCount = pingBuilder.getTotalCount();
Line 269... Line 295...
269
            }
295
            }
270
            if (pingBuilder.getTTL() > 0) {
296
            if (pingBuilder.getTTL() > 0) {
271
                command.add("-m");
297
                command.add("-m");
272
                command.add(String.valueOf(pingBuilder.getTTL()));
298
                command.add(String.valueOf(pingBuilder.getTTL()));
273
            }
299
            }
-
 
300
            if (pingBuilder.getSourceAddress() != null) {
-
 
301
                command.add("-S");
-
 
302
                command.add(pingBuilder.getSourceAddress());
-
 
303
            }
274
 
304
 
275
            command.add(host.getHostAddress());
305
            command.add(host.getHostAddress());
276
 
306
 
277
            return ping(command, "ttl=", totalCount, pingBuilder.getRequiredReplies());
307
            return ping("out=$(" + CollectionUtils.join(command, " ") + ") ; grep -c ttl= <<< \"$out\" ; tail -n1 <<< \"$out\"", totalCount, pingBuilder.getRequiredReplies());
278
        }
308
        }
279
    };
309
    };
280
 
310
 
281
    private static final Platform CYGWIN = new Platform() {
311
    private static final class CygwinPlatform extends Platform {
282
 
312
 
283
        @Override
313
        @Override
284
        public boolean supportsPID() {
314
        public boolean supportsPID() {
285
            return false;
315
            return false;
286
        }
316
        }
Line 324... Line 354...
324
                throw new IllegalStateException(e);
354
                throw new IllegalStateException(e);
325
            }
355
            }
326
        }
356
        }
327
 
357
 
328
        @Override
358
        @Override
329
        public boolean ping(final InetAddress host, final PingBuilder pingBuilder, final int routingTableIndex) throws IOException {
359
        public PingResult ping(final InetAddress host, final PingBuilder pingBuilder, final int routingTableIndex) throws IOException {
330
            if (routingTableIndex > 0)
360
            if (routingTableIndex > 0)
331
                throw new UnsupportedOperationException("Only one routing table on Windows");
361
                throw new UnsupportedOperationException("Only one routing table on Windows");
332
            final List<String> command = new ArrayList<String>(16);
362
            final List<String> command = new ArrayList<String>(16);
333
            command.add("ping");
363
            command.add("ping");
334
            final int totalCount = pingBuilder.getTotalCount();
364
            final int totalCount = pingBuilder.getTotalCount();
Line 349... Line 379...
349
            }
379
            }
350
            if (pingBuilder.getTTL() > 0) {
380
            if (pingBuilder.getTTL() > 0) {
351
                command.add("-i");
381
                command.add("-i");
352
                command.add(String.valueOf(pingBuilder.getTTL()));
382
                command.add(String.valueOf(pingBuilder.getTTL()));
353
            }
383
            }
-
 
384
            if (pingBuilder.getSourceAddress() != null) {
-
 
385
                command.add("-S");
-
 
386
                command.add(pingBuilder.getSourceAddress());
-
 
387
            }
354
 
388
 
355
            command.add(host.getHostAddress());
389
            command.add(host.getHostAddress());
356
 
390
 
357
            return ping(command, "TTL=", totalCount, pingBuilder.getRequiredReplies());
391
            // can't use local variable : never could work out newlines problem
-
 
392
            // see https://cygwin.com/ml/cygwin-announce/2011-02/msg00027.html
-
 
393
            return ping("tmpF=$(mktemp) && " + CollectionUtils.join(command, " ") + " > $tmpF ; grep -c \"TTL=\" < $tmpF ; tail -n1 $tmpF; rm \"$tmpF\"", totalCount, pingBuilder.getRequiredReplies());
-
 
394
        }
-
 
395
 
-
 
396
        // Minimum = 35ms, Maximum = 36ms, Moyenne = 35ms
-
 
397
        private static final Pattern PING_STATS_PATTERN = Pattern.compile("^\\p{Blank}*\\p{Alpha}+ = ([0-9\\.]+)ms, \\p{Alpha}+ = ([0-9\\.]+)ms, \\p{Alpha}+ = ([0-9\\.]+)ms$");
-
 
398
 
-
 
399
        @Override
-
 
400
        protected BigDecimal parsePingAverageRT(String statsLine) {
-
 
401
            final Matcher m = PING_STATS_PATTERN.matcher(statsLine);
-
 
402
            if (!m.matches())
-
 
403
                throw new IllegalArgumentException("Not matching " + PING_STATS_PATTERN + " : " + statsLine);
-
 
404
            return new BigDecimal(m.group(3));
358
        }
405
        }
359
 
406
 
360
        @Override
407
        @Override
361
        public boolean isAdmin() throws IOException {
408
        public boolean isAdmin() throws IOException {
362
            // SID administrators S-1-5-32-544
409
            // SID administrators S-1-5-32-544 or S-1-5-114
363
            return this.exitStatus(this.eval("id -G | grep '\\b544\\b'")) == 0;
410
            return this.exitStatus(this.eval("id -G | egrep '\\b(544|114)\\b'")) == 0;
364
        }
411
        }
365
 
412
 
366
        @Override
413
        @Override
367
        public boolean isSymLink(File f) throws IOException {
414
        public boolean isSymLink(File f) throws IOException {
368
            // links created with "ln" can loose their "test -L" status over a copy (eg between two
415
            // links created with "ln" can loose their "test -L" status over a copy (eg between two
Line 375... Line 422...
375
        public File getNativeSymlinkFile(File dir) {
422
        public File getNativeSymlinkFile(File dir) {
376
            return FileUtils.addSuffix(dir, ".lnk");
423
            return FileUtils.addSuffix(dir, ".lnk");
377
        }
424
        }
378
    };
425
    };
379
 
426
 
-
 
427
    private static final Platform CYGWIN = new CygwinPlatform();
-
 
428
 
380
    public static String toCygwinPath(File dir) {
429
    public static String toCygwinPath(File dir) {
381
        final List<File> ancestors = getAncestors(dir);
430
        final List<File> ancestors = getAncestors(dir);
382
 
431
 
383
        final String root = ancestors.get(0).getPath();
432
        final String root = ancestors.get(0).getPath();
384
        final List<File> rest = ancestors.subList(1, ancestors.size());
433
        final List<File> rest = ancestors.subList(1, ancestors.size());
Line 400... Line 449...
400
            current = current.getParentFile();
449
            current = current.getParentFile();
401
        }
450
        }
402
        return res;
451
        return res;
403
    }
452
    }
404
 
453
 
-
 
454
    public static final class PingResult {
-
 
455
 
-
 
456
        private final int wantedCount, repliesCount, requiredReplies;
-
 
457
        private final BigDecimal averageRTT;
-
 
458
 
-
 
459
        private PingResult(final int wantedCount, final int repliesCount, final int requiredReplies, final BigDecimal averageRTT) {
-
 
460
            this.wantedCount = wantedCount;
-
 
461
            this.repliesCount = repliesCount;
-
 
462
            this.requiredReplies = requiredReplies;
-
 
463
            this.averageRTT = averageRTT;
-
 
464
        }
-
 
465
 
-
 
466
        public final int getRepliesCount() {
-
 
467
            return this.repliesCount;
-
 
468
        }
-
 
469
 
-
 
470
        public final int getRequiredReplies() {
-
 
471
            return this.requiredReplies;
-
 
472
        }
-
 
473
 
-
 
474
        public final boolean hasRequiredReplies() {
-
 
475
            return this.hasEnoughReplies(this.getRequiredReplies());
-
 
476
        }
-
 
477
 
-
 
478
        public final boolean hasEnoughReplies(final int min) {
-
 
479
            return this.getRepliesCount() >= min;
-
 
480
        }
-
 
481
 
-
 
482
        public final BigDecimal getAverageRTT() {
-
 
483
            return this.averageRTT;
-
 
484
        }
-
 
485
 
-
 
486
        @Override
-
 
487
        public String toString() {
-
 
488
            return this.getClass().getSimpleName() + " " + this.getRepliesCount() + "/" + this.wantedCount + " reply(ies), average RTT : " + this.getAverageRTT() + " ms";
-
 
489
        }
-
 
490
    }
-
 
491
 
405
    public static final class PingBuilder {
492
    public static final class PingBuilder {
406
 
493
 
407
        private final Platform platform;
494
        private final Platform platform;
408
 
495
 
409
        // in milliseconds
496
        // in milliseconds
410
        private int waitTime = 4000;
497
        private int waitTime = 4000;
411
        private boolean dontFragment = false;
498
        private boolean dontFragment = false;
412
        private int length = -1;
499
        private int length = -1;
-
 
500
        private String srcAddr = null;
413
        private int ttl = -1;
501
        private int ttl = -1;
414
        private int totalCount = 4;
502
        private int totalCount = 4;
415
        private int requiredReplies = -1;
503
        private int requiredReplies = -1;
416
 
504
 
417
        PingBuilder(final Platform p) {
505
        PingBuilder(final Platform p) {
Line 443... Line 531...
443
        public final PingBuilder setLength(int length) {
531
        public final PingBuilder setLength(int length) {
444
            this.length = length;
532
            this.length = length;
445
            return this;
533
            return this;
446
        }
534
        }
447
 
535
 
-
 
536
        public String getSourceAddress() {
-
 
537
            return this.srcAddr;
-
 
538
        }
-
 
539
 
-
 
540
        public PingBuilder setSourceAddress(String srcAddr) {
-
 
541
            this.srcAddr = srcAddr;
-
 
542
            return this;
-
 
543
        }
-
 
544
 
448
        public final int getTTL() {
545
        public final int getTTL() {
449
            return this.ttl;
546
            return this.ttl;
450
        }
547
        }
451
 
548
 
452
        public final PingBuilder setTTL(int ttl) {
549
        public final PingBuilder setTTL(int ttl) {
Line 472... Line 569...
472
        public final PingBuilder setRequiredReplies(int requiredReplies) {
569
        public final PingBuilder setRequiredReplies(int requiredReplies) {
473
            this.requiredReplies = requiredReplies;
570
            this.requiredReplies = requiredReplies;
474
            return this;
571
            return this;
475
        }
572
        }
476
 
573
 
477
        public final boolean execute(final InetAddress host) throws IOException {
574
        public final boolean isAlive(final InetAddress host) throws IOException {
478
            return this.execute(host, 0);
575
            return this.isAlive(host, 0);
-
 
576
        }
-
 
577
 
-
 
578
        public final boolean isAlive(final InetAddress host, final int routingTableIndex) throws IOException {
-
 
579
            return execute(host, routingTableIndex).hasRequiredReplies();
479
        }
580
        }
480
 
581
 
-
 
582
        public PingResult execute(final InetAddress host) throws IOException {
-
 
583
            return execute(host, 0);
-
 
584
        }
-
 
585
 
481
        public final boolean execute(final InetAddress host, final int routingTableIndex) throws IOException {
586
        public PingResult execute(final InetAddress host, final int routingTableIndex) throws IOException {
482
            return this.platform.ping(host, this, routingTableIndex);
587
            return this.platform.ping(host, this, routingTableIndex);
483
        }
588
        }
484
    }
589
    }
-
 
590
 
-
 
591
    public static final class Ping {
-
 
592
        public static void main(String[] args) throws IOException {
-
 
593
            final int totalCount = Integer.parseInt(System.getProperty("count", "4"));
-
 
594
            final String srcAddr = System.getProperty("srcAddr");
-
 
595
            System.out.println(Platform.getInstance().createPingBuilder().setTotalCount(totalCount).setSourceAddress(srcAddr).execute(InetAddress.getByName(args[0])));
-
 
596
        }
-
 
597
    }
485
}
598
}