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