kio
chmodjob.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <pwd.h>
00025 #include <grp.h>
00026 #include <sys/types.h>
00027 #include <unistd.h>
00028 #include <assert.h>
00029
00030 #include <qtimer.h>
00031 #include <qfile.h>
00032 #include <klocale.h>
00033 #include <kdebug.h>
00034 #include <kmessagebox.h>
00035
00036 #include "kio/job.h"
00037 #include "kio/chmodjob.h"
00038
00039 #include <kdirnotify_stub.h>
00040
00041 using namespace KIO;
00042
00043 ChmodJob::ChmodJob( const KFileItemList& lstItems, int permissions, int mask,
00044 int newOwner, int newGroup,
00045 bool recursive, bool showProgressInfo )
00046 : KIO::Job( showProgressInfo ), state( STATE_LISTING ),
00047 m_permissions( permissions ), m_mask( mask ),
00048 m_newOwner( newOwner ), m_newGroup( newGroup ),
00049 m_recursive( recursive ), m_lstItems( lstItems )
00050 {
00051 QTimer::singleShot( 0, this, SLOT(processList()) );
00052 }
00053
00054 void ChmodJob::processList()
00055 {
00056 while ( !m_lstItems.isEmpty() )
00057 {
00058 KFileItem * item = m_lstItems.first();
00059 if ( !item->isLink() )
00060 {
00061
00062 ChmodInfo info;
00063 info.url = item->url();
00064
00065 info.permissions = ( m_permissions & m_mask ) | ( item->permissions() & ~m_mask );
00066
00067
00068
00069
00070
00071
00072
00073 m_infos.prepend( info );
00074
00075
00076 if ( item->isDir() && m_recursive )
00077 {
00078
00079 KIO::ListJob * listJob = KIO::listRecursive( item->url(), false );
00080 connect( listJob, SIGNAL(entries( KIO::Job *,
00081 const KIO::UDSEntryList& )),
00082 SLOT( slotEntries( KIO::Job*,
00083 const KIO::UDSEntryList& )));
00084 addSubjob( listJob );
00085 return;
00086 }
00087 }
00088 m_lstItems.removeFirst();
00089 }
00090 kdDebug(7007) << "ChmodJob::processList -> going to STATE_CHMODING" << endl;
00091
00092 state = STATE_CHMODING;
00093 chmodNextFile();
00094 }
00095
00096 void ChmodJob::slotEntries( KIO::Job*, const KIO::UDSEntryList & list )
00097 {
00098 KIO::UDSEntryListConstIterator it = list.begin();
00099 KIO::UDSEntryListConstIterator end = list.end();
00100 for (; it != end; ++it) {
00101 KIO::UDSEntry::ConstIterator it2 = (*it).begin();
00102 mode_t permissions = 0;
00103 bool isDir = false;
00104 bool isLink = false;
00105 QString relativePath;
00106 for( ; it2 != (*it).end(); it2++ ) {
00107 switch( (*it2).m_uds ) {
00108 case KIO::UDS_NAME:
00109 relativePath = (*it2).m_str;
00110 break;
00111 case KIO::UDS_FILE_TYPE:
00112 isDir = S_ISDIR((*it2).m_long);
00113 break;
00114 case KIO::UDS_LINK_DEST:
00115 isLink = !(*it2).m_str.isEmpty();
00116 break;
00117 case KIO::UDS_ACCESS:
00118 permissions = (mode_t)((*it2).m_long);
00119 break;
00120 default:
00121 break;
00122 }
00123 }
00124 if ( !isLink && relativePath != QString::fromLatin1("..") )
00125 {
00126 ChmodInfo info;
00127 info.url = m_lstItems.first()->url();
00128 info.url.addPath( relativePath );
00129 int mask = m_mask;
00130
00131
00132
00133 if ( !isDir )
00134 {
00135 int newPerms = m_permissions & mask;
00136 if ( (newPerms & 0111) && !(permissions & 0111) )
00137 {
00138
00139 if ( newPerms & 02000 )
00140 mask = mask & ~0101;
00141 else
00142 mask = mask & ~0111;
00143 }
00144 }
00145 info.permissions = ( m_permissions & mask ) | ( permissions & ~mask );
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 m_infos.prepend( info );
00156 }
00157 }
00158 }
00159
00160 void ChmodJob::chmodNextFile()
00161 {
00162 if ( !m_infos.isEmpty() )
00163 {
00164 ChmodInfo info = m_infos.first();
00165 m_infos.remove( m_infos.begin() );
00166
00167
00168 if ( info.url.isLocalFile() && ( m_newOwner != -1 || m_newGroup != -1 ) )
00169 {
00170 QString path = info.url.path();
00171 if ( chown( QFile::encodeName(path), m_newOwner, m_newGroup ) != 0 )
00172 {
00173 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), QString::null, i18n("&Skip File") );
00174 if (answer == KMessageBox::Cancel)
00175 {
00176 m_error = ERR_USER_CANCELED;
00177 emitResult();
00178 return;
00179 }
00180 }
00181 }
00182
00183 kdDebug(7007) << "ChmodJob::chmodNextFile chmod'ing " << info.url.prettyURL()
00184 << " to " << QString::number(info.permissions,8) << endl;
00185 KIO::SimpleJob * job = KIO::chmod( info.url, info.permissions );
00186
00187 const QString aclString = queryMetaData( "ACL_STRING" );
00188 const QString defaultAclString = queryMetaData( "DEFAULT_ACL_STRING" );
00189 if ( !aclString.isEmpty() )
00190 job->addMetaData( "ACL_STRING", aclString );
00191 if ( !defaultAclString.isEmpty() )
00192 job->addMetaData( "DEFAULT_ACL_STRING", defaultAclString );
00193 addSubjob(job);
00194 }
00195 else
00196
00197 emitResult();
00198 }
00199
00200 void ChmodJob::slotResult( KIO::Job * job )
00201 {
00202 if ( job->error() )
00203 {
00204 m_error = job->error();
00205 m_errorText = job->errorText();
00206 emitResult();
00207 return;
00208 }
00209
00210 switch ( state )
00211 {
00212 case STATE_LISTING:
00213 subjobs.remove(job);
00214 m_lstItems.removeFirst();
00215 kdDebug(7007) << "ChmodJob::slotResult -> processList" << endl;
00216 processList();
00217 return;
00218 case STATE_CHMODING:
00219 subjobs.remove(job);
00220 kdDebug(7007) << "ChmodJob::slotResult -> chmodNextFile" << endl;
00221 chmodNextFile();
00222 return;
00223 default:
00224 assert(0);
00225 return;
00226 }
00227 }
00228
00229
00230 KIO_EXPORT ChmodJob *KIO::chmod( const KFileItemList& lstItems, int permissions, int mask,
00231 QString owner, QString group,
00232 bool recursive, bool showProgressInfo )
00233 {
00234 uid_t newOwnerID = (uid_t)-1;
00235 if ( !owner.isEmpty() )
00236 {
00237 struct passwd* pw = getpwnam(QFile::encodeName(owner));
00238 if ( pw == 0L )
00239 kdError(250) << " ERROR: No user " << owner << endl;
00240 else
00241 newOwnerID = pw->pw_uid;
00242 }
00243 gid_t newGroupID = (gid_t)-1;
00244 if ( !group.isEmpty() )
00245 {
00246 struct group* g = getgrnam(QFile::encodeName(group));
00247 if ( g == 0L )
00248 kdError(250) << " ERROR: No group " << group << endl;
00249 else
00250 newGroupID = g->gr_gid;
00251 }
00252 return new ChmodJob( lstItems, permissions, mask, newOwnerID, newGroupID, recursive, showProgressInfo );
00253 }
00254
00255 void ChmodJob::virtual_hook( int id, void* data )
00256 { KIO::Job::virtual_hook( id, data ); }
00257
00258 #include "chmodjob.moc"