• 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 
41 using namespace TDEIO;
42 
43 ChmodJob::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 
54 void 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 
96 void 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 
160 void 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 
200 void 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 &
230 TDEIO_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 
255 void 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::ChmodJob::ChmodJob
ChmodJob(const KFileItemList &lstItems, int permissions, int mask, int newOwner, int newGroup, bool recursive, bool showProgressInfo)
Create new ChmodJobs using the TDEIO::chmod() function.
Definition: chmodjob.cpp:43
TDEIO::Job
The base class for all jobs.
Definition: jobclasses.h:67
TDEIO::Job::errorText
const TQString & errorText() const
Returns the error text if there has been an error.
Definition: jobclasses.h:110
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::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.1
This website is maintained by Timothy Pearson.