From 20509b27f84320ce607d07174f39fcef7a9f4a1a Mon Sep 17 00:00:00 2001 From: juanf <juanf@ethz.ch> Date: Fri, 26 May 2023 18:23:32 +0200 Subject: [PATCH] SSDM-13521: adding more methods to the Unix replacement library --- .../ch/systemsx/cisd/common/io/Posix.java | 202 ++++++++++++++++-- .../ch/systemsx/cisd/common/io/PosixTest.java | 13 ++ 2 files changed, 196 insertions(+), 19 deletions(-) diff --git a/lib-commonbase/source/java/ch/systemsx/cisd/common/io/Posix.java b/lib-commonbase/source/java/ch/systemsx/cisd/common/io/Posix.java index 7d74a6c5f35..054a6665639 100644 --- a/lib-commonbase/source/java/ch/systemsx/cisd/common/io/Posix.java +++ b/lib-commonbase/source/java/ch/systemsx/cisd/common/io/Posix.java @@ -17,13 +17,18 @@ package ch.systemsx.cisd.common.io; import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked; +import ch.systemsx.cisd.base.unix.FileLinkType; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.attribute.GroupPrincipal; import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.UserPrincipal; +import java.nio.file.attribute.UserPrincipalLookupService; import java.util.HashSet; import java.util.Set; @@ -38,6 +43,10 @@ public final class Posix return true; } + // + // User related methods + // + public static int getGid() { try @@ -95,58 +104,213 @@ public final class Posix } } - public static Set<PosixFilePermission> getPermissions(String path) throws IOExceptionUnchecked { + public static String tryGetUserNameForUid(int uid) + { try { - return Files.getPosixFilePermissions(Path.of(path)); + UserPrincipalLookupService service = FileSystems.getDefault().getUserPrincipalLookupService(); + UserPrincipal user = service.lookupPrincipalByName(Integer.toString(uid)); + return user.getName(); } catch (IOException e) { throw new IOExceptionUnchecked(e); } } - public static void setAccessMode(String path, Set<PosixFilePermission> permissions) throws IOExceptionUnchecked { - try { - Files.setPosixFilePermissions(Path.of(path), permissions); - } catch (IOException e) { + public static String tryGetGroupNameForGid(int gid) + { + try + { + UserPrincipalLookupService service = FileSystems.getDefault().getUserPrincipalLookupService(); + GroupPrincipal group = service.lookupPrincipalByGroupName(Integer.toString(gid)); + return group.getName(); + } catch (IOException e) + { throw new IOExceptionUnchecked(e); } } - public static void setAccessMode(String path, short mode) throws IOExceptionUnchecked { - Set<PosixFilePermission> permissions = new HashSet<>(); + // + // File related methods + // + + public static class Stat + { + private final short permissions; + + private final FileLinkType linkType; + + private final long lastModified; + + private final int uid; + + private final int gid; + + private final String symbolicLinkOrNull; + + private final long size; - if ((400 & mode) == 400) { + public Stat(short permissions, FileLinkType linkType, long lastModified, int uid, int gid, + String symbolicLinkOrNull, long size) + { + this.permissions = permissions; + this.linkType = linkType; + this.lastModified = lastModified; + this.uid = uid; + this.gid = gid; + this.symbolicLinkOrNull = symbolicLinkOrNull; + this.size = size; + } + + public short getPermissions() + { + return permissions; + } + + public FileLinkType getLinkType() + { + return linkType; + } + + public long getLastModified() + { + return lastModified; + } + + public int getUid() + { + return uid; + } + + public int getGid() + { + return gid; + } + + public String getSymbolicLinkOrNull() + { + return symbolicLinkOrNull; + } + + public long getSize() { + return size; + } + } + + private static short getNumericAccessMode(Set<PosixFilePermission> permissions) { + short mode = 0; + if (permissions.contains(PosixFilePermission.OWNER_READ)) { + mode |= 0400; + } + if (permissions.contains(PosixFilePermission.OWNER_WRITE)) { + mode |= 0200; + } + if (permissions.contains(PosixFilePermission.OWNER_EXECUTE)) { + mode |= 0100; + } + if (permissions.contains(PosixFilePermission.GROUP_READ)) { + mode |= 040; + } + if (permissions.contains(PosixFilePermission.GROUP_WRITE)) { + mode |= 020; + } + if (permissions.contains(PosixFilePermission.GROUP_EXECUTE)) { + mode |= 010; + } + if (permissions.contains(PosixFilePermission.OTHERS_READ)) { + mode |= 04; + } + if (permissions.contains(PosixFilePermission.OTHERS_WRITE)) { + mode |= 02; + } + if (permissions.contains(PosixFilePermission.OTHERS_EXECUTE)) { + mode |= 01; + } + return mode; + } + + private static Set<PosixFilePermission> getFilePermissionsMode(short mode) { + Set<PosixFilePermission> permissions = new HashSet<>(); + if ((0400 & mode) == 0400) { permissions.add(PosixFilePermission.OWNER_READ); } - if ((200 & mode) == 200) { + if ((0200 & mode) == 0200) { permissions.add(PosixFilePermission.OWNER_WRITE); } - if ((100 & mode) == 100) { + if ((0100 & mode) == 0100) { permissions.add(PosixFilePermission.OWNER_EXECUTE); } - - if ((40 & mode) == 40) { + if ((040 & mode) == 040) { permissions.add(PosixFilePermission.GROUP_READ); } - if ((20 & mode) == 20) { + if ((020 & mode) == 020) { permissions.add(PosixFilePermission.GROUP_WRITE); } - if ((10 & mode) == 10) { + if ((010 & mode) == 010) { permissions.add(PosixFilePermission.GROUP_EXECUTE); } - - if ((4 & mode) == 4) { + if ((04 & mode) == 04) { permissions.add(PosixFilePermission.OTHERS_READ); } - if ((2 & mode) == 2) { + if ((02 & mode) == 02) { permissions.add(PosixFilePermission.OWNER_WRITE); } - if ((1 & mode) == 1) { + if ((01 & mode) == 01) { permissions.add(PosixFilePermission.OTHERS_EXECUTE); } + return permissions; + } + + public static Stat tryGetLinkInfo(String pathAsString) { + try + { + Path path = Path.of(pathAsString); + short permissions = getNumericAccessMode(Files.getPosixFilePermissions(path)); + FileLinkType linkType; + if (Files.isSymbolicLink(path)) { + linkType = FileLinkType.SYMLINK; + } else if (Files.isDirectory(path)) { + linkType = FileLinkType.DIRECTORY; + } else { + linkType = FileLinkType.OTHER; + } + long lastModified = Files.getLastModifiedTime(path).toMillis(); + int uid = (int) Files.getAttribute(path, "unix:uid"); + int gid = (int) Files.getAttribute(path, "unix:gid"); + String symbolicLinkOrNull = null; + if (linkType == FileLinkType.SYMLINK) { + symbolicLinkOrNull = Files.readSymbolicLink(path).toString(); + } + + long size = Files.size(path); + return new Stat(permissions, linkType, lastModified, uid, gid, symbolicLinkOrNull, size); + } catch (IOException e) + { + throw new IOExceptionUnchecked(e); + } + } + + public static Set<PosixFilePermission> getPermissions(String path) throws IOExceptionUnchecked { + try + { + return Files.getPosixFilePermissions(Path.of(path)); + } catch (IOException e) + { + throw new IOExceptionUnchecked(e); + } + } + public static void setAccessMode(String path, Set<PosixFilePermission> permissions) throws IOExceptionUnchecked { + try { + Files.setPosixFilePermissions(Path.of(path), permissions); + } catch (IOException e) { + throw new IOExceptionUnchecked(e); + } + } + + public static void setAccessMode(String path, short mode) throws IOExceptionUnchecked { try { + Set<PosixFilePermission> permissions = getFilePermissionsMode(mode); Files.setPosixFilePermissions(Path.of(path), permissions); } catch (IOException e) { throw new IOExceptionUnchecked(e); diff --git a/lib-commonbase/sourceTest/java/ch/systemsx/cisd/common/io/PosixTest.java b/lib-commonbase/sourceTest/java/ch/systemsx/cisd/common/io/PosixTest.java index f28bf92bdd6..6bcb80392bc 100644 --- a/lib-commonbase/sourceTest/java/ch/systemsx/cisd/common/io/PosixTest.java +++ b/lib-commonbase/sourceTest/java/ch/systemsx/cisd/common/io/PosixTest.java @@ -25,6 +25,12 @@ public class PosixTest int gid = Posix.getGid(); } + @Test + public void testTryGetGroupNameForGid() { + int gid = Posix.getGid(); + String group = Posix.tryGetGroupNameForGid(gid); + } + @Test public void testSetOwner() throws IOException { @@ -32,4 +38,11 @@ public class PosixTest Posix.setOwner(file.getPath(), Posix.getUid(), Posix.getGid()); file.delete(); } + + @Test + public void testTryGetLinkInfo() throws IOException { + File file = File.createTempFile("pre", "su"); + Posix.Stat stat = Posix.tryGetLinkInfo(file.toString()); + file.delete(); + } } -- GitLab