chmodjob.cpp
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 addSubjob(job);
00187 }
00188 else
00189
00190 emitResult();
00191 }
00192
00193 void ChmodJob::slotResult( KIO::Job * job )
00194 {
00195 if ( job->error() )
00196 {
00197 m_error = job->error();
00198 m_errorText = job->errorText();
00199 emitResult();
00200 return;
00201 }
00202
00203 switch ( state )
00204 {
00205 case STATE_LISTING:
00206 subjobs.remove(job);
00207 m_lstItems.removeFirst();
00208 kdDebug(7007) << "ChmodJob::slotResult -> processList" << endl;
00209 processList();
00210 return;
00211 case STATE_CHMODING:
00212 subjobs.remove(job);
00213 kdDebug(7007) << "ChmodJob::slotResult -> chmodNextFile" << endl;
00214 chmodNextFile();
00215 return;
00216 default:
00217 assert(0);
00218 return;
00219 }
00220 }
00221
00222
00223 KIO_EXPORT ChmodJob *KIO::chmod( const KFileItemList& lstItems, int permissions, int mask,
00224 QString owner, QString group,
00225 bool recursive, bool showProgressInfo )
00226 {
00227 uid_t newOwnerID = (uid_t)-1;
00228 if ( !owner.isEmpty() )
00229 {
00230 struct passwd* pw = getpwnam(QFile::encodeName(owner));
00231 if ( pw == 0L )
00232 kdError(250) << " ERROR: No user " << owner << endl;
00233 else
00234 newOwnerID = pw->pw_uid;
00235 }
00236 gid_t newGroupID = (gid_t)-1;
00237 if ( !group.isEmpty() )
00238 {
00239 struct group* g = getgrnam(QFile::encodeName(group));
00240 if ( g == 0L )
00241 kdError(250) << " ERROR: No group " << group << endl;
00242 else
00243 newGroupID = g->gr_gid;
00244 }
00245 return new ChmodJob( lstItems, permissions, mask, newOwnerID, newGroupID, recursive, showProgressInfo );
00246 }
00247
00248 void ChmodJob::virtual_hook( int id, void* data )
00249 { KIO::Job::virtual_hook( id, data ); }
00250
00251 #include "chmodjob.moc"
This file is part of the documentation for kio Library Version 3.4.1.