1 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2 /*
3 Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 
8   1. Redistributions of source code must retain the above copyright notice,
9      this list of conditions and the following disclaimer.
10 
11   2. Redistributions in binary form must reproduce the above copyright
12      notice, this list of conditions and the following disclaimer in
13      the documentation and/or other materials provided with the distribution.
14 
15   3. The names of the authors may not be used to endorse or promote products
16      derived from this software without specific prior written permission.
17 
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 package com.jcraft.jsch;
31 
32 import java.text.SimpleDateFormat;
33 import java.util.Date;
34 
35 /*
36   uint32   flags
37   uint64   size           present only if flag SSH_FILEXFER_ATTR_SIZE
38   uint32   uid            present only if flag SSH_FILEXFER_ATTR_UIDGID
39   uint32   gid            present only if flag SSH_FILEXFER_ATTR_UIDGID
40   uint32   permissions    present only if flag SSH_FILEXFER_ATTR_PERMISSIONS
41   uint32   atime          present only if flag SSH_FILEXFER_ACMODTIME
42   uint32   mtime          present only if flag SSH_FILEXFER_ACMODTIME
43   uint32   extended_count present only if flag SSH_FILEXFER_ATTR_EXTENDED
44   string   extended_type
45   string   extended_data
46     ...      more extended data (extended_type - extended_data pairs),
47              so that number of pairs equals extended_count
48 */
49 public class SftpATTRS {
50 
51   static final int S_ISUID = 04000; // set user ID on execution
52   static final int S_ISGID = 02000; // set group ID on execution
53   static final int S_ISVTX = 01000; // sticky bit   ****** NOT DOCUMENTED *****
54 
55   static final int S_IRUSR = 00400; // read by owner
56   static final int S_IWUSR = 00200; // write by owner
57   static final int S_IXUSR = 00100; // execute/search by owner
58   static final int S_IREAD = 00400; // read by owner
59   static final int S_IWRITE= 00200; // write by owner
60   static final int S_IEXEC = 00100; // execute/search by owner
61 
62   static final int S_IRGRP = 00040; // read by group
63   static final int S_IWGRP = 00020; // write by group
64   static final int S_IXGRP = 00010; // execute/search by group
65 
66   static final int S_IROTH = 00004; // read by others
67   static final int S_IWOTH = 00002; // write by others
68   static final int S_IXOTH = 00001; // execute/search by others
69 
70   private static final int pmask = 0xFFF;
71 
getPermissionsString()72   public String getPermissionsString() {
73     StringBuffer buf = new StringBuffer(10);
74 
75     if(isDir()) buf.append('d');
76     else if(isLink()) buf.append('l');
77     else buf.append('-');
78 
79     if((permissions & S_IRUSR)!=0) buf.append('r');
80     else buf.append('-');
81 
82     if((permissions & S_IWUSR)!=0) buf.append('w');
83     else buf.append('-');
84 
85     if((permissions & S_ISUID)!=0) buf.append('s');
86     else if ((permissions & S_IXUSR)!=0) buf.append('x');
87     else buf.append('-');
88 
89     if((permissions & S_IRGRP)!=0) buf.append('r');
90     else buf.append('-');
91 
92     if((permissions & S_IWGRP)!=0) buf.append('w');
93     else buf.append('-');
94 
95     if((permissions & S_ISGID)!=0) buf.append('s');
96     else if((permissions & S_IXGRP)!=0) buf.append('x');
97     else buf.append('-');
98 
99     if((permissions & S_IROTH) != 0) buf.append('r');
100     else buf.append('-');
101 
102     if((permissions & S_IWOTH) != 0) buf.append('w');
103     else buf.append('-');
104 
105     if((permissions & S_IXOTH) != 0) buf.append('x');
106     else buf.append('-');
107     return (buf.toString());
108   }
109 
getAtimeString()110   public String  getAtimeString(){
111     Date date= new Date(((long)atime)*1000L);
112     return (date.toString());
113   }
114 
getMtimeString()115   public String  getMtimeString(){
116     Date date= new Date(((long)mtime)*1000L);
117     return (date.toString());
118   }
119 
120   public static final int SSH_FILEXFER_ATTR_SIZE=         0x00000001;
121   public static final int SSH_FILEXFER_ATTR_UIDGID=       0x00000002;
122   public static final int SSH_FILEXFER_ATTR_PERMISSIONS=  0x00000004;
123   public static final int SSH_FILEXFER_ATTR_ACMODTIME=    0x00000008;
124   public static final int SSH_FILEXFER_ATTR_EXTENDED=     0x80000000;
125 
126   static final int S_IFMT=0xf000;
127   static final int S_IFIFO=0x1000;
128   static final int S_IFCHR=0x2000;
129   static final int S_IFDIR=0x4000;
130   static final int S_IFBLK=0x6000;
131   static final int S_IFREG=0x8000;
132   static final int S_IFLNK=0xa000;
133   static final int S_IFSOCK=0xc000;
134 
135   int flags=0;
136   long size;
137   int uid;
138   int gid;
139   int permissions;
140   int atime;
141   int mtime;
142   String[] extended=null;
143 
SftpATTRS()144   private SftpATTRS(){
145   }
146 
getATTR(Buffer buf)147   static SftpATTRS getATTR(Buffer buf){
148     SftpATTRS attr=new SftpATTRS();
149     attr.flags=buf.getInt();
150     if((attr.flags&SSH_FILEXFER_ATTR_SIZE)!=0){ attr.size=buf.getLong(); }
151     if((attr.flags&SSH_FILEXFER_ATTR_UIDGID)!=0){
152       attr.uid=buf.getInt(); attr.gid=buf.getInt();
153     }
154     if((attr.flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){
155       attr.permissions=buf.getInt();
156     }
157     if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){
158       attr.atime=buf.getInt();
159     }
160     if((attr.flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){
161       attr.mtime=buf.getInt();
162     }
163     if((attr.flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){
164       int count=buf.getInt();
165       if(count>0){
166 	attr.extended=new String[count*2];
167 	for(int i=0; i<count; i++){
168 	  attr.extended[i*2]=Util.byte2str(buf.getString());
169 	  attr.extended[i*2+1]=Util.byte2str(buf.getString());
170 	}
171       }
172     }
173     return attr;
174   }
175 
length()176   int length(){
177     int len=4;
178 
179     if((flags&SSH_FILEXFER_ATTR_SIZE)!=0){ len+=8; }
180     if((flags&SSH_FILEXFER_ATTR_UIDGID)!=0){ len+=8; }
181     if((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){ len+=4; }
182     if((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ len+=8; }
183     if((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){
184       len+=4;
185       int count=extended.length/2;
186       if(count>0){
187 	for(int i=0; i<count; i++){
188 	  len+=4; len+=extended[i*2].length();
189 	  len+=4; len+=extended[i*2+1].length();
190 	}
191       }
192     }
193     return len;
194   }
195 
dump(Buffer buf)196   void dump(Buffer buf){
197     buf.putInt(flags);
198     if((flags&SSH_FILEXFER_ATTR_SIZE)!=0){ buf.putLong(size); }
199     if((flags&SSH_FILEXFER_ATTR_UIDGID)!=0){
200       buf.putInt(uid); buf.putInt(gid);
201     }
202     if((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0){
203       buf.putInt(permissions);
204     }
205     if((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ buf.putInt(atime); }
206     if((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0){ buf.putInt(mtime); }
207     if((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){
208       int count=extended.length/2;
209       if(count>0){
210 	for(int i=0; i<count; i++){
211 	  buf.putString(Util.str2byte(extended[i*2]));
212 	  buf.putString(Util.str2byte(extended[i*2+1]));
213 	}
214       }
215     }
216   }
setFLAGS(int flags)217   void setFLAGS(int flags){
218     this.flags=flags;
219   }
setSIZE(long size)220   public void setSIZE(long size){
221     flags|=SSH_FILEXFER_ATTR_SIZE;
222     this.size=size;
223   }
setUIDGID(int uid, int gid)224   public void setUIDGID(int uid, int gid){
225     flags|=SSH_FILEXFER_ATTR_UIDGID;
226     this.uid=uid;
227     this.gid=gid;
228   }
setACMODTIME(int atime, int mtime)229   public void setACMODTIME(int atime, int mtime){
230     flags|=SSH_FILEXFER_ATTR_ACMODTIME;
231     this.atime=atime;
232     this.mtime=mtime;
233   }
setPERMISSIONS(int permissions)234   public void setPERMISSIONS(int permissions){
235     flags|=SSH_FILEXFER_ATTR_PERMISSIONS;
236     permissions=(this.permissions&~pmask)|(permissions&pmask);
237     this.permissions=permissions;
238   }
239 
isType(int mask)240   private boolean isType(int mask) {
241     return (flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0 &&
242            (permissions&S_IFMT)==mask;
243   }
244 
isReg()245   public boolean isReg(){
246     return isType(S_IFREG);
247   }
248 
isDir()249   public boolean isDir(){
250     return isType(S_IFDIR);
251   }
252 
isChr()253   public boolean isChr(){
254     return isType(S_IFCHR);
255   }
256 
isBlk()257   public boolean isBlk(){
258     return isType(S_IFBLK);
259   }
260 
isFifo()261   public boolean isFifo(){
262     return isType(S_IFIFO);
263   }
264 
isLink()265   public boolean isLink(){
266     return isType(S_IFLNK);
267   }
268 
isSock()269   public boolean isSock(){
270     return isType(S_IFSOCK);
271   }
272 
getFlags()273   public int getFlags() { return flags; }
getSize()274   public long getSize() { return size; }
getUId()275   public int getUId() { return uid; }
getGId()276   public int getGId() { return gid; }
getPermissions()277   public int getPermissions() { return permissions; }
getATime()278   public int getATime() { return atime; }
getMTime()279   public int getMTime() { return mtime; }
getExtended()280   public String[] getExtended() { return extended; }
281 
toString()282   public String toString() {
283     return (getPermissionsString()+" "+getUId()+" "+getGId()+" "+getSize()+" "+getMtimeString());
284   }
285   /*
286   public String toString(){
287     return (((flags&SSH_FILEXFER_ATTR_SIZE)!=0) ? ("size:"+size+" ") : "")+
288            (((flags&SSH_FILEXFER_ATTR_UIDGID)!=0) ? ("uid:"+uid+",gid:"+gid+" ") : "")+
289            (((flags&SSH_FILEXFER_ATTR_PERMISSIONS)!=0) ? ("permissions:0x"+Integer.toHexString(permissions)+" ") : "")+
290            (((flags&SSH_FILEXFER_ATTR_ACMODTIME)!=0) ? ("atime:"+atime+",mtime:"+mtime+" ") : "")+
291            (((flags&SSH_FILEXFER_ATTR_EXTENDED)!=0) ? ("extended:?"+" ") : "");
292   }
293   */
294 }
295