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 
00237 ChmodJob *KIO::chmod( const KFileItemList& lstItems, int permissions, int mask,
00238                       QString owner, QString group,
00239                       bool recursive, bool showProgressInfo )
00240 {
00241     uid_t newOwnerID = (uid_t)-1; 
00242     if ( !owner.isEmpty() )
00243     {
00244         struct passwd* pw = getpwnam(QFile::encodeName(owner));
00245         if ( pw == 0L )
00246             kdError(250) << " ERROR: No user " << owner << endl;
00247         else
00248             newOwnerID = pw->pw_uid;
00249     }
00250     gid_t newGroupID = (gid_t)-1; 
00251     if ( !group.isEmpty() )
00252     {
00253         struct group* g = getgrnam(QFile::encodeName(group));
00254         if ( g == 0L )
00255             kdError(250) << " ERROR: No group " << group << endl;
00256         else
00257             newGroupID = g->gr_gid;
00258     }
00259     return new ChmodJob( lstItems, permissions, mask, newOwnerID, newGroupID, recursive, showProgressInfo );
00260 }
00261 
00262 void ChmodJob::virtual_hook( int id, void* data )
00263 { KIO::Job::virtual_hook( id, data ); }
00264 
00265 #include "chmodjob.moc"
 
This file is part of the documentation for kio Library Version 3.2.0.