All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sshtools.sftp.SftpFileAttributes Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2003-2016 SSHTOOLS Limited. All Rights Reserved.
 *
 * For product documentation visit https://www.sshtools.com/
 *
 * This file is part of J2SSH Maverick.
 *
 * J2SSH Maverick is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * J2SSH Maverick 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 J2SSH Maverick.  If not, see .
 */
package com.sshtools.sftp;

import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import com.sshtools.util.ByteArrayReader;
import com.sshtools.util.ByteArrayWriter;
import com.sshtools.util.UnsignedInteger32;
import com.sshtools.util.UnsignedInteger64;

/**
 * This class represents the ATTRS structure defined in the
 * draft-ietf-secsh-filexfer-02.txt which is used by the protocol to store file
 * attribute information.
 * 
 * @author Lee David Painter
 */
public class SftpFileAttributes {

	static final int SSH_FILEXFER_ATTR_SIZE = 0x00000001;
	// This is only used for version <= 3
	static final long SSH_FILEXFER_ATTR_UIDGID = 0x00000002;
	static final long SSH_FILEXFER_ATTR_PERMISSIONS = 0x00000004;
	static final long SSH_FILEXFER_ATTR_ACCESSTIME = 0x00000008;
	static final long SSH_FILEXFER_ATTR_CREATETIME = 0x00000010;
	static final long SSH_FILEXFER_ATTR_MODIFYTIME = 0x00000020;
	static final long SSH_FILEXFER_ATTR_ACL = 0x00000040;
	static final long SSH_FILEXFER_ATTR_OWNERGROUP = 0x00000080;
	static final long SSH_FILEXFER_ATTR_SUBSECOND_TIMES = 0x00000100;
	static final long SSH_FILEXFER_ATTR_EXTENDED = 0x80000000;

	public static final int SSH_FILEXFER_TYPE_REGULAR = 1;
	public static final int SSH_FILEXFER_TYPE_DIRECTORY = 2;
	public static final int SSH_FILEXFER_TYPE_SYMLINK = 3;
	public static final int SSH_FILEXFER_TYPE_SPECIAL = 4;
	public static final int SSH_FILEXFER_TYPE_UNKNOWN = 5;

	private Vector acls = new Vector();
	private Hashtable extendedAttributes = new Hashtable();

	// Posix stats

	/**
	 * Permissions flag: Format mask constant can be used to mask off a file
	 * type from the mode.
	 */
	public static final int S_IFMT = 0xF000;

	/** Permissions flag: Identifies the file as a socket */
	public static final int S_IFSOCK = 0xC000;

	/** Permissions flag: Identifies the file as a symbolic link */
	public static final int S_IFLNK = 0xA000;

	/** Permissions flag: Identifies the file as a regular file */
	public static final int S_IFREG = 0x8000;

	/** Permissions flag: Identifies the file as a block special file */
	public static final int S_IFBLK = 0x6000;

	/** Permissions flag: Identifies the file as a directory */
	public static final int S_IFDIR = 0x4000;

	/** Permissions flag: Identifies the file as a character device */
	public static final int S_IFCHR = 0x2000;

	/** Permissions flag: Identifies the file as a pipe */
	public static final int S_IFIFO = 0x1000;

	/**
	 * Permissions flag: Bit to determine whether a file is executed as the
	 * owner
	 */
	public final static int S_ISUID = 0x800;

	/**
	 * Permissions flag: Bit to determine whether a file is executed as the
	 * group owner
	 */
	public final static int S_ISGID = 0x400;

	/** Permissions flag: Permits the owner of a file to read the file. */
	public final static int S_IRUSR = 0x100;

	/** Permissions flag: Permits the owner of a file to write to the file. */
	public final static int S_IWUSR = 0x80;

	/**
	 * Permissions flag: Permits the owner of a file to execute the file or to
	 * search the file's directory.
	 */
	public final static int S_IXUSR = 0x40;

	/** Permissions flag: Permits a file's group to read the file. */
	public final static int S_IRGRP = 0x20;

	/** Permissions flag: Permits a file's group to write to the file. */
	public final static int S_IWGRP = 0x10;

	/**
	 * Permissions flag: Permits a file's group to execute the file or to search
	 * the file's directory.
	 */
	public final static int S_IXGRP = 0x08;

	/** Permissions flag: Permits others to read the file. */
	public final static int S_IROTH = 0x04;

	/** Permissions flag: Permits others to write to the file. */
	public final static int S_IWOTH = 0x02;

	/**
	 * Permissions flag: Permits others to execute the file or to search the
	 * file's directory.
	 */
	public final static int S_IXOTH = 0x01;

	int version = 3;
	long flags = 0x0000000;
	int type; // Version 4 only
	UnsignedInteger64 size = null;
	String uid = null;
	String gid = null;
	UnsignedInteger32 permissions = null;
	UnsignedInteger64 atime = null;
	UnsignedInteger32 atime_nano = null;
	UnsignedInteger64 createtime = null;
	UnsignedInteger32 createtime_nano = null;
	UnsignedInteger64 mtime = null;
	UnsignedInteger32 mtime_nano = null;
	String username;
	String group;

	char[] types = { 'p', 'c', 'd', 'b', '-', 'l', 's', };

	SftpSubsystemChannel sftp;

	/**
	 * Creates a new FileAttributes object.
	 */
	public SftpFileAttributes(SftpSubsystemChannel sftp, int type) {
		this.sftp = sftp;
		this.version = sftp.getVersion();
		this.type = type;

	}

	public int getType() {
		return type;
	}

	/**
	 * @param sftp
	 * @param bar
	 * @throws IOException
	 */
	public SftpFileAttributes(SftpSubsystemChannel sftp, ByteArrayReader bar)
			throws IOException {
		this.sftp = sftp;
		this.version = sftp.getVersion();

		if (bar.available() >= 4)
			flags = bar.readInt();

		// Work out the type from the permissions field later if we're not using
		// version
		// 4 of the protocol
		if (version > 3) {
			// Get the type if were using version 4+ of the protocol
			if (bar.available() > 0)
				type = bar.read();
		}

		// if ATTR_SIZE flag is set then read size
		if (isFlagSet(SSH_FILEXFER_ATTR_SIZE) && bar.available() >= 8) {
			byte[] raw = new byte[8];
			bar.read(raw);
			size = new UnsignedInteger64(raw);
		}

		if (version <= 3 && isFlagSet(SSH_FILEXFER_ATTR_UIDGID)
				&& bar.available() >= 8) {

			uid = String.valueOf(bar.readInt());
			gid = String.valueOf(bar.readInt());
		} else if (version > 3 && isFlagSet(SSH_FILEXFER_ATTR_OWNERGROUP)
				&& bar.available() >= 8) {
			uid = bar.readString(sftp.getCharsetEncoding());
			gid = bar.readString(sftp.getCharsetEncoding());
		}

		if (isFlagSet(SSH_FILEXFER_ATTR_PERMISSIONS) && bar.available() >= 4) {
			permissions = new UnsignedInteger32(bar.readInt());
		}

		if (version <= 3 && isFlagSet(SSH_FILEXFER_ATTR_ACCESSTIME)
				&& bar.available() >= 8) {
			atime = new UnsignedInteger64(bar.readInt());
			mtime = new UnsignedInteger64(bar.readInt());
		} else if (version > 3 && bar.available() > 0) {
			if (isFlagSet(SSH_FILEXFER_ATTR_ACCESSTIME) && bar.available() >= 8)
				atime = bar.readUINT64();
			if (isFlagSet(SSH_FILEXFER_ATTR_SUBSECOND_TIMES)
					&& bar.available() >= 4) {
				atime_nano = bar.readUINT32();
			}
		}

		if (version > 3 && bar.available() > 0) {
			if (isFlagSet(SSH_FILEXFER_ATTR_CREATETIME) && bar.available() >= 8)
				createtime = bar.readUINT64();
			if (isFlagSet(SSH_FILEXFER_ATTR_SUBSECOND_TIMES)
					&& bar.available() >= 4)
				createtime_nano = bar.readUINT32();
		}

		if (version > 3 && bar.available() > 0) {
			if (isFlagSet(SSH_FILEXFER_ATTR_MODIFYTIME) && bar.available() >= 8)
				mtime = bar.readUINT64();
			if (isFlagSet(SSH_FILEXFER_ATTR_SUBSECOND_TIMES)
					&& bar.available() >= 4)
				mtime_nano = bar.readUINT32();
		}

		// We are currently ignoring ACL and extended attributes
		if (version > 3 && isFlagSet(SSH_FILEXFER_ATTR_ACL)
				&& bar.available() >= 4) {

			int length = (int) bar.readInt();

			if (length > 0 && bar.available() >= length) {
				int count = (int) bar.readInt();
				for (int i = 0; i < count; i++) {

					acls.addElement(new ACL((int) bar.readInt(), (int) bar
							.readInt(), (int) bar.readInt(), bar.readString()));
				}
			}
		}

		if (version >= 3 && isFlagSet(SSH_FILEXFER_ATTR_EXTENDED)
				&& bar.available() >= 4) {
			int count = (int) bar.readInt();
			// read each extended attribute
			for (int i = 0; i < count; i++) {
				if (bar.available() >= 8) {
					extendedAttributes.put(bar.readString(),
							bar.readBinaryString());
				}
			}
		}
	}

	/**
	 * Get the UID of the owner.
	 * 
	 * @return String
	 */
	public String getUID() {
		if (username != null) {
			return username;
		}
		if (uid != null) {
			return uid;
		}
		return "";
	}

	/**
	 * Set the UID of the owner.
	 * 
	 * @param uid
	 */
	public void setUID(String uid) {
		if (version > 3) {
			flags |= SSH_FILEXFER_ATTR_OWNERGROUP;
		} else
			flags |= SSH_FILEXFER_ATTR_UIDGID;
		this.uid = uid;
	}

	/**
	 * Set the GID of this file.
	 * 
	 * @param gid
	 */
	public void setGID(String gid) {

		if (version > 3) {
			flags |= SSH_FILEXFER_ATTR_OWNERGROUP;
		} else
			flags |= SSH_FILEXFER_ATTR_UIDGID;
		this.gid = gid;
	}

	/**
	 * Get the GID of this file.
	 * 
	 * @return String
	 */
	public String getGID() {
		if (group != null) {
			return group;
		}
		if (gid != null) {
			return gid;
		}
		return "";
	}

	public boolean hasUID() {
		return uid != null;
	}

	public boolean hasGID() {
		return gid != null;
	}

	/**
	 * Set the size of the file.
	 * 
	 * @param size
	 */
	public void setSize(UnsignedInteger64 size) {
		this.size = size;

		// Set the flag
		if (size != null) {
			flags |= SSH_FILEXFER_ATTR_SIZE;
		} else {
			flags ^= SSH_FILEXFER_ATTR_SIZE;
		}
	}

	/**
	 * 
	 * Get the size of the file.
	 * 
	 * @return UnsignedInteger64
	 */
	public UnsignedInteger64 getSize() {
		if (size != null) {
			return size;
		}
		return new UnsignedInteger64("0");
	}

	public boolean hasSize() {
		return size != null;
	}

	/**
	 * Set the permissions of the file. This value should be a valid mask of the
	 * permissions flags defined within this class.
	 */
	public void setPermissions(UnsignedInteger32 permissions) {
		this.permissions = permissions;

		// Set the flag
		if (permissions != null) {
			flags |= SSH_FILEXFER_ATTR_PERMISSIONS;
		} else {
			flags ^= SSH_FILEXFER_ATTR_PERMISSIONS;
		}
	}

	/**
	 * Set permissions given a UNIX style mask, for example '0644'
	 * 
	 * @param mask
	 *            mask
	 * 
	 * @throws IllegalArgumentException
	 *             if badly formatted string
	 */
	public void setPermissionsFromMaskString(String mask) {
		if (mask.length() != 4) {
			throw new IllegalArgumentException("Mask length must be 4");
		}

		try {
			setPermissions(new UnsignedInteger32(String.valueOf(Integer
					.parseInt(mask, 8))));
		} catch (NumberFormatException nfe) {
			throw new IllegalArgumentException(
					"Mask must be 4 digit octal number.");
		}
	}

	/**
	 * Set the permissions given a UNIX style umask, for example '0022' will
	 * result in 0022 ^ 0777.
	 * 
	 * @param umask
	 * @throws IllegalArgumentException
	 *             if badly formatted string
	 */
	public void setPermissionsFromUmaskString(String umask) {
		if (umask.length() != 4) {
			throw new IllegalArgumentException("umask length must be 4");
		}

		try {
			setPermissions(new UnsignedInteger32(String.valueOf(Integer
					.parseInt(umask, 8) ^ 0777)));
		} catch (NumberFormatException ex) {
			throw new IllegalArgumentException(
					"umask must be 4 digit octal number");
		}
	}

	/**
	 * Set the permissions from a string in the format "rwxr-xr-x"
	 * 
	 * @param newPermissions
	 */
	public void setPermissions(String newPermissions) {
		int cp = 0;

		if (permissions != null) {
			cp = cp
					| (((permissions.longValue() & S_IFMT) == S_IFMT) ? S_IFMT
							: 0);
			cp = cp
					| (((permissions.longValue() & S_IFSOCK) == S_IFSOCK) ? S_IFSOCK
							: 0);
			cp = cp
					| (((permissions.longValue() & S_IFLNK) == S_IFLNK) ? S_IFLNK
							: 0);
			cp = cp
					| (((permissions.longValue() & S_IFREG) == S_IFREG) ? S_IFREG
							: 0);
			cp = cp
					| (((permissions.longValue() & S_IFBLK) == S_IFBLK) ? S_IFBLK
							: 0);
			cp = cp
					| (((permissions.longValue() & S_IFDIR) == S_IFDIR) ? S_IFDIR
							: 0);
			cp = cp
					| (((permissions.longValue() & S_IFCHR) == S_IFCHR) ? S_IFCHR
							: 0);
			cp = cp
					| (((permissions.longValue() & S_IFIFO) == S_IFIFO) ? S_IFIFO
							: 0);
			cp = cp
					| (((permissions.longValue() & S_ISUID) == S_ISUID) ? S_ISUID
							: 0);
			cp = cp
					| (((permissions.longValue() & S_ISGID) == S_ISGID) ? S_ISGID
							: 0);
		}

		int len = newPermissions.length();

		if (len >= 1) {
			cp = cp
					| ((newPermissions.charAt(0) == 'r') ? SftpFileAttributes.S_IRUSR
							: 0);
		}

		if (len >= 2) {
			cp = cp
					| ((newPermissions.charAt(1) == 'w') ? SftpFileAttributes.S_IWUSR
							: 0);
		}

		if (len >= 3) {
			cp = cp
					| ((newPermissions.charAt(2) == 'x') ? SftpFileAttributes.S_IXUSR
							: 0);
		}

		if (len >= 4) {
			cp = cp
					| ((newPermissions.charAt(3) == 'r') ? SftpFileAttributes.S_IRGRP
							: 0);
		}

		if (len >= 5) {
			cp = cp
					| ((newPermissions.charAt(4) == 'w') ? SftpFileAttributes.S_IWGRP
							: 0);
		}

		if (len >= 6) {
			cp = cp
					| ((newPermissions.charAt(5) == 'x') ? SftpFileAttributes.S_IXGRP
							: 0);
		}

		if (len >= 7) {
			cp = cp
					| ((newPermissions.charAt(6) == 'r') ? SftpFileAttributes.S_IROTH
							: 0);
		}

		if (len >= 8) {
			cp = cp
					| ((newPermissions.charAt(7) == 'w') ? SftpFileAttributes.S_IWOTH
							: 0);
		}

		if (len >= 9) {
			cp = cp
					| ((newPermissions.charAt(8) == 'x') ? SftpFileAttributes.S_IXOTH
							: 0);
		}

		setPermissions(new UnsignedInteger32(cp));
	}

	/**
	 * Get the current permissions value.
	 * 
	 * @return UnsignedInteger32
	 */
	public UnsignedInteger32 getPermissions() {
		if (permissions != null)
			return permissions;
		return new UnsignedInteger32(0);
	}

	/**
	 * Set the last access and last modified times. These times are represented
	 * by integers containing the number of seconds from Jan 1, 1970 UTC. NOTE:
	 * You should divide any value returned from Java's
	 * System.currentTimeMillis() method by 1000 to set the correct times as
	 * this returns the time in milliseconds from Jan 1, 1970 UTC.
	 * 
	 * @param atime
	 * @param mtime
	 */
	public void setTimes(UnsignedInteger64 atime, UnsignedInteger64 mtime) {
		this.atime = atime;
		this.mtime = mtime;

		// Set the flag
		if (atime != null) {
			flags |= SSH_FILEXFER_ATTR_ACCESSTIME;
		} else {
			flags ^= SSH_FILEXFER_ATTR_ACCESSTIME;
		}
	}

	/**
	 * Get the last accessed time. This integer value represents the number of
	 * seconds from Jan 1, 1970 UTC. When using with Java Date/Time classes you
	 * should multiply this value by 1000 as Java uses the time in milliseconds
	 * rather than seconds.
	 * 
	 * @return UnsignedInteger64
	 */
	public UnsignedInteger64 getAccessedTime() {
		return atime;
	}

	/**
	 * Get the last modified time. This integer value represents the number of
	 * seconds from Jan 1, 1970 UTC. When using with Java Date/Time classes you
	 * should multiply this value by 1000 as Java uses the time in milliseconds
	 * rather than seconds.
	 * 
	 * @return UnsignedInteger64
	 */
	public UnsignedInteger64 getModifiedTime() {
		if (mtime != null) {
			return mtime;
		}
		return new UnsignedInteger64(0);
	}

	/**
	 * Returns the modified date/time as a Java Date object.
	 * 
	 * @return
	 */
	public Date getModifiedDateTime() {

		long time = 0;

		if (mtime != null) {
			time = mtime.longValue() * 1000;
		}

		if (mtime_nano != null) {
			time += (mtime_nano.longValue() / 1000000);
		}
		return new Date(time);
	}

	/**
	 * Returns the creation date/time as a Java Date object.
	 * 
	 * @return
	 */
	public Date getCreationDateTime() {

		long time = 0;

		if (createtime != null) {
			time = createtime.longValue() * 1000;
		}

		if (createtime_nano != null) {
			time += (createtime_nano.longValue() / 1000000);
		}
		return new Date(time);
	}

	/**
	 * Returns the last accessed date/time as a Java Date object.
	 * 
	 * @return
	 */
	public Date getAccessedDateTime() {

		long time = 0;

		if (atime != null) {
			time = atime.longValue() * 1000;
		}

		if (atime != null) {
			time += (atime_nano.longValue() / 1000000);
		}
		return new Date(time);
	}

	/**
	 * Get the creation time of this file. This is only supported for SFTP
	 * protocol version 4 and above; if called when protocol revision is lower
	 * this method will return a zero value.
	 * 
	 * @return UnsignedInteger64
	 */
	public UnsignedInteger64 getCreationTime() {
		if (createtime != null)
			return createtime;
		return new UnsignedInteger64(0);
	}

	/**
	 * Determine if a permissions flag is set.
	 * 
	 * @param flag
	 * 
	 * @return boolean
	 */
	public boolean isFlagSet(long flag) {
		return ((flags & (flag & 0xFFFFFFFFL)) == (flag & 0xFFFFFFFFL));
	}

	/**
	 * Returns a formatted byte array suitable for encoding into SFTP subsystem
	 * messages.
	 * 
	 * @return byte[]
	 * 
	 * @throws IOException
	 */
	public byte[] toByteArray() throws IOException {
		ByteArrayWriter baw = new ByteArrayWriter();

		try {
			baw.writeInt(flags);

			if (version > 3)
				baw.write(type);

			if (isFlagSet(SSH_FILEXFER_ATTR_SIZE)) {
				baw.write(size.toByteArray());
			}

			if (version <= 3 && isFlagSet(SSH_FILEXFER_ATTR_UIDGID)) {
				if (uid != null) {
					try {
						baw.writeInt(Long.parseLong(uid));
					} catch (NumberFormatException ex) {
						baw.writeInt(0);
					}
				} else {
					baw.writeInt(0);
				}

				if (gid != null) {
					try {
						baw.writeInt(Long.parseLong(gid));
					} catch (NumberFormatException ex) {
						baw.writeInt(0);
					}
				} else {
					baw.writeInt(0);
				}
			} else if (version > 3 && isFlagSet(SSH_FILEXFER_ATTR_OWNERGROUP)) {
				if (uid != null)
					baw.writeString(uid, sftp.getCharsetEncoding());
				else
					baw.writeString("");

				if (gid != null)
					baw.writeString(gid, sftp.getCharsetEncoding());
				else
					baw.writeString("");
			}

			if (isFlagSet(SSH_FILEXFER_ATTR_PERMISSIONS)) {
				baw.writeInt(permissions.longValue());
			}

			if (version <= 3 && isFlagSet(SSH_FILEXFER_ATTR_ACCESSTIME)) {
				baw.writeInt(atime.longValue());
				baw.writeInt(mtime.longValue());
			} else if (version > 3) {

				if (isFlagSet(SSH_FILEXFER_ATTR_ACCESSTIME)) {
					baw.writeUINT64(atime);
				}

				if (isFlagSet(SSH_FILEXFER_ATTR_SUBSECOND_TIMES)) {
					baw.writeUINT32(atime_nano);
				}

				if (isFlagSet(SSH_FILEXFER_ATTR_CREATETIME)) {
					baw.writeUINT64(createtime);
				}

				if (isFlagSet(SSH_FILEXFER_ATTR_SUBSECOND_TIMES)) {
					baw.writeUINT32(createtime_nano);
				}

				if (isFlagSet(SSH_FILEXFER_ATTR_MODIFYTIME)) {
					baw.writeUINT64(mtime);
				}

				if (isFlagSet(SSH_FILEXFER_ATTR_SUBSECOND_TIMES)) {
					baw.writeUINT32(mtime_nano);
				}

			}

			if (isFlagSet(SSH_FILEXFER_ATTR_ACL)) {
				ByteArrayWriter tmp = new ByteArrayWriter();

				try {
					Enumeration e = acls.elements();
					tmp.writeInt(acls.size());
					while (e.hasMoreElements()) {
						ACL acl = e.nextElement();
						tmp.writeInt(acl.getType());
						tmp.writeInt(acl.getFlags());
						tmp.writeInt(acl.getMask());
						tmp.writeString(acl.getWho());
					}

					baw.writeBinaryString(tmp.toByteArray());
				} finally {
					tmp.close();
				}
			}

			if (isFlagSet(SSH_FILEXFER_ATTR_EXTENDED)) {
				baw.writeInt(extendedAttributes.size());
				Enumeration e = extendedAttributes.keys();
				while (e.hasMoreElements()) {
					String key = e.nextElement();
					baw.writeString(key);
					baw.writeBinaryString(extendedAttributes.get(key));
				}
			}

			return baw.toByteArray();
		} finally {
			try {
				baw.close();
			} catch (IOException e) {
			}
		}
	}

	private int octal(int v, int r) {
		v >>>= r;

		return (((v & 0x04) != 0) ? 4 : 0) + (((v & 0x02) != 0) ? 2 : 0)
				+ +(((v & 0x01) != 0) ? 1 : 0);
	}

	private String rwxString(int v, int r) {
		v >>>= r;

		String rwx = ((((v & 0x04) != 0) ? "r" : "-") + (((v & 0x02) != 0) ? "w"
				: "-"));

		if (((r == 6) && ((permissions.longValue() & S_ISUID) == S_ISUID))
				|| ((r == 3) && ((permissions.longValue() & S_ISGID) == S_ISGID))) {
			rwx += (((v & 0x01) != 0) ? "s" : "S");
		} else {
			rwx += (((v & 0x01) != 0) ? "x" : "-");
		}

		return rwx;
	}

	/**
	 * 
	 * Returns a formatted permissions string.
	 * 
	 * @return String
	 */
	public String getPermissionsString() {
		if (permissions != null) {
			StringBuffer str = new StringBuffer();
			boolean has_ifmt = ((int) permissions.longValue() & S_IFMT) > 0;
			if (has_ifmt)
				str.append(types[(int) (permissions.longValue() & S_IFMT) >>> 13]);
			else
				str.append('-');
			str.append(rwxString((int) permissions.longValue(), 6));
			str.append(rwxString((int) permissions.longValue(), 3));
			str.append(rwxString((int) permissions.longValue(), 0));

			return str.toString();
		}
		return "";
	}

	/**
	 * Return the UNIX style mode mask
	 * 
	 * @return mask
	 */
	public String getMaskString() {
		StringBuffer buf = new StringBuffer();

		if (permissions != null) {
			int i = (int) permissions.longValue();
			buf.append('0');
			buf.append(octal(i, 6));
			buf.append(octal(i, 3));
			buf.append(octal(i, 0));
		} else {
			buf.append("----");
		}
		return buf.toString();
	}

	/**
	 * Determine whether these attributes refer to a directory
	 * 
	 * @return boolean
	 */
	public boolean isDirectory() {
		if (sftp.getVersion() > 3) {
			return type == SSH_FILEXFER_TYPE_DIRECTORY;
		} else if (permissions != null
				&& (permissions.longValue() & SftpFileAttributes.S_IFDIR) == SftpFileAttributes.S_IFDIR) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 
	 * Determine whether these attributes refer to a file.
	 * 
	 * @return boolean
	 */
	public boolean isFile() {

		if (sftp.getVersion() > 3) {
			return type == SSH_FILEXFER_TYPE_REGULAR;
		} else if (permissions != null
				&& (permissions.longValue() & SftpFileAttributes.S_IFREG) == SftpFileAttributes.S_IFREG) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Determine whether these attributes refer to a symbolic link.
	 * 
	 * @return boolean
	 */
	public boolean isLink() {

		if (sftp.getVersion() > 3) {
			return type == SSH_FILEXFER_TYPE_SYMLINK;
		} else if (permissions != null
				&& (permissions.longValue() & SftpFileAttributes.S_IFLNK) == SftpFileAttributes.S_IFLNK) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Determine whether these attributes refer to a pipe.
	 * 
	 * @return boolean
	 */
	public boolean isFifo() {
		if (permissions != null
				&& (permissions.longValue() & SftpFileAttributes.S_IFIFO) == SftpFileAttributes.S_IFIFO) {
			return true;
		}
		return false;
	}

	/**
	 * Determine whether these attributes refer to a block special file.
	 * 
	 * @return boolean
	 */
	public boolean isBlock() {
		if (permissions != null
				&& (permissions.longValue() & SftpFileAttributes.S_IFBLK) == SftpFileAttributes.S_IFBLK) {
			return true;
		}
		return false;
	}

	/**
	 * Determine whether these attributes refer to a character device.
	 * 
	 * @return boolean
	 */
	public boolean isCharacter() {
		if (permissions != null
				&& (permissions.longValue() & SftpFileAttributes.S_IFCHR) == SftpFileAttributes.S_IFCHR) {
			return true;
		}
		return false;
	}

	/**
	 * Determine whether these attributes refer to a socket.
	 * 
	 * @return boolean
	 */
	public boolean isSocket() {
		if (permissions != null
				&& (permissions.longValue() & SftpFileAttributes.S_IFSOCK) == SftpFileAttributes.S_IFSOCK) {
			return true;
		}
		return false;
	}

	void setUsername(String username) {
		this.username = username;
	}

	void setGroup(String group) {
		this.group = group;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy