/* * Copyright (C)2009 - SSHJ Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.schmizz.sshj.sftp; import net.schmizz.sshj.common.Buffer; import net.schmizz.sshj.xfer.FilePermission; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public final class FileAttributes { public static final FileAttributes EMPTY = new FileAttributes(); public static enum Flag { SIZE(0x00000001), UIDGID(0x00000002), MODE(0x00000004), ACMODTIME(0x00000008), EXTENDED(0x80000000); private final int flag; private Flag(int flag) { this.flag = flag; } public boolean isSet(int mask) { return (mask & flag) == flag; } public int get() { return flag; } } private final FileMode mode; private final int mask; private final long size; private final int uid; private final int gid; private final long atime; private final long mtime; private final Map<String, String> ext = new HashMap<String, String>(); private FileAttributes() { size = atime = mtime = uid = gid = mask = 0; mode = new FileMode(0); } public FileAttributes(int mask, long size, int uid, int gid, FileMode mode, long atime, long mtime, Map<String, String> ext) { this.mask = mask; this.size = size; this.uid = uid; this.gid = gid; this.mode = mode; this.atime = atime; this.mtime = mtime; this.ext.putAll(ext); } public boolean has(Flag flag) { return flag.isSet(mask); } public long getSize() { return size; } public int getUID() { return uid; } public int getGID() { return gid; } public FileMode getMode() { return mode; } public Set<FilePermission> getPermissions() { return mode.getPermissions(); } public FileMode.Type getType() { return mode.getType(); } public long getAtime() { return atime; } public long getMtime() { return mtime; } public String getExtended(String type) { return ext.get(type); } public byte[] toBytes() { Buffer.PlainBuffer buf = new Buffer.PlainBuffer(); buf.putUInt32(mask); if (has(Flag.SIZE)) buf.putUInt64(size); if (has(Flag.UIDGID)) { buf.putUInt32(uid); buf.putUInt32(gid); } if (has(Flag.MODE)) buf.putUInt32(mode.getMask()); if (has(Flag.ACMODTIME)) { buf.putUInt32(atime); buf.putUInt32(mtime); } if (has(Flag.EXTENDED)) { buf.putUInt32(ext.size()); for (Entry<String, String> entry : ext.entrySet()) { buf.putString(entry.getKey()); buf.putString(entry.getValue()); } } return buf.getCompactData(); } public static class Builder { private int mask; private long size; private long atime; private long mtime; private FileMode mode = new FileMode(0); private int uid; private int gid; private final Map<String, String> ext = new HashMap<String, String>(); public Builder withSize(long size) { mask |= Flag.SIZE.get(); this.size = size; return this; } public Builder withAtimeMtime(long atime, long mtime) { mask |= Flag.ACMODTIME.get(); this.atime = atime; this.mtime = mtime; return this; } public Builder withUIDGID(int uid, int gid) { mask |= Flag.UIDGID.get(); this.uid = uid; this.gid = gid; return this; } public Builder withPermissions(Set<FilePermission> perms) { mask |= Flag.MODE.get(); this.mode = new FileMode((mode != null ? mode.getTypeMask() : 0) | FilePermission.toMask(perms)); return this; } public Builder withPermissions(int perms) { mask |= Flag.MODE.get(); this.mode = new FileMode((mode != null ? mode.getTypeMask() : 0) | perms); return this; } public Builder withType(FileMode.Type type) { mask |= Flag.MODE.get(); this.mode = new FileMode(type.toMask() | (mode != null ? mode.getPermissionsMask() : 0)); return this; } public Builder withExtended(String type, String data) { mask |= Flag.EXTENDED.get(); ext.put(type, data); return this; } public Builder withExtended(Map<String, String> ext) { mask |= Flag.EXTENDED.get(); this.ext.putAll(ext); return this; } public FileAttributes build() { return new FileAttributes(mask, size, uid, gid, mode, atime, mtime, ext); } } @Override public String toString() { final StringBuilder sb = new StringBuilder("["); if (has(Flag.SIZE)) sb.append("size=").append(size).append(";"); if (has(Flag.UIDGID)) sb.append("uid=").append(uid).append(",gid=").append(gid).append(";"); if (has(Flag.MODE)) sb.append("mode=").append(mode.toString()).append(";"); if (has(Flag.ACMODTIME)) sb.append("atime=").append(atime).append(",mtime=").append(mtime).append(";"); if (has(Flag.EXTENDED)) sb.append("ext=").append(ext); sb.append("]"); return sb.toString(); } }