KIO

statjob.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2000 Stephan Kulow <[email protected]>
4  SPDX-FileCopyrightText: 2000-2009 David Faure <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #include "statjob.h"
10 
11 #include "job_p.h"
12 #include "scheduler.h"
13 #include "slave.h"
14 #include <KProtocolInfo>
15 #include <QTimer>
16 #include <kurlauthorized.h>
17 
18 using namespace KIO;
19 
20 class KIO::StatJobPrivate : public SimpleJobPrivate
21 {
22 public:
23  inline StatJobPrivate(const QUrl &url, int command, const QByteArray &packedArgs)
24  : SimpleJobPrivate(url, command, packedArgs)
25  , m_bSource(true)
26  , m_details(KIO::StatDefaultDetails)
27  {
28  }
29 
30  UDSEntry m_statResult;
31  QUrl m_redirectionURL;
32  bool m_bSource;
33  KIO::StatDetails m_details;
34  void slotStatEntry(const KIO::UDSEntry &entry);
35  void slotRedirection(const QUrl &url);
36 
37  /**
38  * @internal
39  * Called by the scheduler when a @p slave gets to
40  * work on this job.
41  * @param slave the slave that starts working on this job
42  */
43  void start(Slave *slave) override;
44 
45  Q_DECLARE_PUBLIC(StatJob)
46 
47  static inline StatJob *newJob(const QUrl &url, int command, const QByteArray &packedArgs, JobFlags flags)
48  {
49  StatJob *job = new StatJob(*new StatJobPrivate(url, command, packedArgs));
51  if (!(flags & HideProgressInfo)) {
54  emitStating(job, url);
55  }
56  return job;
57  }
58 };
59 
60 StatJob::StatJob(StatJobPrivate &dd)
61  : SimpleJob(dd)
62 {
63  setTotalAmount(Items, 1);
64 }
65 
66 StatJob::~StatJob()
67 {
68 }
69 
70 #if KIOCORE_BUILD_DEPRECATED_SINCE(4, 0)
71 void StatJob::setSide(bool source)
72 {
73  d_func()->m_bSource = source;
74 }
75 #endif
76 
77 void StatJob::setSide(StatSide side)
78 {
79  d_func()->m_bSource = side == SourceSide;
80 }
81 
83 {
84  d_func()->m_details = details;
85 }
86 
87 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 69)
88 void StatJob::setDetails(short int details)
89 {
90  // for backward compatibility
91  d_func()->m_details = detailsToStatDetails(details);
92 }
93 
95 {
96  d_func()->m_details = detail;
97 }
98 
100 {
101  KIO::StatDetails detailsFlag = KIO::StatBasic;
102  if (details > 0) {
103  detailsFlag |= KIO::StatUser | KIO::StatTime;
104  }
105  if (details > 1) {
106  detailsFlag |= KIO::StatResolveSymlink | KIO::StatAcl;
107  }
108  if (details > 2) {
109  detailsFlag |= KIO::StatInode;
110  }
111  return detailsFlag;
112 }
113 #endif
114 
116 {
117  return d_func()->m_statResult;
118 }
119 
121 {
122  const QUrl _url = url();
123 
124  if (_url.isLocalFile()) {
125  return _url;
126  }
127 
128  const UDSEntry &udsEntry = d_func()->m_statResult;
129  const QString path = udsEntry.stringValue(KIO::UDSEntry::UDS_LOCAL_PATH);
130 
131  if (path.isEmpty()) { // Return url as-is
132  return _url;
133  }
134 
135  const QString protoClass = KProtocolInfo::protocolClass(_url.scheme());
136  if (protoClass != QLatin1String(":local")) { // UDS_LOCAL_PATH was set but wrong Class
137  qCWarning(KIO_CORE) << "The protocol Class of the url that was being stat'ed" << _url << ", is" << protoClass
138  << ", however UDS_LOCAL_PATH was set; if you use UDS_LOCAL_PATH, the protocolClass"
139  " should be :local, see KProtocolInfo API docs for more details.";
140  return _url;
141  }
142 
143  return QUrl::fromLocalFile(path);
144 }
145 
146 void StatJobPrivate::start(Slave *slave)
147 {
148  Q_Q(StatJob);
149  m_outgoingMetaData.insert(QStringLiteral("statSide"), m_bSource ? QStringLiteral("source") : QStringLiteral("dest"));
150  m_outgoingMetaData.insert(QStringLiteral("statDetails"), QString::number(m_details));
151 
152  q->connect(slave, &KIO::SlaveInterface::statEntry, q, [this](const KIO::UDSEntry &entry) {
153  slotStatEntry(entry);
154  });
155  q->connect(slave, &KIO::SlaveInterface::redirection, q, [this](const QUrl &url) {
156  slotRedirection(url);
157  });
158 
160 }
161 
162 void StatJobPrivate::slotStatEntry(const KIO::UDSEntry &entry)
163 {
164  // qCDebug(KIO_CORE);
165  m_statResult = entry;
166 }
167 
168 // Worker got a redirection request
169 void StatJobPrivate::slotRedirection(const QUrl &url)
170 {
171  Q_Q(StatJob);
172  // qCDebug(KIO_CORE) << m_url << "->" << url;
173  if (!KUrlAuthorized::authorizeUrlAction(QStringLiteral("redirect"), m_url, url)) {
174  qCWarning(KIO_CORE) << "Redirection from" << m_url << "to" << url << "REJECTED!";
175  q->setError(ERR_ACCESS_DENIED);
176  q->setErrorText(url.toDisplayString());
177  return;
178  }
179  m_redirectionURL = url; // We'll remember that when the job finishes
180  // Tell the user that we haven't finished yet
181  Q_EMIT q->redirection(q, m_redirectionURL);
182 }
183 
184 void StatJob::slotFinished()
185 {
186  Q_D(StatJob);
187 
188  if (!d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid()) {
189  // qCDebug(KIO_CORE) << "StatJob: Redirection to " << m_redirectionURL;
190  if (queryMetaData(QStringLiteral("permanent-redirect")) == QLatin1String("true")) {
191  Q_EMIT permanentRedirection(this, d->m_url, d->m_redirectionURL);
192  }
193 
194  if (d->m_redirectionHandlingEnabled) {
195  d->m_packedArgs.truncate(0);
196  QDataStream stream(&d->m_packedArgs, QIODevice::WriteOnly);
197  stream << d->m_redirectionURL;
198 
199  d->restartAfterRedirection(&d->m_redirectionURL);
200  return;
201  }
202  }
203 
204  // Return worker to the scheduler
206 }
207 
208 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 101)
209 void StatJob::slotMetaData(const KIO::MetaData &_metaData)
210 {
211  SimpleJob::slotMetaData(_metaData);
212 }
213 #endif
214 
215 StatJob *KIO::stat(const QUrl &url, JobFlags flags)
216 {
217  // Assume sideIsSource. Gets are more common than puts.
218  return statDetails(url, StatJob::SourceSide, KIO::StatDefaultDetails, flags);
219 }
220 
221 static bool isUrlValid(const QUrl &url)
222 {
223  if (!url.isValid()) {
224  qCWarning(KIO_CORE) << "Invalid url:" << url << ", cancelling job.";
225  return false;
226  }
227 
228  if (url.isLocalFile()) {
229  qCWarning(KIO_CORE) << "Url" << url << "already represents a local file, cancelling job.";
230  return false;
231  }
232 
233  if (KProtocolInfo::protocolClass(url.scheme()) != QLatin1String(":local")) {
234  qCWarning(KIO_CORE) << "Protocol Class of url" << url << ", isn't ':local', cancelling job.";
235  return false;
236  }
237 
238  return true;
239 }
240 
242 {
243  StatJob *job = statDetails(url, StatJob::SourceSide, KIO::StatDefaultDetails, flags);
244  if (!isUrlValid(url)) {
245  QTimer::singleShot(0, job, &StatJob::slotFinished);
246  Scheduler::cancelJob(job); // deletes the worker if not 0
247  }
248  return job;
249 }
250 
251 #if KIOCORE_BUILD_DEPRECATED_SINCE(4, 0)
252 StatJob *KIO::stat(const QUrl &url, bool sideIsSource, short int details, JobFlags flags)
253 {
254  // qCDebug(KIO_CORE) << "stat" << url;
255  KIO_ARGS << url;
256  StatJob *job = StatJobPrivate::newJob(url, CMD_STAT, packedArgs, flags);
257  job->setSide(sideIsSource ? StatJob::SourceSide : StatJob::DestinationSide);
258  job->setDetails(details);
259  return job;
260 }
261 #endif
262 
263 StatJob *KIO::statDetails(const QUrl &url, KIO::StatJob::StatSide side, KIO::StatDetails details, JobFlags flags)
264 {
265  // TODO KF6: rename to stat
266  // qCDebug(KIO_CORE) << "stat" << url;
267  KIO_ARGS << url;
268  StatJob *job = StatJobPrivate::newJob(url, CMD_STAT, packedArgs, flags);
269  job->setSide(side);
270  job->setDetails(details);
271  return job;
272 }
273 
274 #if KIOCORE_BUILD_DEPRECATED_SINCE(5, 69)
275 StatJob *KIO::stat(const QUrl &url, KIO::StatJob::StatSide side, short int details, JobFlags flags)
276 {
277  // qCDebug(KIO_CORE) << "stat" << url;
278  KIO_ARGS << url;
279  StatJob *job = StatJobPrivate::newJob(url, CMD_STAT, packedArgs, flags);
280  job->setSide(side);
281  job->setDetails(details);
282  return job;
283 }
284 #endif
285 
286 #include "moc_statjob.cpp"
KIOCORE_EXPORT KIO::StatDetails detailsToStatDetails(int details)
Converts the legacy stat details int to a StatDetail Flag.
Definition: statjob.cpp:99
virtual void registerJob(KJob *job)
QString number(int n, int base)
Q_EMITQ_EMIT
QString scheme() const const
@ StatTime
atime, mtime, btime
Definition: global.h:373
@ StatAcl
ACL data.
Definition: global.h:377
Q_SCRIPTABLE Q_NOREPLY void start()
void setSide(StatSide side)
A stat() can have two meanings.
Definition: statjob.cpp:77
@ StatInode
dev, inode
Definition: global.h:379
const QUrl & url() const
Returns the SimpleJob's URL.
Definition: simplejob.cpp:70
bool authorizeUrlAction(const QString &action, const QUrl &baseURL, const QUrl &destURL)
Returns whether a certain URL related action is authorized.
QString queryMetaData(const QString &key)
Query meta data received from the worker.
Definition: job.cpp:217
QUrl mostLocalUrl() const
most local URL
Definition: statjob.cpp:120
KIOCORE_EXPORT KJobTrackerInterface * getJobTracker()
Returns the job tracker to be used by all KIO jobs (in which HideProgressInfo is not set)
Definition: jobtracker.cpp:14
@ StatUser
uid, gid
Definition: global.h:371
QString stringValue(uint field) const
Definition: udsentry.cpp:376
bool isValid() const const
virtual void slotFinished()
Called when the worker marks the job as finished.
Definition: simplejob.cpp:200
void permanentRedirection(KIO::Job *job, const QUrl &fromUrl, const QUrl &toUrl)
Signals a permanent redirection.
@ StatResolveSymlink
Resolve symlinks.
Definition: global.h:375
virtual void slotMetaData(const KIO::MetaData &_metaData)
MetaData from the worker is received.
Definition: simplejob.cpp:302
bool isEmpty() const const
QUrl fromLocalFile(const QString &localFile)
StatDetail
Describes the fields that a stat command will retrieve.
Definition: global.h:365
KIOCORE_EXPORT KJobUiDelegate * createDefaultJobUiDelegate()
Convenience method: use default factory, if there's one, to create a delegate and return it.
void setFinishedNotificationHidden(bool hide=true)
void setDetails(KIO::StatDetails details)
Selects the level of details we want.
Definition: statjob.cpp:82
@ StatBasic
Filename, access, type, size, linkdest.
Definition: global.h:369
const UDSEntry & statResult() const
Result of the stat operation.
Definition: statjob.cpp:115
@ UDS_LOCAL_PATH
A local file path if the KIO worker display files sitting on the local filesystem (but in another hie...
Definition: udsentry.h:252
bool isLocalFile() const const
void setUiDelegate(KJobUiDelegate *delegate)
KIOCORE_EXPORT StatJob * statDetails(const QUrl &url, KIO::StatJob::StatSide side, KIO::StatDetails details=KIO::StatDefaultDetails, JobFlags flags=DefaultFlags)
Find all details for one file or directory.
Definition: statjob.cpp:263
A namespace for KIO globals.
@ HideProgressInfo
Hide progress information dialog, i.e. don't show a GUI.
Definition: job_base.h:275
static void cancelJob(SimpleJob *job)
Stop the execution of a job.
Definition: scheduler.cpp:795
KIOCORE_EXPORT StatJob * stat(const QUrl &url, JobFlags flags=DefaultFlags)
Find all details for one file or directory.
Definition: statjob.cpp:215
KIOCORE_EXPORT StatJob * mostLocalUrl(const QUrl &url, JobFlags flags=DefaultFlags)
Tries to map a local URL for the given URL, using a KIO job.
Definition: statjob.cpp:241
Q_D(Todo)
@ StatDefaultDetails
Default StatDetail flag when creating a StatJob.
Definition: global.h:389
static QString protocolClass(const QString &protocol)
Returns the protocol class for the specified protocol.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Nov 30 2023 03:52:32 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.