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