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(
"&Skip File") );
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"