1 /***************************************************************************
2 sftpfileattr.cpp - description
4 begin : Sat Jun 30 2001
5 copyright : (C) 2001 by Lucas Fisher
6 email : ljfisher@iastate.edu
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
18 #include "sftpfileattr.h"
21 #include <sys/types.h>
24 #include <kio/global.h>
25 #include <kremoteencoding.h>
26 #include <kio/udsentry.h>
30 sftpFileAttr::sftpFileAttr(){
35 sftpFileAttr::sftpFileAttr(KRemoteEncoding
* encoding
){
42 /** Constructor to initialize the file attributes on declaration. */
43 sftpFileAttr::sftpFileAttr(quint64 size
, uid_t uid
, gid_t gid
,
44 mode_t permissions
, time_t atime
,
45 time_t mtime
, quint32 extendedCount
) {
53 mPermissions
= permissions
;
54 mExtendedCount
= extendedCount
;
57 sftpFileAttr::~sftpFileAttr(){
60 /** Returns a UDSEntry describing the file.
61 The UDSEntry is generated from the sftp file attributes. */
62 UDSEntry
sftpFileAttr::entry() {
65 entry
.insert(KIO::UDSEntry::UDS_NAME
, mFilename
);
67 if( mFlags
& SSH2_FILEXFER_ATTR_SIZE
) {
68 entry
.insert(KIO::UDSEntry::UDS_SIZE
, mSize
);
71 if( mFlags
& SSH2_FILEXFER_ATTR_ACMODTIME
) {
72 entry
.insert(KIO::UDSEntry::UDS_ACCESS_TIME
, mAtime
);
74 entry
.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME
, mMtime
);
77 if( mFlags
& SSH2_FILEXFER_ATTR_UIDGID
) {
78 if( mUserName
.isEmpty() || mGroupName
.isEmpty() )
81 entry
.insert(UDSEntry::UDS_USER
, mUserName
);
83 entry
.insert(UDSEntry::UDS_GROUP
, mGroupName
);
86 if( mFlags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) {
87 entry
.insert(UDSEntry::UDS_ACCESS
, mPermissions
);
89 mode_t type
= fileType();
91 // Set the type if we know what it is
93 entry
.insert(UDSEntry::UDS_FILE_TYPE
, (mLinkType
? mLinkType
:type
) );
97 entry
.insert(UDSEntry::UDS_LINK_DEST
, mLinkDestination
);
104 /** Use to output the file attributes to a sftp packet */
105 QDataStream
& operator<< (QDataStream
& s
, const sftpFileAttr
& fa
) {
106 s
<< (quint32
)fa
.mFlags
;
108 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_SIZE
)
109 { s
<< (quint64
)fa
.mSize
; }
111 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_UIDGID
)
112 { s
<< (quint32
)fa
.mUid
<< (quint32
)fa
.mGid
; }
114 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_PERMISSIONS
)
115 { s
<< (quint32
)fa
.mPermissions
; }
117 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_ACMODTIME
)
118 { s
<< (quint32
)fa
.mAtime
<< (quint32
)fa
.mMtime
; }
120 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_EXTENDED
) {
121 s
<< (quint32
)fa
.mExtendedCount
;
122 // XXX: Write extensions to data stream here
123 // s.writeBytes(extendedtype).writeBytes(extendeddata);
129 /** Use to read a file attribute from a sftp packet */
130 QDataStream
& operator>> (QDataStream
& s
, sftpFileAttr
& fa
) {
132 // XXX Add some error checking in here in case
133 // we get a bad sftp packet.
140 fn
.truncate( fn
.size() );
142 fa
.mFilename
= fa
.mEncoding
->decode( fn
);
145 fa
.mLongname
.truncate( fa
.mLongname
.size() );
146 //kDebug() << ">>: ftpfileattr long filename (" << fa.mLongname.size() << ")= " << fa.mLongname << endl;
149 s
>> fa
.mFlags
; // get flags
151 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_SIZE
) {
154 fa
.setFileSize(fileSize
);
159 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_UIDGID
) {
160 s
>> x
; fa
.setUid(x
);
161 s
>> x
; fa
.setGid(x
);
164 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_PERMISSIONS
) {
165 s
>> x
; fa
.setPermissions(x
);
168 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_ACMODTIME
) {
169 s
>> x
; fa
.setAtime(x
);
170 s
>> x
; fa
.setMtime(x
);
173 if( fa
.mFlags
& SSH2_FILEXFER_ATTR_EXTENDED
) {
174 s
>> x
; fa
.setExtendedCount(x
);
175 // XXX: Read in extensions from data stream here
176 // s.readBytes(extendedtype).readBytes(extendeddata);
179 fa
.getUserGroupNames();
182 /** Parse longname for the owner and group names. */
183 void sftpFileAttr::getUserGroupNames(){
184 // Get the name of the owner and group of the file from longname.
186 if( mLongname
.isEmpty() ) {
187 // do not have the user name so use the user id instead
194 int l
= mLongname
.length();
196 QString longName
= mEncoding
->decode( mLongname
);
198 kDebug(7120) << "Decoded: " << longName
;
200 // Find the beginning of the third field which contains the user name.
201 while( field
!= 2 ) {
202 if( longName
[i
].isSpace() ) {
204 while( i
< l
&& longName
[i
].isSpace() ) { i
++; }
208 // i is the index of the first character of the third field.
209 while( i
< l
&& !longName
[i
].isSpace() ) {
210 user
.append(longName
[i
]);
214 // i is the first character of the space between fields 3 and 4
215 // user contains the owner's user name
216 while( i
< l
&& longName
[i
].isSpace() ) {
220 // i is the first character of the fourth field
221 while( i
< l
&& !longName
[i
].isSpace() ) {
222 group
.append(longName
[i
]);
225 // group contains the name of the group.
232 /** No descriptions */
233 kdbgstream
& operator<< (kdbgstream
& s
, sftpFileAttr
& a
) {
234 s
<< "Filename: " << a
.mFilename
235 << ", Uid: " << a
.mUid
236 << ", Gid: " << a
.mGid
237 << ", Username: " << a
.mUserName
238 << ", GroupName: " << a
.mGroupName
239 << ", Permissions: " << a
.mPermissions
240 << ", size: " << a
.mSize
241 << ", atime: " << a
.mAtime
242 << ", mtime: " << a
.mMtime
243 << ", extended cnt: " << a
.mExtendedCount
;
245 if (S_ISLNK(a
.mLinkType
)) {
246 s
<< ", Link Type: " << a
.mLinkType
;
247 s
<< ", Link Destination: " << a
.mLinkDestination
;
253 /** Make sure it builds with NDEBUG */
254 kndbgstream
& operator<< (kndbgstream
& s
, sftpFileAttr
& ) {
258 /** Clear all attributes and flags. */
259 void sftpFileAttr::clear(){
268 mGroupName
= QString();
270 mLinkDestination
.clear();
276 /** Return the size of the sftp attribute. */
277 quint32
sftpFileAttr::size() const{
278 quint32 size
= 4; // for the attr flag
279 if( mFlags
& SSH2_FILEXFER_ATTR_SIZE
)
282 if( mFlags
& SSH2_FILEXFER_ATTR_UIDGID
)
285 if( mFlags
& SSH2_FILEXFER_ATTR_PERMISSIONS
)
288 if( mFlags
& SSH2_FILEXFER_ATTR_ACMODTIME
)
291 if( mFlags
& SSH2_FILEXFER_ATTR_EXTENDED
) {
293 // add size of extensions
298 /** Returns the file type as determined from the file permissions */
299 mode_t
sftpFileAttr::fileType() const{
302 if( S_ISLNK(mPermissions
) )
305 if( S_ISREG(mPermissions
) )
307 else if( S_ISDIR(mPermissions
) )
309 else if( S_ISCHR(mPermissions
) )
311 else if( S_ISBLK(mPermissions
) )
313 else if( S_ISFIFO(mPermissions
) )
315 else if( S_ISSOCK(mPermissions
) )
321 void sftpFileAttr::setEncoding( KRemoteEncoding
* encoding
)
323 mEncoding
= encoding
;