26 #define QT_NO_CAST_FROM_ASCII
31 #include <config-kioslave-file.h>
33 #include <QtCore/QFile>
34 #include <QtCore/QDir>
49 #if defined(HAVE_LIMITS_H)
54 #if defined HAVE_SENDFILE && defined Q_OS_LINUX
55 #define USE_SENDFILE 1
59 #include <sys/sendfile.h>
64 #define MAX_IPC_SIZE (1024*32)
67 same_inode(
const KDE_struct_stat &src,
const KDE_struct_stat &dest)
69 if (src.st_ino == dest.st_ino &&
70 src.st_dev == dest.st_dev)
76 extern int write_all(
int fd,
const char *buf,
size_t len);
79 int _mode, JobFlags _flags )
81 kDebug(7101) <<
"copy(): " << srcUrl <<
" -> " << destUrl <<
", mode=" << _mode;
85 QByteArray _src( QFile::encodeName(src));
86 QByteArray _dest( QFile::encodeName(dest));
87 KDE_struct_stat buff_src;
92 if ( KDE_stat( _src.data(), &buff_src ) == -1 ) {
93 if ( errno == EACCES )
100 if ( S_ISDIR( buff_src.st_mode ) ) {
104 if ( S_ISFIFO( buff_src.st_mode ) || S_ISSOCK ( buff_src.st_mode ) ) {
109 KDE_struct_stat buff_dest;
110 bool dest_exists = ( KDE_lstat( _dest.data(), &buff_dest ) != -1 );
113 if (S_ISDIR(buff_dest.st_mode))
134 if ((_flags & KIO::Overwrite) && S_ISLNK(buff_dest.st_mode))
137 remove( _dest.data() );
141 int src_fd = KDE_open( _src.data(), O_RDONLY);
148 posix_fadvise(src_fd,0,0,POSIX_FADV_SEQUENTIAL);
154 initialMode = _mode | S_IWUSR;
158 int dest_fd = KDE_open(_dest.data(), O_CREAT | O_TRUNC | O_WRONLY, initialMode);
160 kDebug(7101) <<
"###### COULD NOT WRITE " << dest;
161 if ( errno == EACCES ) {
171 posix_fadvise(dest_fd,0,0,POSIX_FADV_SEQUENTIAL);
174 #ifdef HAVE_POSIX_ACL
175 acl = acl_get_fd(src_fd);
176 if ( acl && !isExtendedACL( acl ) ) {
177 kDebug(7101) << _dest.data() <<
" doesn't have extended ACL";
182 totalSize( buff_src.st_size );
188 bool use_sendfile=buff_src.st_size < 0x7FFFFFFF;
194 off_t sf = processed_size;
197 if ( n == -1 && ( errno == EINVAL || errno == ENOSYS ) ) {
198 kDebug(7101) <<
"sendfile() not supported, falling back ";
199 use_sendfile =
false;
211 if ( use_sendfile ) {
212 kDebug(7101) <<
"sendfile() error:" << strerror(errno);
213 if ( errno == ENOSPC )
216 remove( _dest.data() );
220 i18n(
"Cannot copy file from %1 to %2. (Errno: %3)",
228 #ifdef HAVE_POSIX_ACL
229 if (acl) acl_free(acl);
236 if ( !use_sendfile ) {
243 if ( errno == ENOSPC )
246 remove( _dest.data() );
250 kWarning(7101) <<
"Couldn't write[2]. Error:" << strerror(errno);
253 #ifdef HAVE_POSIX_ACL
254 if (acl) acl_free(acl);
262 processedSize( processed_size );
267 if (::
close( dest_fd))
269 kWarning(7101) <<
"Error when closing file descriptor[2]:" << strerror(errno);
271 #ifdef HAVE_POSIX_ACL
272 if (acl) acl_free(acl);
280 if ( (::
chmod(_dest.data(), _mode) != 0)
281 #ifdef HAVE_POSIX_ACL
282 || (acl && acl_set_file(_dest.data(), ACL_TYPE_ACCESS, acl) != 0)
289 warning(
i18n(
"Could not change permissions for\n%1", dest));
292 #ifdef HAVE_POSIX_ACL
293 if (acl) acl_free(acl);
298 ut.actime = buff_src.st_atime;
299 ut.modtime = buff_src.st_mtime;
300 if ( ::
utime( _dest.data(), &ut ) != 0 )
302 kWarning() << QString::fromLatin1(
"Couldn't preserve access and modification time for\n%1").arg(dest);
305 processedSize( buff_src.st_size );
315 kDebug(7101) <<
"redirecting to " << redir.
url();
320 const QByteArray _path(QFile::encodeName(path));
321 DIR* dp = opendir(_path.data());
333 i18n(
"No media in device for %1", path));
350 const QString pathBuffer(QDir::currentPath());
351 if (!QDir::setCurrent(path)) {
357 const QString sDetails = metaData(QLatin1String(
"details"));
358 const int details = sDetails.isEmpty() ? 2 : sDetails.toInt();
362 #ifndef HAVE_DIRENT_D_TYPE
365 KDE_struct_dirent *ep;
366 while ((ep = KDE_readdir(dp)) != 0 ) {
369 const QString filename = QFile::decodeName(ep->d_name);
383 #ifdef HAVE_DIRENT_D_TYPE
385 (ep->d_type == DT_DIR) ? S_IFDIR : S_IFREG );
386 const bool isSymLink = (ep->d_type == DT_LNK);
389 if (KDE_lstat(ep->d_name, &st) == -1) {
393 (S_ISDIR(st.st_mode)) ? S_IFDIR : S_IFREG );
394 const bool isSymLink = S_ISLNK(st.st_mode);
401 listEntry(entry,
false);
404 if (createUDSEntry(filename, QByteArray(ep->d_name), entry, details,
true)) {
405 listEntry(entry,
false);
411 listEntry(entry,
true);
414 QDir::setCurrent(pathBuffer);
420 KIO::JobFlags _flags )
422 char off_t_should_be_64_bits[
sizeof(off_t) >= 8 ? 1 : -1]; (void) off_t_should_be_64_bits;
425 const QByteArray _src(QFile::encodeName(src));
426 const QByteArray _dest(QFile::encodeName(dest));
427 KDE_struct_stat buff_src;
428 if ( KDE_lstat( _src.data(), &buff_src ) == -1 ) {
429 if ( errno == EACCES )
436 KDE_struct_stat buff_dest;
439 bool dest_exists = ( KDE_lstat( _dest.data(), &buff_dest ) != -1 );
442 if (S_ISDIR(buff_dest.st_mode))
461 if ( KDE_rename( _src.data(), _dest.data()))
463 if (( errno == EACCES ) || (errno == EPERM)) {
466 else if (errno == EXDEV) {
469 else if (errno == EROFS) {
485 if ( ::
symlink( QFile::encodeName(target), QFile::encodeName(dest) ) == -1 )
488 if ( errno == EEXIST )
493 if ( unlink( QFile::encodeName(dest) ) != 0 )
499 symlink( target, destUrl, flags );
503 KDE_struct_stat buff_dest;
504 if (KDE_lstat(QFile::encodeName(dest), &buff_dest) == 0 && S_ISDIR(buff_dest.st_mode))
524 const QByteArray _path( QFile::encodeName(path));
530 kDebug(7101) <<
"Deleting file "<< url;
532 if ( unlink( _path.data() ) == -1 ) {
533 if ((errno == EACCES) || (errno == EPERM))
535 else if (errno == EISDIR)
547 kDebug( 7101 ) <<
"Deleting directory " << url.
url();
548 if (metaData(QLatin1String(
"recurse")) == QLatin1String(
"true")) {
549 if (!deleteRecursive(path))
552 if ( ::
rmdir( _path.data() ) == -1 ) {
553 if ((errno == EACCES) || (errno == EPERM))
569 const QByteArray _path( QFile::encodeName(path) );
575 struct passwd *p = ::getpwnam(owner.toLatin1());
579 i18n(
"Could not get user id for given user name %1", owner ) );
588 struct group *p = ::getgrnam(group.toLatin1());
592 i18n(
"Could not get group id for given group name %1", group ) );
599 if ( ::
chown(_path, uid, gid) == -1 ) {
621 kDebug(7101) <<
"redirecting to " << redir.
url();
634 const QByteArray _path( QFile::encodeName(path));
635 const QString sDetails = metaData(QLatin1String(
"details"));
636 const int details = sDetails.isEmpty() ? 2 : sDetails.toInt();
639 if ( !createUDSEntry( url.
fileName(), _path, entry, details,
true ) )
645 MetaData::iterator it1 = mOutgoingMetaData.begin();
647 for ( ; it1 != mOutgoingMetaData.end(); it1++ ) {
648 kDebug(7101) << it1.key() <<
" = " << it1.data();
QString i18n(const char *text)
KAutostart::StartPhase readEntry(const KConfigGroup &group, const char *key, const KAutostart::StartPhase &aDefault)
QDebug perror(QDebug s, KDebugTag)
virtual void listDir(const KUrl &url)
static List currentMountPoints(DetailsNeededFlags infoNeeded=BasicInfoNeeded)
virtual void symlink(const QString &target, const KUrl &dest, KIO::JobFlags flags)
void insert(uint field, const QString &value)
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
virtual void chown(const KUrl &url, const QString &owner, const QString &group)
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KSharedConfigPtr config()
virtual void copy(const KUrl &src, const KUrl &dest, int mode, KIO::JobFlags flags)
virtual void rename(const KUrl &src, const KUrl &dest, KIO::JobFlags flags)
void setProtocol(const QString &proto)
SimpleJob * chown(const KUrl &url, const QString &owner, const QString &group)
SimpleJob * chmod(const KUrl &url, int permissions)
SimpleJob * rmdir(const KUrl &url)
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
SimpleJob * symlink(const QString &target, const KUrl &dest, JobFlags flags=DefaultFlags)
virtual void stat(const KUrl &url)
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
static bool same_inode(const KDE_struct_stat &src, const KDE_struct_stat &dest)
Ptr findByPath(const QString &path) const
int write_all(int fd, const char *buf, size_t len)
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
virtual void del(const KUrl &url, bool isfile)
int utime(const QString &filename, struct utimbuf *buf)
KAction * close(const QObject *recvr, const char *slot, QObject *parent)