• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/tdeio
 

tdeio/tdeio

  • tdeio
  • tdeio
chmodjob.cpp
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
3 David Faure <faure@kde.org>
4 Waldo Bastian <bastian@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include <config.h>
23
24#include <pwd.h>
25#include <grp.h>
26#include <sys/types.h>
27#include <unistd.h>
28#include <assert.h>
29
30#include <tqtimer.h>
31#include <tqfile.h>
32#include <tdelocale.h>
33#include <kdebug.h>
34#include <tdemessagebox.h>
35
36#include "tdeio/job.h"
37#include "tdeio/chmodjob.h"
38
39#include <kdirnotify_stub.h>
40
41using namespace TDEIO;
42
43ChmodJob::ChmodJob( const KFileItemList& lstItems, int permissions, int mask,
44 int newOwner, int newGroup,
45 bool recursive, bool showProgressInfo )
46 : TDEIO::Job( showProgressInfo ), state( STATE_LISTING ),
47 m_permissions( permissions ), m_mask( mask ),
48 m_newOwner( newOwner ), m_newGroup( newGroup ),
49 m_recursive( recursive ), m_lstItems( lstItems )
50{
51 TQTimer::singleShot( 0, this, TQ_SLOT(processList()) );
52}
53
54void ChmodJob::processList()
55{
56 while ( !m_lstItems.isEmpty() )
57 {
58 KFileItem * item = m_lstItems.first();
59 if ( !item->isLink() ) // don't do anything with symlinks
60 {
61 // File or directory -> remember to chmod
62 ChmodInfo info;
63 info.url = item->url();
64 // This is a toplevel file, we apply changes directly (no +X emulation here)
65 info.permissions = ( m_permissions & m_mask ) | ( item->permissions() & ~m_mask );
66 /*kdDebug(7007) << "\n current permissions=" << TQString::number(item->permissions(),8)
67 << "\n wanted permission=" << TQString::number(m_permissions,8)
68 << "\n with mask=" << TQString::number(m_mask,8)
69 << "\n with ~mask (mask bits we keep) =" << TQString::number((uint)~m_mask,8)
70 << "\n bits we keep =" << TQString::number(item->permissions() & ~m_mask,8)
71 << "\n new permissions = " << TQString::number(info.permissions,8)
72 << endl;*/
73 m_infos.prepend( info );
74 //kdDebug(7007) << "processList : Adding info for " << info.url.prettyURL() << endl;
75 // Directory and recursive -> list
76 if ( item->isDir() && m_recursive )
77 {
78 //kdDebug(7007) << "ChmodJob::processList dir -> listing" << endl;
79 TDEIO::ListJob * listJob = TDEIO::listRecursive( item->url(), false /* no GUI */ );
80 connect( listJob, TQ_SIGNAL(entries( TDEIO::Job *,
81 const TDEIO::UDSEntryList& )),
82 TQ_SLOT( slotEntries( TDEIO::Job*,
83 const TDEIO::UDSEntryList& )));
84 addSubjob( listJob );
85 return; // we'll come back later, when this one's finished
86 }
87 }
88 m_lstItems.removeFirst();
89 }
90 kdDebug(7007) << "ChmodJob::processList -> going to STATE_CHMODING" << endl;
91 // We have finished, move on
92 state = STATE_CHMODING;
93 chmodNextFile();
94}
95
96void ChmodJob::slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList & list )
97{
98 TDEIO::UDSEntryListConstIterator it = list.begin();
99 TDEIO::UDSEntryListConstIterator end = list.end();
100 for (; it != end; ++it) {
101 TDEIO::UDSEntry::ConstIterator it2 = (*it).begin();
102 mode_t permissions = 0;
103 bool isDir = false;
104 bool isLink = false;
105 TQString relativePath;
106 for( ; it2 != (*it).end(); it2++ ) {
107 switch( (*it2).m_uds ) {
108 case TDEIO::UDS_NAME:
109 relativePath = (*it2).m_str;
110 break;
111 case TDEIO::UDS_FILE_TYPE:
112 isDir = S_ISDIR((*it2).m_long);
113 break;
114 case TDEIO::UDS_LINK_DEST:
115 isLink = !(*it2).m_str.isEmpty();
116 break;
117 case TDEIO::UDS_ACCESS:
118 permissions = (mode_t)((*it2).m_long);
119 break;
120 default:
121 break;
122 }
123 }
124 if ( !isLink && relativePath != TQString::fromLatin1("..") )
125 {
126 ChmodInfo info;
127 info.url = m_lstItems.first()->url(); // base directory
128 info.url.addPath( relativePath );
129 int mask = m_mask;
130 // Emulate -X: only give +x to files that had a +x bit already
131 // So the check is the opposite : if the file had no x bit, don't touch x bits
132 // For dirs this doesn't apply
133 if ( !isDir )
134 {
135 int newPerms = m_permissions & mask;
136 if ( (newPerms & 0111) && !(permissions & 0111) )
137 {
138 // don't interfere with mandatory file locking
139 if ( newPerms & 02000 )
140 mask = mask & ~0101;
141 else
142 mask = mask & ~0111;
143 }
144 }
145 info.permissions = ( m_permissions & mask ) | ( permissions & ~mask );
146 /*kdDebug(7007) << "\n current permissions=" << TQString::number(permissions,8)
147 << "\n wanted permission=" << TQString::number(m_permissions,8)
148 << "\n with mask=" << TQString::number(mask,8)
149 << "\n with ~mask (mask bits we keep) =" << TQString::number((uint)~mask,8)
150 << "\n bits we keep =" << TQString::number(permissions & ~mask,8)
151 << "\n new permissions = " << TQString::number(info.permissions,8)
152 << endl;*/
153 // Prepend this info in our todo list.
154 // This way, the toplevel dirs are done last.
155 m_infos.prepend( info );
156 }
157 }
158}
159
160void ChmodJob::chmodNextFile()
161{
162 if ( !m_infos.isEmpty() )
163 {
164 ChmodInfo info = m_infos.first();
165 m_infos.remove( m_infos.begin() );
166 // First update group / owner (if local file)
167 // (permissions have to set after, in case of suid and sgid)
168 if ( info.url.isLocalFile() && ( m_newOwner != -1 || m_newGroup != -1 ) )
169 {
170 TQString path = info.url.path();
171 if ( chown( TQFile::encodeName(path), m_newOwner, m_newGroup ) != 0 )
172 {
173 int answer = KMessageBox::warningContinueCancel( 0, i18n( "<qt>Could not modify the ownership of file <b>%1</b>. You have insufficient access to the file to perform the change.</qt>" ).arg(path), TQString::null, i18n("&Skip File") );
174 if (answer == KMessageBox::Cancel)
175 {
176 m_error = ERR_USER_CANCELED;
177 emitResult();
178 return;
179 }
180 }
181 }
182
183 kdDebug(7007) << "ChmodJob::chmodNextFile chmod'ing " << info.url.prettyURL()
184 << " to " << TQString::number(info.permissions,8) << endl;
185 TDEIO::SimpleJob * job = TDEIO::chmod( info.url, info.permissions );
186 // copy the metadata for acl and default acl
187 const TQString aclString = queryMetaData( "ACL_STRING" );
188 const TQString defaultAclString = queryMetaData( "DEFAULT_ACL_STRING" );
189 if ( !aclString.isEmpty() )
190 job->addMetaData( "ACL_STRING", aclString );
191 if ( !defaultAclString.isEmpty() )
192 job->addMetaData( "DEFAULT_ACL_STRING", defaultAclString );
193 addSubjob(job);
194 }
195 else
196 // We have finished
197 emitResult();
198}
199
200void ChmodJob::slotResult( TDEIO::Job * job )
201{
202 if ( job->error() )
203 {
204 m_error = job->error();
205 m_errorText = job->errorText();
206 emitResult();
207 return;
208 }
209 //kdDebug(7007) << " ChmodJob::slotResult( TDEIO::Job * job ) m_lstItems:" << m_lstItems.count() << endl;
210 switch ( state )
211 {
212 case STATE_LISTING:
213 subjobs.remove(job);
214 m_lstItems.removeFirst();
215 kdDebug(7007) << "ChmodJob::slotResult -> processList" << endl;
216 processList();
217 return;
218 case STATE_CHMODING:
219 subjobs.remove(job);
220 kdDebug(7007) << "ChmodJob::slotResult -> chmodNextFile" << endl;
221 chmodNextFile();
222 return;
223 default:
224 assert(0);
225 return;
226 }
227}
228
229// antlarr: KDE 4: Make owner and group be const TQString &
230TDEIO_EXPORT ChmodJob *TDEIO::chmod( const KFileItemList& lstItems, int permissions, int mask,
231 TQString owner, TQString group,
232 bool recursive, bool showProgressInfo )
233{
234 uid_t newOwnerID = (uid_t)-1; // chown(2) : -1 means no change
235 if ( !owner.isEmpty() )
236 {
237 struct passwd* pw = getpwnam(TQFile::encodeName(owner));
238 if ( pw == 0L )
239 kdError(250) << " ERROR: No user " << owner << endl;
240 else
241 newOwnerID = pw->pw_uid;
242 }
243 gid_t newGroupID = (gid_t)-1; // chown(2) : -1 means no change
244 if ( !group.isEmpty() )
245 {
246 struct group* g = getgrnam(TQFile::encodeName(group));
247 if ( g == 0L )
248 kdError(250) << " ERROR: No group " << group << endl;
249 else
250 newGroupID = g->gr_gid;
251 }
252 return new ChmodJob( lstItems, permissions, mask, newOwnerID, newGroupID, recursive, showProgressInfo );
253}
254
255void ChmodJob::virtual_hook( int id, void* data )
256{ TDEIO::Job::virtual_hook( id, data ); }
257
258#include "chmodjob.moc"
KFileItem
A KFileItem is a generic class to handle a file, local or remote.
Definition: tdefileitem.h:42
KFileItem::isLink
bool isLink() const
Returns true if this item represents a link in the UNIX sense of a link.
Definition: tdefileitem.h:200
KFileItem::url
const KURL & url() const
Returns the url of the file.
Definition: tdefileitem.h:113
KFileItem::permissions
mode_t permissions() const
Returns the permissions of the file (stat.st_mode containing only permissions).
Definition: tdefileitem.h:148
KFileItem::isDir
bool isDir() const
Returns true if this item represents a directory.
Definition: tdefileitem.cpp:844
TDEIO::ChmodJob
This job changes permissions on a list of files or directories, optionally in a recursive manner.
Definition: chmodjob.h:38
TDEIO::Job
The base class for all jobs.
Definition: jobclasses.h:67
TDEIO::Job::emitResult
void emitResult()
Utility function to emit the result signal, and suicide this job.
Definition: job.cpp:249
TDEIO::Job::addSubjob
virtual void addSubjob(Job *job, bool inheritMetaData=true)
Definition: job.cpp:183
TDEIO::Job::errorText
const TQString & errorText() const
Returns the error text if there has been an error.
Definition: jobclasses.h:110
TDEIO::Job::addMetaData
void addMetaData(const TQString &key, const TQString &value)
Definition: job.cpp:434
TDEIO::Job::error
int error() const
Returns the error code, if there has been an error.
Definition: jobclasses.h:94
TDEIO::Job::queryMetaData
TQString queryMetaData(const TQString &key)
Definition: job.cpp:422
TDEIO::ListJob
A ListJob is allows you to get the get the content of a directory.
Definition: jobclasses.h:1391
TDEIO::SimpleJob
A simple job (one url and one command).
Definition: jobclasses.h:527
TDEIO
A namespace for TDEIO globals.
Definition: authinfo.h:29
TDEIO::chmod
TDEIO_EXPORT ChmodJob * chmod(const KFileItemList &lstItems, int permissions, int mask, TQString newOwner, TQString newGroup, bool recursive, bool showProgressInfo=true)
Creates a job that changes permissions/ownership on several files or directories, optionally recursiv...
Definition: chmodjob.cpp:230
TDEIO::UDS_LINK_DEST
@ UDS_LINK_DEST
Name of the file where the link points to Allows to check for a symlink (don't use S_ISLNK !...
Definition: global.h:369
TDEIO::UDS_FILE_TYPE
@ UDS_FILE_TYPE
File type, part of the mode returned by stat (for a link, this returns the file type of the pointed i...
Definition: global.h:366
TDEIO::UDS_ACCESS
@ UDS_ACCESS
Access permissions (part of the mode returned by stat)
Definition: global.h:356
TDEIO::UDS_NAME
@ UDS_NAME
Filename - as displayed in directory listings etc.
Definition: global.h:335
TDEIO::listRecursive
TDEIO_EXPORT ListJob * listRecursive(const KURL &url, bool showProgressInfo=true, bool includeHidden=true)
The same as the previous method, but recurses subdirectories.
Definition: job.cpp:2222

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdeio by doxygen 1.9.4
This website is maintained by Timothy Pearson.